Professional Documents
Culture Documents
Anand Sivasubramaniam
Two Parts
Architecture Independent Memory
Should be flexible and portable enough across
platforms
Implementation for a specific architecture
Architecture Independent
Memory Model
Process virtual address space divided into pages
Page size given in PAGE_SIZE macro in asm/page.h
(4K for x86 and 8K for Alpha)
The pages are divided between 4 segments
User Code, User Data, Kernel Code, Kernel Data
In User mode, access only User Code and User Data
But in Kernel mode, access also needed for User Data
Index into
Page Dir.
Index into
Index into
Page Middle Page Table
Dir.
Page
Offset
_end
_bss_start
_edata
_etext
0x84000000
bss
Data
Code
Header
Shared Libs
Region Descriptors
Struct vm_operations_struct {
void (*open)(struct vm_area_struct *);
void (*close)(struct vm_area_struct *);
void (*unmap)();
void (*protect)()
void (*sync)();
unsigned long (*nopage)(struct vm_area_struct *, unsigned long
address, unsigned long page, int write_access);
void (*swapout)(struct vm_area_struct *, unsigned long, pte_t *);
pte_t (*swapin)(struct vm_area_struct *, unsigned long, unsigned long);
}
Traditional mmap()
int do_mmap(struct file *, unsigned long addr,
unsigned long len, unsigned long prot, unsigned
long flags, unsigned long off);
Kernel Segment
On a sys call, CS points to kernel segment. DS and ES are set to
kernel segment as well.
Next, FS is set to user data segment.
Put_user() and get_user() can then access user space if needed.
The address parameters to these functions cannot exceed
0xc0000000.
Violation of this should result in a trap, together with any writes to
a read-only page (creates a problem on 386, while the problem
does not exist in 486/Pentium)
Hence, verify_area() is typically called before performing such
operations.
Physical and Virtual addresses are same except for those allocated
using vmalloc().
Kernel segment shared across processes (not switched!)
Dynamic
Void *kmalloc(size, priority), Void kfree (void *) // in mm/kmalloc.c
Void *vmalloc(size), void *vmfree(void *) // in mm/vmalloc.c
Kmalloc is used for physically contiguous pages while vmalloc does not
necessarily allocate physically contiguous pages
Memory allocated is not initialized (and is not paged out).
size_descriptor
page_descriptor
Null
bh
bh
bh
bh
bh
bh
Null
vmalloc()
vmstruct
next
size
addr
VAS
next
size
addr
vmlist
vmalloc vs kmalloc
Contiguous vs non-contiguous physical memory
kmalloc is faster but less flexible
vmalloc involves __get_free_page() and may need to
block to find a free physical page
DMA requires contiguous physical memory
Paging
All kernel segment pages are locked in memory (no swapping)
User pages can be paged out:
Complete block device
Fixed length files in a file system
First 4096 bytes are a bitmap indicating that space for that page is
available for paging.
At byte 4086, string SWAP_SPACE is stored.
Hence, max swap of 4086*8-1 = 32687 pages = 130784KB per
device or file
MAX_SWAPFILES specifies number of swap files or devices
Swap device is more efficient than swap file.
free_area_list[0 1 2]
free_area_map
0
Page Fault
Error code written onto stack, and the VA is stored in register CR2
do_page_fault(struct pt_regs *regs, unsigned long
error_code) is now called.
If faulting address is in kernel segment, alarm messages are
printed out and the process is terminated.
If faulting address is not in a virtual memory area, check if
VM_GROWSDOWN for the nexy virtual memory area is set (I.e.
Stack). If so, expand VM. If error in expanding send SIGSEGV.
If faulting address is in a virtual memory area, check if protection
bits are OK. If not legal, send SIGSEGV. Else, call do_no_page()
or do_wp_page().