Linux内核start_kernel()函数


Linux内核start_kernel()函数
  1. asmlinkage void __init start_kernel(void)  
  2. {  
  3.     char * command_line;  
  4.     extern struct kernel_param __start___param[], __stop___param[];  
  5.   
  6.     smp_setup_processor_id();   
  7.     //空函数   
  8.   
  9.     /* 
  10.      * Need to run as early as possible, to initialize the 
  11.      * lockdep hash: 
  12.      */  
  13.   
  14.       
  15.     lockdep_init();/*初始化一些数据*/  
  16.     debug_objects_early_init();  
  17.     cgroup_init_early();  
  18.   
  19.     local_irq_disable(); /*关闭中断*/  
  20.     early_boot_irqs_off();  
  21.     /*   
  22.      * 每一个中断都有一个中断描述符(struct irq_desc)来进行描述,这个函数的   
  23.      * 作用就是设置所有中断描述符的锁   
  24.      */    
  25.     early_init_irq_lock_class();  
  26.   
  27. /* 
  28.  * Interrupts are still disabled. Do necessary setups, then 
  29.  * enable them 
  30.  */  
  31.     lock_kernel(); /*锁上内核,Linux是支持抢占CPU,放弃启动被中断(针对多处理器)*/  
  32.     tick_init(); /*初始化时钟*/  
  33.     boot_cpu_init();/*//这个实际上是在多CPU环境下选择CPU,这里直接CPUID选择的是0号cpu*/  
  34.     page_address_init(); /* 初始化页地址,使用链表将其链接起来 */    
  35.     printk(KERN_NOTICE);  
  36.     printk(linux_banner); /*打印Linux版本*/  
  37.     setup_arch(&command_line); /* 这是一个重量级的函数了,会比较仔细地分析一下,主要完成了4个方面的工作,一个就是取得MACHINE和PROCESSOR的信息然或将他们赋值给kernel相应的全局变量,然后呢是对boot_command_line和tags接行解析,再然后呢就是memory、cach的初始化,最后是为kernel的后续运行请求资源。 */  
  38.     /*初始化内存*/  
  39.     mm_init_owner(&init_mm, &init_task);  
  40.     setup_command_line(command_line); /*保存命令行参数*/  
  41.     setup_per_cpu_areas();/* 为每个cpu申请内存空间 */  
  42.     setup_nr_cpu_ids();  
  43.     smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks//设置启动的CPU为在线状态.在多CPU架构下 */  
  44.   
  45.     /* 
  46.      * Set up the scheduler prior starting any interrupts (such as the 
  47.      * timer interrupt). Full topology setup happens at smp_init() 
  48.      * time - but meanwhile we still have a functioning scheduler. 
  49.      */  
  50.     sched_init();/*初始化进程调度器*/  
  51.     /* 
  52.      * Disable preemption - early bootup scheduling is extremely 
  53.      * fragile until we cpu_idle() for the first time. 
  54.      */  
  55.     preempt_disable(); /*禁止系统调用,即禁止抢占*/  
  56.     build_all_zonelists(); /*建立内存区域链表*/  
  57.     page_alloc_init();/*内存页初始化*/  
  58.     printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line);/*打印Linux命令行启动参数*/  
  59.     parse_early_param();/*解析参数*/  
  60.     parse_args("Booting kernel", static_command_line, __start___param,  
  61.            __stop___param - __start___param,  
  62.            &unknown_bootoption); //执行命令行解析,若参数不存在,则调用unknown_bootoption   
  63.     if (!irqs_disabled()) {  
  64.         printk(KERN_WARNING "start_kernel(): bug: interrupts were "  
  65.                 "enabled *very* early, fixing it\n");  
  66.         local_irq_disable();  
  67.     }/*判断中断是否关闭,若打开则关闭中断*/  
  68.     sort_main_extable(); /*对异常处理函数排序*/  
  69.     trap_init();/*空函数*/  
  70.     rcu_init();/*初始化互斥机制*/  
  71.     /* init some links before init_ISA_irqs() */  
  72.     early_irq_init();/*中断向量的初始化*/  
  73.     init_IRQ();/*完成其余中断向量的初始化*/  
  74.     pidhash_init();/*进程Hash table的初始化*/  
  75.     init_timers();/*初始化定时器*/  
  76.     hrtimers_init();/*高精度时钟初始化*/  
  77.     softirq_init();/*软中断初始化*/  
  78.     timekeeping_init();/*共用时钟的初始化*/  
  79.     time_init();/*初始化系统时钟*/  
  80.     sched_clock_init();/*进程调度时钟初始化*/  
  81.     profile_init(); /* 对内核的profile(一个内核性能调式工具)功能进行初始化 */    
  82.     if (!irqs_disabled())  
  83.         printk(KERN_CRIT "start_kernel(): bug: interrupts were "  
  84.                  "enabled early\n");  
  85.     early_boot_irqs_on(); /*打开IRQ中断*/  
  86.     local_irq_enable();  
  87.   
  88.     /* 
  89.      * HACK ALERT! This is early. We're enabling the console before 
  90.      * we've done PCI setups etc, and console_init() must be aware of 
  91.      * this. But we do want output early, in case something goes wrong. 
  92.      */  
  93.     console_init();/*打印中断的初始化*/  
  94.     if (panic_later)  
  95.         panic(panic_later, panic_param);  
  96.   
  97.     lockdep_info();  
  98.   
  99.     /* 
  100.      * Need to run this when irqs are enabled, because it wants 
  101.      * to self-test [hard/soft]-irqs on/off lock inversion bugs 
  102.      * too: 
  103.      */  
  104.     locking_selftest();  
  105.   
  106. #ifdef CONFIG_BLK_DEV_INITRD   
  107.     if (initrd_start && !initrd_below_start_ok &&  
  108.         page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) {  
  109.         printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "  
  110.             "disabling it.\n",  
  111.             page_to_pfn(virt_to_page((void *)initrd_start)),  
  112.             min_low_pfn);  
  113.         initrd_start = 0;  
  114.     }  
  115. #endif   
  116.     vmalloc_init(); /*内存池的初始化*/  
  117.     vfs_caches_init_early();/*虚拟文件系统的初始化*/  
  118.     cpuset_init_early();/*空函数*/  
  119.     page_cgroup_init();/**/  
  120.     mem_init();/*对全局的物理页变量初始化,对没有分配的页面初始化*/  
  121.     enable_debug_pagealloc();  
  122.     cpu_hotplug_init();/*空函数*/  
  123.     kmem_cache_init();/*内核内存缓冲池的初始化*/  
  124.     debug_objects_mem_init();  
  125.     idr_init_cache();/*idr初始化缓冲*/  
  126.     setup_per_cpu_pageset();/*空函数*/  
  127.     numa_policy_init();/*空函数*/  
  128.     if (late_time_init)  
  129.         late_time_init();  
  130.     calibrate_delay(); /*校验延时函数的精确度*/  
  131.     pidmap_init();/*进程号位图初始化,一般用一个page来只是所有的进程PID占用情况*/  
  132.     pgtable_cache_init();/*空函数*/  
  133.     prio_tree_init();/*初始化优先级数组*/  
  134.     anon_vma_init();/*空函数*/  
  135. #ifdef CONFIG_X86   
  136.     if (efi_enabled)  
  137.         efi_enter_virtual_mode();  
  138. #endif   
  139.     thread_info_cache_init();/*空函数*/  
  140.     cred_init();  
  141.     fork_init(num_physpages);/*初始化fork()环境*/  
  142.     proc_caches_init();/*为proc文件系统创建高速缓存*/  
  143.     buffer_init();/*空函数*/  
  144.     key_init();/*没有键盘为空,有键盘初始化一个高速缓存*/  
  145.     security_init();/*空函数*/  
  146.     vfs_caches_init(num_physpages); /*虚拟文件系统挂载*/  
  147.     radix_tree_init();/*radix树的初始化,供页面查找*/  
  148.     signals_init();/*初始化信号量*/  
  149.     /* rootfs populating might need page-writeback */  
  150.     page_writeback_init();/*CPU在内存中开辟高速缓存,CPU直接访问高速缓存提以高速度。当cpu更新了高速缓存的数据后,需要定期将高速缓存的数据写回到存储介质中,比如磁盘和flash等。这个函数初始化写回的周期*/  
  151. #ifdef CONFIG_PROC_FS   
  152.     proc_root_init();/*如果配置了proc文件系统,则需初始化并加载proc文件系统。在根目录的proc文件夹就是proc文件系统,这个文件系统是ram类型的,记录系统的临时数据,系统关机后不会写回到flash中*/  
  153. #endif   
  154.     cgroup_init();/*空函数*/  
  155.     cpuset_init();/*空函数*/  
  156.     taskstats_init_early();/*进程状态初始化,实际上就是分配了一个存储线程状态的高速缓存*/  
  157.     delayacct_init();/*空函数*/  
  158.   
  159.     check_bugs();/*测试CPU的缺陷,记录检测的缺陷,便于内核其他部分工作的需要*/  
  160.   
  161.     acpi_early_init(); /* before LAPIC and SMP init */  
  162.   
  163.     ftrace_init();  
  164.   
  165.     /* Do the rest non-__init'ed, we're now alive */  
  166.     rest_init(); /* 创建init进程 */    
  167. }  

相关内容