现在的位置: 首页 > 综合 > 正文

Linux各个部份初始化过程–待续

2013年08月25日 ⁄ 综合 ⁄ 共 2797字 ⁄ 字号 评论关闭

[内核版本:Linux-2.6.30]

众所周知,Linux C代码初始化入口是start_kernel() [init/main.c]函数。以下进行单核CPU进行分析。

先列出start_kernel内执行的调用:

start_kernel [init/main.c]

    --> char * command_line;

    --> extern struct kernel_param __start___param[ ], __stop___param[ ];

    --> smp_setup_process_id() [NOP, init/main.c]

    --> lockdep_init(); [NOP,include/linux/lockdep.h]

    --> debug_objects_early_init(); [NOP, include/linux/debugobjects.h]

    --> boot_init_stack_canary(); [NOP, include/linux/stackprotector.h]

    --> cgroup_init_early(); [return 0; include/linux/cgroup.h]

    --> local_irq_disable(); [ ?? ]

    --> early_boot_irqs_off(); [NOP, include/linux/lockdep.h]

    --> early_init_irq_lock_class(); [kernel/irq/handle.c]

    --> lock_kernel(); [ NOP, include/linux/smp_lock.h ]

    --> tick_init(); [ kernel/time/tick-common.c ]

    --> boot_cpu_init(); [ init/main.c ]

    --> page_address_init(); [ NOP, include/linux/mm.h ]

    --> printk(KERN_NOTICE "%s", linux_banner); [
init/version.c
]

    --> setup_arch(&command_line);

    --> mm_init_owner(&init_mm, &init_task); [ (undefined CONFIG_MM_OWNER)
NOP, include/linux/sched.h ]

    --> setup_command_line(command_line);

    --> setup_per_cpu_areas();

    --> setup_nr_cpu_ids();

    --> smp_prepare_boot_cpu();

    --> sched_init();

    --> preempt_disable();

    --> build_all_zonelist(); [ include/linux/mmzone.h; mm/page_alloc.c ]

    --> page_alloc_init(); [ mm/page_alloc.c ]

    --> 

下面具体分析Linux各个部份初始化过程。

内存部份

start_kernel [init/main.c] -->

     --> 

     --> build_all_zonelist(void)

     --> page_alloc_init();

     --> vmalloc_init();         [ mm/vmalloc.c ]

     --> page_cgroup_init();       [ NOP; include/linux/page_cgroup.h ]

     --> mem_init [arch/arm/mm/init.c] 

     --> kmem_cache_init [ mm/slab.c ]

     --> kmemtrace_init() [ NOP; kernel/trace/kmemtrace.c ]

虚拟文件系统部份

start_kernel [init/main.c] --> vfs_caches_init_early [fs/dcache.c  == NOP] --> vfs_caches_init [fs/dcache.c] --> mnt_init [fs/namespace.c]
--> sysfs_init [fs/sysfs/mount.c]

以下简单分析一下sysfs_init。

sysfs_init    

    --> sysfs_dir_cachep = kmem_cache_create("sysfs_dir_cache", sizeof(struct sysfs_dirent), 0, 0, NULL)

    --> sysfs_inode_init();

    --> register_filesystem(&sysfs_fs_type)

    --> sysfs_mount = kern_mount(&sysfs_fs_type)

驱动关部份

start_kernel [init/main.c] --> reset_init() --> kernel_init --> do_basic_setup --> do_initcalls --> do_one_initcall(initcall_t fn) --> fn();

其中do_initcalls是一个for循环,其代码如下:

for (call = __early_initcall_end; call < __initcall_end; call++)
		do_one_initcall(*call);

其中__early_initcall_end和__initcall_end,在arch/arm/kernel/vmlinux.lds有如下定义:

__early_initcall_end = .; *(.initcall0.init) *(.initcall0s.init) *(.initcall1.init) *(.initcall1s.init) *(.initcall2.init) *(.initcall2s.init) *(.initcall3.init) *(.initcall3s.init) *(.initcall4.init) *(.initcall4s.init) *(.initcall5.init) *(.initcall5s.init) *(.initcallrootfs.init) *(.initcall6.init) *(.initcall6s.init) *(.initcall7.init) *(.initcall7s.init)
  __initcall_end = .;

工作队列相关部分

start_kernel [init/main.c] --> reset_init() --> kernel_init() --> do_basic_setup() --> init_workqueues() [kernel/workqueue.c ]

抱歉!评论已关闭.