linux源碼分析(二)-啟動過程


前置:這里使用的linux版本是4.8,x86體系。

這篇是 http://home.ustc.edu.cn/~boj/courses/linux_kernel/1_boot.html 的學習筆記。

linux的啟動過程有點像是小魚吃大魚,最后吃成一個胖子。

計算機中的PC寄存器是用來指示下個執行程序。最開始的時候,pc寄存器都是指向0xfffffff0。這個程序是指向BIOS的POST程序的。POST全稱是Power On Self Test,意思是加點自檢。過程包括內存檢查,系統總線檢查等。

POST過程結束,就進入到了自舉過程,自舉過程把MBR(主引導扇區)加載到內存中,並且執行它。這個主引導扇區是第一個扇區的前512字節。

Master Boot Record過程是為了后面一個過程准備的。它主要做的是讀入GRUB stage2所在的扇區。並且執行它。

GRUB stage2 將系統切換到保護模式。設置C運行環境。

然后進入到x86/boot/header.S中執行。在這里面,你能找到main的函數入口。這個對應到x86/boot/main.c的main函數。

這個main函數執行到最后會進入go_to_protected_mode(); 進入到pm.c的這個函數的定義,除了初始化一些邏輯以外,主要是protected_mode_jump

下面就進入到boot/pmjump.S的protected_mode_jump

29 protected_mode_jump:
30        movl    %edx, %esi              # Pointer to boot_params table
31
32        xorl    %ebx, %ebx
33        movw    %cs, %bx                # 將實模式的代碼段放入 bx
34        shll    $4, %ebx                # 轉換為線性地址
35        addl    %ebx, 2f                # 將 in_pm32 的實模式地址轉換為線性地址
36
37        movw    $__BOOT_DS, %cx        # ds 段選擇子
38        movw    $__BOOT_TSS, %di        # tss 段選擇子
39
40        movl    %cr0, %edx
41        orb    $X86_CR0_PE, %dl        # Protected mode
42        movl    %edx, %cr0              # 將 cr0 的0位置0是進入保護模式的標志
43        jmp    1f                      # Short jump to serialize on 386/486
44 1:
45        # 下面這段作用是跳轉到 in_pm32,由於已經在保護模式,所以需要考慮段的問題
46        # Transition to 32-bit mode
47        .byte  0x66, 0xea              # ljmpl opcode
48 2:      .long  in_pm32                # offset
49        .word  __BOOT_CS              # segment
50
51        .size  protected_mode_jump, .-protected_mode_jump
52
53        .code32
54        .type  in_pm32, @function
55 in_pm32:        # 下面的注釋挺清楚,就不翻譯了
56        # Set up data segments for flat 32-bit mode
57        movl    %ecx, %ds
58        movl    %ecx, %es
59        movl    %ecx, %fs
60        movl    %ecx, %gs
61        movl    %ecx, %ss
62        # The 32-bit code sets up its own stack, but this way we do have
63        # a valid stack if some debugging hack wants to use it.
64        addl    %ebx, %esp
65
66        # Set up TR to make Intel VT happy
67        ltr    %di                    # 這個比較有意思
68
69        # Clear registers to allow for future extensions to the
70        # 32-bit boot protocol
71        xorl    %ecx, %ecx
72        xorl    %edx, %edx
73        xorl    %ebx, %ebx
74        xorl    %ebp, %ebp
75        xorl    %edi, %edi
76
77        # Set up LDTR to make Intel VT happy
78        lldt    %cx                    # 又是一個騙 CPU 的東西

79        # eax 是 protected_mode_jump 的第一個參數,即 header.S 中定義的 boot_params.hdr.code32_start,即 vmlinux 的入口地址
80        jmpl    *%eax                  # Jump to the 32-bit entrypoint
81
82        .size  in_pm32, .-in_pm32

最后的jmpl就跳轉到
arch/x86/kernel/head_32.S的startup_32

ENTRY(initial_code)
    .long i386_start_kernel

進入到arch/x86/kernel/head32.c

asmlinkage __visible void __init i386_start_kernel(void)
{
    cr4_init_shadow();
    sanitize_boot_params(&boot_params);

    x86_early_init_platform_quirks();

    /* Call the subarch specific early setup function */
    switch (boot_params.hdr.hardware_subarch) {
    case X86_SUBARCH_INTEL_MID:
        x86_intel_mid_early_setup();
        break;
    case X86_SUBARCH_CE4100:
        x86_ce4100_early_setup();
        break;
    default:
        i386_default_early_setup();
        break;
    }

    start_kernel();
}

這里最后是調用了start_kernel,這里的start_kernel是與操作系統無關的init/main.c里面了。

參考

http://home.ustc.edu.cn/~boj/courses/linux_kernel/1_boot.html
http://blog.csdn.net/alais/article/details/5129005


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM