我有一个基于 DOS 的 HDD 实用程序,称为 spinrite。我想使用 freedos 操作系统创建一个可启动闪存驱动器,并在创建后将可执行实用程序复制到该驱动器中。
我尝试使用 gparted 对驱动器进行分区,将其格式化为 Fat32 并设置启动标志。完成后,我无法看到如何安装操作系统并添加可执行文件。我有一个 Freedos 的映像文件,如果我尝试用它制作闪存驱动器,那么它无法启动。任何帮助是极大的赞赏。
答案1
官方 FreeDOS 映像(截至撰写本文时)似乎并不打算用作“live CD”,而是用作安装介质。因此,要制作适合您的目的的可启动媒体,您可以修改官方 FreeDOS 安装程序映像之一。但是,您可能会受到所选介质大小的限制,尤其是在使用软盘映像时。
在这个答案中,我将重点关注在 Linux 中从头开始创建一个最小的 FreeDOS 启动磁盘映像(您需要的任何大小),然后编写 MBR、VBR、启动所需的最小 FreeDOS 文件集以及单个程序(spinrite) )或任何 DOS 实用程序,如 BIOS 更新工具等。
然后,您可以使用 PXE 启动来启动此 FreeDOS 映像,或者使用以下命令将其写入 USB 驱动器dd
创建 FreeDOS 启动驱动器。当然,您可以扩展此处使用的步骤来创建您想要的任何 FreeDOS 媒体,包括添加 FreeDOS 完整版附带的全套软件。
在 Windows 机器上,您可以使用类似的工具鲁弗斯来做这件事。但在 Linux 上你可以使用ms-sys
(Rufus 内部使用的源代码)。
以下是创建可启动 FreeDOS 映像的步骤:
警告/免责声明!!!如果使用不当,下面使用的某些命令可能会从您的磁盘驱动器中擦除数据。在继续操作之前,请阅读每个程序的手册页以了解命令用法。您可能希望在没有您宝贵数据的辅助/虚拟机上尝试这些命令。
第 1 步:安装先决条件 (ms-sys):
ms-sys
如果您的包管理器不支持从源代码安装:$ wget https://sourceforge.net/projects/ms-sys/files/ms-sys%20stable/2.6.0/ms-sys-2.6.0.tar.gz $ tar -xzvf ms-sys-2.6.0.tar.gz $ cd ms-sys-2.6.0
编译 ms-sys 需要使用可以安装在 Debian/Ubuntu 上的软件包
msgfmt
:gettext
$ sudo apt install gettext
编译并安装:
$ make $ sudo make install
步骤2:创建空白磁盘映像并创建msdos分区:
为磁盘映像创建一个空文件:
$ truncate -s 50M disk.img
注意:此处创建了 50 MiB 大小的磁盘映像,但您可以将其设置为您需要的任何大小
对磁盘映像进行分区:
$ fdisk disk.img Command (m for help): o Created a new DOS disklabel with disk identifier 0x1234abcd. Command (m for help): n Partition type p primary (0 primary, 0 extended, 4 free) e extended (container for logical partitions) Select (default p): p Partition number (1-4, default 1): <ENTER> First sector (2048-102399, default 2048): 2048 Last sector, +sectors or +size{K,M,G,T,P} (2048-102399, default 102399): <ENTER> Command (m for help): t Selected partition 1 Partition type (type L to list all types): c Command (m for help): a Selected partition 1 The bootable flag on partition 1 is enabled now. Command (m for help): w
注意:
fdisk
上面的命令假设您需要 FAT32 文件系统。如果您想使用 FAT16 文件系统,则对于上述问题,Partition type (type L to list all types):
请输入e
而不是c
第三步:确认第一个分区的起始扇区位置:
使用 fdisk 确定起始扇区:
$ fdisk -l disk.img Disk disk.img: 50 MiB, 52428800 bytes, 102400 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x1234abcd Device Boot Start End Sectors Size Id Type disk.img1 * 2048 102399 100352 49M c W95 FAT32 (LBA)
注意:从上面的
fdisk
输出我们可以看到起始扇区偏移量是2048扇区或 2048 x 扇区大小字节 = 2048 x 512 字节 =1048576字节。实际上我们明确指定了起始扇区第2步但我包含了此步骤,因为当分区已创建时它可能很有用。这些数字:2048和1048576在下面的命令中使用。
步骤 4:使用 FAT 文件系统格式化分区
搜索免费循环设备:
$ losetup -f /dev/loop0
创建分区的循环设备(位于 offset=1048576磁盘映像):
$ sudo losetup -o1048576 /dev/loop0 disk.img
创建FAT文件系统:
要创建 FAT16 文件系统:
$ sudo mkfs.vfat -F16 -R8 -h2048 /dev/loop0
要创建 FAT32 文件系统:
$ sudo mkfs.vfat -F32 -h2048 /dev/loop0
注:在
mkfs.vfat
参数-h2048
为必填项。mkfs.vfat
不会将分区之前的隐藏扇区写入引导记录,除非您指定此参数并且引导映像需要该参数)。这里同样2048
是扇区中分区 1 的偏移量,如步骤3。该参数-R8
是可选的,但建议使用。
步骤 5:用于ms-sys
写入主引导记录 (MBR) 和卷引导记录 (VBR):
首先在分区仍作为循环设备加载时写入 VBR:
要创建 FAT16 文件系统:
$ sudo ms-sys --fat16free /dev/loop0
要创建 FAT32 文件系统:
$ sudo ms-sys --fat32free /dev/loop0
笔记:
- 不要使用此命令:
ms-sys --partition /dev/loop0
即使在某些ms-sys
文档中讨论了某些情况下需要的命令。它将覆盖已正确写入的隐藏扇区字段mkfs.vfat
ms-sys
只写入第一引导记录。ms-sys
与 Rufus 不同,Rufus 不会写入 FAT32 的备份引导记录,但这不应阻止映像的可引导。
- 不要使用此命令:
接下来从循环设备中卸载/分离磁盘映像文件:
$ sudo losetup -d /dev/loop0
最后将 Windows 7 MBR 写入磁盘映像:
$ ms-sys --mbr7 --force disk.img
注意:写入常规(非设备)文件时
ms-sys
需要参数。--force
步骤 6:将基本 FreeDos 文件和您需要的任何其他程序写入磁盘映像上的分区:
挂载分区:
$ mkdir mnt $ sudo mount -o loop,offset=1048576 disk.img mnt/
下载并解压所需的 FreeDOS 文件:
$ wget https://github.com/pbatard/rufus/archive/v3.6.tar.gz $ tar -xvf v3.6.tar.gz rufus-3.6/res/freedos/
注意:这些文件是从 Rufus github 存储库下载的,但是从 FreeDOS 官方网站提取的。参见
readme.txt
上https://github.com/pbatard/rufus/tree/master/res/freedos/有关 Rufus 从官方 FreeDOS 来源获取二进制文件的详细信息。将文件复制到分区:
$ sudo mkdir mnt/LOCALE $ sudo cp rufus-3.6/res/freedos/!(COMMAND.COM|KERNEL.SYS) mnt/LOCALE/ $ sudo cp rufus-3.6/res/freedos/{COMMAND.COM,KERNEL.SYS} mnt/ $ printf '@echo off\r\nset PATH=.;\\;\\LOCALE\r\necho Using US-English keyboard with US-English codepage [437]\r\n' | sudo tee mnt/AUTOEXEC.BAT $ sudo fatattr +h +s mnt/COMMAND.COM $ sudo fatattr +h +s mnt/KERNEL.SYS
笔记:
- 使磁盘映像可引导真正需要的唯一文件是
COMMAND.COM
和KERNEL.SYS
。其余文件是可选的 - 现在,您还可以在卸载之前将任何其他文件复制到磁盘映像(例如:spinrite.exe)。
- 这些命令是可选的,但按照惯例
fatattr
向文件添加隐藏和系统属性。在 Debian/Ubuntu 系统上,您可以使用以下命令安装该程序COMMAND.COM
KERNEL.SYS
fatattr
sudo apt-get install fatattr
- 使磁盘映像可引导真正需要的唯一文件是
第7步:你就完成了!
卸载磁盘映像:
$ sudo umount mnt/
答案2
以下是我自定义 FreeDOS 镜像的方法:
从我从 Freedos 站点下载的可启动软盘映像开始。不幸的是,它充满了我不需要运行一些一次性实用程序(例如 BIOS 更新程序)的东西。
使用以下命令安装它的副本:
mkdir -p ./floppy cp -a ./freedos-1440kb.img freedos-empty.img mount -o loop,rw freedos-empty.img ./floppy
cd ./floppy
并删除所有不需要的内容。最终,1.44MB 的映像上应该有大约 1.2 或 1.3MB 的可用空间。cd .. ; umount ./floppy
这给了我一个几乎空的可启动映像,我可以用它来制作任意数量的自定义映像。然后我复制一份,然后将我需要的任何内容复制到上面。例如
cp -a ./freedos-empty.img ./freedos-spinrite.img mount -o loop,rw freedos-spinrite.img ./floppy cp spinrite.exe ./floppy umount ./floppy
然后可以将该映像复制到软盘驱动器、闪存驱动器等(例如, USB 记忆棒的设备节点在cat freedos-spinrite.img > /dev/sdX
哪里)。sdX
我几乎从不费心这样做,因为当我需要一个空的、可用的闪存驱动器时,我永远找不到一个……这也比使用 grub 或 tftp 菜单需要更多的工作和更长的时间。而且启动 U 盘比存储在本地硬盘或我的 tftp 服务器上的磁盘映像慢。
就我而言,我将其复制到我的/boot/images/
目录并运行update-grub
...然后将scp
其复制到可能需要它的其他计算机上,并update-grub
通过 ssh 在它们上运行。
我还将它复制到我的/var/lib/tfptboot/freedos/
并运行我编写的脚本来*.img
为该目录中的所有文件生成菜单条目。
这让我可以在启动时从 grub 菜单启动 freedos 映像,并在任何启动时具有“从网卡启动”选项的机器上通过 ipxe 和 tftp 通过网络启动 freedos 映像(即现在几乎所有机器。如果您包括ipxe
也可以从 grub 启动的事实)。
我用它来构建可启动映像以更新主板上的 BIOS、将 LSI SAS 卡重新刷新为 IT 模式以及将固件更新应用于某些 Seagate 硬盘等。
顺便说一句,这就是为什么我喜欢创建“超大”/boot
分区(1 或 2GB 或更多) - 这样我就可以启动任何“合理”大小的任何映像。另外,这样我就不会耗尽 /boot 中的空间,并且必须始终清除旧的内核映像。它对于启动gparted
或镜像等也很有用clonezilla
。
额外的东西:设置 grub
最初为此进行设置tftp
是一项相当大的工作,因此我不会在这里详细介绍该过程(我很确定我已经在本网站的另一个答案中描述了该过程,并且我的 tftp 脚本位于我的github帐户 - 但我还没有上传 memdisk/freedos 脚本),但需要做的事情很少grub
:
- 安装
syslinux
(或者至少memdisk
从中获取二进制文件的副本)。 cp memdisk /boot
- mkdir -p /启动/图像
- 将您的可启动
*.img
图像*.iso
文件复制到/boot/images
. - 将脚本
42_memdisk
(见下文)复制到/etc/grub.d/
并使其可执行chmod +x /etc/grub.d/42_memdisk
update-grub
以 root 身份运行
注意:以上内容适用于 Debian 和大多数相关/衍生发行版,例如 Ubuntu 和 Mint。其他发行版的设置略有不同grub
,因此您必须相应地调整过程。
memdisk
可以启动任何可启动的磁盘映像 - 从软盘映像到 CD-ROM/DVD 映像,再到硬盘映像。
42_内存盘(这是为 grub 生成菜单条目的脚本):
#!/bin/sh
set -e
IMAGES=/boot/images
. /usr/lib/grub/grub-mkconfig_lib
if test -e /boot/memdisk ; then
echo "Found memdisk: $MEMDISKPATH" >&2
MEMDISKPATH="$( make_system_path_relative_to_its_root "/boot/memdisk" )"
find "$IMAGES" -name '*.img' -o -name '*.iso' | sort |
while read image ; do
IMAGEPATH="$( make_system_path_relative_to_its_root "$image" )"
echo "Found image: $IMAGEPATH" >&2
cat << EOF
menuentry "Bootable image: $(basename $IMAGEPATH | sed -E -e 's/\.(img|iso)$//i')" {
EOF
prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e 's/^/\t/'
cat << EOF
linux16 $MEMDISKPATH bigraw
initrd16 $IMAGEPATH
}
EOF
done
fi
IIRC,这是我几年前在谷歌搜索如何做这样的事情时发现的脚本修改的(我不记得在哪里)。
输出示例:
# update-grub
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-4.14.0-2-amd64
Found initrd image: /boot/initrd.img-4.14.0-2-amd64
Found linux image: /boot/vmlinuz-4.14.0-1-amd64
Found initrd image: /boot/initrd.img-4.14.0-1-amd64
Found linux image: /boot/vmlinuz-4.12.0-2-amd64
Found initrd image: /boot/initrd.img-4.12.0-2-amd64
Found iPXE image: /boot/ipxe.lkrn
Found memtest86 image: /memtest86.bin
Found memtest86+ image: /memtest86+.bin
Found memdisk:
Found image: /images/LSI.img
Found image: /images/Seagate-PH-CC49.img
Found image: /images/fd-asus-m5a97.img
Found image: /images/freedos-empty.img
done