万字详文干货:从无盘启动volumio看Linux启动原理( 二 )

  • UEFI 固件被加载 , 并由它初始化启动要用的硬件 。
  • 固件读取其引导管理器以确定从何处(比如 , 从哪个硬盘及分区)加载哪个 UEFI 应用 。
  • 固件按照引导管理器中的启动项目 , 加载 UEFI 应用 。
  • 已启动的 UEFI 应用还可以启动其他应用(对应于 UEFI shell 或 rEFInd 之类的引导管理器的情况)或者启动内核及 initramfs(对应于 GRUB 之类引导器的情况) , 这取决于 UEFI 应用的配置
  • 2. PXE回到我的 BIOS 老爷机 , 上电自检完成后 BIOS 按照设置的启动顺序应该交棒磁盘 , 但是 但是 但是 这个机器没有硬盘 , 也没有插入 U 盘 , 找不到任何启动设备的 BIOS 将控制权交给了网卡 , BIOS 光荣退场进入了 PXE 阶段 。
    预启动执行环境(Preboot eXecution Environment , PXE , 也被称为预执行环境) 提供了一种使用网络接口启动计算机的机制 。 这种机制让计算机的启动可以不依赖本地数据存储设备(如硬盘)或本地已安装的操作系统 。
    万字详文干货:从无盘启动volumio看Linux启动原理文章插图
    2.1 PXE 原理
    1. Client 向 DHCP 发送 IP 地址请求消息 , DHCP 返回 Client 的 IP 地址 , 同时将启动文件(如:pxelinux.0)的位置信息(通常是 TFTP 路径)一并传送给 Client
    2. Client 向 TFTP 发送获取启动文件请求消息 , TFTP 接收到消息之后再向 Client 发送启动文件大小信息 , 试探 Client 是否满意 , 当 TFTP 收到 Client 发回的同意大小信息之后 , 正式向 Client 发送启动文件 Client 执行接收文件
    3. Client 向 TFTP 发送针对本机的配置信息文件请求 , TFTP 将配置文件发回 Client , 继而 Client 根据配置文件执行后续操作 。
    4. Client 会加载启动文件 , 之后根据配置执行动作 。 这里有多重方案进行下一步操作 。
    5. 可以直接通过 Http 协议获取 Linux kernel 和 ramdisk 然后启动
    6. 或者加载一块 iscsi 磁盘 , 将 linux kernel 和 ramdisk 等信息放在 iscsi 磁盘中 , 走正常磁盘引导 。 我用的是这种方案

    万字详文干货:从无盘启动volumio看Linux启动原理文章插图
    2.2 iPXE上面说到了启动文件 , 普通的 pxe 启动文件功能有限 , 通常只能从 tftp 服务器上获取文件 , 不支持 HTTP 协议和其他共享协议 , 更别说我们要支持的 iscsi 磁盘挂载了 。 这里推荐一个高端开源 pxe 启动文件:iPXE() 。 它支持从 HTTP、iscsi SAN、 Fibre Channel SAN、AoE SAN 等多种方式启动 , 甚至还支持无线网卡 。 此外它还可以定制一个启动脚本和菜单 。
    iPXE 需要根据自己硬件对应的平台进行编译 , 编译前需要搞清楚几个要点:
    • 启动方式:BIOS 或者 EFI 前面已经说了 。
    • 平台:X86 或 ARM , 如果用树莓派等产品就是 ARM , PC 是 x86
    • CPU 位:32 或 64 , 32 位机器只支持 32 位固件 , 64 位机器可以兼容 32 位和 64 位固件 。 注意:如果使用 64 位固件需要保证后续所有环节使用兼容 64 位的软件 , 我就遇到了 SysLinux 不支持 64 位 , 导致卡死的问题 。
    使用如下命令编译(更多细节见:appnote/buildtargets):
    git clone git://git.ipxe.org/ipxe.git
    make [platform]/[driver].[extension]
    Platform 支持如下:按照上面说的启动方式、平台、CPU 情况选择 。
    • bin (alias for bin-i386-pcbios)
    • bin-i386-pcbios
    • bin-i386-efi
    • bin-i386-linux
    • bin-x86_64-efi
    • bin-x86_64-linux
    • bin-x86_64-pcbios
    • bin-arm32-efi
    • bin-arm64-efi
    Driver:主要选择支持的网卡驱动类型 , 一般选 ipxe(表示所有支持的网卡 , 但可能导致生成的启动文件过大 , 如果过大可以酌情选其它)
    Boot type:和启动方式、启动介质有关 , 参考下表:
    万字详文干货:从无盘启动volumio看Linux启动原理文章插图
    编译时添加 EMBED={脚本名称} 可以关联一个启动脚本 。 推荐一个大佬做好的脚本可以直接使用 。
    我最终命令如下:
    git clone git://git.ipxe.org/ipxe.git
    cd ./ipxe/src
    wget
    make bin-i386-pcbios/ipxe.pxe EMBED=menu.ipxe
    完成之后在/data/ipxe/src/bin-i386-pcbios/ipxe.pxe 可以拿到最终的启动文件 。
    2.3 DHCP、TFTP 配置如何配置 DHCP 和 TFTP 服务器不是本文重点 , 如果需要命令行方式配置可以参考这篇文章的前半部分
    如今大部分高端路由器或开源路由器固件都内置了 DHCP 和 TFTP 配置功能 。 我家的 LEDE 路由器配置界面如下 。
    万字详文干货:从无盘启动volumio看Linux启动原理文章插图