__init和__initdata Linux在arch/$(ARCH)/kernel/vmlinux.lds中定义了.init段。__init和__initdata属性的数据都在这个段中,当内核启动完毕后,这个段中的内存会被释放掉供其他使用。 __init和__initdata宏定义如下: /* include/linux/init.c */ #define __init __attribute__ ((__section__ (".init.text"))) #define __initdata __attribute__ ((__section__ (".init.data"))) vmlinux.lds内容如下: /* arch/arm/kernel/vmlinux.lds */ OUTPUT_ARCH(arm) ENTRY(stext) jiffies = jiffies_64; SECTIONS { . = (0xc0000000) + 0x00008000; .init : { /* Init code aand data */ _stext = .; _sinittext = .; *(.init.text) _einittext = .; __proc_info_begin = .; *(.proc.info.init) __proc_info_end = .; __arch_info_begin = .; *(.arch.info.init) __arch_info_end = .; __tagtable_begin = .; *(.taglist.init) __tagtable_end = .; . = ALIGN(16); __setup_start = .; *(.init.setup) __setup_end = .; __early_begin = .; *(.early_param.init) __early_end = .; __initcall_start = .; *(.initcall1.init) *(.initcall2.init) *(.initcall3.init) *(.initcall4.init) *(.initcall5.init) *(.initcall6.init) *(.initcall7.init) __initcall_end = .; __con_initcall_start = .; *(.con_initcall.init) __con_initcall_end = .; __security_initcall_start = .; *(.security_initcall.init) __security_initcall_end = .; . = ALIGN(32); __initramfs_start = .; usr/built-in.o(.init.ramfs) __initramfs_end = .; . = ALIGN(64); __per_cpu_start = .; *(.data.percpu) __per_cpu_end = .; __init_begin = _stext; *(.init.data) . = ALIGN(4096); __init_end = .; } …… } 可以发现__init对应的section(.init.text)和__initdata对应的section(.init.data)都在.init段中。同样,这里定义的其他一些section也都会在使用完后被释放,如.init.setup,.initcall1.init等。 释放memory的大小会在系统启动过程中打印出来: eth0: link up IP-Config: Complete: device=eth0, addr=192.168.167.15, mask=255.255.255.0, gw=192.168.167.254, host=192.168.167.15, domain=, nis-domain=(none), bootserver=192.168.167.170, rootserver=192.168.167.170, rootpath= Looking up port of RPC 100003/2 on 192.168.167.170 Looking up port of RPC 100005/1 on 192.168.167.170 VFS: Mounted root (nfs filesystem). Freeing init memory: 128K |