Chapter 4. Overview of the Projects

Table of Contents

1. Project Descriptions
2. Required Software
3. Setting Up the GeekOS Distribution
4. Starting a Project
5. Continuing to a New Project
6. Compiling a Project
7. Running GeekOS Using Bochs
8. Troubleshooting
9. Project Hints

This chapter gives a brief overview of the projects in which you will add important new functionality to the GeekOS kernel. It also discusses all of the requirements for compiling and running GeekOS.

1. Project Descriptions

There are a total of seven projects. For the most part, each project builds on the one before it, so you will need to do them in order. The projects were originally developed as part of a senior level undergraduate operating systems course, so the complete sequence will require a significant amount of effort to complete. Some projects will be more difficult than others; in particular, the virtual memory project (Chapter 9, Project 4: Virtual Memory) and the filesystem project (Chapter 10, Project 5: A Filesystem) require you to write a fairly large amount of code (several hundred to a thousand lines of code for each project). The good news is that when you complete the last project, GeekOS will be a functional operating system, capable of running multiple process with full memory protection.

Project 0 (Chapter 5, Project 0: Getting Started) serves as an introduction to modifying, building, and running GeekOS. You will add a kernel thread to read keys from the keyboard and echo them to the screen.

For Project 1 (Chapter 6, Project 1: Loading Executable Files), you become familiar with the structure of an executable file. You are provided with code for loading and running executable files, but you need to first become familiar with the ELF file format, then write code to parse the provided file and pass it to the loader.

In Project 2 (Chapter 7, Project 2: Adding Processes), you will add support for user mode processes. Rather than using virtual memory to provide separate user address spaces, this project uses segmentation, which is simpler to understand.

Project 3 (Chapter 8, Project 3: Scheduling) improves the GeekOS scheduler and adds support for semaphores to coordinate multiple processes.

Project 4 (Chapter 9, Project 4: Virtual Memory) replaces the segmentation based user memory protection added in Project 1 with paged virtual memory. Pages of memory can be stored on disk in order to free up RAM when the demand for memory exceeds the amount available.

Project 5 (Chapter 10, Project 5: A Filesystem) adds a hierarchical read/write filesystem to GeekOS.

Project 6 (Chapter 11, Project 6: ACLs and Inter-process Communication) adds access control lists (ACLs) to the filesystem, and adds interprocess communication using anonymous half-duplex pipes. Upon the completion of this project, GeekOS will resemble a very simple version of Unix.

2. Required Software

Compiling GeekOS requires a number of tools. The good news is that if you are running on a Linux/x86 or FreeBSD/x86 system, or if you are running Cygwin on Windows, you probably have most or all of the software you need to compile GeekOS already installed. If you don't, it is generally not too difficult to obtain the required software.

The following is a complete list of software needed to compile GeekOS.

  • gcc, version 2.95.2 or later, targeting any i386/ELF platform, or targeting PECOFF under Cygwin

  • Any ANSI-compliant C compiler for the host platform (the computer you are planning to compile GeekOS on); unless you are cross-compiling, this can be the same compiler you use to compile GeekOS

  • GNU binutils, targeting any i386/ELF platform, or PECOFF under Cygwin; you probably already have this if you have gcc

  • GNU Make; the GeekOS makefile will not work with other versions of make

  • Perl, version 5 or later

  • egrep

  • AWK

  • diff3

  • NASM; on Linux or FreeBSD systems, this is probably the only required software not already installed

3. Setting Up the GeekOS Distribution

Projects will be accomplished in groups (nominally 2 persons in each group). Each group will have an account defined. The login names for the accounts are Group0, Group1, Group2, etc. There are also Unix file access groups defined, with names group0, group1, group2, etc. These unix groups are the primary group for each of the Group accounts. Once the students working together in a group have been defined, the students' individual logins will be added to the membership of the appropriate unix group.

For example, suppose students Alan Turing, with login turing_a, and Fred Brooks, with login brooks_f are working together in group 2. The shared account would be Group2, and the membership of unix group group2 would include Group2, turing_a, and brooks_f.

We will use the Group account to store the CVS repository, and will create a separate project within the CVS repository for each of the seven GeekOS projects. The Group account will also be used for storage of the full GeekOS distribution, and as a staging area as we import the set of files for each project into their respective CVS repository project tree.

