新闻详情

新闻详情

首页 / 资讯中心 / 详情

LinuxKit raw-efi 镜像构建深度解析:基于 systemd-boot 与 UKI 的 ESP 生成全流程

发布时间:2026/9/28 2:30:50来源:尧图网络
LinuxKit raw-efi 镜像构建深度解析:基于 systemd-boot 与 UKI 的 ESP 生成全流程
操作系统云原生容器运行时【免费下载链接】linuxkitA toolkit for building secure, portable and lean operating systems for containers项目地址https://gitcode.com/gh_mirrors/li/linuxkit点击查看免费下载导读tools/mkimage-raw-efi/是 LinuxKit 项目中负责生成raw EFI 磁盘镜像raw-efi输出格式的核心工具它接收一个包含内核、initrd 与命令行参数的 tarball在容器内完成 EFI System PartitionESP的初始化、systemd-boot 引导器与 Linux Unified Kernel ImageUKI的组装最终在标准输出上吐出一份可直接写入磁盘的 GPT 格式原始镜像。读完本文你将掌握该工具从 stdin 协议、UKI 构建、FAT32 最小化计算到 GPT 分区组装的完整工作原理并能通过linuxkit build -format raw-efi在本地复现这一镜像构建流程。一、工具定位LinuxKit 的 EFI 启动盘输出格式LinuxKit 的linuxkit build命令支持多种输出格式其中raw-efi专门面向UEFI 固件启动场景。在 output.go 中可以看到它的注册逻辑raw-efi: func(base string, image io.Reader, size int, arch string) error { kernel, initrd, cmdline, _, err : tarToInitrd(image) if err ! nil { return fmt.Errorf(error converting to initrd: %v, err) } err outputImg(outputImages[raw-efi], base-efi.img, kernel, initrd, cmdline, arch) if err ! nil { return fmt.Errorf(error writing raw-efi output: %v, err) } return nil },构建产物命名为base-efi.img其镜像包由 images.yaml 中声明的linuxkit/mkimage-raw-efi:c00e49ece2f03e47f3a8e047a2eeea7bd4228a34提供——这正是本目录下 Dockerfile 构建出的工具镜像。与 BIOS 时代的raw-bios使用 syslinux见 make-bios不同raw-efi走的是UEFI 原生启动路径ESP 中只放 systemd-boot 引导器与一个 UKI 内核镜像不依赖 MBR 引导扇区。二、ESP 分区布局官方 README 核心内容README.md 明确指出脚本通过mkfs.vfat初始化 EFI System Partition并向其中填充 systemd-boot 与 LinuxKit UKI 所需的目录和文件。最终 ESP 的目录结构如下ESP ├── EFI │ ├── BOOT # 根据架构放置以下引导器二进制之一 │ │ ├── BOOTX64.EFI # amd64 │ │ ├── BOOTAA64.EFI # arm64 │ │ └── BOOTRISCV64.EFI # riscv64 │ └── Linux │ └── linuxkit.efi # LinuxKit Unified Kernel Image (UKI) └── loader └── loader.conf # systemd-boot 配置文件布局中两个要点值得注意引导器文件名按 UEFI 规范命名EFI/BOOT/BOOTX64.EFIamd64、BOOTAA64.EFIarm64、BOOTRISCV64.EFIriscv64。这些是 UEFI 固件约定的可移除介质默认引导路径文件名固件无需读取配置即可按架构自动发现。UKI 自动发现机制放在EFI/Linux目录下的 UKI 不需要在loader/entries中显式添加启动条目——systemd-boot 会自动扫描该目录并生成启动菜单项。这正是 loader 目录下只有loader.conf一个配置文件的原因。三、工具链与运行环境Dockerfile 揭示了该工具的构建与运行环境它采用多阶段构建第一阶段从linuxkit/systemd-boot镜像提取编译好的 systemd-boot EFI 二进制第二阶段基于linuxkit/alpine准备运行时通过apk add安装dosfstools提供mkfs.vfat用于创建 FAT32 文件系统mtools提供mmd/mcopy用于向 FAT 镜像写入目录与文件sgdisk/sfdiskGPT 分区表工具libarchive-tools提供bsdtar用于解压 stdin 输入的 tarballpy3-pefileukify 构建 UKI 时的 PE 文件解析依赖binutils、busybox、xfsprogs等基础工具最终阶段从 scratch 组装COPY --frommirror /out/ /带入 Alpine 根文件系统COPY --fromsystemd-boot . .带入引导器COPY . .带入make-efi脚本本身并以ENTRYPOINT [ /make-efi ]作为容器入口。四、标准输入/输出协议与输入内容约定make-efi脚本tools/mkimage-raw-efi/make-efi以 Unix 管道的方式工作其协议在脚本注释中写明# input is a tarball on stdin with kernel and cmdline in /boot # output is an iso on stdout输入标准输入上的压缩 tarball其中必须包含/boot下的内核与命令行参数文件输出标准输出上的 raw 磁盘镜像脚本末尾的cat $IMGFILE完成这一职责。解压与中间产物提取的关键代码[ -t 0 ] || bsdtar xzf - INITRD$(find . -name *.img) KERNEL./kernel CMDLINE_FILE$(find . -name cmdline) CMDLINE$(cat $CMDLINE_FILE ) UKI_FILElinuxkit.efi[ -t 0 ] || bsdtar xzf -仅当标准输入不是 tty 时才从 stdin 解压。注释特别说明 BSD 版 tar 能自动识别压缩格式而 GNU tar 不能这也是选择libarchive-tools的原因若 stdin 是 tty则依赖挂载的卷提供文件调试场景。通过find定位*.imginitrd与cmdline文件内核固定命名为kernel命令行内容直接读出拼入启动参数。五、UKIUnified Kernel Image的构建脚本为 root 分区预生成一个随机 PARTUUID并调用 systemd 的ukify工具将内核、initrd 与命令行打包为单个 EFI 可执行文件# PARTUUID for root PARTUUID$(cat /proc/sys/kernel/random/uuid) # this is displayed as boot loader entry name OS_RELEASENAME\LinuxKit\ cat loader.conf EOF timeout 0 EOF ukify build --linux$KERNEL \ --initrd$INITRD \ --cmdline$CMDLINE text \ --os-release$OS_RELEASE \ --output$UKI_FILEukify build将--linux内核、--initrdinitrd 镜像、--cmdline内核命令行合并进一个linuxkit.efi文件。命令行为原有的$CMDLINE追加了text参数强制内核使用文本模式控制台便于在串口等无图形环境下排障。--os-releaseNAMELinuxKit写入 UKI 的 os-release 段systemd-boot 会用该名称显示启动菜单项。loader.conf仅写入timeout 0即启动菜单不等待、直接引导默认项符合 LinuxKit 追求快速无交互启动的定位。值得一提的是PARTUUID变量随后被用作 ESP 分区的--partition-guid为分区表提供一个确定的、可被根文件系统rootPARTUUID引用的标识见下节 GPT 组装。六、FAT32 文件系统参数与最小化尺寸计算这是脚本中最精细的部分为了让 ESP 尽量小它对 FAT32 的各个结构做了逐项手工核算而不是直接交给mkfs.vfat按默认值分配。6.1 固定参数FAT_SIZE32 SECTOR_SIZE512 SECTORS_PER_CLUSTER8 # these always include the Boot Sector and FS Information Sector (sector 0 and 1) among others for FAT32 RESERVED_SECTORS32参数值含义FAT_SIZE32FAT32 类型每条目 4 字节SECTOR_SIZE512扇区大小字节SECTORS_PER_CLUSTER8每簇 8 扇区即 4KB 簇RESERVED_SECTORS32保留扇区包含引导扇区sector 0与 FS 信息扇区sector 1等6.2 数据量与 FAT 开销递推UKI_FILE_SIZE$(stat -c %s $UKI_FILE) EFI_FILE_SIZE$(stat -c %s $BOOTFILE_DST) SYSTEMD_BOOT_FILE_SIZE$(stat -c %s loader.conf) # this is the minimum size of our EFI System Partition ESP_DATA_SIZE$(( $UKI_FILE_SIZE $EFI_FILE_SIZE $SYSTEMD_BOOT_FILE_SIZE )) ESP_DATA_SECTORS$(( $ESP_DATA_SIZE / $SECTOR_SIZE )) # File Allocation Table Sectors (clusters 2) * bytes per cluster / sector size FILE_ALLOCATION_TABLE_SECTORS$(( ( $ESP_DATA_SECTORS / $SECTORS_PER_CLUSTER 2 ) * ( $FAT_SIZE / 8 ) / $SECTOR_SIZE )) # there are two file allocation tables hence 2 * $FILE_ALLOCATION_TABLE_SECTORS FAT_OVERHEAD_SECTORS$(( $RESERVED_SECTORS ( 2 * $FILE_ALLOCATION_TABLE_SECTORS ) )) FAT_OVERHEAD_SIZE$(( $FAT_OVERHEAD_SECTORS * $SECTOR_SIZE ))计算链条清晰可循数据量ESP 至少容纳三个文件——UKI、systemd-boot 二进制、loader.conf三者字节数之和即ESP_DATA_SIZE簇数ESP_DATA_SECTORS / SECTORS_PER_CLUSTER得到占用的簇数FAT32 的 FAT 表条目数 簇数 2两个保留条目0 与 1 号簇标记单张 FAT 表扇区数(簇数 2) × 4 字节FAT32 每条目/ 512总开销保留扇区32 两张 FAT 表FAT32 默认镜像两份 FAT换算成字节得FAT_OVERHEAD_SIZE。6.3 对齐到 2048 扇区# (x1024)/1024*1024 rounds up to multiple of 1024KB, or 2048 sectors # some firmwares get confused if the partitions are not aligned on 2048 blocks # we will round up to the nearest multiple of 2048 blocks # since each block is 512 bytes, we want the size to be a multiple of # 2048 blocks * 512 bytes 1048576 bytes 1024KB ESP_FILE_SIZE_KB$(( ( ( ($ESP_DATA_SIZE $FAT_OVERHEAD_SIZE 1024 - 1) / 1024 ) 1024 - 1) / 1024 * 1024 )) ESP_FILE_SIZE_SECTORS$(( $ESP_FILE_SIZE_KB * 1024 / $SECTOR_SIZE ))脚本注释点明了原因部分固件在分区未按 2048 块对齐时会出现识别混乱。因此 ESP 文件总尺寸被向上取整到 1024KB2048 块 × 512 字节的整数倍。七、ESP 镜像写入mkfs.vfat mtools得到精确尺寸后脚本用mkfs.vfat创建最小化 FAT32 镜像再通过 mtools 系列命令填充目录结构mkfs.vfat -v -F $FAT_SIZE -S $SECTOR_SIZE -s $SECTORS_PER_CLUSTER -R $RESERVED_SECTORS -C $ESP_FILE $(( $ESP_FILE_SIZE_KB )) /dev/null echo mtools_skip_check1 /etc/mtools.conf \ mmd -i $ESP_FILE ::/EFI mmd -i $ESP_FILE ::/EFI/BOOT mmd -i $ESP_FILE ::/EFI/Linux mmd -i $ESP_FILE ::/loader mcopy -i $ESP_FILE $BOOTFILE_DST ::/EFI/BOOT/ mcopy -i $ESP_FILE $UKI_FILE ::/EFI/Linux/ mcopy -i $ESP_FILE loader.conf ::/loadermkfs.vfat的-F 32FAT32、-S 512扇区、-s 8每簇扇区、-R 32保留扇区与脚本手算参数一一对应-C表示直接创建指定大小KB的文件镜像mmd依次建立EFI/BOOT、EFI/Linux、loader目录与 README 中的布局完全一致mcopy将三个文件按规划路径拷入引导器进EFI/BOOT/UKI 进EFI/Linux/配置进/loadermtools_skip_check1跳过 mtools 的磁盘一致性预检因为该 FAT 镜像由脚本精确构造。八、GPT 分区表与最终磁盘镜像组装ESP 文件就绪后脚本开始组装最终磁盘镜像ONEMB$(( 1024 * 1024 )) SIZE_IN_BYTES$(( $(stat -c %s $ESP_FILE) 4*$ONEMB )) BLKSIZE512 MB_BLOCKS$(( $SIZE_IN_BYTES / $ONEMB )) dd if/dev/zero of$IMGFILE bs1M count$MB_BLOCKS ESP_SECTOR_START2048 ESP_SECTOR_END$(( $ESP_SECTOR_START $ESP_FILE_SIZE_SECTORS - 1 )) sgdisk --clear \ --new 1:$ESP_SECTOR_START:$ESP_SECTOR_END --typecode1:ef00 --change-name1:EFI System --partition-guid1:$PARTUUID \ --attributes 1:set:2 \ $IMGFILE dd if$ESP_FILE of$IMGFILE bs$BLKSIZE count$ESP_FILE_SIZE_SECTORS convnotrunc seek$ESP_SECTOR_START总尺寸ESP 文件大小 4MB 余量脚本注释说明分别预留 BIOS boot、MBR 与 GPT 的 1MB 空间先dd从 /dev/zero 生成空白底图保证分区表之外的区域为零填充对齐起点ESP 从扇区 2048 开始1MB 边界兼容传统 BIOS 引导区与 GPT 头部结束扇区与 ESP 文件精确吻合分区属性sgdisk创建单个分区——类型码ef00EFI System Partition、名称EFI System、--partition-guid1:$PARTUUID写入前文生成的随机 GUID--attributes 1:set:2设置第 2 个属性位即legacy BIOS bootable标志使该 ESP 在 BIOS 兼容模式下同样可被识别为可引导分区写入最后用dd convnotrunc seek2048将 ESP 镜像按扇区数精确拷入磁盘镜像的对应偏移。九、架构选择与 systemd-boot 二进制映射make-efi通过TARGETARCH环境变量缺省回退到uname -m选择对应架构的引导器ARCH${TARGETARCH:-uname -m} case $ARCH in x86_64) BOOTFILE_SRC/usr/lib/systemd/boot/efi/systemd-bootx64.efi BOOTFILE_DSTBOOTX64.EFI ;; aarch64) BOOTFILE_SRC/usr/lib/systemd/boot/efi/systemd-bootaa64.efi BOOTFILE_DSTBOOTAA64.EFI ;; riscv64) BOOTFILE_SRC/usr/lib/systemd/boot/efi/systemd-bootriscv64.efi BOOTFILE_DSTBOOTRISCV64.EFI ;; esac映射关系与 README 中的布局注释一一对应x86_64 → BOOTX64.EFI、aarch64 → BOOTAA64.EFI、riscv64 → BOOTRISCV64.EFI源文件来自容器内 systemd-boot 包的/usr/lib/systemd/boot/efi/目录由 Dockerfile 第一阶段从linuxkit/systemd-boot镜像带入。这解释了为何该工具可以跨 amd64 / arm64 / riscv64 三个架构产出各自的 EFI 启动盘。十、在 LinuxKit 构建流程中使用 raw-efi 格式将 raw-efi 接入标准构建流程的方式是使用linuxkit build的-format参数。在 build.go 中buildFormats是一个可重复指定的formatList支持逗号分隔或多次传参合法取值来自mobybuild.OutputTypes()。典型用法linuxkit build -format raw-efi linuxkit.yml构建后会在当前目录生成名字-efi.img命名规则见 output.go 的base-efi.img。该原始镜像可直接dd到磁盘或 U 盘在支持 UEFI 的机器上启动也可以交给 QEMU 等虚拟机验证。需要留意的是兼容性前提官方文档 platform-qemu.md 明确说明qcow-efi与raw-efi格式可能可用但当前未测试The formats qcow-efi and raw-efi may also work, but are currently not tested。因此在生产使用前建议先在目标平台或 QEMU 上做一次实际启动验证。十一、调试技巧脚本为排障保留了钩子set -e # for debugging [ -n $DEBUG ] set -x设置DEBUG环境变量即可开启 shell 的-x跟踪打印每一步执行的命令与变量展开结果。此外脚本把除最终镜像外的所有日志重定向到 stderr# we want everything except the final result to stderr ( exec 12; ... ) cat $IMGFILE这意味着 stdout 上只出现纯粹的磁盘镜像字节流任何警告、进度信息都走 stderr——既保证了管道下游如linuxkit build或dd收到的数据纯净也便于在容器日志中观察构建过程。结语tools/mkimage-raw-efi/虽小却完整演示了现代 UEFI 启动盘的构造艺术从 stdin 协议接收内核与 initrd用 ukify 合成 UKI手工推演 FAT32 的最小化布局再以 sgdisk 组装 GPT 分区最终通过 stdout 交付一份对齐、紧凑、可直接启动的 raw 磁盘镜像。理解它的每个计算步骤不仅能帮你排查 LinuxKit EFI 启动问题也能为自研嵌入式或云原生引导镜像提供一套可复用的参考实现。赞分享操作系统云原生容器运行时【免费下载链接】linuxkitA toolkit for building secure, portable and lean operating systems for containers项目地址https://gitcode.com/gh_mirrors/li/linuxkit点击查看免费下载相关推荐鸣潮重复流程3步全托管ok-ww自动战斗、声骸刷取与日常托管完整新手指南鸣潮重复流程3步全托管ok ww自动战斗、声骸刷取与日常托管完整新手指南 凌晨两点你的电脑还在安静地跑着副本窗口最小化在任务栏里。等醒来再打开游戏日常已GUI 自动化计算机视觉RPA人工智能3步完成Telegraf容器化从零到生产级监控采集实战3步完成Telegraf容器化从零到生产级监控采集实战 还在为服务器监控配置繁琐而头疼吗面对分布式系统的指标采集你是否希望找到一种更高效、更灵活的部署方案可观测性指标监控运维Spring Boot Admin 与 GraalVM 原生镜像基于 sample-servlet-graalvm 的构建与运行实战指南Spring Boot Admin 与 GraalVM 原生镜像基于 sample servlet graalvm 的构建与运行实战指南 Spring Boo后端可观测性指标监控监控大盘MCP 服务上一篇攻克iOS内存难题SDWebImage智能缓存清理与成本计算全攻略下一篇如何使用PHPoAuthLib快速实现第三方登录从入门到精通的完整教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

