好的操作系统必然要有好的内存管理系统来支持,
Linux Kernel启动过程中的内存管理
。好的内存管理系统就像一个艺术品,因为在其中我们可以看到空间优化和时间优化的完美平衡(既要省内存又要分配和释放足够快)。Linux为我们提供了这样一个范例,关于它的内存管理在很多讲kernel的书都可以找到。但在这一切还没有建立起来时,系统又是怎么工作的呢?在系统启动时内存分配大致经历了这样几个阶段(基于kernel 2.6.29):
1. 静态分配(如果这也算一种的话。。。)
2. e820表
3. bootmem allocator
4. zone allocator(buddy system)
5. slab allocator
6. 虚拟空间分配,如用vmalloc, mmap这些函数分配
当然以上的几个阶段的时间界限并不总是很明显,有些时候是并存的。以下是初始化代码中几个关键点:
start_kernel()
setup_arch()
setup_memory_map() //从boot_params.e820_map读入e820表信息,以后就可以用find_e820_area()分配了,
电脑资料
《Linux Kernel启动过程中的内存管理》(https://www.unjs.com)。init_memory_mapping()
kernel_physical_mapping_init() //在虚拟空间映射kernel页表的low mem部分,创建页表过程中需要分配内存就是通过find_e820_area()。
initmem_init()
setup_bootmem_allocator() //初始化bootmem allocator,bootmem allocator可用。
early_res_to_bootmem() //把之前静态分配或者从通过find_e820_area()分配的区域置成保留。
paging_init() //完成kernel页表high mem中persistent kernel mapping和temporary kernel mapping部分的初始化,之后可以通过kmap()或kmap_atomic()把物理页映射到high mem区域。
zone_sizes_init() //初始化zone allocator,但只是初始化,还没法用它分配,因为所有的freelist还是被置成空的。
vmalloc_init() //初始化分配noncontiguous memory area所需要的结构。vmalloc能分配high mem中从VMALLOC_START到VMALLOC_END的虚拟空间。加上前面paging_init()中提到的两种,针对kernel的high mem的三种映射方式就全了。该函数中通过bootmem allocator分配自身需要的内存。