Editing of files and building versions of your GeekOS kernel will not occur in the Group account. We will use the facilities of CVS to create a working copy of the files into an area in each students' individual accounts. This working area is known as a sandbox. Within the sandbox, files will be created and/or edited, and then compiled, and tested. Once a stable set of changes have been made, these will be reflected back into the CVS repository in the group account through a commit operation. More on CVS as we go along.

We use the unix group file access controls to allow individual group members to read and write the files in the shared Group account. We must make sure, however, that once one member creates or writes a file, that other members may subsequently write the same file. To do this, we need to make sure that all files and directories created by any of the members of the group have file system rights for the group members.  To do this, we need to take two steps.  First, the home directory of the group should have the sgid (set group id) bit set for both owner and group.  Second, we change the umask to open up permissions for group members.

First, login to your Group account and take the following steps:

$ cd
$ chmod ug+rwxs .
$ umask 0007

[Note] Note

This document assumes that you are using a Unix-like system such as Linux, FreeBSD, or MacOS/X, and that you are using the bash shell, or a similar shell such as the Bourne (/bin/sh) or Korn (/bin/ksh) shells.

Test these instructions by logging into your individual account and try creating a file in the Group account. Be sure and first set your umask to 0007 as we did above. The created file should be owned by the student user, but should be assigned to the unix group and should be readable and writeable by both user and group. For the scenario given above, a created file foo would look as follows by an 'ls -l':

-rw-rw---- 1 turing_a group2 0 Aug 14 08:12 foo

If this is successful, then it is time to lay down the GeekOS distribution in the group account. A GeekOS distribution is a file whose name looks like geekos-version.zip. For example, let's say you are using GeekOS version 0.3.0. The distribution is geekos-0.3.0.zip (and is available at the link). Log into your Group account and download the distribution into the home directory of the account.

For illustration, we will continue to use Group2 as the example group. To install the distribution, execute the following commands from the Group account:

$ cd
$ umask 0007
$ unzip geekos-0.3.0.zip
$ rm geekos-0.3.0.zip
$ mkdir import
$ mkdir repository
$ CVSROOT=/home/Group2/repository
$ export CVSROOT
$ cvs init

Edit your .bash_profile in your individual accounts so that you can automate the setting of umask and the shell environment variables that are needed during GeekOS development. Login to your account and add the following commands to your .bash_profile in the appropriate places:

umask 0007
CVSROOT=/home/Group2/repository
export CVSROOT
GEEKOS_HOME=/home/Group2/geekos-0.3.0
export GEEKOS_HOME
PATH=$GEEKOS_HOME/scripts:$PATH
export PATH

4. Starting a Project

Once you have installed the GeekOS distribution and all of the software required to compile it, you are ready to extract Project 0. If you are using CVS, then the steps include first the extraction of Project0 (in the group directory) and then the import of the Project0 files into the CVS repository.  Once the files have been imported, users can log in to their individual accounts and work on the project.

 Let's say you have chosen the directory /home/Group1/import to contain the directory for this project. Then you would run the following command:

$ cd /home/Group1/import
$ startProject project0 $GEEKOS_HOME/src

This will create a directory /home/Group1/import/project0 containing the GeekOS source code, ready to be imported
into CVS as the initial version..

[Important]Important

It is an extremely good idea to use CVS or a similar version control system to store your project files. Each time you reach a stable point in your project, commit the source files. That way, you will always be able to revert to a stable version if something goes wrong with your code.

$ cd /home/Group1/import/project0
$ cvs import -m 'Import following startProject of project0' project0 vendor start

5. Continuing to a New Project

Each project contains a slightly different version of the base GeekOS system. For example, the buffer cache system is introduced in the fourth project because it is required by the filesystem. Also, code is sometimes removed because it is no longer needed.

To make it easy for you to move your code from one project to the next, the startProject script can automatically merge your code from the previous project into the code for the new project. For example, let's say you have completed Project 0 and are ready to move onto Project 1. You would run the following commands:

$ cd /home/group1/cs372/import
$ startProject project1 $GEEKOS_HOME/src <location of latest project0>
$ cd project1
$ cvs import -m 'Import following startProject of project1' project1 vendor start

Although the process of incorporating your old code into the new project is largely automatic, you will sometimes see messages like the following:

Warning: Conflicts detected in merge of file src/geekos/main.c

