5

我对计算机的启动过程和引导加载程序调用操作系统的部分有一些基本的问题。

所以我知道 BIOS 将前 512 个字节从可引导驱动器复制到内存中并执行代码——这就是引导块。

  • 但是那个小汇编程序是如何从操作系统引导引导加载程序的呢?
  • 引导加载程序是否继续运行并且仍然充当软件和硬件之间的“发送器”?或者控制权完全交给了操作系统?
  • 为什么所有引导加载程序都是用汇编程序编写的?
  • 为什么在编写操作系统时必须从 C++ 回到 C?

最好的问候,喇嘛

4

6 回答 6

12

1)引导加载程序通常包含一些简单的指令来从磁盘加载更多数据并执行它。

2)不,

3)尽量减少它们占用的空间。

4)你没有。

于 2010-01-10T17:55:26.297 回答
6
  • 但是那个小汇编程序是如何从操作系统引导引导加载程序的呢?

是的,引导加载程序很小,但 BIOS 不是,它实现了 .. 始终实现 .. DOS I/O“系统调用”。这个 I/O 系统最初在 DOS 和早期的 Windows 时代运行整个 OS I/O 系统。现在它只是一个控制台,负责加载真正的操作系统,然后提供所有自己的驱动程序。它是一种用于引导加载程序的设备驱动程序库和原始 IBM PC 模拟器。

  • 引导加载程序是否继续运行并且仍然充当软件和硬件之间的“发送器”?或者控制权完全交给了操作系统?

操作系统运行后,引导加载程序就会启动。这是一个很好的问题,因为在最初的 PC 概念中,BIOS 为操作系统和引导加载程序进行 I/O,因此系统的一部分在加载操作系统时确实存在。

  • 为什么所有引导加载程序都是用汇编程序编写的?

几个原因:它们需要很小,它们有固定地址布局限制,它们必须执行int $x样式的 BIOS 调用,并且考虑到它们的大小以及其中一些必须在汇编中的事实,没有太多可做的通过占用 128 个字节左右并说“好的,这部分你可以用 C 编写,尽量不要写超过 10 个左右的语句”来获得收益。

  • 为什么在编写操作系统时必须从 C++ 回到 C?

C++ 今天很好;回到今天的大内核开始时,情况有所不同。

于 2010-01-10T18:54:04.827 回答
2

但是那个小汇编程序是如何从操作系统引导引导加载程序的呢?

因为你不能在 512 字节的代码中做很多事情(尽管事实上,引导加载程序并不严格限制在 512 字节),引导加载程序通常只会将更大的代码块从磁盘加载到 RAM 中然后执行它。

引导加载程序是否继续运行并且仍然充当软件和硬件之间的“发送器”?或者控制权完全交给了操作系统?

我认为一旦引导加载程序代码完成了它的工作,并跳转到它已经加载到内存中的附加代码,它就可以被覆盖,因为它不再需要了。

为什么所有引导加载程序都是用汇编程序编写的?

我想这主要是出于一个原因:如果你用高级语言编写引导加载程序,生成的代码很可能依赖于某种运行时库,其中包含基本功能。然而,引导加载程序通常不需要这些,因此会增加其代码大小。

为什么在编写操作系统时必须从 C++ 回到 C?

您不必严格要求。只是 C 代码比 C++ 更接近机器。使用 C++,您不能总是猜测会生成什么代码,以及这是否会像您希望的那样高效。

编辑:我也听说过一些操作系统开发人员坚持使用 C 语言的论点,因为在不同的编程范式和风格中的选择比在 C++ 中的选择要少。因此,对于具有通用代码库的团队来说,它更容易工作,因为每个人都会编写更多“相似”的代码。(由于我自己没有参与任何开源或操作系统的开发,我无法根据经验判断这是否是一个有效的说法。)

于 2010-01-10T18:02:35.127 回答
1

回答您的最后一个问题:内核不需要用 C 语言编写。但是在尝试分配内存时,它使它们更容易。

C++ 有很多不同的情况,您可以为临时变量等隐式分配内存,这些在代码检查时并不总是很明显。这使得编写内核变得更加困难,因为您必须避免在某些情况下分配内存。

但是,它并不完全排除用 C++ 编写内核。有办法解决这个问题。

于 2010-01-10T18:05:59.543 回答
0

关于为什么用汇编语言编写它的所有答案中都缺少一个重要点:因为:

一个。MMU仍未设置,

湾。没有现有的加载器进程正在运行来加载您编译的二进制文件 - 因为内存区域不是同质的 - 某些部分是硬连线用于 DMA/BIO 目的等,因此需要大量重新映射工作。

因此,当您在汇编中编写它时,您必须明确指定所有内存位置 - 数据位于何处,可执行文件位于何处等,并确保这些约束不冲突。

如果你用 C 编写,gcc 会将它编译成某种 ABI 标准格式,并且有一个预先存在的加载器(它可能只是一个库)将二进制文件加载到内存中。由于通常二进制文件中使用的内存多于物理内存中可用的内存,并且内存的某些部分保留用于硬件用途 - 特定于平台/硬件 - 因此在加载这些二进制文件之前设置 MMU 很重要。

ELF 加载只是复杂性的一个方面:

http://wiki.osdev.org/ELF#Loading_ELF_Binaries

但是确实存在像 uClinux 这样的发行版,它不需要设置 MMU:

http://www.uclinux.org/

有人必须教我更多关于那个......

于 2011-06-08T05:59:42.950 回答
0

引导加载程序从磁盘加载操作系统。

这就是为什么它被称为引导加载程序的原因 - 它通过在任何磁盘操作系统从磁盘加载任何内容之前从磁盘加载磁盘操作系统来在引导带中提升自身。

当操作系统被加载时,它接管并且加载器被丢弃。

引导加载程序通常用汇编程序编写,因为它在总体控制和可读性之间取得了很好的平衡。它可以用普通的机器代码编写(第一个可能是),但这更难阅读。它可以用 C 之类的低级语言编写,但很难在 BIOS 中实现加载所需的低级例程,而且由于编译后的代码往往具有很多开销。

操作系统通常是用像 C 这样的低级语言编写的(引导加载程序和硬件驱动程序等仍然在汇编程序中)。你可以用 C++ 编写它,因为它是基于 C 构建的,但这几乎没有意义,因为你不会使用 C++ 添加的大部分内容。在编写操作系统时,面向对象根本不是很有用。

于 2010-01-10T18:13:39.647 回答