别再满世界找“AI论文软件第一名”了:智慧农业毕设,选对环节比选名气更香 [特殊字符][特殊字符] 2026/9/28 3:35:11

别再满世界找“AI论文软件第一名”了:智慧农业毕设,选对环节比选名气更香 [特殊字符][特殊字符]

先抛结论:“当前流行的 AI 论文生成软件排名”并没有一份适合所有人的权威总榜。尤其你读的是工学 / 农业工程 / 智慧农业系统工程,论文往往不是单纯写文字,而是“农业场景 物联网数据 模型算法 系统设计 工程验证”的交叉任务。 这篇就…

阅读更多 →
LunaTranslator 内嵌翻译:7 个开关与乱码修复 2026/9/28 3:35:11

LunaTranslator 内嵌翻译:7 个开关与乱码修复

LunaTranslator 内嵌翻译:7 个开关与乱码修复 【免费下载链接】LunaTranslator 视觉小说翻译器 / Visual Novel Translator 项目地址: https://gitcode.com/GitHub_Trending/lu/LunaTranslator 玩 Galgame 时,外挂翻译只把译文放在单独的窗口里&a…

阅读更多 →
具身智能协同演化动力学(7):VLA-世界模型-TVA协同演化的不可替代逻辑 2026/9/28 3:34:58

