从start_kernel函数了解内核架构(一)

刘昆

《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 


内核init目录下的main.c文件定义了内核启动第二阶段的主干函数,start_kernel(),通过分析start_kernel的执行过程,将有助于切入内核架构的完整分析,时间仓促,仅分析了start_kernel的前半部分和最重要的rest_init().

/*

  asmlinkage:被函数执行过程中,通过堆栈传参

 __visible :新添宏,可能指symbol可标注debugger信息

 __init: 该函数为主切入函数(模块入口函数等)

 */

asmlinkage __visible void __init start_kernel(void)


{

  int i;

char *command_line;

char *after_dashes;


/*

* Need to run as early as possible, to initialize the

* lockdep hash:

*/

lockdep_init(); //哈希表初始化

set_task_stack_end_magic(&init_task);

  /*init_task为结构体数据,内核运行栈信息相关初始化

   struct task_struct {

   u64 curr_chain_key;

   int lockdep_depth;

   unsigned int lockdep_recursion;

   struct held_lock held_locks[MAX_LOCK_DEPTH];

   gfp_t lockdep_reclaim_gfp;

   int pid;

   char comm[17];

   };

   */

smp_setup_processor_id();  //预留接口,函数体无内容,但arch目录中个别平台代码有该函数定义

  debug_objects_early_init(); //初始化操作object tracker


/*

* Set up the the initial canary ASAP:

*/

boot_init_stack_canary(); //一种堆栈保护算法


cgroup_init_early();  //加载内核态中完整subsystem信息


local_irq_disable();    //宏函数,start_kernel是内核启动的第二阶段,仍然需要disable中断请求

early_boot_irqs_disabled = true;


/*

 * Interrupts are still disabled. Do necessary setups, then

 * enable them

 */

boot_cpu_init();  //CPU相关初始化,如设置CPUonlineactivepresent以满足SMP等特殊需求

page_address_init();//CPU相关内存页相关检查

pr_notice("%s", linux_banner); //内核版本等相关信息,启动无关代码

setup_arch(&command_line);   //设置内核启动时显示的command_line信息格式等

mm_init_cpumask(&init_mm);   //CPU相关内存初始化相关

setup_command_line(command_line); //command_line虚拟内存与物理内存信息传递

setup_nr_cpu_ids();         //cpu相关初始化

setup_per_cpu_areas();

smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */


build_all_zonelists(NULL, NULL); //初始化zonelistset_node

page_alloc_init();    //仍然是CPU相关内存初始化


pr_notice("Kernel command line: %s\n", boot_command_line);

parse_early_param();   //command_line参数解析相关

after_dashes = parse_args("Booting kernel",

  static_command_line, __start___param,

  __stop___param - __start___param,

  -1, -1, &unknown_bootoption);

if (!IS_ERR_OR_NULL(after_dashes))

parse_args("Setting init args", after_dashes, NULL, 0, -1, -1,

  set_init_arg);


jump_label_init();  //添加label跳转标签


/*

* These use large bootmem allocations and must precede

* kmem_cache_init()

*/

setup_log_buf(0);   //日志相关

pidhash_init();  //pidhash表初始化

vfs_caches_init_early(); //虚拟文件系统初始化前准备,dcashinode相关hash表初始化

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();  //禁用优先抢占模式

.........


/* Do the rest non-__init'ed, we're now alive */

rest_init();

  /*内核启动的相关运行环境初始化完毕后,将

   开始驱动模块初始化,

   用户态运行环境相关初始化,

   以及开启第一个用户态进程init进程,

   SYSTEM状态由启动状态切换至运行状态,

   内核进入轮转,由cpu_idle()主导执行流程*/

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值