| 6.097: OPERATING SYSTEM ENGINEERING |
| Fall 2002 |
| Lab 3 Solutions |
These solutions were derived in part from work by Jason Gift.
start: (locore.S) | Sets up the initial GDT and CS and ESP so that C code can run. |
i386_init() | Calls all initialization routines and creates an environment (or two) |
cninit() | Intializes the console. |
i386_detect_memory() | Discovers how much physical RAM the system has |
i386_vm_init() | Sets up the initial page directory and page tables for the kernel and allocates space for __envs[] and ppages[] |
ppage_init() | Sets up ppages[] to reflect what has actually been used so far, and puts free pages on free list. |
idt_init() | Sets up the interrupt descriptor table (tells the processor where it is and adds entries to it for the defined handlers) |
pic_init() | Initializes the programmable interrupt controller and masks all interrupts |
clock_init() | Sets up the clock to generate 100 interrupts a second and unmasks the clock interrupt in the PIC |
env_init() | Marks all envs are free and adds them to the free env list |
env_create() | Creates an environment for a binary (e.g. spin), and loads the binary |
yield() | Searches for the next runnable env and runs it (does it in a round-robin fashion so that no env gets precedence over another) |
env_run() | Saves register of old env, and
switches to the new env, calls env_pop_tf() to start it
running |
env_pop_tf() | Restores the registers in the trapframe into the CPU's register. |
setgate was 3. This value allows the user process,
running at CPL = 3, to invoke the break point
with "int $0x3". Otherwise (CPL != 3), the user
does not have permission, so GPF is generated.
Note: setgate() should not set up any handlers as trap
gates. In a trap gate, the CPU will not clear the FL_IF
of the %eflags register when the exception occurs,
leaving interrupts enabled. We do not want interrupts to be enabled
while we are executing in the kernel. This would seriously complicate
kernel programming. Thus, all gates should be set as interrupt gates.
The registers from one "alice" process could be restored into the other "alice" process without generating an error.
As some people pointed out, if env_run() never saves
registers, the original register set will be continually restored.
The process will be started over at the initially point in the code;
never making progress, and never dividing by zero. However, this
error exists even if there is just one process.
ULIM) is identical.
And since we are executing in the kernel the VA address of 'e' is
above ULIM. Thus, after the page directory is switched,
'e' still (and all of the kernel VA space) translates to the same
physical address as before the switch.