我正在尝试创建一个发行版映像(通过 Linux 的dd
命令)来获取可与硬盘和闪存介质配合使用的操作系统。我已成功创建映像,但无法使其正确启动。我将以下步骤布局:
这将创建一个包含整个图像的空白文件:
dd if=/dev/zero of=/tmp/test.img bs=512 count=1250000
将环回设备文件与图像文件关联:
losetup /dev/loop0 /tmp/test.img
在我们可以操作之前
parted
我们必须定义一个媒体标签类型:parted -s /dev/loop0 mklabel msdos
在映像文件中创建第一个分区,大小为 512MB:
parted -s -a opt /dev/loop0 mkpart primary ext2 '0%' 512MB
将第一个分区设置为“可启动”:
parted -s /dev/loop0 set 1 boot on
在第一个分区上创建 Ext2 文件系统:
mkfs.ext2 -b 1024 /dev/loop0p1
安装 grub 引导代码的 stage1,同时保留上面创建的分区表:
dd if=/boot/grub/stage1 of=/dev/loop0 bs=446 count=1
在媒体的前 512 个字节之后安装 grub 引导代码的第 2 阶段(跳过第 1 阶段和分区表):
dd if=/boot/grub/stage2 of=/dev/loop0 bs=512 seek=1
将映像文件的第一个分区挂载到挂载点:
mount /dev/loop0p1 /mnt/image
将所有数据复制到分区并卸载。
dd
将图像文件复制到任何硬盘或闪存介质。
使用这些步骤,我可以将dd
映像文件复制到硬盘驱动器或闪存驱动器,然后启动到 grub legacy 控制台,在那里我可以启动,但只能通过指定root
、kernel
和initrd
值。如果我尝试通过root
和setup
命令安装 grub legacy,我不会收到任何错误,但设备启动时会显示乱码。运行和fdisk -l
会产生:
Partition 1 has different physical/logical beginnings (non-Linux?):
phys(0,32,33) logical(0,37,14)
Partition 1 has different physical/logical endings:
phys(62,53,55) logical(336,27,19)
我认为创建映像文件的方式存在问题,因为它负责创建(混乱的)分区表。有人可以使用这些(修改后的)步骤来制作可启动的媒体吗?
答案1
在镜像文件中创建第一个分区,大小为 512MB
parted -s -a opt /dev/loop0 mkpart primary ext2 '0%' 512MB
在步骤#4中,您使用实用程序来修改分区表的第一个条目,该条目位于扇区/块的末尾,还包含MBR的引导加载程序。
安装 grub 引导代码的 stage1,同时保留上面创建的分区表:
dd if=/boot/grub/stage1 of=/dev/loop0 bs=446 count=1
在步骤 #7 中,您尝试将引导加载程序安装到第一个扇区/块中,该扇区/块已包含有效分区表。
但是日是一个块传输实用程序,它从源读取块,并将这些块写入目标。
在这种情况下,目标设备是 HDD 或 SSD,大概基于 512(或 4096)字节扇区。对块设备的读取或写入操作必须针对整个扇区。
当尝试仅写入 446 字节的“短”数据时,磁盘控制器(或操作系统)会执行此操作,但会附加 66(或 3650)字节的零以将扇区填充到其正确/完整长度。
块写入不是为了部分修改扇区并保留“未写入部分”。
因此,此写入操作将覆盖先前安装的分区表。
简单的解决方案是在步骤 #4 之前执行步骤 #7。这将使用空分区表写入整个 MBR 扇区,然后仅编辑一个条目。