我试着学习引导装载程序和操作系统和bios。所以
我找到这个链接https://dev.to/frosnerd/writing-my-own-boot-loader-3mld
这导致了一位大学教授的冗长教程。从教程中我读到引导装载程序/BIOS的方式(这两个术语是互换使用的作者,我认为)区分寻找可执行的操作系统和数据和事情是通过使用循环和检查一个东西称为幻数,这是存储在每个磁盘的特定地址位置一次。幻数是0xaa55
。因此,这意味着它写在硬盘(S)。所以让我们说,我有两个或三个操作系统安装,并在 Boot 选项,我可以选择从哪一个启动。在第二个操作系统的幻数存储,如果我只有一个硬盘设备,但多个分区。作为引导扇区幻数位置,只有磁盘是由第一个操作系统幻数:目前在柱面0,头0,扇区0。因为我可以使分区,分为多个部分的磁盘,让我们说Linux-A和Linux-B分区。作者说
So, the easiest place for BIOS to find our OS is in the first sector of one of the
disks (i.e. Cylinder 0, Head 0, Sector 0),
...
an unsophisticated means is adopted here by BIOS, whereby the last two
bytes of an intended boot sector must be set to the magic number 0xaa55
以上让我想到幻数可能是每个磁盘一个,但在磁盘分区的概念之后就不再是了。2我想知道如果有多个操作系统和具有多个分区的单个磁盘,操作系统的起始地址是如何找到的
也是0xaa 55,考虑到同一磁盘上没有分区,是否所有CPU体系结构都相同(0xaa 55是不是x86和x86-64的幻数)和硬盘相关?或者它是一个bios或 Bootstrap 相关。就像如果有人制作自己的 Bootstrap 或编辑grub
代码,那么可以考虑任何数字作为幻数,比如说0xabcd。什么东西定义了幻数应该是0xaa 55。
2条答案
按热度按时间rkue9o1l1#
我自己对这些事情的理解也有点粗糙,但希望我能给你一点启示,让你继续你的道路。如果有人能纠正我文本中的错误,我会很高兴!
首先,BIOS和bootloader不是一回事。BIOS是一堆代码,存储在主板上的一个特殊芯片中(你可以用主板制造商的“BIOS更新”来更新这些代码)。当你的计算机打开时,主板会将这些代码加载到RAM中,然后设置CPU开始执行它。它实际上是当你的计算机打开时运行的第一个代码。
BIOS完成工作并初始化了需要初始化的硬件后,它开始寻找要 Boot 的操作系统。它通过四处询问各种设备,直到找到一个可以引导的设备来完成这一工作。现代BIOS可以从各种设备引导,如硬盘驱动器、USB驱动器、软盘驱动器、CD、网络适配器、RAID控制器和其他可能的外来设备。
对于这些设备中的每一个,询问过程各不相同,但是对于硬盘驱动器,BIOS会在预先确定的位置查找您提到的神奇字节。实际上,BIOS所做的是将驱动器的前512个字节加载到内存中(过去所有硬盘驱动器都具有512字节扇区,所以在奥登,这应该是1个扇区),然后检查魔术字节。如果它找到他们,它设置CPU执行该扇区的第一个(我认为)字节,这就是它的工作结束。
前512个字节是 Bootstrap 。实际上,512个字节并不多。事实上,如果你有一个MBR风格的分区方案,你有甚至更少,因为整个分区表也必须适合那里。它肯定没有足够的字节显示提示给用户或做几乎任何其他有用的事情。当然,如果你写自己的 Bootstrap ,这可能是足够的。但是对于现代的引导加载程序来说,它甚至还远未接近。所以这512字节所做的一切就是从硬盘驱动器的其他地方加载更多的代码。而这些代码很可能从其他地方加载更多的代码,等等。最终,你已经在RAM中加载了足够的数据,拥有了一个功能齐全的引导加载程序,它可以向用户呈现提示,显示闪屏等等。
引导加载程序接下来要做什么以及如何加载操作系统是特定于特定操作系统的,所以这就是共同点的结束。如果系统上有多个操作系统,引导加载程序也需要知道它们,而它是如何做到这一点的也因引导加载程序而异。你可以制定自己的方案。
现在,关于兼容性的说明,这整个方案是“IBM PC BIOS”方案,它首先用于IBM PC,但是它们变得如此流行以至于每个人都开始制造自己的“IBM PC兼容”机器,因此他们也必须包括一个工作相同的BIOS。
你看,在早期的时候,操作系统非常简单。“驱动程序”的概念还不存在,BIOS填补了它的空间。因为它知道它将在什么硬件上运行(PC定制远没有达到今天的水平),它还可以包括一些知道如何处理硬件的代码。因此,即使BIOS将控制权交给引导加载程序,它仍然会在内存中的预定位置留下一堆代码,引导装载程序(以及后来的操作系统和程序)可以使用这些代码与硬件交互,比如阅读磁盘、在屏幕上显示内容、通过串行/并行端口发送数据等。
现在,现代的操作系统已经不再关心这个问题了。它们有自己的驱动程序,通过自己的代码与硬件交互,所以BIOS中剩余的代码对它们来说毫无用处。但由于兼容性是如此重要,所有的BIOS甚至到了现代都必须模仿这些老化的标准。更重要的是,它们必须在启动时初始化所有的硬件--无论如何,现代操作系统都会重做这件事。所以只是白费力气。
由于这种和其它低效率,UEFI标准诞生了。它取代了BIOS,而且......它相当复杂,我真的不知道它是如何工作的。我所知道的是,操作系统实际上可以将特殊驱动程序加载到UEFI中(反之亦然?),使硬件初始化工作不被浪费。它还可以检查 Bootstrap 的数字签名,以防止恶意代码和其他事情。这导致了更快的 Boot 过程,但所有关于magic bytes和诸如此类的东西都会飞出窗口。我真的不知道UEFI是如何切换到引导加载程序的。
而且,是的--这些都是个人电脑领域特有的。我不知道Mac电脑是如何工作的。新的M1 Mac电脑也很可能有不同的工作方式。智能手机和嵌入式系统等其他类型的设备也有完全不同的 Boot 方案。
另外,以防万一,关于MBR和GPT -你真的不需要用它们中的任何一个分区。它们只是大多数操作系统制造商同意的两个标准,以便他们可以使用彼此的磁盘。但这只是一个惯例。BIOS不关心你的磁盘是如何布局的。它只关心第一个扇区。只要你的引导加载程序和操作系统能够理解并使用你的自定义花哨方案,一切都很好。除了我认为UEFI * 确实 * 要求磁盘格式化为GPT,因为它实际上读取了更多的数据...但我不确定。BIOS肯定不关心。
juzqafwq2#
在Mac M1上,打开终端并运行system_profiler