Review session 07 Notes Section 1: Homework problems - Page walk: +------------+ +------------+ +------------+ +------------+ 0xf0f02ffc | 0xf00f3007 | 0xff005ffc | 0xbebeebee | 0xffff1ffc | 0xd5202007 | 0xffff5ffc | 0xdeadbeef | +------------+ +------------+ +------------+ +------------+ | ... | | ... | | ... | | ... | +------------+ +------------+ +------------+ +------------+ 0xf0f02800 | 0xff005007 | 0xff005800 | 0xf00f8000 | 0xffff1800 | 0xef005007 | 0xffff5800 | 0xff005000 | +------------+ +------------+ +------------+ +------------+ | ... | | ... | | ... | | ... | +------------+ +------------+ +------------+ +------------+ 0xf0f02000 | 0xffff5007 | 0xff005000 | 0xc5201000 | 0xffff1000 | 0xf0f02007 | 0xffff5000 | 0xc5202000 | +------------+ +------------+ +------------+ +------------+ The content of %cr3 (the pointer to the page directory) is 0xffff1000. Output of this is: int *ptr1 = (int *) 0x0; int *ptr2 = (int *) 0x200ffc; printf("%x\n", *ptr1); printf("%x\n", *ptr2); answer: 0xc5202000 0xbebeebee - TLB / page faults Assuming 0x200000 and 0x300000 are stored on disk [context switch - tlb is flushed (x86)] 0x500 movl 0x200000, %eax # move data in address 0x200000 to register %eax 0x504 incl %eax, 1 # add one to %eax 0x508 movl %eax, 0x300000 # move register %eax to memory location 0x300000 0x512 push %ecx # push %ecx onto the stack How many tlb misses? 3 (0x500, 0x200000, 0x300000) How many page faults? 3 (0x200000, 0x300000, ) Section 2: MemOS Lab hints and tips - Kernel virtual address Kernel is setup to use an identity mapping [0, MEM_PHYSICAL) -> [0, MEM_PHYSICAL) - Physical pages' meta data is recorded in page_info array, whose elements contains refcount, owner owner can be kernel, reserved, free, or pid - Process control block: * Your usual process registers, process state * Process page table - a pointer (kernel virtual address - identical physical address) to a page directory page directory's first entry points to a page table Our job mainly consists of manipulating the page tables, and page info array - High level evolution of the lab: We have five programs: kernel + 4 processes Ex1. five guys share the same page table. virtual addresses are all PTE_U | PTE_P | PTE_W Job: mark some of the addresses as (PTE_P | PTE_W), i.e. not user accessible Ex2. Each program uses its own page table. kernel already has a page table The job is to allocate and populate a page table for each process. The process break-down as helper functions: 1. allocate a new page for process pid, and zero it (important) 2. alloc two pages, use one as page dir, the other as snd level page table, connect pgdir -> pgtbl by populating the first entry with proper value 3. populate the snd level pagetable, we memcpy kernel's In order to achieve the screenshot, after memcpying, we have to mark [prog_addr_start, virtual_addr_size) as not-present. Ex3. Physical page allocation Motivation: Before this, during sys_page_alloc, when process asks for a specific virtual page, the identity mapping is employed to find the physical page. But it is too restrictive and with virtual memory, the process does not really care which physical page it gets If we have implemented the function 1 mentioned in Ex2, then we are mostly good to go and just use that function. We also need to connect virtual-physical by setting the corresponding page table entry. Use virtual_memory_map Ex4. Overlapping virtual addresses Motivation: Every process has its own page table & accessible virtual addresses (PTE_P portions), we don't need to restrict processes to use different parts of the virtual memory. They can overlap, as long as the physical pages backing them are not overlapped. Easy to do: in process_setup, we just use (MEM_PHYSICAL - PAGESIZE) instead of the complicated arithmetic Ex5. Fork High level goal: Produce a mostly identical process (minus the reg_eax). What does it mean to be an identical process?? 1 same binary 2 same process registers 3 AND same memory state / contents 3 basically covers 1 because the binary is loaded in memory too. 2 is easy to achieve (lab 1) The goal here is mainly to achieve 3. Fork creates a copy: the memory state has to a copy! Question: What does it mean to make a copy of memory? - They are backed by physical pages, so we alloc new physical pages and copy the content to new pages (memcpy) - Then connect virtual to physical by setting the page table The address space is potentially 4GB large, do we copy 4GB? How do we know which parts to copy? - Walk down the second level page table, find pages that is (PTE_P | PTE_U | PTE_W) Given a page table entry, how do you check if it is user RW-able? Filling the blanks: pte_val _ (PTE_P | PTE_W | PTE_U) == ___ How do you find its corresponding physical page? PTE_ADDR - Useful functions to implement for said manipulations: * find a PO_FREE physical page and assign it to a process (Useful for ex2, 3, 4, 5) * allocate empty page dir + page table for a process (Ex2, 4) * make a copy of existing page table and assign it to a process (Ex2, 5) * implement your own helper functions as you see fit Tip: Zero the allocated page before using it!! (memset) - Some useful functions/macros: PTE_ADDR : PTE_ENTRY -> Physical address PAGENUMBER : a phyiscal address -> corresponding index into page info array PAGEADDR : PAGENUMBER^{-1} virtual_memory_lookup(pagetable, va) Q&A