CS452 - Real-Time Programming - Spring 2008
Lecture 9 - Kernel Code
Questions & Comments
- Hand back the first assignment, with comments.
- PSW
- TD of active
- interrupts
- Trains lab
Hardware Facts for Eos
Memory Map
- 0x000000 to 0x09FFFF: low memory (size is 640K)
- 0x0A0000 to 0x0FFFFF: VGA, etc (size is 360K)
- 0x100000 to 0x1XXXXF: your kernel (size is determined by you)
- (Ox1XXXXF + 0x1) to 0x1FFFFF: free memory for tasks (size is the
remainder of 2 Mbyte)
Devices
Accessed by special I/O instructions
Architecture of X86
General Purpose Registers
- E[A-D]X: general purpose registers
- ESP: the stack pointer
- EBP: the base pointer
- ESI, EDI: ??
All these registers have special names for the low 16 bits. (drop the E),
and for the low 8 bits (add an L), and for the second 8 bits (add an H)
Addressing Memory
Physical address is
- start of segment + offset
Helps to provide
- position independent (relocatable) code
- memory protection
- program owns segment(s)
- segment has low and high limits
- program can't access outside the limits
Six segment registers
- CS
- DS
- ES
- FS
- GS
- SS
Each segment register is an index into a Global Descriptor Table (GDT),
which contains
- low limit
- high limit
- etc.
Index is actually contents of register >> 3.
Setting up a Task
Every task requires at least two GDTs
- accessed through CS and DS
- This includes the kernel
The compiler assumes that DS = SS
- That is, the stack is in the data segment.
Set DS = ES = FS = GS = SS for each task
There is no GDT in place when the kernel boots
How is this done
- The address of the table is kept in the special register GDTR
- lgdt sets GDTR; sgdt reads GDTR
Yet another register EFLAGS contains processor state such as
- condition codes
- what is enabled
- Getting started you want to have interrupts disabled!
Setting up a tas
- CS points to code in ELF executable
- DS points to memory you allocate for the task.
Context Switch in the 386
int <vector>
- pushes EFLAGS, CS, EIP onto the active task's stack
- finds entry
<vector> in the interrupt descriptor
table (IDT)
- jumps to the address in the
IDT[<vector>]
iretl
- pops EFLAGS, CS, EIP from the active task's stack
- puts them in the registers
Task to kernel
int <vector> in task
pushal saves all the active task's registers on the active
task's stack
- switch to kernel stack
- you got CS, EIP from IDT
- ESP from your magic place
- DS from the kernel variables
- restore remainder of kernel state from stack
Kernel to task
- save kernel state on kernel stack
- switch to active task's stack
- restore general purpose registers:
popal
- iretl gets EFLAGS, CS, EIP from the task stack.
To get a task going
- Set up its stack so that it's all ready to run its first
instruction
- Schedule
- Kernel to task
For the first user task there is only one possibility for active.
Return to: