X86内核启动分析三 内核的实模式阶段

来源:互联网 发布:铃声大全 for mac 编辑:程序博客网 时间:2024/06/07 04:43

开始入口的地方如下:

header.S (c:\linux\linux-2.6.23\arch\i386\boot) //真正的入口是从第二个512字节开始的,bootloader(lilo/grub/uboot)会将控制权交给它_start    =>.byte 0xeb        # short (2-byte) jump    .byte   start_of_setup-1f //跳转到start_of_setup    =>start_of_setup:    #ifdef SAFE_RESET_DISK_CONTROLLER    # Reset the disk controller.//复位硬盘控制器        movw    $0x0000, %ax       # Reset disk controller        movb    $0x80, %dl     # All disks        int $0x13    #endif    =># We will have entered with %cs = %ds+0x20, normalize %cs so    # it is on par with the other segments.        pushw   %ds        pushw   $setup2  //跳转到setup2          lretw    =>setup2:    # Force %es = %ds        movw    %ds, %ax        movw    %ax, %es        cld    =>andw  $~3, %sp  # dword align (might as well...)  //对齐堆栈到16B或者32B        jnz 1f        movw    $0xfffc, %sp   # Make sure we're not zero    1:  movzwl  %sp, %esp   # Clear upper half of %esp        sti    =># Check signature at end of setup  //检查55AA    cmpl    $0x5a5aaa55, setup_sig    jne setup_bad    =># Zero the bss    movw    $__bss_start, %di    movw    $_end+3, %cx    xorl    %eax, %eax    subw    %di, %cx    shrw    $2, %cx    rep; stosl    =># Jump to C code (should not return)    calll   main

保护模式准备

main    =>copy_boot_params();//与bootloader交互的参数都在这里面进行二次加工,例如hdr和cmdline    =>validate_cpu()// x86指令检查一下CPU    =>detect_memory();        =>detect_memory_e820()//通过 int $0x15 中断获取内存分布    =>go_to_protected_mode();machine_specific_memory_setup    =>who = "BIOS-e820";    =>sanitize_e820_map(E820_MAP, &E820_MAP_NR);//去掉重叠的entry    =>if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0)// Copy the BIOS e820 map into a safe place.            copy_e820_map                =>do {//循环所有的entry,加入到map表里面                    unsigned long long start = biosmap->addr;                    unsigned long long size = biosmap->size;                    unsigned long long end = start + size;                    unsigned long type = biosmap->type;                    add_memory_region(start, size, type);                } while (biosmap++,--nr_map);           if (ALT_MEM_K < EXT_MEM_K) {////如果e820不可获取,那么按照默认方式构建可用物理内存            mem_size = EXT_MEM_K;            who = "BIOS-88";        } else {            mem_size = ALT_MEM_K;            who = "BIOS-e801";        }        e820.nr_map = 0;        add_memory_region(0, LOWMEMSIZE(), E820_RAM);        add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM);
阅读全文
0 0