CS 452/652 Winter 2022 - Kernel (Part 1)

(Version: 1)

Due Date: Wed, Jan 26, 9:00am


In the first part of your development of the kernel, you make it possible to create and run a task. To do so you need to have working
  1. a context switch in and out of the kernel,
  2. a collection of task descriptors,
  3. a request mechanism for providing arguments and returning results,
  4. priority queues for scheduling, and
  5. kernel algorithms for manipulating task descriptors and ready queues.
It is not necessary to implement memory management or protection, but you must not have any task accessing the kernel's or another task's memory at any time. It is necessary for the kernel to access task memory, because the kernel must copy messages that are presented to it in the form of pointers. It might happen as a result of programming bugs that you inadvertently overwrite kernel memory from a user task. This is considered to be a bug, and usually, but not always, acts like a bug.

In addition to the kernel primitives, you must program the first user task, and another task. These tasks will provide the marker with a test of your task creation, your context switch, and your task scheduling.



To accomplish this part of the kernel you must have the following kernel primitives operating:

int Create(int priority, void (*function)()),
int MyTid(),
int MyParentTid(),
void Yield(), and
void Exit().

See the kernel description for details of how these primitives should operate.

Yield() does not play a role in future assignments. It is implemented in this part of kernel development in order to make it possible to test the kernel in its incomplete state.

In addition you must program a first user task, which is the task automatically started by the kernel as part of its initialization, and a user task, which is to be instantiated four times.

The first user task is responsible for bootstrapping the application into existence by creating other user tasks. An operating system similar to single-user Unix could be built on top of your kernel by having the first user task login the user and providing an interactive shell after a successful login. You are not required to make your first user task login or a shell, but you are also not forbidden to do so. The other tasks, of which there will be four instances, are remainder of the application.

User Tasks

The following user tasks test your kernel.

First User Task

The first user task should create four instances of a test task.

The Other Tasks

The tasks created by the first user task have the same code, but possibly different data.

Hand In

Hand in the following, nicely formatted.
  1. A pointer to your code repository, readable by the TAs and instructor, containing the source code of your assignment, instructions how to make the executable, and documentation (see below). The code and documentation must remain unmodified after submission until the assignments have been marked. Email the commit SHA to the instructor before the deadline.
  2. A description of how to access, make, and operate your program in a README file, including the full pathname of your executable file, which we might download for testing.
  3. The names of your group members in the same README file.
  4. A description of the structure of your kernel so far. We will judge your kernel primarily on the basis of this description. Describe which algorithms and data structures you used and why you chose them. Describe your choices for critical system parameters and limitations, such as stack size, maximum number of tasks, etc.
  5. The output produced by your program and an explanation of why it occurs in the order it does.
  6. Note that we intend to perform code reviews with students. A TA/instructor and might contact you to set up a (virtual) meeting.