OSD Home

Resolving memory conflicts created by multitasking

If you have multitasking, you have multiple tasks in memory. Will they all occupy the same address? How will you prevent conflicts?

Address translation

This means the virtual addresses generated by a program are different from the physical addresses that go onto the address bus; to the memory chips. The translation of virtual addresses to physical addresses is performed by special hardware inside the CPU called a memory management unit (MMU).

Address translation can be used for the kernel as well as the tasks. This lets you link the kernel to run at a specific address, but load the kernel anywhere in memory.

Besides address translation, the MMU usually provides memory protection. Ranges of memory can be made to cause a page fault or general protection fault by any combination of

x86 segment-based address translation

Linear address translation. Every byte in the address space has the same virtual-to-physical conversion value. If you want different v-to-p values, you need multiple segments (and therefore far pointers).

The v-to-p value is simply the segment base address.

Example: a kernel compiled to run at virtual address C0000000h (3 gig) but loaded to physical address 00100000h (1 meg). The kernel will run properly if the segment base addresses are set to 40100000h:

virtual address generated by kernel code + conversion value (i.e. segment base address) = physical address
C0000000h (3 gig) + 40100000h = 00100000h (1 meg)

Advantages of segmentation over paging:

The only freely-available C compiler that supports both 32-bit code and multiple segments is Watcom C. See http://www.openwatcom.org

Page-based address translation

Non-linear address translation. Each 4K page can have a different v-to-p value.

The v-to-p values come from a system of page tables, created and stored in memory.

Advantages of paging over segmentation:

Translation of virtual addresses to physical addresses, using 2-level paging as found on x86. In this image, note:

Paged address spaces

Identity-mapped memory

For identity-mapped memory, the page tables are programmed so that no address translation is performed (virtual addresses = physical). These pages are still subject to page-based protection. Kernel memory must be identity-mapped while paging is initialized. From 'Intel Architecture Software Developer's Manual':
        17.22.3. Enabling and Disabling Paging

        Paging is enabled and disabled by loading a value into
        control register CR0 that modifies the PG flag. For
        backward and forward compatibility with all Intel
        Architecture processors, Intel recommends that the
        following operations be performed when enabling or
        disabling paging:

        1. Execute a MOV CR0,REG instruction to either set
           (enable paging) or clear (disable paging) the PG flag.
        2. Execute a near JMP instruction.

        The sequence bounded by the MOV and JMP instructions
        should be identity mapped (that is, the instructions
        should reside on a page whose linear and physical
        addresses are identical).
The page table entries used to identity-map kernel memory can be deleted once paging and virtual addresses are enabled.

If you want to run 32-bit code in the BIOS ROMs (e.g. PCI BIOS), the ROMs must also be identity-mapped.

Many kernel data structures are <= 4K in size. Since memory fragmentation is not an issue for these, they may be stored in identity-mapped memory or kernel virtual memory, whichever is more convenient.

Inaccessible memory

The task virtual memory for a task other than the current task can not be accessed unless:
  1. the memory for the other task is shared with the current task
  2. the memory is (temporarily) shared with the kernel
  3. the kernel switches address spaces.
Switching address spaces causes the TLB to be reloaded. This is slow, and should be avoided unless the task in the new address space is the next task to run. (In other words, switching address spaces should be done only by the scheduler.)

DMA restrictions on virtual memory

Since DMA operates directly on memory, it doesn't know about virtual addresses. There are several ways to handle this:

Code snippets

Links

A good introduction to paging, with nice graphics: http://www.embedded.com/98/9806fe2.htm
Linux VM commentary: http://www.csn.ul.ie/~mel/projects/vm/. Also discusses the buddy algorithm and slab allocator.
Tim Robinson's virtual memory tutorials: http://www.gaat.freeserve.co.uk/tutes

VM systems of popular OSes:

Virtual memory tutorial: http://www.cne.gmu.edu/modules/vm/submap.html
Alexei Frounze's paging tutorial: http://alexfru.chat.ru/epm.html#pagetrans
Chris Giese's paging demo: http://my.execpc.com/~geezer/os/paging.zip

TO DO

- Demand-loading.
- Shared memory between tasks, for IPC or DLLs. Shared copy-on-
  write (COW) memory, for fork(). Other shared memory
  (e.g. framebuffer in task data segment)
- Swapping. Choosing pages to swap out. LRU, NRU, clock algorithm,
  working sets.
- Memory-mapped files.

- When must you invalidate the TLB? two ways to do it:
    - 386 method (reload CR3); flushes entire TLB
    - 486+ method (INVLPG instruction); flushes one TLB entry
  Which of these two methods is faster and when?
  Improved (tagged) TLBs on non-x86 CPUs.
- P6+ CPUs allow "global" pages. The mappings for these are not
  flushed from the TLB when CR3 is reloaded (only by INVLPG).
  See bit b7 of register CR4.

- Paging code in detail: pseudocode or walk-through of page fault
  handler, state diagram or life-cycle of a page.
- Virtual memory layout of common OSes: Windows NT, Windows 9x,
  Linux, BSD, other?
- Accessing page tables with virtual addresses: make one entry in
  the page directory point to the page directory itself, then
  addresses that go through this entry let you treat the page
  tables as pages
- Kernel's view of memory
- Task memory layout in detail
- Intel documents use the term 'linear address' where these
  documents use the term 'virtual address'. I think the word
  'linear' is confusing because it's used for about a million
  other things.

REPORT BUGS OR ERRORS IN THIS DOCUMENT