140 likes | 265 Vues
Dive into the Linux kernel's memory management to understand how the 'mem_map[]' array and the 'kmap()' function work. This discussion covers direct mapping of physical memory, page frames, and the usage of 'struct.page' objects which describe each page frame's status in the kernel. Explore how these structures help manage low and high memory zones and learn to utilize device drivers like 'dram.c' to analyze memory usage. Engage with hands-on activities like creating a '/proc/mem_map' pseudo-file to examine memory entries, showcasing the kernel's memory allocation and page usage.
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