对于老的x86来说,bootloader把内核看成两部分,实模式部分和保护模式部分。bootloader分别把实模式和保护模式加载到内存的不同地方,然后跳转到实模式部分。实模式最后跳转到保护模式部分。

不同的bootloader必须都按照这个规矩来。

下面以uboot为例讲解流程

struct boot_params *load_zimage(char *image, unsigned long kernel_size, ulong *load_addressp)
    =>setup_base = (struct boot_params *)DEFAULT_SETUP_BASE;/* base address for real-mode segment */ 
    /*
     * Memory lay-out:
     *
     * relative to setup_base (which is 0x90000 currently)
     *
     *    0x0000-0x7FFF    Real mode kernel
     *    0x8000-0x8FFF    Stack and heap
     *    0x9000-0x90FF    Kernel command line
     */
     =>/* determine size of setup *///决定内核实模式程序setup.bin的大小
    if (0 == hdr->setup_sects) {
        printf("Setup Sectors = 0 (defaulting to 4)\n");
        setup_size = 5 * 512;
    } else {
        setup_size = (hdr->setup_sects + 1) * 512;
    }
    =>bootproto = get_boot_protocol(hdr);//老内核需要执行setup.bin,新内核应该可以直接进入保护模式,只有hdr等参数有用
    =>/* Determine image type */
    big_image = (bootproto >= 0x0200) &&
            (hdr->loadflags & BIG_KERNEL_FLAG);

/* Determine load address *///决定保护模式内核uImage的加载地址
    if (big_image)
        *load_addressp = BZIMAGE_LOAD_ADDR;
    else
        *load_addressp = ZIMAGE_LOAD_ADDR;
    =>memset(setup_base, 0, sizeof(*setup_base));//初始化setup_base
    setup_base->hdr = params->hdr;

if (bootproto >= 0x0204)
        kernel_size = hdr->syssize * 16;
    else
        kernel_size -= setup_size;

if (bootproto == 0x0100) {
        /*
         * A very old kernel MUST have its real-mode code
         * loaded at 0x90000
         */
        if ((ulong)setup_base != 0x90000) {
            /* Copy the real-mode kernel *///老内核需要实模式的setup.bin引导
            memmove((void *)0x90000, setup_base, setup_size);

/* Copy the command line */
            memmove((void *)0x99000,
                (u8 *)setup_base + COMMAND_LINE_OFFSET,
                COMMAND_LINE_SIZE);

/* Relocated */
            setup_base = (struct boot_params *)0x90000;
        }

/* It is recommended to clear memory up to the 32K mark */
        memset((u8 *)0x90000 + setup_size, 0,
               SETUP_MAX_SIZE - setup_size);
    }
    =>memmove((void *)*load_addressp, image + setup_size, kernel_size);//将保护模式内核拷贝到内存指定地方,保护模式参数作为出参返回
    =>return setup_base;//返回实模式地址

如果protocol为0x100才加载setup.bin。所以猜测uboot在保护模式下直接启动linux的保护模式uImage,而跳过了内核的实模式部分。

而grub则不一定,估计是实模式加载setup.bin然后跳转。

将来有机会仔细研究。

linux boot 学习
https://blog.csdn.net/zeflove/article/details/7565269

慢慢欣赏linux x86 bootloader加载kernel的策略相关推荐

  1. 全志A10/A20 Bootloader加载过程分析

    原文 : http://blog.csdn.net/allen6268198/article/details/12905425 从这里开始:http://linux-sunxi.org/Bootabl ...

  2. 【转】全志A10/A20 Bootloader加载过程分析

    原文 : http://blog.csdn.net/allen6268198/article/details/12905425 从这里开始:http://linux-sunxi.org/Bootabl ...

  3. 转 A10/A20 Bootloader加载过程分析

    A10/A20 Bootloader加载过程分析 注:由于全志A10和A20在加载Bootloader过程方面基本一致,下面仅以A20叙述,但同时也适用于A10.另外在不需要区分Cubieboard1 ...

  4. 转:A10/A20 Bootloader加载过程分析

    来自:http://blog.csdn.net/allen6268198/article/details/12905425 A10/A20 Bootloader加载过程分析 注:由于全志A10和A20 ...

  5. linux内核被加载的过程

    现采取的措施是 在loader加载kernel的同时 也加载initial RAM Disk ==initrd 到内存中. initrd在一般命名为/boot/initrd(14M) 其作用是挂载内存 ...

  6. linux ipv6模块,有关Linux ipv6模块加载失败的问题

    有关Linux ipv6模块加载失败的问题 同事一个SUSE11sp3环境配置ipv6地址失败,提示不支持IPv6,请求帮助,第一反应是应该ipv6相关内核模块没有加载. 主要检查内容: ipv6地址 ...

  7. Linux重新读写分区的命令,用partprobe、blockdev、hdparm、partx命令在Linux中重新加载分区表...

    本文介绍Linux操作系统重新加载分区表的方法:使用partprobe.blockdev.hdparm.partx命令. 背景 作为Linux管理员,你可以在一天内多次执行磁盘分区任务.大多数情况下, ...

  8. Linux环境变量加载的研究

    我们经常遇到在linux执行某条命令时出现xxx文件没找到的问题.很多情况都不是库没有安装,而是环境变量的错误. 但是,我明明是设置了环境变量啊.所以,我对此进行了试验. 我们登录linux有很多种, ...

  9. linux path环境变量检索目录,Linux下动态链接库加载路径及搜索路径问题

    引子 近日,服务器迁移后,偷懒未重新编译nginx的,直接./nginx启动,结果遇到如下问题: "error while loading shared libraries" 这是 ...

最新文章

  1. html5 响应式布局
  2. 【桌面虚拟化】之四设计方法
  3. pandas read_csv 出现中文乱码
  4. 【计组实验】P4 Verilog多周期处理器微系统 MIPS指令集
  5. (一)Neo4j在Centos7虚拟机上的安装
  6. 字符串p型编码(信息学奥赛一本通-T1145)
  7. C++:获取图片文件信息-图片名称、类型、像素宽高
  8. Django多域名配置之Django-hosts插件的使用
  9. Angualr8 ViewChild报错
  10. prim算法_最小生成树(Kruskal和Prim算法)
  11. python共享内存mmap_python - IPC在单独的Docker容器中的Python脚本之间共享内存 - 堆栈内存溢出...
  12. 卧槽!真可恶,竟然有人贩卖儿童软色情表情包,网友:...
  13. 众多时间时钟Flash动画素材一键即可获取
  14. WebS WebStorm WebStorm WebS官方版下载
  15. 游戏测试主要工作及主要流程
  16. matlab 日期加小时数_将EXCEL 中的日期 时间 导入到MATLAB坐标轴中
  17. ffmpeg滤镜专题2-高斯模糊
  18. 副高 职称计算机 上海,高级职称评定
  19. 不积跬步无以至千里,不积小流无以成江海
  20. UE4流关卡与无缝地图切换总结

热门文章

  1. 超简单:3分钟制作惊艳的词云图
  2. Window Internal 读书笔记
  3. java编程思想初始化引用,JAVA编程思想--第5章 初始化与清理
  4. 【DX-BT24蓝牙模块-AT命令与手机透传教程】
  5. hive中文繁简转化opencc4j
  6. 求平方根问题 (C++ 实现)
  7. 都这个点了,尽然还写博客啊,总结
  8. 清华大学计算机博后,科学网—我在清华做博士后的收获 - 喻海良的博文
  9. R语言如何实现Excel中的数据筛选功能
  10. jQuery性能优化