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

来源:互联网 发布:淘宝子账号可以删除吗 编辑:程序博客网 时间:2024/05/19 22:47

刘昆

《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 __visiblevoid __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
原创粉丝点击