进入start_kernel就是进入了kernel启动的主线。其定义在init/main.c里面。start_kernel里面包含了一长串的init代码。看实际代码之前,我来猜一下有哪些需要初始化的:
1. CPU和SMP的初始化的初始化
2. 内存管理的初始化
3. 互斥和同步
4. 进程管理
5. 文件系统
6. 各类总线的初始化
7. 初始化硬件设备
好了,回头看看代码里面到底做了哪些初始化(以下的注解都是望文生义,我会随着以后对于每个模块的源码解读进行更新):
- asmlinkage void __init start_kernel(void)
-
{
-
char * command_line;
-
extern const struct kernel_param __start___param[], __stop___param[];
-
-
smp_setup_processor_id(); //确定SMP系统中每个CPU的id
-
-
/*
-
* Need to run as early as possible, to initialize the
-
* lockdep hash:
-
*/
-
lockdep_init(); //初始化互斥锁的dependency。
-
debug_objects_early_init(); //初始化debug kernel相关
-
-
/*
-
* Set up the the initial canary ASAP:
-
*/
-
boot_init_stack_canary(); //stack_canary的是带防止栈溢出攻击保护的堆栈。
-
-
cgroup_init_early(); //cgroup是什么??有待查找
-
-
local_irq_disable(); //这个太直白了。
-
early_boot_irqs_off(); //这个也很直白。
-
-
/*
-
* Interrupts are still disabled. Do necessary setups, then
-
* enable them
-
*/
-
tick_init(); //初始化time ticket,时钟
-
boot_cpu_init(); //用以启动的CPU进行初始化。也就是初始化CPU0
-
page_address_init();//初始化页面
-
printk(KERN_NOTICE "%s", linux_banner);
-
setup_arch(&command_line); //CPU架构相关的初始化
-
mm_init_owner(&init_mm, &init_task); //初始化内存管理
-
setup_command_line(command_line); //处理启动命令行
-
setup_nr_cpu_ids(); //nr_cpu_id是什么?
-
setup_per_cpu_areas(); //为每个CPU开辟一块区域?
-
smp_prepare_boot_cpu();//准备boot_cpu. /* arch-specific boot-cpu hooks */
-
-
build_all_zonelists(NULL); //建立什么样的zone??
-
page_alloc_init(); //初始化page allocation相关结构
-
-
printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line);
-
parse_early_param();
-
parse_args("Booting kernel", static_command_line, __start___param,
-
__stop___param - __start___param,
-
&unknown_bootoption);//解析启动参数
-
/*
-
* These use large bootmem allocations and must precede
-
* kmem_cache_init()
-
*/
-
pidhash_init();//初始化process ID hash表
-
vfs_caches_init_early(); //文件系统caches预初始化
-
sort_main_extable(); //初始化exception table
-
trap_init(); //初始化trap,用以处理错误执行代码
-
mm_init(); //初始化内存管理
-
/*
-
* Set up the scheduler prior starting any interrupts (such as the
-
* timer interrupt). Full topology setup happens at smp_init()
-
* time - but meanwhile we still have a functioning scheduler.
-
*/
-
sched_init(); //进程调度初始化
-
/*
-
* Disable preemption - early bootup scheduling is extremely
-
* fragile until we cpu_idle() for the first time.
-
*/
-
preempt_disable(); //这个是什么东东?
-
if (!irqs_disabled()) {
-
printk(KERN_WARNING "start_kernel(): bug: interrupts were "
-
"enabled *very* early, fixing it\n");
-
local_irq_disable();
-
}
-
rcu_init(); //Read_Copy_Update机制初始
-
radix_tree_init(); //什么是radlx_tree
-
/* init some links before init_ISA_irqs() */
-
early_irq_init();
-
init_IRQ(); //初始化中断
-
prio_tree_init(); //这是啥?以后要弄懂
-
init_timers(); //初始化时钟
-
hrtimers_init();//初始化高精时钟
-
softirq_init();//初始化软中断
-
timekeeping_init();//初始化时钟源
-
time_init();//初始化时间例程
-
profile_init(); //Profile?这是什么profile?
-
if (!irqs_disabled())
-
printk(KERN_CRIT "start_kernel(): bug: interrupts were "
-
"enabled early\n");
-
early_boot_irqs_on();
-
local_irq_enable();
-
-
/* Interrupts are enabled now so all GFP allocations are safe. */
-
gfp_allowed_mask = __GFP_BITS_MASK;
-
-
kmem_cache_init_late();//初始化CPU Cache
-
-
/*
-
* HACK ALERT! This is early. We're enabling the console before
-
* we've done PCI setups etc, and console_init() must be aware of
-
* this. But we do want output early, in case something goes wrong.
-
*/
-
console_init(); //初始化console
-
if (panic_later)
-
panic(panic_later, panic_param);
-
-
lockdep_info();
-
-
/*
-
* Need to run this when irqs are enabled, because it wants
-
* to self-test [hard/soft]-irqs on/off lock inversion bugs
-
* too:
-
*/
-
locking_selftest(); //自测试锁
-
-
#ifdef CONFIG_BLK_DEV_INITRD
-
if (initrd_start && !initrd_below_start_ok &&
-
page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) {
-
printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
-
"disabling it.\n",
-
page_to_pfn(virt_to_page((void *)initrd_start)),
-
min_low_pfn);
-
initrd_start = 0;
-
}
-
#endif
-
page_cgroup_init(); //页面初始
-
enable_debug_pagealloc(); //页面分配debug启用
-
kmemleak_init(); //memory leak 侦测初始化
-
debug_objects_mem_init(); //debug object是什么?
-
idr_init_cache(); //idr是什么?
-
setup_per_cpu_pageset(); //设置每个CPU的页面集合
-
numa_policy_init();// NUMA (Non Uniform Memory Access) policy
-
if (late_time_init)
-
late_time_init();
-
sched_clock_init();//初始化调度时钟
-
calibrate_delay(); //协同不同CPU的时钟
-
pidmap_init();//pid是process id还是processor id?
-
anon_vma_init();//anonymous page?什么意思?
-
#ifdef CONFIG_X86
-
if (efi_enabled)
-
efi_enter_virtual_mode();
-
#endif
-
thread_info_cache_init(); //初始化thread info
-
cred_init(); //credential
-
fork_init(totalram_pages); //初始化fork
-
proc_caches_init(); //初始化/proc的cache?
-
buffer_init(); // buffer
-
key_init(); //key
-
security_init();//security
-
dbg_late_init();//debug
-
vfs_caches_init(totalram_pages);//文件系统cache初始化
-
signals_init();//signal
-
/* rootfs populating might need page-writeback */
-
page_writeback_init();page_writeback
-
#ifdef CONFIG_PROC_FS
-
proc_root_init();
-
#endif
-
cgroup_init(); //cgroup?
-
cpuset_init(); //cpuset
-
taskstats_init_early(); //task
-
delayacct_init();
-
-
check_bugs(); //检查什么bug?
-
-
acpi_early_init();//acpi /* before LAPIC and SMP init */
-
sfi_init_late(); //simple firmware interface
-
-
ftrace_init();
-
-
/* Do the rest non-__init'ed, we're now alive */
-
rest_init();
-
}
将这些函数归归类,以后就按照类型来读:
setup_arch(&command_line);
fork_init(totalram_pages);
thread_info_cache_init();
vfs_caches_init(totalram_pages);
debug_objects_early_init();
enable_debug_pagealloc();
debug_objects_mem_init();
efi_enter_virtual_mode();
build_all_zonelists(NULL);
阅读(329) | 评论(0) | 转发(0) |