Linux内核启动过程中打印的内存信息是怎么计算的
Linux内核启动过程中打印的内存信息是怎么计算的
对于一个这样的参数 mem=151M mem=118M@768M 内核中是怎么处理的已经在前篇文章里提到。这里再详细分析一下由这三个数据而引发的一连串的计算。使用这个参数的内核在启动过程中打印的内存信息:
- [ 0.000000] Determined physical RAM map:
- [ 0.000000] memory: 04000000 @ 00000000 (usable)
- [ 0.000000] User-defined physical RAM map:
- [ 0.000000] memory: 09700000 @ 00000000 (usable)
- [ 0.000000] memory: 07600000 @ 30000000 (usable)
- [ 0.000000] Zone PFN ranges:
- [ 0.000000] Normal 0x00000000 -> 0x00020000
- [ 0.000000] HighMem 0x00020000 -> 0x00037600
- [ 0.000000] Movable zone start PFN for each node
- [ 0.000000] early_node_map[2] active PFN ranges
- [ 0.000000] 0: 0x00000000 -> 0x00009700
- [ 0.000000] 0: 0x00030000 -> 0x00037600
- [ 0.000000] On node 0 totalpages: 68864
- [ 0.000000] Normal zone: 1152 pages used for memmap
- [ 0.000000] Normal zone: 0 pages reserved
- [ 0.000000] Normal zone: 37504 pages, LIFO batch:7
- [ 0.000000] Initialising map node 0 zone 0 pfns 0 -> 131072
- [ 0.000000] HighMem zone: 842 pages used for memmap
- [ 0.000000] HighMem zone: 29366 pages, LIFO batch:7
- [ 0.000000] Initialising map node 0 zone 1 pfns 131072 -> 226816
- [ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 66870
- …………
- [ 0.092000] Memory: 266060k/154624k available (3044k kernel code, 9152k reserved, 1166k data, 152k init, 120832k highmem)
下面对这一大堆数据慢慢地做做计算, 看看它们到底是怎么得来的。
- [ 0.000000] Zone PFN ranges:
- [ 0.000000] Normal 0x00000000 -> 0x00020000
- [ 0.000000] HighMem 0x00020000 -> 0x00037600
- [ 0.000000] Movable zone start PFN for each node
- [ 0.000000] early_node_map[2] active PFN ranges
- [ 0.000000] 0: 0x00000000 -> 0x00009700
- [ 0.000000] 0: 0x00030000 -> 0x00037600
代码位置:head.S --> start_kernel --> setup_arch --> arch_mem_init --> paging_init --> free_area_init_nodes
这一段log就是由free_area_init_nodes函数打印的。
Zone PFN ranges打印的是每个Zone最小和最大可能的PFN取值。这只是一个允许的取值范围,并不一定是真正用到的PFN值。真正使用的PFN肯定是该范围的一个子集。我们的系统中配置有两个Zone分别是Normal和HighMem.
- [ 0.000000] Normal 0x00000000 -> 0x00020000
计算方法是: 遍历boot_mem_map,找到最大的RAM物理地址,计算其PFN赋给max_low_pfn。但是如果已经超过了HIGHMEM_START,则把HIGHMEM_START的PFN值赋给max_low_pfn。
在我们的系统中HIGHMEM_START为512M,而启动参数配置的最大RAM地址0x37600000(即768M+118M=886M)已经超过了512M,所以max_low_pfn=0x20000.
- [ 0.000000] HighMem 0x00020000 -> 0x00037600
TODO: 如果板子上的RAM实际只有512M,那么配置了highmem会怎么处理呢?会映射到真正的RAM上吗?
- [ 0.000000] Movable zone start PFN for each node
- [ 0.000000] early_node_map[2] active PFN ranges
- [ 0.000000] 0: 0x00000000 -> 0x00009700
- [ 0.000000] 0: 0x00030000 -> 0x00037600
是从early_node_map数组中打印的,该数组由 add_active_range(0, start, end);填充。函数调用过程为:
head.S --> start_kernel --> setup_arch --> arch_mem_init --> bootmem_init --> add_active_range
- /**
- * add_active_range - Register a range of PFNs backed by physical memory
- * @nid: The node ID the range resides on
- * @start_pfn: The start PFN of the available physical memory
- * @end_pfn: The end PFN of the available physical memory
- *
- * These ranges are stored in an early_node_map[] and later used by
- * free_area_init_nodes() to calculate zone sizes and holes. If the
- * range spans a memory hole, it is up to the architecture to ensure
- * the memory is not freed by the bootmem allocator. If possible
- * the range being registered will be merged with existing ranges.
- */
|
评论暂时关闭