主要任务一览:
(1)解析uboot传进来的参数
(2)串口控制台初始化
(3)内存管理初始化
(4)时间相关的初始化
(5)启动init进程
注:下面函数注释后边打上“xx”号的不是内核原理入门重点,先跳过不分析
asmlinkage void __init start_kernel(void)
{
char * command_line;
extern struct kernel_param __start___param[], __stop___param[];//这两个外部变量,是内核编译时用于定位的内核参数
smp_setup_processor_id();//这是一个空函数,只有是多个CPU的时候,它返回的是当前启动时的CPU ID
/*
* Need to run as early as possible, to initialize the
* lockdep hash:
*/
lockdep_init(); //第一次初始化哈希链表,该函数定义于linux/kernel/lockdep.c
debug_objects_early_init(); //xx 条件编译宏CONFIG_DEBUG_OBJECTS_FREE未定义
boot_init_stack_canary(); //xx
cgroup_init_early(); //xx
local_irq_disable(); //再次确保关闭当前的CPU中断,虽说之前是一直都没有开启cpu中断的
early_boot_irqs_off(); //xx
early_init_irq_lock_class(); //设置每一个IRQ描述符都有相同的锁(每个中断都有对应的IRQ描述符)
/*
* Interrupts are still disabled. Do necessary setups, then
* enable them
* 启动内核早期要先关闭中断,先进行一些必要的设置,然后再打开中断
*/
lock_kernel(); //xx 内核锁信号:这里相当于do { } while(0)空操作,因为没有定义宏CONFIG_LOCK_KERNEL,它是指大内核锁,本质上是自旋锁,但又不同于自旋锁,自旋锁不可以递归获得锁的,因为那样会导致死锁,但大内核锁可以递归获得锁,大内核锁用于保护整个内核,而自旋锁用于保护非常特定的某一共享资源。从2.6.11内核起,大内核锁可以通过配置内核来实现,但一般在内核中使用较少
/*
它是指大内核锁,本质上是自旋锁,但又不同于自旋锁,自旋锁不可以递归获得锁的,因为那样会导致死锁,
但大内核锁可以递归获得锁,大内核锁用于保护整个内核ÿ