linux 启动顺序

来源:互联网 发布:淘宝买家好评率95% 编辑:程序博客网 时间:2024/05/02 02:32

1.BIOS阶段

  有关BIOS就不在这里进行叙述,BIOS用于将启动设备中第一个扇区拷贝到RAM中,而这个扇区可能是存放MBR,后者直接是GRUB等引导程序。引导程序存放在RAM中的0x7C00地址上,

2.引导程序执行阶段

    在BIOS阶段中引导程序已经被拷贝到0x00007C00地址上,现在PC指针跳转到该地址上,即执行引导程序指令。这里假设引导程序是GRUB,在linux旧的版本中,GRUB将内核镜像bzImage中setup部分拷贝到0x00009000地址上,将其余部分拷贝到0x000010000上。而对于Linux新版本中,GRUB将内核镜像bzImage中setup部分拷贝到0x10000 以下的某个地址X,而将其余部分拷贝到0x000100000地址上。注意,这里setup部分指的是实模式有关代码,即/arch/XX/boot/。有关内存分布可参考 /Documentation/x86/boot.txt中内容。

3.setup实模式阶段 

   实模式主要用于检测内存,键盘等设备,基本初始化,最后切换到保护模式下工作,这里通常跳转到0x100000执行保护模式代码。

    copy_boot_params();        复制 boot header 到 "zeropage"        validate_cpu();               确保支持当前运行的CPU        set_bios_mode();            告诉BIOS什么CPU我们将要去运行        detect_memory();            检测Memory        keyboard_set_repeat();      设置键盘 repeat rate (Why ?)        set_video();                  设置 Video mode        query_mca();                 获得 MCA 信息        query_voyager();             Voyager ?        query_ist();                   获得  Query Intel SpeedStep (IST) 信息        query_apm_bios();            获得APM 信息        query_edd();                  获得EDD信息

protected_mode_jump(boot_params.hdr.code32_start,
   (u32)&boot_params + (ds() << 4));

code32_start参数在header.s中(arch/i386/boot/header.s) 设置如下 : code32_start:                           # here loaders can put a different                                        # start address for 32-bit code.                .long   0x100000        # 0x100000 = default for big kernel


4.保护模式阶段

     通常0x100000地址上存放vmlinux.bin,但是为了防止内核过大,采用压缩内核的方式减少内核大小,因此vmlinux.bin一般是压缩后的内核,vmlinux.bin包括/boot/compressed/中代码,压缩内核piggy,及解压缩代码,而vmlinux.bin中的入口函数是startup_32(arch/x86//boot/compress/head_32.S),因此跳转到startup_32中执行,这里包括内核解压缩,最终跳转到真正的内核入口的startup_32函数(arch/x86/kernel/head_32.S)中执行。