170 likes | 184 Views
IA32 Paging Scheme. Introduction to the Pentium’s support for “virtual” memory. A quick review. We’ve learned how to create ‘/proc’ files We wrote a simple device-driver: ‘dram.c’ We displayed a task’s page-directory We looked at Linux’s ‘mem_map[]’ array
E N D
IA32 Paging Scheme Introduction to the Pentium’s support for “virtual” memory
A quick review • We’ve learned how to create ‘/proc’ files • We wrote a simple device-driver: ‘dram.c’ • We displayed a task’s page-directory • We looked at Linux’s ‘mem_map[]’ array • Now we want to understand the ‘kmap()’ function, used by modules to get a virtual address for any physical page-frame
‘Traditional’ Linux HIGH MEMORY User space Kernel space 0x38000000 NORMAL MEMORY 1G (896MB) 0x00000000 Physical addresses Most of the kernel’s 1GB address-space is directly mapped to physical RAM at all times 3G But mappings to the ‘high memory’ page-frames are, by definition, only temporarily available and are not mapped according to a predictable rule Virtual addresses
How ‘mappings’ work • There are two aspects to consider: • the Pentium’s address-translation mechanism • the policies Linux applies to CPU capabilities • Example of this distinction: • The ‘page-directory’ array is a Pentium object • The ‘mem_map’ array is a Linux data-object
Control Register 4 This register consists of bits that enable various architectural extensions to the standard features of the Pentium processor, including two that affect virtual-to-physical memory mapping. 31 5 4 0 P A E P S E Legend: PSE = Page-Size Extensions (1=enabled, 0=disabled) PAE = Page-Address Extensions (1=enabled, 0=disabled) Recall that we saw our classroom workstations had CR4 = 000006D0
Two-Level Translation Scheme PAGE TABLES PAGE DIRECTORY PAGE FRAMES CR3
Control Register 3 31 12 4 3 Page-directory base-address P C D P W T The ‘page-directory base-address’ field holds the upper 20 address-bits of a physical page-frame that contains the current task’s page-directory entries; the lower 12 address-bits of any page-frame are zeros, of course, so can be used by the processor for other purposes (i.e., PCD [bit 4] and PWT [bit 3]: PWT = Page Write-Through (1=yes, 0 = no) PCD = Page Cache-Disable (1 = yes, 0 = no)
Your ‘/proc/cr3’ pseudo-file • Recall that you created a kernel module (named ‘cr3.c’) which allows applications to obtain the current value in register CR3 • This CR3 value gives the physical address for the current task’s page-directory, if the ‘traditional’ 3G/1G user-kernel mapping is employed (but not with the 4G/4G “patch”) • Using ‘fileview’ you saw a page-directory!
Format of a Page-Directory entry 31 12 11 10 9 8 7 6 5 4 3 2 1 0 PAGE-TABLE BASE ADDRESS AVAIL G P S 0 A P C D P W T U W P LEGEND P = Present (1=yes, 0=no) W = Writable (1 = yes, 0 = no) U = User (1 = yes, 0 = no) A = Accessed (1 = yes, 0 = no) G = Global (1 = yes, 0 = no) PS = Page-Size (0=4KB, 1 = 4MB) PWT = Page Write-Through (1=yes, 0 = no) PCD = Page Cache-Disable (1 = yes, 0 = no)
Format of a Page-Table entry 31 12 11 10 9 8 7 6 5 4 3 2 1 0 PAGE-FRAME BASE ADDRESS AVAIL G 0 D A P C D P W T U W P LEGEND P = Present (1=yes, 0=no) W = Writable (1 = yes, 0 = no) U = User (1 = yes, 0 = no) A = Accessed (1 = yes, 0 = no) D = Dirty (1 = yes, 0 = no) G = Global (1 = yes, 0 = no) PWT = Page Write-Through (1=yes, 0 = no) PCD = Page Cache-Disable (1 = yes, 0 = no)
kernel mappings • The ‘kmap()’ function is used by modules to obtain the virtual address for a physical page-frame: void * kmap( struct page * page ); • On systems with 1GB of installed memory, the majority of physical page-frames are permanently mapped to kernel addresses, but page-frames in ‘high’ memory can only be ‘temporarily’ mapped into kernel space
Normal page-mapping • For a virtual address in kernel space that is below the high-memory start-address, the corresponding physical address can be gotten by a simple subtraction: phys_addr = virt_addr – PAGE_OFFSET • Recall: PAGE_OFFSET = 0xC0000000
Mapping ‘high’ memory • For addresses in kernel space in the range from 0xF8000000 to 0xFFFFFFFF there might be no current mapping to ram • So the action of the ‘kmap()’ function must be more complex in these cases (i.e., it’s necessary to create a temporary mapping if it happens one does not already exist)
A limited number of kmaps • In kernel 2.6 there is only one page-table that is reserved for ‘kmap()’ to use when temporary mappings into high-memory need to be created • This is called the ‘kmap_page_table’ • Its page-table entries are forever changing as kernel code calls the functions ‘kmap()’ and ‘kunmap()’
PKMAP_BASE • We can watch the ‘kmap_page_table’ as it undergoes these dynamic changes – if we know where to find it in physical memory • We can do a ‘page-table walk’ to locate it • There are 1024 virtual page-frames used for temporary ‘kmap()’ addresses, starting with the virtual address PKMAP_BASE
In-class exercise #1 • Use the ‘init_mm.c’ module to locate the page-directory belonging to the ‘init’ task • Use ‘fileview’ to see these directory entries • Determine the value of PKMAP_BASE • Which directory-entry contains the address of the ‘pkmap_page_table’? (It’s the entry that ‘maps’ virtual-address PKMAP_BASE to a page-frame in physical memory)
In-class exercise #2 • Use the result from your ‘page-table walk’ to assign the correct value to ‘zone_base’ in our ‘kmapsnow.cpp’ demo-program • Run the ‘kmapsnow’ in one window while you execute some other commands from inside a different window, to view changes in the set of currently active kmaps • Log in remotely from an adjacent station