【问题标题】:How do I write a bin file (512 bytes) to the first sector (sector 0) of a floppy disk?如何将 bin 文件(512 字节)写入软盘的第一个扇区(扇区 0)?
【发布时间】:2015-12-29 20:43:24
【问题描述】:

如何将 .bin 文件写入软盘/虚拟软盘/软盘映像的第一个扇区?

我正在尝试启动一个简单的 512 字节引导加载程序。到处都是“512 字节”的大小,所以我应该已经很好了。

其他信息:

引导加载程序只是显示一个字符串,我正在学习 simple 汇编。有些工作是在 Windows 中完成的,有些是在 Ubuntu 14.04 (Trusty Tahr) 中完成的(如果这很重要的话)。

即使有引导加载程序标志,它也无法启动。

【问题讨论】:

  • 可能我在发鬼,或者人们不再关心我,这很可悲。
  • 回答它。只要回答它。是的,你应该这样做。
  • 你在问一个非常高级的问题.. 大多数技术人员都不知道,而且这个问题(就像这里的许多问题一样)有 27 次浏览......比如 1027 次浏览。通常,搜索最广泛的问题获得最多的浏览量.. 但大多数人没有搜索这个.. 它非常小众和老技术
  • 另外我对你使用的学习材料很感兴趣..'因为我也有兴趣学习那种低级的东西
  • 谢谢!我将写入我的 USB 的第一个字节并启动它。

标签: assembly bootloader bios osdev floppy


【解决方案1】:

听起来很迷人。

过去,我已经多次写入软盘的前 512 个字节。我想更深入地了解它。

Roadkil 的扇区编辑器可以做到这一点,它可以让您打开屏幕上的前 512 个字节,并将其保存到一个文件中,然后打开一个包含前 512 个字节的文件,并将其保存到软盘中。

http://www.roadkil.net/program.php?ProgramID=24

有趣的是,有一个关于启动东西的经典网站,由与您同名的人,starman..http://starman.vertcomp.com/asm/mbr/ 虽然软盘是非分区媒体,因此没有 MBR。

我确定我已经保存了前 512 个字节,例如一张 Windows 98 软盘,上面写着正在启动 Windows 98,然后转到 C 提示符。它可以更改为例如一张 Windows 95 软盘。如果 3 个核心文件之一出现问题,您知道 XP 可以有一个 3 个文件的引导盘。嗯,它有一个不同的引导扇区。它不是dos启动盘。我记得XP中的format命令和98中的不同。98和DOS一样,它有一个格式/s来制作系统盘。我认为 XP 真的不能。我注意到 Win7 格式命令也不能。尽管在 XP 或 7 中,我认为您可以通过在“我的电脑”中右键单击 A 后勾选一个框来从 GUI 制作一个 dos 启动盘。您可以使用的另一件事是 *nix 风格的 dd 命令。或 ddrescue(它提供了比 dd 更多的信息)。一个类似的程序是 Bart 的 BBIE,它可以获取 CD 的可引导部分并将其解压缩。 Nero 曾经(也许现在仍然是)能够获取 512 字节软盘的引导扇区,并以此为基础创建 CD。所以如果你有一个可引导的 DOS 磁盘,你可以制作一个可引导的 DOS 光盘。它有一个选项,既可以让您浏览到带有该引导记录的映像,也可以将软盘放入并让它提取它。

【讨论】:

  • @MichaelPetch 我从 wikipedia en.wikipedia.org/wiki/Master_boot_record 得到了这个消息,“MBR 不存在于非分区媒体上,例如软盘、超级软盘或其他配置为类似行为的存储设备。”但从你所说的来看,很明显维基百科是错误的。引导记录、主引导记录和引导扇区这两个术语之间有什么区别(如果有)?
  • @MichaelPetch 软盘是无分区的吗? MBR 和 GPT 的一般类别和名称是什么?它们是分区表的类型吗?那么,软盘会有没有分区的分区表吗?还是他们有分区?很多网站+维基百科,说软驱没有分区。
  • @MichaelPetch 您自己的链接并没有说软盘有 MBR。 “然后将执行转移到新加载的引导记录。在软盘上,引导记录的所有 512 字节(保存最后两个签名字节)可能包含可执行代码。在硬盘驱动器上,主引导记录 (MBR) 保存偏移量 0x0000 - 0x01bd 处的可执行代码,后跟四个主分区的表条目,每个条目使用 16 个字节 (0x01be - 0x01fd) 和两个字节的签名 (0x01fe - 0x01ff)。”
【解决方案2】:

如果您在 Linux 上,您可以使用 DD 实用程序来完成。还有一个适用于 Microsoft Windows 的 DD 版本。


