140 likes | 253 Views
Managing physical memory. Examining the Linux kernel’s ‘mem_map[]’ array. ‘kmap()’. Recall that our ‘dram.c’ device-driver used the kernel’s ‘kmap()’ function This function offered us a uniform way of accessing a page of physical memory, no matter which memory-zone it belonged to
E N D
Managing physical memory Examining the Linux kernel’s ‘mem_map[]’ array
‘kmap()’ • Recall that our ‘dram.c’ device-driver used the kernel’s ‘kmap()’ function • This function offered us a uniform way of accessing a page of physical memory, no matter which memory-zone it belonged to • In order to understand our ‘dram.c’ device driver’s ‘read()’ method, we need to study how the Linux kernel’s ‘kmap()’ works
Direct ‘linear’ mapping user-space (3GB) kernel-space (1GB) kernel-space (1GB) 896MB HIGH MEMORY 896MB virtual addresses
‘kmap()’ hides page differences • For physical pages in the lowest memory zones (i.e., bottom 896MB), a direct map exists into kernel-space, so kmap() is trivial for these pages: they are visible to the kernel at predictable locations • But for physical pages in ‘high memory’, they’re not always ‘mapped’ -- and even if mapped, the addresses aren’t predictable
Pentium ‘page frames’ • The system’s physical memory is made up of fixed-size blocks (called ‘page frames’) • For the Intel x86 architecture, the size of each page frame is 4096 bytes (=0x1000) • You can tell which page a byte lies in from its physical address: byte at 0x00012345 lies in page-number 0x12 (at offset 0x345) • The kernel’s ‘num_physpages’ variable is equal to the total number of page frames
The ‘struct page’ object • The Linux kernel uses a data-structure to keep track of each physical page frame • This data-structure is called a ‘struct page’ • The size of each ‘struct page’ is 32-bytes • These ‘struct page’ objects form an array, named ‘mem_map[]’, whose number of entries is the ‘num_physpages’ value
The ‘struct page’ fields struct page ( 8 longwords ) flags _count _mapcount private mapping index lru.next lru.prev The ‘struct page’ definition is in the <linux/mm.h> header along with the declaration for the ‘mem_map[ ]’ array
The ‘mem_map[ ]’ array mem_map[ 0 ] describes page frame 0 mem_map[ 1 ] describes page frame 1 mem_map[ 2 ] describes page frame 2 mem_map[ 3 ] etc. mem_map[ 4 ] mem_map[ 5 ] . . .
The ‘flags’ field • This field consists of individual bits which indicate the page frame’s current status • Examples: PG_locked bit 0 PG_uptodate bit 3 PG_dirty bit 4 PG_active bit 6 PG_highmem bit 8 PG_reserved bit 11
Other ‘struct page’ fields … • ‘_count’ is the page frames usage count • ‘_mapcount’ is how many pte’s contain it • ‘private’ is used in managing swap-space • ‘index’ gives the frame’s offset in a mmap • ‘lru.next’ points to next element in link-list • ‘lru.prev’ points to prev element in link-list
Lots of ‘struct page’ objects • Our classroom machines have 1GB RAMs • So number of page-frames is: 1GB / 4KB • i.e., roughly a quarter-million page-frames • And their uses are dynamically changing! • So studying them all in action isn’t trivial
We can use ‘/dev/dram’ • If we can locate the ‘mem_map[ ]’ array, we can use our ‘dram’ device-driver and our ‘fileview’ tool to at least look at a few of the ‘struct page’ array-entries • We could write a program that examines the ‘flags’ field for every page frame, to gather some statistics about their usage
In-class exercise #1 • Use the ‘newinfo’ wizard to quickly build a module that will create a ‘/proc/mem_map’ pseudo-file showing where ‘mem_map[ ]’ is located, and how many entries are in it • You’ll need to convert the virtual address of ‘mem_map[ ]’ into its physical addrress in order to find it in ‘/dev/dram’ (via ‘lseek’)
In-class exercise #2 • Write a developer-tool application that will read the entire ‘mem_map[ ]’ array, so it can show the contents of all ‘struct page’ array-entries (in hexadecimal format) on the display monitor (all quarter-million!) • You can pipe your program-output through the ‘more’ program (to see the info slowly) • Include page-use statistics in your output