title: 从pxe重新认识iso
created: 2026-09-17
updated: 2026-09-17
type: entity
tags:
- linux
- install
- kernel
- ipmi
- reboot
- entity
sources:
- raw/scripts/离线安装.sh
- raw/scripts/更新内核,修改启动项.md
从pxe重新认识iso
装系统只有一条链路,介质只是"货从哪来":
固件 → 引导器 → 内核 + initrd → 安装程序 → 分区/装包 → 装 bootloader → 重启进系统
① ② ③ ④ ⑤ ⑥
- 前半(一~三章):ISO 是什么,介质怎么从光盘走到 U 盘和 Ventoy(换的是 ①②③ 的货源);
- 后半(四~六章):PXE 怎么工作、怎么彻底不用盘,以及系统到底怎么起来的(④⑤⑥ 永远一样)。
一、ISO 是什么
ISO 文件 = 一张光盘的整盘裸镜像。 从第 0 扇区开始把光盘扇区逐字节照抄进一个文件,挂载它就相当于插了张光盘。
"ISO"本身是标准编号:ISO 9660 是 1988 年的 CD-ROM 文件系统标准(等价 ECMA-119)。
1.1 它不是压缩包
| 压缩包(.tar.gz / .zip) | ISO 镜像 | |
|---|---|---|
| 本质 | 一堆文件打包 + 压缩 | 一张光盘的扇区逐字节照抄 |
| 当设备用 | 不能 | 能:mount -o loop 就是块设备 |
dd 到 U 盘 |
无意义 | 能,这就是 U 盘装系统的原理 |
ISO 是设备镜像(和 Ghost/RAW 同类),不是文件归档,所以压不动。
1.2 四个扩展撑起了它
基础层是 ISO 9660 文件系统,靠扩展补功能:
| 扩展 | 解决什么 |
|---|---|
| El Torito(1995,Phoenix+IBM) | 让光盘能开机(ISO 开头登记一张引导目录) |
| Rock Ridge | 保留 Unix 权限、符号链接、长文件名 |
| Joliet | Windows 长文件名(UCS-2) |
| UDF | DVD 时代:突破单文件大小限制 |
同一个 ISO 在 Windows 和 Linux 下挂载,文件名可能不一样——前者读 Joliet,后者读 Rock Ridge。
1.3 两个"为什么"
为什么刻盘能开机?——El Torito 在 ISO 开头维护一张 boot catalog,登记两条路:BIOS 用 isolinux.bin,UEFI 用类型 0xEF 的条目指向内置 ESP 镜像 efiboot.img。
"一个 ISO 同时支持 BIOS 和 UEFI",本质是登记了两条路,不是固件有多聪明。
为什么 dd 到 U 盘也能开机?——isohybrid 把一段 MBR 引导码写进了 ISO 第一个扇区。于是同一个文件:刻盘走 El Torito,dd 到 U 盘走 MBR。
这是 ISO 历史上最关键的一次改造——没有 isohybrid 的老 ISO,dd 到 U 盘引导不起来。
1.4 两个数字、两种 ISO
| 数字 | 来源 | 后果 |
|---|---|---|
| 4.7 GB | 单层 DVD 的介质容量 | 安装 ISO 贴着这个上限做 |
| 4 GiB | ISO 9660 的单文件上限(32 位长度字段) | 放超过 4G 的单文件必须上 UDF |
CD 是 700 MB,所以 2000 年代初的发行版动辄 4~6 张 CD,换 DVD 后才一张盘装完。
| 类型 | 内容 | 例子 |
|---|---|---|
| 安装型 | 安装程序 + 包仓库 | Rocky DVD、Debian netinst |
| Live 型 | 一个能跑起来的完整系统(squashfs)+ 安装器 | Ubuntu Desktop |
1.5 ISO 里到底有什么
Rocky-9.4-x86_64-dvd.iso
├── isolinux/ # ← BIOS 引导路径
│ ├── isolinux.bin # 引导扇区代码(El Torito 指向它)
│ ├── isolinux.cfg # 引导菜单
│ └── ldlinux.c32 / menu.c32 # 核心模块,缺了起不来
├── EFI/BOOT/ # ← UEFI 引导路径
│ ├── BOOTX64.EFI / grubx64.efi
│ └── grub.cfg
├── images/
│ ├── pxeboot/{vmlinuz,initrd.img} # ★ PXE 要的就是这两个文件
│ ├── install.img # 安装程序 stage2(squashfs,几百 MB)
│ └── efiboot.img
├── BaseOS/ + AppStream/ # ★ 软件包 + repodata(RHEL8+ 双仓库)
└── RPM-GPG-KEY-*
Debian / Ubuntu 同一套骨架换名字:casper/(Live)、install.amd/(netinst)、pool/ + dists/(仓库)。
1.6 ISO ↔ PXE 映射表(前后半在这里接上)
| ISO 里的东西 | PXE 里的对应物 |
|---|---|
| MBR / El Torito 引导目录 | 网卡 PXE ROM + DHCP 66/67 |
isolinux.bin + ldlinux.c32 |
TFTP 上的 pxelinux.0 + ldlinux.c32 |
isolinux.cfg |
TFTP 上的 pxelinux.cfg/default |
EFI/BOOT/BOOTX64.EFI |
TFTP 上的 grubx64.efi(Secure Boot 先 shimx64.efi) |
images/pxeboot/vmlinuz+initrd.img |
TFTP/HTTP 上的同名文件 |
images/install.img |
HTTP 上的 install.img |
BaseOS/+AppStream/+repodata/ |
HTTP/NFS 上的 inst.repo= 目标 |
结论:PXE 不是"另一种装机方式",而是"把 ISO 拆成几份、用网络分别送达"。
所以 inst.repo=http://x.x.x.x/iso/ 让你填的,就是 ISO 里 BaseOS/ 那一层的网络版——HTTP 目录下必须直接是 BaseOS/、repodata/,不能再套一层。
1.7 常用命令
file x.iso # isohybrid 过的会同时报 "DOS/MBR boot sector"
isoinfo -d -i x.iso # 读卷标、El Torito 引导目录
sudo mount -o loop,ro x.iso /mnt # 当只读文件系统挂载
7z x x.iso -o/tmp/iso_x/ # 不挂载直接解包
sudo dd if=x.iso of=/dev/sdX bs=4M status=progress oflag=sync # 写 U 盘
二、从光盘到 U 盘:介质沿革
2.1 时间线
| 年代 | 介质 | 装机方式 | 代表技术 |
|---|---|---|---|
| 1990s 初 | 软盘 1.44 MB | 十几张软盘轮流插 | rawrite、dd |
| 1990s 中 | CD-ROM 700 MB | 软盘引导 + 刻盘 | El Torito(1995) |
| 2000s 初 | DVD 4.7 GB | 一张盘装完 | mkisofs |
| 2000s 中 | U 盘 | BIOS 认 U 盘启动 | isohybrid、UNetbootin |
| 2010s | U 盘 | 一个盘一个系统 | Rufus、Etcher |
| 2010s 末 | 大 U 盘 | 一个盘 N 个系统 | Ventoy(2020) |
| 贯穿全程 | 网络 | 机房批量无人值守 | PXE(1999)、iPXE、Cobbler |
2.2 三个转折点
| 转折 | 之前 | 之后 |
|---|---|---|
| El Torito(1995) | 光盘开不了机,得插引导软盘(1.44 MB,只有引导扇区+光驱驱动)当钥匙,起来后再把控制权交给光盘 | 光盘自立,软盘退场。但容量还是问题——RHEL 4/5 时代 4~6 张 CD,装到一半提示"请插入第 3 张" |
| isohybrid | U 盘启动模式很乱:USB-FDD(模拟软驱,只认小容量)、USB-ZIP(兼容性玄学)、USB-HDD | ISO 自带 MBR,原封不动 dd 进 U 盘就行,不用任何专用工具。USB-HDD 一统天下 |
| Ventoy(2020) | 一个盘一个系统,运维攒一堆 U 盘;YUMI/GRUB4DOS 拼菜单要重做、兼容性看运气 | 引导器和数据彻底分家,加系统只要把 ISO 拷进去 |
同期另一条"解包式"路线(UNetbootin,2007)把 ISO 解开塞进 FAT32 再装 SYSLINUX,好处是盘还能存东西,坏处是引导故障多,今天基本被直写取代。
2.3 写盘工具谱系
| 工具 | 形态 | 定位 |
|---|---|---|
dd |
Linux 命令行 | 原生、最可靠,单 ISO,盘全清 |
| Rufus | Windows GUI | 能选 UEFI/Legacy,能处理非 isohybrid 的老 ISO |
| balenaEtcher | 跨平台 GUI | 傻瓜式 + 写后校验 |
| UNetbootin | 跨平台 GUI | 解包式(非直写),老工具,故障多 |
| Ventoy | 装一次用到底 | 不写盘,拷 ISO 进数据区就行(第三章) |
| BMC 虚拟光驱 | 服务器 | 不写盘,ISO 直接挂到服务器光驱 |
iPXE sanboot / memdisk |
网络 | 盘都不要(第五章) |
趋势:写一个盘 → 一个盘装多个系统 → 不用盘。
2.4 那为什么机房没换掉 PXE?
U 盘的优点在机房全都不成立:
| 需求 | U 盘 | PXE |
|---|---|---|
| 装 50 台 | 插 50 次,人要守着 | 配一次,全自动 |
| 无人在机房 | 做不到 | BMC 远程开关机即可 |
| 镜像/配置要改 | 每个盘重做 | 服务端改一份,全机房生效 |
| 服务器前置 USB 口驱动不全 | 常见故障 | 无所谓 |
| 装完个性化(IP/主机名) | 手工 | kickstart 自动 |
U 盘适合单台救急,PXE 适合批量标准化。
三、Ventoy
U 盘分两块:32 MB 的 VTOYEFI 分区放引导程序,剩下的 exFAT 数据区放 ISO。加系统直接把 ISO 拷进去。
tar -xzf ventoy-1.0.99-linux.tar.gz && cd ventoy-1.0.99
sudo sh Ventoy2Disk.sh -i /dev/sdX # 安装(数据区重建)
sudo sh Ventoy2Disk.sh -u /dev/sdX # 升级 Ventoy,保留数据区 ISO
sudo sh Ventoy2Disk.sh -I -g /dev/sdX # -g 用 GPT 分区(默认 MBR)
ventoy/ventoy.json 常用插件:
| 插件 | 作用 |
|---|---|
menu_alias |
给 ISO 起好认的名字,别让人对着文件名猜 |
menu_class |
按关键字分类/着色,ISO 一多就好找 |
auto_install |
挂 kickstart / preseed,U 盘也能无人值守 |
persistence |
给 Live ISO 挂持久化数据文件 |
injection |
安装时自动注入驱动包(老 RAID 卡、专用网卡) |
注意: 数据区保持 exFAT,别格成 NTFS(部分 UEFI 固件不认);换完 ISO 菜单没刷新就重新插拔;某些 Windows 安装盘、厂商专用镜像不兼容,只能回去 dd 单写。
四、PXE
PXE(Preboot eXecution Environment,Intel 1999)只干一件事:让网卡在操作系统之前,从网络取到一个引导程序。
4.1 装机只要五样东西
| # | 需要什么 | 提供者 | 协议 |
|---|---|---|---|
| 1 | 引导指令(去哪拿引导器) | DHCP Server | option 66/67 |
| 2 | 引导器本体 | TFTP Server | TFTP 69/udp |
| 3 | 内核 + initrd | TFTP 或 HTTP | TFTP / HTTP |
| 4 | 安装源(软件包仓库) | HTTP / NFS | HTTP / NFS |
| 5 | 装的时候怎么选 | kickstart / preseed | HTTP |
在 ISO 里这五样全打包进一个文件;在 PXE 里散落在五个服务上。
4.2 原理链路
客户端网卡 PXE ROM
│ ① DHCP 广播:要 IP
▼
DHCP Server ──► 回 IP + next-server(66) + filename(67)
│ ② 按 filename 去 TFTP 取引导程序
▼
TFTP Server ──► pxelinux.0(Legacy)/ grubx64.efi(UEFI)
│ ③ 引导程序再取配置与内核
▼
HTTP/NFS Server ──► vmlinuz + initrd.img + 安装源
│ ④ 内核按 kickstart / preseed 自动装完
▼
重启进系统(启动项要改回硬盘)
4.3 服务端:dnsmasq 一体方案
dnsmasq 同时做 DHCP + TFTP,比 bind + dhcpd + tftpd-hpa 三件套省事得多。
sudo apt install -y dnsmasq
/etc/dnsmasq.conf:
interface=eth1
bind-interfaces
dhcp-range=192.168.1.100,192.168.1.200,255.255.255.0,12h
dhcp-boot=pxelinux.0,pxeserver,192.168.1.34 # UEFI 换成 grubx64.efi
enable-tftp
tftp-root=/srv/tftp
log-dhcp
同一网段不能有两个 DHCP。PXE 一般给服务器划独立管理网/VLAN,或临时关掉上层 DHCP。
4.4 TFTP 目录与菜单
/srv/tftp/
├── pxelinux.0 # Legacy 引导器(= ISO 里的 isolinux.bin 那一族)
├── ldlinux.c32 / menu.c32 # 核心模块,少 ldlinux.c32 就卡死
├── pxelinux.cfg/default # 引导菜单(= ISO 里的 isolinux.cfg)
├── grubx64.efi / grub.cfg # UEFI
├── images/{vmlinuz,initrd.img} # ← 从 ISO 的 images/pxeboot/ 拷
└── ks/{rocky-ks.cfg,ubuntu-preseed.cfg}
sudo apt install -y syslinux syslinux-common
sudo cp /usr/lib/syslinux/modules/bios/{pxelinux.0,ldlinux.c32,menu.c32,libutil.c32} /srv/tftp/
sudo chmod -R a+r /srv/tftp # dnsmasq 以非 root 身份读文件
pxelinux.cfg/default:
DEFAULT menu.c32
PROMPT 0
TIMEOUT 50
MENU TITLE PXE Boot Menu
LABEL rocky9
MENU LABEL Rocky 9.4 自动安装
KERNEL images/vmlinuz
APPEND initrd=images/initrd.img inst.ks=http://192.168.1.34/ks/rocky-ks.cfg inst.repo=http://192.168.1.34/iso/ ip=dhcp
LABEL local
MENU LABEL 从硬盘启动
LOCALBOOT 0
UEFI 的 grub.cfg 用 linuxefi/initrdefi:
menuentry 'Rocky 9.4 自动安装' {
linuxefi images/vmlinuz inst.ks=http://192.168.1.34/ks/rocky-ks.cfg inst.repo=http://192.168.1.34/iso/ ip=dhcp
initrdefi images/initrd.img
}
菜单搜索顺序(按机器下发不同配置就靠这里):先按 MAC pxelinux.cfg/01-52-54-00-12-34-56 → 再按 IP 十六进制逐步截短 C0A80164 → C0A8016 → … → C → 兜底 default。
4.5 安装源 + 应答文件
sudo mkdir -p /srv/http/{iso,ks}
sudo mount -o loop Rocky-9.4-x86_64-dvd.iso /srv/http/iso # 临时用
cd /srv/http && sudo python3 -m http.server 80 # 验证;生产用 nginx
# 源目录下必须直接是 BaseOS/ AppStream/ repodata/,不能再套一层
应答文件只列关键行(完整文件按发行版文档补):
# rocky-ks.cfg(RHEL 系)
text
network --bootproto=dhcp --device=link --activate
rootpw --iscrypted $6$xxxxxxxx
timezone Asia/Shanghai --isUtc
clearpart --all --initlabel
part /boot --fstype=xfs --size=1024
part / --fstype=xfs --size=102400
reboot
%packages
@^minimal-environment
%end
# preseed.cfg(Debian 系)
d-i debian-installer/locale string zh_CN.UTF-8
d-i netcfg/choose_interface select auto
d-i partman-auto/method string regular
d-i passwd/root-password-crypted password $6$xxxxxxxx
d-i time/zone string Asia/Shanghai
d-i pkgsel/include string openssh-server
d-i grub-installer/only_debian boolean true
挂到引导参数上(openssl passwd -6 '密码' 生成加密口令):
inst.ks=http://192.168.1.34/ks/rocky-ks.cfg # RHEL 系
auto=true priority=critical url=http://192.168.1.34/ks/ubuntu-preseed.cfg # Debian 系
4.6 与 BMC 联动做真无人值守
PXE 装完若不改启动项,下次重启还会走网络。
# kickstart 里改回本地盘(UEFI)
%post
efibootmgr -o 0001,0002
%end
# 或者用 BMC 远程切换
ipmitool -I lanplus -H <bmc-ip> -U <u> -P <p> chassis bootdev pxe
ipmitool -I lanplus -H <bmc-ip> -U <u> -P <p> power reset # 开始装
ipmitool -I lanplus -H <bmc-ip> -U <u> -P <p> chassis bootdev disk
ipmitool -I lanplus -H <bmc-ip> -U <u> -P <p> power reset # 装完切回硬盘
用
chassis bootdev pxe设置后必须power reset,OS 里reboot可能不生效。详见 硬件信息采集。
4.7 故障速查
| 现象 | 处理 |
|---|---|
PXE-E51: No DHCP or proxyDHCP offers |
确认 dnsmasq 监听对网卡;查同网段有无第二个 DHCP |
PXE-E32: TFTP open timeout |
tftp 192.168.1.34 -c "get pxelinux.0" 手测;放行 69/udp |
取了 pxelinux.0 后卡住 |
缺 ldlinux.c32、libutil.c32,拷进 TFTP 根目录 |
| UEFI 客户端拿不到引导 | UEFI 要 grubx64.efi;双栈用下面配置分流 |
| 找不到安装源 | curl -I .../iso/BaseOS/ 手测;SELinux 放行 httpd 读该目录 |
| 卡在 dracut 阶段 | inst.ks= 在起界面之前就要拉;加 inst.sshd 看日志 |
| Secure Boot 下跳过网卡启动 | 关 Secure Boot,或用签名的 shimx64.efi |
Legacy / UEFI 双栈:
dhcp-match=set:efi-x86_64,option:client-arch,7
dhcp-boot=tag:efi-x86_64,grubx64.efi,pxeserver,192.168.1.34
dhcp-boot=tag:!efi-x86_64,pxelinux.0,pxeserver,192.168.1.34
五、无盘化:iPXE + memdisk + boot.iso
PXE 那一套要把 ISO 拆成几个文件摆在 TFTP/HTTP 上。无盘化换思路:客户端什么都不落地——不写 U 盘、不刻盘、硬盘都还没系统,整条引导链全从网络取。
5.1 三条网络引导路线
| 路线 | 做法 | 内存占用 | 适合 |
|---|---|---|---|
| 拆散分发 | 内核/initrd 走 TFTP,install.img+仓库走 HTTP |
小 | 批量正式装机(第四章) |
sanboot |
iPXE 把远端 ISO 当虚拟光驱挂载,边读边用 | 小(流式) | 单台重装、救急 |
memdisk |
把整个 ISO 下载到内存,再引导它 | ≈ ISO 大小 | 小镜像(boot.iso)、老机器 |
后两条都要 iPXE:标准 PXE 只能用 TFTP 搬小文件,又慢又笨。iPXE 支持 HTTP 引导、iSCSI/AoE,还能从原厂 PXE ROM 链式加载自己(Legacy 用 undionly.kpxe,UEFI 用 ipxe.efi):
# DHCP 指向这个入口;之后全程 HTTP,不再用 TFTP
#!ipxe
dhcp
chain http://192.168.1.34/boot.ipxe
5.2 路线 A:sanboot —— 一行挂 ISO
#!ipxe
dhcp
sanboot http://192.168.1.34/iso/Rocky-9.4-x86_64-dvd.iso
客户端把它当成插了一张 DVD,按需从 HTTP 流式读取,内存占用小,连 4.7 G 的 DVD 版都能挂。
sanboot走 iPXE 的虚拟光驱(INT 13h / UEFI Block I/O)。Legacy 下最稳,UEFI 下依赖固件支持。
5.3 路线 B:memdisk + boot.iso —— 纯内存无盘
memdisk(SYSLINUX 家族老成员)只干一件事:把整张磁盘/光盘镜像加载到内存,然后假装它是本地设备交给引导代码。
#!ipxe
dhcp
initrd http://192.168.1.34/ipxe/memdisk # 第一个 initrd 是 memdisk 本体
initrd http://192.168.1.34/iso/boot.iso # 第二个才是被引导的镜像
chain memdisk iso raw # iso=按光盘引导,raw=原始扇区
| 参数 | 含义 |
|---|---|
iso |
按 El Torito 光盘引导(.iso 用这个) |
floppy / harddisk |
按软盘 / 硬盘引导(.img、DOS 镜像) |
raw |
不解析分区表,整块原始扇区 |
关键:用 boot.iso,不要用 DVD 版。
| 镜像 | 大小 | 无盘化用哪个 |
|---|---|---|
boot.iso(RHEL / Rocky / Alma) |
约 700 MB | 用它 |
netinst.iso(Debian) |
数百 MB | 可以,同理 |
| DVD 版 Full ISO | 4.7 GB | 别用,全下到内存太蠢 |
boot.iso 是 RHEL 系的纯安装器镜像(等价 Debian 的 netinst):只有 vmlinuz+initrd+install.img,不含任何软件包。所以它天然适合无盘化——引导走内存,包走网络:
memdisk 载 boot.iso(≈700 MB,进内存)
└─ anaconda 起来
└─ inst.repo=http://192.168.1.34/iso/ ← 包从 HTTP 拉,不占客户端内存
⚠️ 三个坑:
memdisk只支持 Legacy BIOS,UEFI 下不能用。 它是 BIOS 组件,靠 INT 13h 模拟设备。UEFI 机器请走sanboot或第四章的拆散分发。- 内存要够:镜像大小 + 安装程序运行内存,700 MB 的
boot.iso建议客户端 ≥4 GB RAM。 - ISO 换版本要重传,不能像拆散分发那样只换增量。
5.4 netboot.xyz:现成的网络引导菜单
自己拼 iPXE 脚本、维护菜单很烦。netboot.xyz 一个文件搞定上百种发行版:
#!ipxe
dhcp
chain --autofree https://boot.netboot.xyz
内部就是本节三种路线的混合实现,还带 Live 维护工具(GParted、Clonezilla、memtest)。手上没盘、单台救急时最实用。
5.5 顺带分清:无盘"装机" vs 无盘"运行"
| 无盘装机 | 无盘运行 | |
|---|---|---|
| 范围 | 引导介质全是网络,最终还是装到本地硬盘 | 连根文件系统都在网络上,本地完全没硬盘 |
| 技术 | iPXE / memdisk / sanboot / PXE(本章) | NFS root、iSCSI root |
| 场景 | 服务器批量交付 | 瘦客户端、网吧、考场、LTSP / DRBL |
| 代价 | 一次性,装完就独立 | 断网整批停摆,对网络和存储要求高 |
后者走的是 6.4 里那跳 switch_root——只不过目标根在 NFS/iSCSI 上。
六、系统是怎么起来的
要点:装机时的启动链,和装完之后的启动链是两条不同的链。 很多人卡在"为什么 PXE 装完还要改启动项"、"为什么
/boot里那个 initramfs 和安装时的 initrd 不是一回事",就是把两条链混成了一条。
6.1 两条链的区别
| 装机时的链 | 装完之后的链 | |
|---|---|---|
| 引导器 | PXE/ISO 上的 pxelinux.0、isolinux.bin |
硬盘上的 GRUB2 |
| 内核 | 安装介质里的 vmlinuz(安装内核) |
/boot/vmlinuz-<ver>(正式内核) |
| initrd | initrd.img(安装器 stage1) |
/boot/initramfs-<ver>.img(dracut 生成) |
| 谁在跑 | 安装程序 anaconda | 目标系统的 systemd |
两条链共用同一套机制,只是载荷不同。理解一条就理解两条。
6.2 阶段 0:固件决定去哪找引导器
| 固件 | 动作 |
|---|---|
| Legacy BIOS | INT 19h → 读第一个可引导设备的 MBR(前 446 字节) → 跳活动分区引导扇区 |
| UEFI | 读 NVRAM 的 Boot#### 条目 → 加载 \EFI\BOOT\BOOTX64.EFI |
| UEFI + Secure Boot | 加载前验签名,第一个执行的是微软签名的 shimx64.efi |
| PXE | 网卡 option ROM 插队,先于磁盘发起 DHCP |
[ -d /sys/firmware/efi ] && echo UEFI || echo Legacy-BIOS
efibootmgr -v # 仅 UEFI:列出 NVRAM 启动项
6.3 阶段 1:引导器
GRUB2 在 Legacy 下是三段式("系统起不来"的高发区):
① boot.img 446 字节,装在 MBR,只干一件事:跳去 core.img
② core.img 装在磁盘开头的 embedding area(MBR 后、第一个分区前),
含文件系统驱动,用来读 /boot/grub/
③ /boot/grub/ grub.cfg + 一堆 .mod 模块 → 决定启动哪个内核、传什么参数
那块 embedding area 被别的工具(分区迁移、某些备份还原)覆盖掉,开机就停在 GRUB loading..——这就是经典的"MBR 被冲掉"。UEFI 下没有三段式:固件直接执行 ESP 里的 grubx64.efi,它读 /boot/grub/grub.cfg。
| 引导器 | 用在哪 | 关键文件 |
|---|---|---|
| SYSLINUX / ISOLINUX / PXELINUX / EXTLINUX | FAT / 光盘 / 网络 / ext | ldlinux.sys、isolinux.bin、pxelinux.0、extlinux |
| GRUB2 | 现在主流 | grubx64.efi, grub.cfg(UEFI 用 linuxefi 直启 EFI stub 内核) |
| iPXE | 网络引导 | ipxe.efi, undionly.kpxe(HTTP 引导、sanboot) |
| memdisk | 镜像载入内存 | memdisk(仅 Legacy BIOS) |
| wimboot / shim | WinPE / Secure Boot | wimboot + boot.wim / shimx64.efi |
| GRUB Legacy、gPXE、GRUB4DOS | 历史遗留 | grub.conf、grldr |
它们共享同一套设计:读一个小配置文件,按里面的 KERNEL/APPEND(GRUB 是 linux/linuxefi)加载内核和参数。
6.4 阶段 2~4:内核 → initramfs → 用户态
引导器把内核镜像、initrd、命令行参数三样交给内核。
| 内核镜像形态 | 对应固件 | 引导方式 |
|---|---|---|
bzImage(含实模式 stub) |
Legacy | 按 boot protocol 载入内存、cmd_line_ptr 传参 |
| EFI stub 可执行文件 | UEFI | GRUB 用 linuxefi/initrdefi 直启 |
内核参数是装机的控制面板:
| 参数 | 作用 |
|---|---|
inst.ks= / auto=true url= |
指定应答文件(RHEL 系 / Debian 系) |
inst.repo= / inst.stage2= |
安装源 / 安装程序本体位置 |
ip=dhcp |
安装环境自身的网络 |
console=ttyS0,115200 |
串口输出(无显卡服务器必备) |
nomodeset |
关掉内核 KMS,绕开显卡驱动导致的安装程序黑屏 |
rd.live.ram |
把 LiveOS 整个载入内存(慢,但拔盘也能装完) |
inst.sshd |
安装期间开 SSH,远程看日志(排障神器) |
initrd 是 dracut 生成的迷你根文件系统(cpio 压缩包),只有内核模块和"去把 stage2 拉下来"的逻辑。
| 发行版 | stage1(initrd 里) | stage2(安装程序本体) |
|---|---|---|
| RHEL / Rocky | dracut + 网络模块 | install.img(squashfs,含 anaconda,几百 MB) |
| Debian | initrd.gz + d-i udeb 环境 |
直接从 mirror 在线拉 deb |
| Ubuntu Live | casper | filesystem.squashfs |
⚠️ 应答文件就在这个阶段被取下来——安装程序起界面之前先解析 inst.ks=。所以 kickstart 拿不到时你会看到"卡在 dracut 阶段",而不是"界面里少个选项"。
接着是整条链里最容易被忽略的一跳:
内核把 initrd 解成 tmpfs 挂为临时根
└─ 执行 /init(dracut 脚本)
├─ 加载真正需要的模块:存储控制器 / RAID / LVM / 加密 / 网络
├─ 找到「真正的根文件系统」(可能是 LUKS 加密、LVM 上、或 iSCSI 远端的)
├─ 挂载到 /sysroot
└─ switch_root /sysroot /sbin/init ← 换根,抛弃临时根
└─ systemd 挂 fstab 剩余项、拉起服务、给你登录提示符
为什么必须有 initramfs:内核自己只会挂简单根设备。加密、LVM、软 RAID、网络根这些"要先解密/先组卷/先联网才能挂"的情况内核做不到,只能在用户态先干完再 switch_root 移交。
这就是为什么改了 LVM/加密/RAID 配置后必须
dracut -f重建 initramfs;也是无盘运行(5.5)的落点。
6.5 装机时多出来的十步(anaconda)
1. 探测硬件,加载存储/网络驱动
2. 分区:clearpart --all → part /boot → part / → part swap(或 autopart)
3. mkfs 格式化
4. 挂载到 /mnt/sysimage
5. 事务化装包:解析依赖 → 下载 rpm → rpm --root=/mnt/sysimage 逐个安装
6. 写配置:/etc/fstab、hostname、网络、用户、SELinux、时区
7. 装 bootloader:UEFI → grub2-install 到 ESP + efibootmgr 写 NVRAM;BIOS → 写 MBR
8. dracut 为新系统生成 initramfs ← 装完那条链的 initrd 在这一步诞生
9. 执行 %post 脚本
10. 卸载、reboot → 从此走 6.1 右侧那条链
Debian 的 debian-installer 是同一套路:partman 分区 → 从 mirror 拉 deb → dpkg 装基础系统 → tasksel 选任务 → grub-installer → late_command。
第 7、8 步是"装"与"拷"的分水岭:bootloader 和 initramfs 必须按当前硬件重新生成。这也是克隆式部署(Clonezilla)同型号一把梭、换型号就翻车的根本原因。
6.6 排障对照:卡在哪一步,看什么
| 现象 | 卡在 | 先查 |
|---|---|---|
| 开机黑屏、无提示 | 阶段 0 固件 | BMC 串口 / console=ttyS0;启动顺序;UEFI 还是 Legacy |
GRUB loading.. 后停住 |
阶段 1 GRUB ② | embedding area 被覆盖,grub2-install /dev/sdX 重装 |
| GRUB 菜单出现但选了没反应 | 阶段 1 配置 | grub.cfg 内核路径、linuxefi vs linux |
dracut-initqueue timeout |
initramfs | 缺存储驱动,或 LVM/加密配置变了没重建 initramfs |
You are in emergency mode |
用户态 systemd | /etc/fstab 有挂不上的条目(UUID 写错、盘序变了) |
| PXE 装完重启又进网络引导 | 阶段 0 启动项 | 4.6 的 efibootmgr -o 或 BMC bootdev disk |
七、经典软件总览
| 层 | 软件 | 角色 |
|---|---|---|
| 引导 | SYSLINUX 家族 1994– / GRUB2 2010– | 轻量引导器(ISO/PXE 默认) / UEFI 主流 |
| iPXE 2010– / memdisk 2000s | HTTP 引导与 sanboot / 镜像载入内存(仅 BIOS) |
|
| wimboot 2013– / shim 2013– | 网络引导 WinPE / Secure Boot 第一级 | |
| GRUB Legacy、gPXE/Etherboot、GRUB4DOS | 历史遗留,老文档常见 | |
| 网络服务 | dnsmasq、isc-dhcp-server、tftpd-hpa、nginx/httpd、NFS、Squid | DHCP / TFTP / HTTP / 网络根 / 缓存 |
| 应答文件 | Kickstart、preseed、autoinstall、AutoYaST、unattend.xml | 无人值守(安装阶段) |
| cloud-init | 首次启动阶段 | |
| 批量框架 | Cobbler(+koan)、MAAS、Foreman、xCAT、Spacewalk/Satellite、WDS/MDT/SCCM | 安装式:逐包装,灵活可异构 |
| FOG、Clonezilla SE/DRBL | 克隆式:灌镜像,快但换型号翻车 | |
| 介质制作 | xorriso/mkisofs、isohybrid、mksquashfs、Ventoy、Rufus、Etcher、dd、partclone | 造 ISO、打包、写盘、克隆 |
| 安装程序 | anaconda、debian-installer、subiquity、YaST、Calamares、WinPE | 装机本体 |
| 无盘 | netboot.xyz、iPXE、LTSP、DRBL | 无盘启动与无盘运行 |
八、选型速查
| 需求 | 用哪个 |
|---|---|
| 有 BMC,单台装系统 | ISO 挂虚拟光驱,不碰 U 盘 |
| 没 BMC,单台 | dd / Rufus 写 U 盘 |
| 随身维护盘,系统常换 | Ventoy |
| 一个 U 盘做无人值守 | Ventoy + auto_install 插件 |
| 机房十几台起 | PXE + kickstart/preseed(第四章) |
| 完全不写盘、单台网络装机 | iPXE sanboot 挂 ISO(5.2) |
| 老机器、要引导整个 ISO 镜像 | iPXE + memdisk + boot.iso(5.3,仅 BIOS) |
| 手上没盘、要现成的多系统网络菜单 | netboot.xyz(5.4) |
| 连本地硬盘都没有 | 无盘运行:NFS/iSCSI root + PXE(5.5) |
| 同型号机器灌几十台,追求速度 | Clonezilla SE / FOG(克隆式) |
| 装完还要批量初始化 | cloud-init / Ansible(见 Linux 常规操作与优化) |
相关页面
- 硬件信息采集 — BMC/IPMI 远程改启动项、Redfish 批量操作
- Linux 常规操作与优化 — 装完之后的系统配置、离线安装、开机自启、内核升级
- 硬盘 分区 RAID — 装机前的磁盘与 RAID 卡准备
- cpu2dpu 拓扑演变 — 装完后的 NUMA/PCIe 拓扑核对
- 原始脚本:
raw/scripts/离线安装.sh、raw/scripts/自启.sh、raw/scripts/更新内核,修改启动项.md