了解完kernel启动以前的汇编之后我们来看看正式的c语言启动代码,也就是我们的start_kernel函数了。start_kernel相当大,里面每一个调用到的函数都足够我们伤脑筋了,我这里只是浅尝辄止的描述一下函数的功能,从而对kernel启动的过程有一个比较直观的了解。很多函数真正理解需要对linux相关体系有很深的了解,暂时没有时间深入,留待以后了。
说实话启动的代码看到现在唯一的感觉就是kernel的全局变量实在太多了,要了解一个过程跟踪一个变量的值的变化相当痛苦啊,不过耐心看下来,收获还是比较丰富的,对很多概念都有了一个比较直观的理解。闲话就不多说了,直接来上代码~~
smp_setup_processor_id();
//这个函数现在是空的;
lockdep_init();
//Runtime locking correctness validator, see Documentation/lockdep_design.txt
debug_objects_early_init();
cgroup_init_early();
//Control group, read Documentation/cgroup.txt
local_irq_disable();
//使用arm cpsid i指令来禁止IRQ
early_boot_irqs_off();
early_init_irq_lock_class();
lock_kernel();
tick_init();
//和时钟相关的初始化,好像是注册notify事件,没有仔细研究过
boot_cpu_init();
//这个实际上是在SMP环境下选择CPU,这里直接CPUID选择的是0号cpu
page_address_init();
//初始化high memory,在arm环境下实际上这个函数是空的,也就是说arm不支持high memory
printk(KERN_NOTICE);
printk(linux_banner);
//这里的KER_NOTICE是字符串<5>,不太明白它的意思。。。后面的linux_banner定义在kernel/init/version.c里面,这里的printk是门高深的学问,以后看console的时候会仔细分析
setup_arch(&command_line);
request_standard_resources(&meminfo, mdesc);
这个函数用来申请一些应该是内存资源,具体的内容没有仔细研究,看不大懂。。
cpu_init();
初始化CPU,这里主要是对arm寄存器cpsr的操作
init_arch_irq = mdesc->init_irq;
system_timer = mdesc->timer;
init_machine = mdesc->init_machine;
这里将体系结构相关的几个函数,中断,初始化,定时器之类的赋值给kernel全局变量;
conswitchp = &vga_con;
这里设置了关于console的一个变量,具体不知道怎么用的,以后看console的时候再仔细分析
early_trap_init();
不知道这个函数具体做什么用的。。。 */
差不多这边就讲到这里,下一篇将start_kernel的剩余部分讲完~~