基本的OS启动问题

时间:2010-01-10 17:52:02

标签: assembly operating-system boot bios

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

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

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

祝你好运, 喇嘛

6 个答案:

答案 0 :(得分:12)

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

2)不,

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

4)你没有。

答案 1 :(得分:6)

  • 但是那个小型汇编程序如何从操作系统启动引导加载程序?

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

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

一旦操作系统运行,引导加载程序就会响铃。这是一个很好的问题,因为在最初的PC概念中,BIOS为操作系统和引导加载程序执行了I / O,因此系统的一部分在加载操作系统后仍然存在。

  • 为什么所有的bootloader都是用汇编语言编写的?

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

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

C ++今天很好;当今天的大核心开始时,情况就不同了。

答案 2 :(得分:2)

  

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

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

  

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

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

  

为什么所有的bootloader都是用汇编语言编写的?

我认为这主要是出于一个原因:如果您使用高级语言编写引导加载程序,则生成的代码很可能依赖于某种包含基本函数的运行时库。但是,引导加载程序通常不需要它们,因此会使代码大小膨胀。

  

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

你没有严格要求。只是C代码比C ++更接近机器。使用C ++,您无法总是猜出将生成哪些代码,以及它是否会像您希望的那样高效。

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

答案 3 :(得分:1)

回答你的上一个问题:内核不需要用C语言编写。但是当尝试分配内存时,它会使它们变得容易得多。

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

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

答案 4 :(得分:0)

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

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

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

引导加载程序通常用汇编语言编写,因为它在总控制和可读性之间取得了很好的平衡。它可以用普通的机器代码编写(并且可能是第一个),但是更难以阅读。它可以用像C这样的低级语言编写,但很难达到你需要加载的BIOS中的低级例程,并且很难将它保持在大小限制内,因为编译后的代码往往有一个很多开销。

操作系统通常用低级语言编写,例如C(引导加载程序和硬件驱动程序之类的东西仍在汇编程序中)。您可以使用C语言编写它,因为它是基于C构建的,但是这将是毫无意义的,因为您不会使用C ++添加的大部分内容。在编写操作系统时,面向对象并不是很有用。

答案 5 :(得分:0)

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

一个。 MMU仍未设置,

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

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

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

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

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

但确实存在像uClinux那样的分发,它不需要设置MMU:

http://www.uclinux.org/

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