http://blog.csdn.net/voice_shen/article/details/6690201
[内核版本: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循环,其代码如下:
其中__early_initcall_end和__initcall_end,在arch/arm/kernel/vmlinux.lds有如下定义:
工作队列相关部分:
start_kernel [init/main.c] --> reset_init() --> kernel_init() --> do_basic_setup() --> init_workqueues() [kernel/workqueue.c ]