linux 内存初始化,解读dmesg中的内存初始化信息

Linux kernel在引导过程中会在dmesg中报告如下的内存初始化信息,其实此时引导过程并未完成,initrd和init所占的内存尚未释放,最终kernel可用的内存比dmesg报告的available内存还会更多一点。

# dmesg | grep Memory

[ 0.000000] Memory: 3789320k/4915200k available (6243k kernel code, 795332k absent, 330548k reserved, 4180k data, 1604k init)

1

2

# dmesg | grep Memory

[0.000000]Memory:3789320k/4915200kavailable(6243kkernelcode,795332kabsent,330548kreserved,4180kdata,1604kinit)

要理解以上信息的含义,还是看源代码吧,这条信息是在 mem_init() 函数中输出的:

void __init mem_init(void)

{

long codesize, reservedpages, datasize, initsize;

unsigned long absent_pages;

pci_iommu_alloc();

/* clear_bss() already clear the empty_zero_page */

register_page_bootmem_info();

/* this will put all memory onto the freelists */

totalram_pages = free_all_bootmem();

absent_pages = absent_pages_in_range(0, max_pfn);

reservedpages = max_pfn - totalram_pages - absent_pages;

after_bootmem = 1;

codesize = (unsigned long) &_etext - (unsigned long) &_text;

datasize = (unsigned long) &_edata - (unsigned long) &_etext;

initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;

/* Register memory areas for /proc/kcore */

kclist_add(&kcore_vsyscall, (void *)VSYSCALL_START,

VSYSCALL_END - VSYSCALL_START, KCORE_OTHER);

printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, "

"%ldk absent, %ldk reserved, %ldk data, %ldk init)\n",

nr_free_pages() << (PAGE_SHIFT-10),

max_pfn << (PAGE_SHIFT-10),

codesize >> 10,

absent_pages << (PAGE_SHIFT-10),

reservedpages << (PAGE_SHIFT-10),

datasize >> 10,

initsize >> 10);

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

void__initmem_init(void)

{

longcodesize,reservedpages,datasize,initsize;

unsignedlongabsent_pages;

pci_iommu_alloc();

/* clear_bss() already clear the empty_zero_page */

register_page_bootmem_info();

/* this will put all memory onto the freelists */

totalram_pages=free_all_bootmem();

absent_pages=absent_pages_in_range(0,max_pfn);

reservedpages=max_pfn-totalram_pages-absent_pages;

after_bootmem=1;

codesize=(unsignedlong)&_etext-(unsignedlong)&_text;

datasize=(unsignedlong)&_edata-(unsignedlong)&_etext;

initsize=(unsignedlong)&__init_end-(unsignedlong)&__init_begin;

/* Register memory areas for /proc/kcore */

kclist_add(&kcore_vsyscall,(void*)VSYSCALL_START,

VSYSCALL_END-VSYSCALL_START,KCORE_OTHER);

printk(KERN_INFO"Memory: %luk/%luk available (%ldk kernel code, "

"%ldk absent, %ldk reserved, %ldk data, %ldk init)\n",

nr_free_pages()<

max_pfn<

codesize>>10,

absent_pages<

reservedpages<

datasize>>10,

initsize>>10);

}

以上代码中,free_all_bootmem()需要详细解释:在内核引导的初始阶段,buddy allocator和slab allocator等内存管理机制尚未就绪,所以使用的是bootmem allocator,到运行mem_init()的时候,bootmem的历史任务已经完成,所以调用free_all_bootmem()把它管理的内存中未分配的部分全都释放掉。

absent_pages_in_range()用于统计物理内存中对kernel不可用的部分,因为有一些物理内存是被BIOS保留的,kernel用不了。

在全部物理内存中,除掉bootmem释放出来的空闲内存和kernel无法使用的absent内存,剩下的就是在kernel引导过程中已经分配掉的内存,称为reserved内存。Reserved内存主要包括initrd、初始化代码init、内核代码及数据(内核数据是动态变化的,这里所说的是引导阶段截至mem_init为止所产生的数据,包括存放页描述符struct page的mem_map[]数组等)。

注:initrd和初始化代码init在引导完成之后会被释放掉,所以最终的可用内存会比dmesg显示的available更多一点,相应的源代码可参见:

arch/x86/mm/init.c: free_initrd_mem() 和 free_initmem()。

在dmesg中可以看到释放时输出的日志,注意看init的大小:

# dmesg

...

[ 0.000000] Memory: 3789320k/4915200k available (6243k kernel code, 795332k absent, 330548k reserved, 4180k data, 1604k init)

...

[ 0.008325] Freeing SMP alternatives: 24k freed

...

[ 0.541160] Freeing initrd memory: 18088k freed

...

[ 0.660810] Freeing unused kernel memory: 1604k freed

...

1

2

3

4

5

6

7

8

9

10

# dmesg

...

[0.000000]Memory:3789320k/4915200kavailable(6243kkernelcode,795332kabsent,330548kreserved,4180kdata,1604kinit)

...

[0.008325]FreeingSMPalternatives:24kfreed

...

[0.541160]Freeinginitrdmemory:18088kfreed

...

[0.660810]Freeingunusedkernelmemory:1604kfreed

...

正因如此,最终用”free”命令看到的total memory比dmesg里看到的available memory更多,以本系统为例,”free”命令看到的total 3809036k,比dmesg看到的available memory 3789320k更多,(3809036k – 3789320k) = (24k + 18088k + 1604k):

# free -k

total used free shared buff/cache available

Mem: 3809036 2473876 313400 175572 1021760 837288

1

2

3

# free -k

totalusedfreesharedbuff/cacheavailable

Mem:380903624738763134001755721021760837288

所以内存初始化信息的解读如下:

3789320k/4915200k available:

分母4915200k表示物理内存的大小,

分子3789320k表示可供kernel分配的 free memory的大小;

795332k absent:

表示不可用的物理内存大小。譬如有一些物理内存被BIOS保留、对kernel是不可用的,这部分物理内存被计入”absent”之中。

330548k reserved:

包括【initrd】和【内核代码及数据】等,详见上面的解释。其中内核代码和部分数据包含在下列统计值中:

6243k kernel code :

表示kernel的代码,属于reserved memory;

4180k data :

表示kernel的数据,属于reserved memory;

1604k init :

表示init code和init data,属于reserved memory,但引导完成之后会释放给free memory。

它们之间的关系如下:

available = 物理内存 – absent – reserved

reserved 包括 kernel code, data 和 init,由于它还包括initrd和其它更多的内容,所以reserved远远大于 kernel code + data + init 之和。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值