struct page**pages;unsigned int nr_pages;//vmalloc映射的page数目phys_addr_t phys_addr;//用来映射硬件设备的IO共享内存,其他情况下为0constvoid*caller;//调用vmalloc函数的函数的地址}; vmalloc 主要分以下三步: 从VMALLOC_START到VMALLOC_END查找空闲的虚拟地址空间(hole) 根据分配的size,调用alloc_page依次分配单个页面. 把分配的单个...
Linux内核 " 动态分配内存 " 是通过 " 系统接口 " 实现的 , 下面介绍几个重要的 接口函数 ; ①以 " 页 " 为单位分配内存 :alloc_pages,__get_free_page; ②以 " 字节 " 为单位分配 " 虚拟地址连续的内存块 " :vmalloc; ③以 " 字节 " 为单位分配 " 物理地址连续的内存块 " :kmalloc; 注意 该...
vmalloc最小分配一个page,并且分配到的页面不保证是连续的,因为vmalloc内部调用alloc_page多次分配单个页面。 vmalloc的区域就是在上图中VMALLOC_START - VMALLOC_END之间,可通过/proc/vmallocinfo查看。 数据结构 vmap_area 描述一段虚拟地址的区域,可以将struct vm_struct构成一个链表,维护多段映射。 struct vmap_ar...
不同之处,在于vmap建立映射时,page是函数传入进来的,而vmalloc是通过调用alloc_page接口向Buddy System申请分配的。 vmalloc VS kmalloc到现在,我们应该能清楚vmalloc和kmalloc的差异了吧,kmalloc会根据申请的大小来选择基于slub分配器或者基于Buddy System来申请连续的物理内存。而vmalloc则是通过alloc_page申请order = 0...
if (!size || (size >> PAGE_SHIFT) > num_physpages) return NULL; //取得一个有效的VM,这个函数我们在前面已经详细的分析过了 area = get_vm_area(size, VM_ALLOC); if (!area) return NULL; //所要映射的页面总数 nr_pages = size >> PAGE_SHIFT; ...
①以 " 页 " 为单位分配内存 :alloc_pages , __get_free_page ; ②以 " 字节 " 为单位分配 " 虚拟地址连续的内存块 " :vmalloc ; ③以 " 字节 " 为单位分配 " 物理地址连续的内存块 " :kmalloc ; 注意 该 " 物理地址连续的内存...
从过程中可以看出,vmalloc和vmap的操作,大部分的逻辑操作是一样的,比如从VMALLOC_START ~ VMALLOC_END区域之间查找并分配vmap_area, 比如对虚拟地址和物理页框进行映射关系的建立。不同之处,在于vmap建立映射时,page是函数传入进来的,而vmalloc是通过调用alloc_page接口向Buddy System申请分配的。
alloc_page/alloc_pages/free_pages物理连续4MB页Normal/Vmalloc都可CONFIG_FORCE_MAX_ZONEORDER定义了最大页面数2^11,一次能分配到的最大页面数是1024。 2.1 vmalloc 2.1 重要数据结构 在进行vmalloc代码走读之前,先简单看一下两个重要的数据结构:struct vm_struct(vmalloc描述符)和struct vmap_area(记录在vmap_are...
if(!size ||(size>>PAGE_SHIFT)>totalram_pages) gotofail; area =__get_vm_area_node(size, align, VM_ALLOC | VM_UNINITIALIZED, start, end, node, gfp_mask, caller); if(!area) gotofail; addr =__vmalloc_area_node(area, gfp_mask, prot, node); ...
{void*addr;struct vm_struct*area;size=PAGE_ALIGN(size);// 内存对齐if(!size||(size>>PAGE_SHIFT)>num_physpages){BUG();returnNULL;}area=get_vm_area(size,VM_ALLOC);// 申请一个合法的虚拟地址if(!area)returnNULL;addr=area->addr;// 映射物理内存地址if(vmalloc_area_pages(VMALLOC_VMADDR(...