具身智能协同演化动力学(7):VLA-世界模型-TVA协同演化的不可替代逻辑

前沿技术探索:TVA智能体(简称TVA)TVA智能体(亦称“AI智能体视觉”)是依托Transformer架构与“因式智能体”理论构建的新型工业视觉系统,也是当前最具代表性的具身视觉技术之一。它有机融合深度强化学习&…

阅读更多 →
Accurate and Interpretable Postmenstrual Age Prediction via Multimodal Large Language Model 2026/9/28 3:34:45

Accurate and Interpretable Postmenstrual Age Prediction via Multimodal Large Language Model

文章主要内容和创新点 主要内容 本文旨在解决新生儿月经后年龄(PMA)预测中准确性与可解释性的双重挑战。研究基于多模态大型语言模型(MLLM)Qwen2.5-VL-7B,通过参数高效微调(PEFT)策略(结合指令微调与低秩适应LoRA),利用新生儿脑部MRI衍生的4种2D皮质表面投影图(皮…

阅读更多 →
langchain4j-RAG企业真实项目实战-检索生成 2026/9/28 3:34:45

langchain4j-RAG企业真实项目实战-检索生成

LangChain4j 实战系列第三篇,也是我认为最见功力的一篇:检索生成。前两篇我们把项目骨架和文档入库讲完了,知识已经"存"进去了,这一篇解决另一半问题——用户开口提问之后,系统怎么把对的知识、以对的形式、…

阅读更多 →
具身智能创新设计方案(32):从单点突破到底座协同的范式进化必然性 2026/9/28 3:34:38

具身智能创新设计方案(32):从单点突破到底座协同的范式进化必然性

前沿技术探索:TVA智能体(简称TVA)TVA智能体(亦称“AI智能体视觉”)是依托Transformer架构与“因式智能体”理论构建的新型工业视觉系统,也是当前最具代表性的具身视觉技术之一。它有机融合深度强化学习&…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