Linux如何为物理分配器分配内存?

我最近深入研究了Linux内存pipe理的细节,因为我想为自己的玩具内核实现类似的东西,所以我希望熟悉细节的人能帮助我理解一件事情。 显然,物理内存pipe理器是一个好友algorithm,它进一步专门用于返回特定顺序(0到9,0只是一个页面)的页面块。 对于每个订单,块被存储为链接列表。 假设一个5阶的数据块被请求,但在5阶数据块的列表中没有被find,那么该algorithm将按顺序search一个数据块,将数据块分成两部分,给出请求的一半,并将另一半移动到一个较低的阶数它是一半大小)。 我没有得到的是内核如何存储这些结构,或者如何为它们分配空间。 因为对于0页的页面,您需要1M条目(每个页面是4KiB页面),这是否意味着内核分配1MiB * sizeof(struct page)? 那1阶以上的块呢? 内核是否通过将分配的块标记为更高的顺序来重用已分配的块,以及何时需要将块分割成两块,然后返回块并得到一个未使用的块?

我没有得到的是内核如何存储这些结构,或者如何为它们分配空间。 因为对于0页的页面,您需要1M条目(每个页面是4KiB页面),这是否意味着内核分配1MiB * sizeof(struct page)?

区域初始化通过调用paging_init() (arch / x86 / mm / init_32.c;一些描述 – https://www.kernel.org/doc/gorman/html/understand/understand005.html 2.3区域初始化和http native_pagetable_init()和/或间接调用1166 x86_init.paging.pagetable_init(); )从setup_arch()初始化内核页表) :

 690 /* 691 * paging_init() sets up the page tables - note that the first 8MB are 692 * already mapped by head.S. ...*/ 697 void __init paging_init(void) 698 { 699 pagetable_init(); ... 711 zone_sizes_init(); 712 } 

pagetable_init()在1024 pgd_t s的swapper_pg_dir数组中创建内核页表。

zone_sizes_init()实际上定义了物理内存的区域,并调用free_area_init_nodes()来初始化实际完成的工作(对于free_area_init_nodes()中的每个NUMA节点for_each_online_node(nid) {...} ),

  • calculate_node_totalpages()打印dmesg中每个节点的页数
  • alloc_node_mem_map()为此节点中的每个物理页面分配struct page实际工作; 它们的内存由bootmem分配器doc1 doc2 分配 (你可以通过bootmem_debug=1内核启动选项来看到它的调试情况):

4936 size = (end - start) * sizeof(struct page);

4937 map = alloc_remap(pgdat->node_id, size);

if (!map) map = memblock_virt_alloc_node_nopanic(size, pgdat->node_id);

free_area_init_core()free_area_init_core()中构建内存映射,并初始化freelists和buddy位图。

免费的每个区域的订单列表被初始化,订单被标记为没有任何空闲页面: free_area_init_core() – > init_currently_empty_zone() – > zone_init_free_lists

 4147 static void __meminit zone_init_free_lists(struct zone *zone) 4148 { 4149 unsigned int order, t; 4150 for_each_migratetype_order(order, t) { 4151 INIT_LIST_HEAD(&zone->free_area[order].free_list[t]); 4152 zone->free_area[order].nr_free = 0; 4153 } 4154 } 

PS:在内核中有init(),它被称为start_kernel() ,而LXR(Linux交叉引用)将帮助你在函数之间导航(我发布了链接到lxr.free-electrons.com,但是有几个在线LXRs):

 501 asmlinkage __visible void __init start_kernel(void) ... 528 boot_cpu_init(); 529 page_address_init(); 530 pr_notice("%s", linux_banner); 531 setup_arch(&command_line);