本文共 2095 字,大约阅读时间需要 6 分钟。
第五阶段建立的是 vmalloc
vmalloc_init 完成后 -> 没有终点
可以说是buddy 管理的所有内存
vmalloc __vmalloc_node __vmalloc_node_range struct vm_struct *area; // 在 [VMALLOC_START, VMALLOC_END] 找到符合大小的空闲vmalloc区域 // A.获取虚拟地址 area = __get_vm_area_node struct vmap_area *va; // 注意 不同于 struct vm_area_struct struct vm_struct *area; // 注意 不同于 struct mm_struct area = kzalloc_node va = alloc_vmap_area addr = __alloc_vmap_area(size, align, vstart, vend); va->va_start = addr; va->va_end = addr + size; insert_vmap_area(va, &vmap_area_root, &vmap_area_list); setup_vmalloc_vm(area, va setup_vmalloc_vm_locked(vm, va, flags, caller); va->vm = vm; // 进行实际的页面分配,更新页表 __vmalloc_area_node(area,...); // 计算当前分配的内存大小需要占用多少个page // 然后通过kmalloc分配一组struct page指针数组,struct page指针数组 在 vm_struct 中 struct page **pages; pages = kmalloc_node __kmalloc_node kmalloc_slab slab_alloc_node area->pages = pages; // 再通过调用buddy allocator接口alloc_page() // 每次获取一个物理页框填入到vm_struct中的struct page* 数则 // B.获取物理页框 for (i = 0; i < area->nr_pages; i++) { struct page * page = alloc_page(gfp_mask); area->pages[i] = page; } // 修改内核使用的页表项,将pages数组中的每个页框分别映射到连续的vmalloc区中 // C. 做 物理页框中的 物理地址 与 虚拟地址的 映射 map_kernel_range((unsigned long)area->addr, get_vm_area_size(area), prot, pages) map_kernel_range_noflush vmap_p4d_range vmap_pud_range vmap_pmd_range vmap_pte_range set_pte_at return area->addr;vmalloc 三个流程 A B Cvmap 两个流程 A C详细请参考 http://www.zyiz.net/tech/detail-96064.html
VMA 极度类似 vmalloc 机制.rodata .init .text 是 代码段 VMA , 在 进程地址视图的 .rodata .init .text , 用一个 vm_area_struct 表示.bss .data 是 数据段 VMA,在 进程地址视图的 .bss .data , 用一个vm_area_struct 表示vm_area_struct 中 vm_start 和 vm_end 成员 表示了 该 VMA 的起始和结束地址vm_area_struct 被插入 mm_struct 结构体 的 链表(mmap成员)和 红黑树(mm_rb成员)中// vmap_area 被 插入 vmap_area_list链表 和 vmap_area_root红黑树 中这是不是说明 vm_area_struct 是 进程相关的(某个进程才能用) , vmap_area 是 内核(非进程)(所有进程都能用)相关的
转载地址:http://bjigi.baihongyu.com/