100 likes | 282 Views
High_Memory. Yuan Lin 20130223. What is high memory ?. 0GB. 3GB. 4GB. Process. User Space. Kernel Space. 0GB. 1GB. 4GB. Kernel. How to access ?. In 32bit system. What is high memory ?. 3GB + 896MB. 0GB. 3GB. 4GB. Process. User Space. Kernel Space. 0GB + 896MB. 0GB.
E N D
High_Memory Yuan Lin 20130223
What is high memory ? 0GB 3GB 4GB Process User Space Kernel Space 0GB 1GB 4GB Kernel How to access ? In 32bit system
What is high memory ? 3GB + 896MB 0GB 3GB 4GB Process User Space Kernel Space 0GB + 896MB 0GB 4GB Kernel In 32bit system
What is high memory ? 3GB + 896MB 3GB 4GB Process PAGE_OFFSET high memory PKMAP_BASE FIXADDR_START VMALLOC_START VMALLOC_END vmalloc address space kmap address mapping fixed virtual address mapping gap
vmalloc // vmalloc Step 1: vmalloc(mm/Vmalloc.c) Step 2: __vmalloc_node (mm/Vmalloc.c) PAGE_ALIGN -- 对齐 get_vm_area_node -- 首先利用kmalloc分配一个vm_struct *area __vmalloc_area_node-- 然后分配物理页,并保存信息至vm_struct *area __vmalloc_area_node -> map_vm_area-- 最后修改页表的映射 数据结构: vm_struct-- 每次vmalloc都新建一个实例,保存分配到的虚拟地址和物理页 vmlist-- 上面分配的所有实例的链表(何时初始化的?) kernel 2.6.24
kmap // 初始化 Step1: start_kernel (init/main.c) -> setup_arch (arch/x86/kernel/Setup_32.c) -> paging_init (arch/x86/mm/Init_32.c) -> pagetable_init (arch/x86/mm/Init_32.c) -> permanent_kmaps_init (arch/x86/mm/Init_32.c) page_table_range_init -- 为永久内核映射部分建立新的页表 pkmap_page_table-- 指向为永久内核映射部分建立的页表 Step2: start_kernel (init/main.c) -> setup_arch (arch/x86/kernel/Setup_32.c) -> paging_init (arch/x86/mm/Init_32.c) -> kmap_init (arch/x86/mm/Init_32.c) kmap_pte-- 获得永久内存映射部分中临时映射的第一个页表 kmap_prot -- 页表的属性 kernel 2.6.24
kmap // kmap Step 1: kmap (arch/x86/mm/Highmem_32.c) might_sleep -- 可能休眠 如果不是highmem,直接返回对应的线性地址 如果是,则调用kmap_high返回 Step 2: kmap_high (mm/Highmem.c) page_address-- 看是否被映射虚拟地址 map_new_virtual-- 如果没被映射过,则调用该接口获得虚拟地址 pkmap_count-- 记录同一物理页映射虚拟地址的次数 Step3: map_new_virtual (mm/Highmem.c) set_pte_at-- 配置相应的页表项,使虚拟地址映射至物理页 kernel 2.6.24
kmap_atomic // kmap_atomic Step1: kmap_atomic (arch/x86/mm/Highmem_32.c) Step2: kmap_atomic_prot(arch/x86/mm/Highmem_32.c) 如果不是highmem,直接返回对应的线性地址 如果是,则由该算法直接获得虚拟地址 vaddr= __fix_to_virt(FIX_KMAP_BEGIN + idx) -- 算法和管理较简单 set_pte-- 最后修改相应的页表 kernel 2.6.24
Appendix http://blog.csdn.net/gxfan/article/details/2723455 http://linux.chinaunix.net/techdoc/system/2008/09/17/1032546.shtml http://hi.baidu.com/rwen2012/item/a39950bcb499bf402bebe321