start_kernel

01.void __init x86_64_start_kernel(char * real_mode_data)  
02.{  
03.    int i;  
04.  
05.    /* 内核映像和模块区域映射的完整性检查 */  
06.    ...  
07.  
08.    /* clear bss before set_intr_gate with early_idt_handler */  
09.    clear_bss();  
10.  
11.    /* Make NULL pointers segfault */  
12.    zap_identity_mappings();  
13.  
14.    /* KERNEL_IMAGE_START = 0xffffffff80000000UL    KERNEL_IMAGE_SIZE = 512M 
15.     * PAGE_OFFSET =    0xffff880000000000UL    PAGE_SHIFT =        12 
16.     */  
17.    max_pfn_mapped = KERNEL_IMAGE_SIZE >> PAGE_SHIFT;  
18.  
19.    for (i = 0; i < NUM_EXCEPTION_VECTORS; i++)  // segment.h中定义NUM_EXCEPTION_VECTORS = 32   
20.        set_intr_gate(i, early_idt_handler);    // 往idt_table[i]数组中写入一个门描述符,处理函数是early_idt_handler   
21.  
22.    /* struct desc_ptr idt_descr = { NR_VECTORS * 16 - 1, (unsigned long) idt_table }; 
23.     * lidt汇编指令利用idt_descr变量初始化idtr寄存器,NR_VECTORS = 256 */  
24.    load_idt((const struct desc_ptr *)&idt_descr);  
25.  
26.    x86_64_start_reservations(real_mode_data);  
27.}  
28.  
29.static void __init zap_identity_mappings(void)  
30.{  
31.    /* (pgd_t *)(init_mm.pgd + pgd_index(addr)) = (pgd_t)0 */  
32.    pgd_t *pgd = pgd_offset_k(0UL);  
33.    pgd_clear(pgd);  
34.  
35.    /* Read-Modify-Write to CR4 */  
36.    __flush_tlb_all();  
37.}  
38.  
39.static void __init clear_bss(void)  
40.{ memset(__bss_start, 0, (unsigned long) __bss_stop - (unsigned long) __bss_start); }  
41.  
42.static void __init copy_bootdata(char *real_mode_data)  
43.{  
44.    char * command_line;  
45.  
46.    memcpy(&boot_params, real_mode_data, sizeof boot_params);  
47.    if (boot_params.hdr.cmd_line_ptr) {  
48.        command_line = __va(boot_params.hdr.cmd_line_ptr);  
49.        memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);  
50.    }  
51.}  
52.void __init x86_64_start_reservations(char *real_mode_data)  
53.{  
54.    copy_bootdata(__va(real_mode_data));  
55.    memblock_init();  
56.    memblock_x86_reserve_range(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");  
57.  
58.#ifdef CONFIG_BLK_DEV_INITRD   
59.    /* Reserve INITRD */  
60.    if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) {  
61.        /* Assume only end is not page aligned */  
62.        unsigned long ramdisk_image = boot_params.hdr.ramdisk_image;  
63.        unsigned long ramdisk_size  = boot_params.hdr.ramdisk_size;  
64.        unsigned long ramdisk_end   = PAGE_ALIGN(ramdisk_image + ramdisk_size);  
65.        memblock_x86_reserve_range(ramdisk_image, ramdisk_end, "RAMDISK");  
66.    }  
67.#endif   
68.  
69.    reserve_ebda_region();  
70.    /* At this point everything still needed from the boot loader or BIOS or kernel text  
71.     * should be early reserved or marked not RAM in e820. All other memory is free game. */  
72.    start_kernel();  
73.}  
74.  
75.  
76.asmlinkage void __init start_kernel(void)  
77.{  
78.    char * command_line;  
79.    extern const struct kernel_param __start___param[], __stop___param[];  
80.  
81.    /* 当只有一个CPU的时候这个函数什么都不做,SMP时,返回在启动的时候的那个CPU号 */  
82.    smp_setup_processor_id();  
83.  
84.    /* Need to run as early as possible, to initialize the lockdep hash: */  
85.    lockdep_init();  
86.    debug_objects_early_init();  
87.  
88.    /* Set up the the initial canary ASAP: */  
89.    boot_init_stack_canary();  
90.    cgroup_init_early();    /* 系统启动时的cgroup初始化,初始化那些要求early init的子系统 */  
91.    local_irq_disable();  
92.    early_boot_irqs_disabled = true;  
93.    /* Interrupts are still disabled. Do necessary setups, then enable them */  
94.    tick_init();  
95.    boot_cpu_init();  
96.    /* 初始化页地址,使用链表将其链接起来 */  
97.    page_address_init();  
98.    printk(KERN_NOTICE "%s", linux_banner);  
99.  
100.    /* 体系结构相关函数,由源码树顶层目录下的Makefile中的ARCH变量决定 */  
101.    setup_arch(&command_line);  
102.    mm_init_owner(&init_mm, &init_task);    /* init_mm.owner = &init_task */  
103.    mm_init_cpumask(&init_mm);  
104.    setup_command_line(command_line);  
105.    setup_nr_cpu_ids();         /* nr_cpu_ids = NR_CPUS */  
106.    setup_per_cpu_areas();  
107.    smp_prepare_boot_cpu();         /* arch-specific boot-cpu hooks */  
108.  
109.    build_all_zonelists(NULL);  
110.    page_alloc_init();  
111.  
112.    printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line);  
113.  
114.    /* 对内核选项的两次解析 */  
115.    parse_early_param();  
116.    parse_args("Booting kernel", static_command_line, __start___param,  
117.           __stop___param - __start___param, &unknown_bootoption);  
118.  
119.    /* These use large bootmem allocations and must precede kmem_cache_init() */  
120.    setup_log_buf(0);  
121.  
122.    /* 初始化hash表,便于从进程的PID获得对应的进程描述符指针 */  
123.    pidhash_init();  
124.  
125.    /* 虚拟文件系统初始化,包括dcache\inode\files\mnt\bdev_cache\chrdev_init() */  
126.    vfs_caches_init_early();  
127.    sort_main_extable();  
128.  
129.    /* trap_init函数完成对系统保留中断向量(异常、非屏蔽中断以及系统调用)的初始化 
130.     * init_IRQ函数则完成其余中断向量的初始化 
131.     */  
132.    trap_init();  
133.    mm_init();  
134.  
135.    /* Set up the scheduler prior starting any interrupts (such as the 
136.     * timer interrupt). Full topology setup happens at smp_init() 
137.     * time - but meanwhile we still have a functioning scheduler. 
138.     */  
139.    sched_init();  
140.    /* 
141.     * Disable preemption - early bootup scheduling is extremely 
142.     * fragile until we cpu_idle() for the first time. 
143.     */  
144.    preempt_disable();  
145.    if (!irqs_disabled()) {  
146.        printk(KERN_WARNING "start_kernel(): bug: interrupts were "  
147.                "enabled *very* early, fixing it\n");  
148.        local_irq_disable();  
149.    }  
150.    idr_init_cache();  
151.  
152.    /* NOTE: */  
153.    perf_event_init();  
154.  
155.    rcu_init();  
156.    radix_tree_init();  
157.    /* init some links before init_ISA_irqs() */  
158.    early_irq_init();  
159.    init_IRQ();  
160.    prio_tree_init();  
161.  
162.    /* 初始化定时器相关的数据结构*/  
163.    init_timers();  
164.  
165.    /* 对高精度时钟进行初始化 */  
166.    hrtimers_init();  
167.  
168.    softirq_init();  
169.    timekeeping_init();  
170.  
171.    /* 初始化系统时钟源 */  
172.    time_init();  
173.  
174.    /* 对内核的profile功能(一个内核性能调试工具)进行初始化 */  
175.    profile_init();  
176.    call_function_init();  
177.    if (!irqs_disabled())  
178.        printk(KERN_CRIT "start_kernel(): bug: interrupts were "  
179.                 "enabled early\n");  
180.    early_boot_irqs_disabled = false;  
181.    local_irq_enable();  
182.  
183.    /* Interrupts are enabled now so all GFP allocations are safe. */  
184.    gfp_allowed_mask = __GFP_BITS_MASK;  
185.  
186.    /* slab初始化 */  
187.    kmem_cache_init_late();  
188.  
189.    /* 
190.     * HACK ALERT! This is early. We're enabling the console before 
191.     * we've done PCI setups etc, and console_init() must be aware of 
192.     * this. But we do want output early, in case something goes wrong. 
193.     */  
194.    /* 控制台初始化以显示printk的内容,在此之前调用的printk只是把数据存到缓冲区里 */  
195.    console_init();  
196.    if (panic_later)  
197.        panic(panic_later, panic_param);  
198.  
199.    /* 如果定义了CONFIG_LOCKDEP宏,则打印锁依赖信息,否则什么也不做 */  
200.    lockdep_info();  
201.  
202.    /* 
203.     * Need to run this when irqs are enabled, because it wants 
204.     * to self-test [hard/soft]-irqs on/off lock inversion bugs 
205.     * too: 
206.     */  
207.    locking_selftest();  
208.  
209.#ifdef CONFIG_BLK_DEV_INITRD   
210.    if (initrd_start && !initrd_below_start_ok &&  
211.        page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) {  
212.        printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "  
213.            "disabling it.\n",  
214.            page_to_pfn(virt_to_page((void *)initrd_start)),  
215.            min_low_pfn);  
216.        initrd_start = 0;  
217.    }  
218.#endif   
219.    page_cgroup_init();  
220.    enable_debug_pagealloc();  
221.    debug_objects_mem_init();  
222.    kmemleak_init();  
223.    setup_per_cpu_pageset();  
224.    numa_policy_init();  
225.    if (late_time_init)  
226.        late_time_init();  
227.    sched_clock_init();  
228.  
229.    /* 根据CPU在1s内执行极短循环的次数,得到BogoMIPS值 */  
230.    calibrate_delay();  
231.    pidmap_init();  
232.    anon_vma_init();  
233.#ifdef CONFIG_X86   
234.    if (efi_enabled)  
235.        efi_enter_virtual_mode();  
236.#endif   
237.    thread_info_cache_init();  
238.    cred_init();  
239.  
240.    /* 根据物理内存大小计算允许创建进程数量 */  
241.    fork_init(totalram_pages);  
242.    proc_caches_init();  
243.    buffer_init();  
244.    key_init();  
245.    security_init();  
246.    dbg_late_init();  
247.    vfs_caches_init(totalram_pages);  
248.    signals_init();  
249.    /* rootfs populating might need page-writeback */  
250.    page_writeback_init();  
251.#ifdef CONFIG_PROC_FS   
252.    proc_root_init();  
253.#endif   
254.    cgroup_init();      /* 注册cgroup文件系统并创建/proc/cgroup文件,初始化所有在cgroup_init_early中没有初始化的子系统 */  
255.    cpuset_init();  
256.    taskstats_init_early();  
257.    delayacct_init();  
258.  
259.    /* 测试CPU的各种缺陷,记录检测到的缺陷,以便于内核的其他部分可以使用它们的工作 
260.     * check_bugs=>identify_boot_cpu=>identify_cpu会做很多工作,包括select_idle_routine以及intel_init_thermal  
261.     */  
262.    check_bugs();  
263.  
264.    acpi_early_init(); /* before LAPIC and SMP init */  
265.    sfi_init_late();  
266.  
267.    ftrace_init();  
268.  
269.    /* Do the rest non-__init'ed, we're now alive */  
270.    /* 创建init进程 */  
271.    rest_init();  
272.}  


 

转自:http://blog.csdn.net/wlp600/article/details/6935731

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值