如何引导完全用C ++编写的操作系统?

时间:2019-02-10 16:19:48

标签: c++ operating-system boot

我写了一个用C ++编写的简单操作系统的基础,但是对于研究如何为该操作系统编写一个简单的引导加载程序以便与GRUB结合使用或使编写引导加载程序变得更简单的类似方法没有运气。看看it's GitHub repository,看看我要引导什么代码。

该操作系统需要一些非常简单的东西才能运行并具有完整的功能。它需要能够使用标准C ++库(例如iostreamfstreamstring.h,甚至可能是iomanip)。它还需要具有任何排序的文件系统(NTFS,FAT,FAT32,Ext4等)。而且,最重要的是,它需要一种执行其他可执行文件的方式(通过system()或任何更安全的方法)。

当前,它可以从硬编码目录运行可执行文件(称为“命令”),在完全加载内核之前运行可执行文件(称为“ kautorun”),并且可以在Win32和GNU / Linux之上编译和运行。

最好,我希望能够使编写引导加载程序变得容易,并且我正在考虑使用GRUB,并且一些特殊的编译器命令可以做到这一点。我只是不确定如何解决这个问题。我该怎么做才能使它正常工作?而且,我是从错误的角度来解决这个问题吗?

编辑:要缩小一点,我需要一个引导加载程序来运行这些可执行文件,保留我使用的C ++库并保持目录结构完整。希望可以将其范围缩小到足够小,并解决这个问题,因为它范围太广。

2 个答案:

答案 0 :(得分:1)

老实说,您的代码与编写操作系统无关。它只是一个能够运行一些命令的控制台应用程序,甚至与shell实现也不相近。

要更好地了解编写操作系统所需的内容,建议您至少阅读OSDev Wiki上的一些初学者文章。您还应该查看here,以查看在独立环境(即没有OS的环境)中可以使用哪些C ++标准头。您会注意到那里没有文件系统或I / O标头,也没有system()函数,因为没有外壳程序可以运行它。

基本上,所有这一切都意味着开发您自己的OS就是自己实现所有这些功能:内存管理,多任务,I / O等。此外,您确实需要引导加载程序来引导OS和您可以使用GRUB使事情变得更轻松,但是引导加载程序不会为您提供其他任何其他功能(进程,I / O等),它唯一要做的就是将控制权转移到您的代码,之后,您就一个人了。

关于使用C ++进行OS开发,是的,您可以使用C ++编写大多数OS ,但是您仍然必须至少使用内联汇编来完成特定于硬件的任务用C ++表示,例如:用于与硬件通信的端口I / O,加载特殊处理器寄存器(控制寄存器,特定于模型的寄存器),加载全局描述符表(描述内存段),加载中断描述符表(其中设置用于硬件中断的处理程序),也许还有更多...

答案 1 :(得分:0)

编写引导操作系统需要大量工作。我建议使用类似IncludeOS之类的东西,它允许您编写一个可以启动的“应用程序”。

编写启动加载程序,您将需要知道要启动的硬件。对于PC,主要有两个。

由于您在谈论GRUB,因此很可能在谈论BIOS计算机。

一台BIOS机器使用您可以使用的BIOS服务引导进入16位x86模式。通过将主HD的第一个扇区加载到地址“ 0x0000:0x7C00”中进行引导,然后跳转到该地址。

第一个扇区通常是带有分区表的MBR。一个被标记为“启动”分区(或者您得到某种“菜单”启动)。然后,MBR代码将引导分区的第一个扇区加载到地址“ 0x0000:0x7C00”,然后跳转到该地址。

分区的第一个扇区通常称为BPB

BPB通常是有关分区类型(FAT,NTFS,EXT等)的数据和用于启动操作系统引导的代码的混合。由于仅加载了1个扇区,因此代码空间非常有限。因此,这仅是用汇编程序编写的,该代码使用BIOS服务在文件系统中查找操作系统的“真实”启动代码,并将其加载到内存中并跳转到该内存。

UEFI与BIOS类似,但是提供了完整的引导环境,您可以在其中编写EUFI应用程序,并且引导菜单配置将运行该应用程序以引导操作系统。该应用程序可以用C ++编写,您可以使用UEFI服务(例如,当您获得用于网络和图形的API时,它包含的服务要比BIOS多得多)。此引导代码通常使用引导配置从分区加载初始OS引导代码并跳转到该分区(并关闭UEFI服务,以及从某些时候开始通常不使用它们)。

从这一点来看,操作系统启动代码的作用很大程度上取决于正在启动的操作系统。他们通常是:

  • 切换到保护模式并设置protection ring environment
  • 加载“驱动程序”以处理特定的硬件(PC旧版硬件和PNP硬件)

IncludeOS通过将上述内容的非常简化的版本提供到一个简单的库中而使操作变得更加容易。