All pastes #773160 Raw Edit

Something

public text v1 · immutable
·published 2007-11-14 09:25 UTC
rendered paste body
Overview of address space handling:

-For simplicity (so that kernel code doesn't need to change) we map kernel
 memory directly from logical to physical addresses.
-Threads are part of the kernel; they use the kernel's page directory and page
 table.
-Use each logical address only once over all processes. That should simplify
 some things.
 HOWEVER:
 -Screen memory will be mapped into each process's address space at the same
  address for each process.
 -Kernel memory will be mapped from logical to physical without translation
  everywhere. While a process rarely needs direct access to kernel memory,
  this will probably simplify some things like system calls.
-As the stack is pinned we don't need to handle it in paging code. For
 simplicity we can have the stack at the same logical address in each process.
 If there are problems with that we give it a logical address resulting from
 adding a fixed offset to the stack's *physical* address.
-I'm not sure yet how to handle concurrency. We need one spinlock for each
 group of data structures that needs internal consistency.
-I have not said anything about privilege bits. The kernel would still work if
 every process was allowed access to every memory location. Protection would be
 a "nice to have". In a real OS it is vital, of course.


init_memory():
-Set up the page directory and page table for kernel space. We will only need
 one page table as it can cover 4 MB which is enough.
-Set the paging flag in CR0 to enable paging
-Set up a data structure to keep track of free pages. As we only have 29 pages
 to take care of, a simple bitmap in a (32 bit) integer might suffice.

setup_page_table():
-Set up the page directory, page table, and pages for code and data.
-Mark the code and data pages as not present.
-page_alloc(TRUE) a physical page for the stack and set up a page for the
 stack.
-Mark the stack page as present.

page_fault_handler():
-ASSERT() that the fault address actually belongs to the process using the
 pcb's swap_size entry. In a real OS we'd terminate the process if that
 happened (SIGSEGV on Linux).
-Call page_swap_in()

page_alloc():
-page_swap_out() a random page to floppy if no physical page is available.
 To do this we might need to search through all pcbs if we don't keep track
 of allocations in some other way. See description of init_memory().
-It is simpler to first choose a random process and then a random page in that
 process than to choose a truly random page. The simpler method has the
 disadvantage that not every page will have the same chance of getting swapped
 out.

page_swap_in():
-We can assume that the page belongs to the current_running process.
-Call page_alloc() to allocate physical page.
-Find the sectors we need to swap in using the pcb's fault_addr and swap_loc
 entries.
-Read the sectors from floppy
-Mark the page as present.

page_swap_out():
-Find the process to which the page belongs. This is simplified by the fact
 that every logical address in the address range of processes is only mapped
 in one process.
 Still, we usually need to search through some pcbs until we find the right
 one. This can be improved by some special data structure in the kernel...
-Write the page to diskette
-In the data structure keeping track of free pages, mark the physical page as
 free. (In practice we can leave it marked as busy because it will be reused
 right away.)
-In the page table of the process whose page we swapped out, mark the page as
 not present.