一般 DD 用法

如果您希望制作一个 720K 软盘大小的零填充虚拟磁盘映像,您可以像这样使用 dd

dd if=/dev/zero of=disk.img bs=1024 count=720

这将创建一个名为 disk.img 的文件,大小为 1024*720 = 737280 字节。可以使用以下命令创建一个 1.44MB 的零填充软盘映像:

dd if=/dev/zero of=disk.img bs=1024 count=1440

从图像的开头开始将二进制图像写入虚拟软盘可以这样完成:

dd if=bootload.bin of=disk.img conv=notrunc 

此示例将文件bootload.bin 放在磁盘映像的开头(在本例中称为disk.img)而不截断(conv=notrunc)如果您不在虚拟磁盘上使用conv=notrunc image 它将写入bootload.bin 并将磁盘映像截断为引导加载程序的大小。


DD 还可以通过跳转到磁盘开头以外的点来写入磁盘映像的特定部分。如果您需要在特定扇区中放置信息(代码/数据),这很有用。此示例可用于将引导加载程序的第二阶段放置在磁盘映像的第一个 512 字节扇区之后:

dd if=stage2.bin of=disk.img bs=512 seek=1 conv=notrunc

bs=512 将块大小设置为 512(使其更容易,因为它是大多数软盘扇区的典型大小)。 seek=1 查找图像开头之后的第一个块(512 字节),然后写入文件 stage2.bin 。我们再次需要conv=notrunc,因为我们不希望DDstage2.bin 结束的位置截断磁盘映像。

dd if=stage2.bin of=disk.img bs=512 seek=18 conv=notrunc

此示例与上一个示例类似,但它在写入 stage2.bin 之前跳过了 9216 个字节(512*18)


如果你有一张软盘连接到 Linux 系统(和 root 访问权限),你可以用类似的东西编写引导加载程序

dd if=bootload.bin of=/dev/fd0 

其中/dev/fd0 是您的软盘设备。 /dev/fd0 通常是软盘 A(如果有),/dev/fd1 是软盘 B(如果有)。


DD for Windows

如果您在 Microsoft Windows 上运行,则有一个版本的 DD 实用程序可用here。最新下载为dd-0.6beta3.zip,是最低推荐版本。它有一些旧版本没有的功能。只需打开 zip 文件并将其解压缩到 Windows 路径上的某个位置即可。

【讨论】:

  • 你的意思是conv=notrunc。我假设conv=noconv 是一个错字,而不是其他一些 dd 版本接受的东西。
  • 一次错误输入 + 复制并多次粘贴到 SO 答案中。在 DD(即使对于 Windows)中也没有这样的东西 ;) 已修复,谢谢
  • 我在 Windows 上将 /dev/fd0 替换为 E:\ 但它说找不到输出文件
  • @Kid8 :我的另一个 SO 答案有一些关于在 Windows 上使用 Chrysocome DD 的信息。检查屏幕截图上方的部分stackoverflow.com/a/36052385/3857942
【解决方案3】:

要将一个文件写入另一个文件,您可以编写一个程序。以下 sn-p 在 C 中。

char buf[512];
int floppy_desc, file_desc;
file_desc = open("xx.bin", O_RDONLY);
read(file_desc, buf, 512);
close(file_desc);

floppy_desc = open("floppy.img", O_RDWR);
lseek(floppy_desc, 512, SEEK_SET);
write(floppy_desc, buf, 512);
close(floppy_desc);

【讨论】:

  • 它不检查错误,如果floppy.img可读+可写但xx.bin不可读,则将垃圾写入。
  • write() 之前的输出中寻找512 会将其写入第二个扇区,而不是引导扇区。这也可能很有用(对于第二阶段的引导加载程序,正如 MichaelPetch 的回答所指出的那样),但这个问题是询问关于写入第一扇区的问题。
  • 您正在使用 POSIX 系统调用 (open(2)/read(2)/write(2)),而不是 ISO C stdio 函数 (fopen(3)/fread(3)/fwrite(3))。所以这只有在你有一个类 Unix 环境可用时才有效,在这种情况下你要么已经有 dd(1) 或者可以轻松安装它。
  • 如果您解决了这些问题,请给我回复,我很乐意投票。 (特别是如果你在它周围包裹一个 main() 以便它编译)。但是,危险/低质量的答案比没有答案更糟糕,所以我将不得不投反对票。不过,我确实在投票前考虑过。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-05
  • 1970-01-01
  • 2012-09-02
  • 2012-10-28
  • 1970-01-01
  • 2020-06-17
  • 2016-07-27
相关资源
最近更新 更多