When you look at the file in the new project directory that was reported to contain a merge conflict, you will see something like the following:

<<<<<<< Your version of src/geekos/main.c
=======
static void Mount_Filesystems(void);
static void Spawn_Init_Process(void);
>>>>>>> Master version of src/geekos/main.c from project1

In this case, two function prototypes were added to the source file src/geekos/main.c.

Note that the merge operation inserted these markers into the source code, and this version of the source code has now been imported into CVS as the first version of this project maintained in the CVS repository.  To remedy any conflicts, you will login to your individual account and checkout this newly created project into your working area, and then start resolving any conflicts. 

In general, you should resolve conflicts by simply deleting the conflict markers (the lines reading "<<<<<<<", "=======", and ">>>>>>>"). This will have the effect of including the code from both your previous project and the new code from the master source for the new project. Sometimes you will need to comment out code from your previous project that will not be needed in the new project.

When you have removed all of the conflict markers, you can start working on getting the project to compile. Once the code compiles, you can start working on adding the new features that the project requires.

6. CVS Checkout and Working in your Individual Account

Development work should be constrained to your individual account.  The basic process works as follows:

  1. You use CVS to checkout a version of the project you want to work on.  With no additional arguments, this retrieves the latest version that has been committed to the CVS repository.  The checkout operation copies the CVS maintained files into a local directory named the same as the project.  This is your sandbox or workspace

  2. Within this checkout target directory structure, you develop in the normal manner, modifying source files and using make to build new versions of the software.

  3. When your development reaches a stable point, or when you wish to share your current version of the source files with other members of your group, you commit those changes back to the CVS repository.

  4. If, during the course of development, you have added new directories or new source files that you wish to also be maintained by CVS, these elements need to be added to the CVS repository.

  5. If your group partner has committed changes to the CVS repository and you want these changes to be reflected in your own sandbox, you perform an update operation to synchronize your sandbox with the CVS repository.

7. Compiling a Project

Once you have used the startProject script to create a an initial version of your project, and you have imported the initial version into CVS, and you have installed all of the software required to compile GeekOS, it should be a simple matter to compile the project. Let's say you are going to compile Project 0. Assuming you have set your CVSROOT environment variable appropriately, here are the commands you would use:

$ mkdir -p /home/fred/cs372/sandbox
$ cd /home/fred/cs372/sandbox
$ cvs checkout project0
$ cd project0/build
$ make depend
$ make

7. Running GeekOS Using Bochs

Although GeekOS targets a real hardware platform, it is intended to be run in the Bochs PC emulator. Bochs runs as an ordinary user process in your host operating system, and is available for most common operating systems. We recommend that you use Bochs version 2.0 or later; as of the time of this writing, the latest version of Bochs is 2.1.1, which works well with GeekOS.

Once you have installed Bochs, you will need to edit the file build/.bochsrc in the working directory for your project. In this file, you will see two entries that look like the following:

# You will need to edit these lines to reflect your system.
vgaromimage: /software/bochs-2.0.2/share/bochs/VGABIOS-lgpl-latest
romimage: file=/software/bochs-2.0.2/share/bochs/BIOS-bochs-latest, address=0xf0000

You should change the lines beginning vgaromimage and romimage so that they reflect the directory in which you installed Bochs. For example, if you installed Bochs in the directory /usr/local/bochs-2.1, you should replace the occurrences of /software with /usr/local/bochs-2.1.

After editing the .bochsrc file, you are ready to start bochs. Add the directory containing the bochs executable to your PATH environment, and then invoke the bochs command from within the build directory of the project. You be prompted with a set of options. Choose Begin simulation, or simply hit the Enter or Return key to choose the default.

If GeekOS has been compiled successfully, and Bochs is configured properly, a window should appear emulating the VGA text screen. You are now running GeekOS!

8. Troubleshooting

If GeekOS does not run correctly, look at the file bochs.out produced in the build directory of the project. If errors prevented Bochs from running, or if GeekOS crashed, this file will usually contain diagnostic information which identifies the problem.

9. Project Hints

Every project contains placeholders indicating where you need to add code. These placeholders use the TODO macro. Here is an example from Project 0:

TODO("Start a kernel thread to echo pressed keys");

These placeholders are often accompanied by a comment giving you ideas about how to approach the new functionality that needs to be added.