Notes by Alisha Ukani
Virtual Memory
early_pagetable[1]
covers 512GB of address space bc it has 512 entries (it's 4096 bytes) and each level 3 pagetable entry covers 1 GB of address space (and, with aPTE_PS
entry, 1GB of physical memory)- Entries 0, 256, and 511 of
early_pagetable[0]
point toearly_pagetable[1]
- So, virtual addresses 0 to 0x80'0000'0000, 0xffff'8000'0000'0000, and some other regions can access canonical physical addresses (but see below)
- The virtual address regions that can access canonical physical addresses alternate with regions that can access non-canonical addresses
- Only 510GB of address space is directly mapped in
early_pagetable[1]
- Entry 510 of
early_pagetable[1]
points to physical address 0x0 - Entry 511 points to physical address 1G (0x4000'0000)
- Entry 510 of
- Physical memory between 2G and 509 G are pointed to once
- 0x0000'8000'0000'0000 is the lowest non-canonical address, 0xffff'7fff'ffff'ffff is the highest non-canonical address
In paper notes: line of code for last diagram:
early_pagetable->entry[0] = early_pagetable->entry[256];
early_pagetable[2].entry[510] = 0 | PTE_P | PTE_W | PTE_PS;
early_pagetable[2].entry[511] = (1 << 30) | PTE_P | PTE_W | PTE_PS;
Where things are
- Virtual addresses 0 to 0x7f'8000'0000 are just for boot
- Virtual addresses 0xffff'8000'0000'0000 to ??? are just for kernel
- The top 2GB of memory have the kernel text addresses
Context switches
- Goal is to switch from one logical thread of control to another, allowing resumption
- Logical thread of control = some registers and a stack (in terms of the machine)
- Even the kernel has one!
- Requirements:
- Save the state of the yielding logical thread
- Choose a new logical thread
- Resume the chosen logical thread
- We need hardware support if we're changing privilege as we change threads
WeensyOS
- WeensyOS is not suspendable, only uniprocessor
- We use interrupts as one method of hardware support that we use
- The kernel runs an
exception()
function (so%rip
is different from process)- So, the hardware MUST save
%rip
,%cs
(code segment, contains privilege),%rsp
, stack segment (%ss
),%rflags
- So, the hardware MUST save
- Kernel pushes the saved registers onto the kernel stack, which is configured
- When kernel is loading the user process again, it pops the registers from its stack and then restores the registers
Idea: what if we can teach programmers about privilege by making an analogy to privileged code in the systems context?