镜像、分区与文件系统.img到底是什么仓库已经开源所有教程主线内核移植跑新版本imx-linux/uboot都在这里或者一起来尝试跑7.0的Linux欢迎各位大佬观摩喜欢的话点个⭐仓库地址https://github.com/Awesome-Embedded-Learning-Studio/imx-forge静态网页https://awesome-embedded-learning-studio.github.io/imx-forge/前言它不是一个文件夹压缩包很多人第一次接触.img时会下意识把它当成压缩包。这也很正常。因为我们平时看到.zip、.tar.gz里面都是一堆文件看到rootfs.tar.gz也确实可以解开得到一个根文件系统目录。但这里的imx6ull-aes-sd.img或imx6ull-aes-emmc.img不是这种东西。它不是“把 boot 目录和 rootfs 目录压成一个包”。它更像是把一整张 SD 卡从第 0 字节开始复制成了一个普通文件。换句话说.tar.gz 关心的是文件。 .img 关心的是整块盘的字节布局。理解了这一点后面很多命令就不奇怪了。sfdisk -d xxx.img能看分区表是因为这个.img里面真的有分区表。dd能把它写进 SD 卡是因为它本来就是按整盘布局生成的。从整盘到文件中间有几层我们先用一个层级把概念摆正整盘设备 └── 分区表 ├── 分区 1 │ └── 文件系统 │ ├── zImage │ └── imx6ull-aes.dtb └── 分区 2 └── 文件系统 ├── /bin ├── /etc └── /lib这几层不要混整盘设备是一块完整存储例如一张 SD 卡或者一颗 eMMC。分区表记录这块盘上有哪些分区每个分区从哪里开始到哪里结束。分区是一段连续的存储范围。文件系统是在分区里面组织文件的一套格式比如 ext4。文件才是我们平时能ls、cp、cat的东西比如zImage、.dtb、/etc/inittab。如果把这几层混了就会出现很典型的误会以为把u-boot-dtb.imx拷进 boot 分区板子下次上电就会从它启动。实际上不会因为项目里的 U-Boot 不属于 boot 分区里的普通文件。MBR 是做什么的MBR 可以先简单理解成一种老派但够用的分区表格式。它放在整盘的开头告诉系统第 1 个分区从哪个扇区开始有多大 第 2 个分区从哪个扇区开始有多大 每个分区是什么类型 哪个分区带 bootable 标记当前镜像脚本会写一个 DOS/MBR 风格的分区表。你用下面命令看镜像sfdisk-dout/release-latest/images/imx6ull-aes-emmc.img能看到类似label: dos unit: sectors ...img1 : start32768, size131072, type83, bootable ...img2 : start163840, size..., type83这里start32768的意思是第 1 个分区从第 32768 个扇区开始。一个扇区按 512 字节算正好是 16 MiB。这就是为什么.img可以被sfdisk读懂。它虽然是一个普通文件但文件开头的内容按整盘格式写好了。boot 分区和 rootfs 分区当前镜像里有两个分区。第 1 个是 boot 分区。它放启动 Linux 需要的普通文件zImage imx6ull-aes.dtb boot.cmdzImage是 Linux 内核镜像。.dtb是设备树告诉内核这块板子的硬件长什么样。boot.cmd记录脚本为这个镜像生成的启动命令。第 2 个是 rootfs 分区。Linux 内核启动后会把它挂载成// ├── bin ├── etc ├── lib └── ...这就是用户空间。BusyBox、init 脚本、配置文件、你后续放进去的应用都会在 rootfs 里。所以启动链路里有一个很自然的顺序U-Boot 读取 boot 分区里的 zImage 和 DTB Linux 内核启动 Linux 挂载 rootfs 分区作为根目录 进入用户空间文件系统是什么分区只是“一段空间”。要在这段空间里放文件还需要文件系统。当前脚本把 boot 分区和 rootfs 分区都做成 ext4。这样 U-Boot 可以用ext4load读取内核和设备树Linux 也能直接挂载 rootfs。ext4 文件系统负责回答这些问题这个目录里有哪些文件 这个文件的数据块在哪里 这个文件权限是什么 软链接指向哪里也就是说zImage能以文件形式存在是因为 boot 分区里面有 ext4 文件系统。/etc/inittab能被cat也是因为 rootfs 分区里面有 ext4 文件系统。脚本用mke2fs -d生成 ext4 文件系统镜像这样可以把一个目录直接灌进文件系统里不需要sudo mount。后面脚本拆解章节会细讲这件事。U-Boot raw 区域不是普通文件现在回到最容易混的地方U-Boot。项目里的u-boot-dtb.imx不放在 boot 分区里作为普通文件启动。镜像脚本会把它写到整盘偏移 1 KiB 的位置offset 1 KiB - u-boot-dtb.imx这段区域在分区前面属于 raw disk 区域。raw 的意思可以先理解成不经过文件系统直接按字节或扇区写。这里没有文件名也没有目录。你不能在 Linux 挂载 boot 分区后ls出“1 KiB 偏移处的 U-Boot”。它不在文件系统里。这就是为什么我们要区分zImage / DTBboot 分区里的普通文件 u-boot-dtb.imx整盘 raw 区域里的启动镜像把zImage拷到 boot 分区是文件操作。把u-boot-dtb.imx写到 1 KiB是 raw 写盘操作。这两件事不在同一层。为什么 sfdisk 能看 .imgsfdisk不是只能看真实磁盘。只要一个文件的内容按“整盘布局”组织它也能读。所以这条命令sfdisk-dout/release-latest/images/imx6ull-aes-sd.img本质上是在问这个文件开头有没有我认识的分区表 如果有每个分区从哪里开始有多大它不会挂载分区也不会读 ext4 里的文件。它只是读分区表。如果你想看文件系统层面的信息可以用更偏文件系统的工具比如dumpe2fs-hboot.ext4 debugfs-Rls -l /boot.ext4这些命令的层次就不一样了。sfdisk看整盘分区表dumpe2fs和debugfs看 ext4 文件系统。为什么完整镜像要写整盘现在就能解释上一章那句话了。完整.img里面同时包含整盘前面的 raw U-Boot 整盘前面的 MBR 分区表 第 1 分区的 ext4 文件系统 第 2 分区的 ext4 文件系统所以它必须从目标设备的第 0 字节开始写。写到整盘设备of/dev/sdb意思是把这些层级完整放回一张真实 SD 卡。写到分区设备of/dev/sdb1意思是把整盘布局塞进第 1 个分区内部。这样外层分区表、raw U-Boot 位置都不对。这也是为什么很多教程会反复强调看清楚lsblk确认目标是disk不是part。小结这一章把.img拆成了几层整盘 → 分区表 → 分区 → 文件系统 → 文件zImage、DTB、rootfs 里的内容都是文件系统里的普通文件。U-Boot 则写在整盘前面的 raw 区域不属于 boot 分区。下一章我们继续看 i.MX6ULL 的启动链路。重点解决一个问题为什么项目脚本偏偏把u-boot-dtb.imx写到 1 KiB而 boot 分区又从 16 MiB 开始。