如何用高级语言对操作系统进行编码



我刚刚开始深入到操作系统的世界,我了解到进程有一定的内存空间,它们可以寻址,由操作系统处理。我不太明白用c和c++这样的高级语言编写的操作系统是如何获得这种内存管理功能的。

您已经发现了这个错误,但没有治愈方法:-)

你用来编写操作系统的语言与操作系统的操作方式几乎没有关系。是的,大多数人使用C/C++,但也有其他人。至于语言,您确实需要一种语言,可以让您直接与计划管理的硬件进行通信,组装是该部分的主要选择。然而,这还不到整个项目的5%。

您编写的代码不能依赖于任何现有的操作系统。即:您必须自己编写所有函数的代码,或者调用现有的库。然而,必须编写这些现有的库,这样它们就不会依赖于其他任何东西。

一旦你有了基础,你就可以用你选择的任何语言编写你的操作系统,其中的小部分是汇编,这是高级语言不允许的。事实上,在64位代码中,一些编译器不再允许内联汇编,所以这使得我上面提到的5%更像15%。

找出你想做什么,然后找出是否可以用你选择的语言来做。例如,主要的操作系统组件可以用C编写,而实际的处理器管理(中断等)必须在汇编中完成。你的引导代码也必须在程序集中,至少大部分是这样

正如在另一篇文章中提到的,我有一些早期的示例代码,你可能想看看。引导是在汇编中完成的,而加载程序代码,包括Legacy BIOS和EFI,大多是C代码。

为了澄清fysnet的答案,您必须至少使用一点汇编的原因是,您只能显式访问C/C++中的可寻址内存(通过指针),而硬件寄存器(如程序计数器或堆栈指针)通常没有内存地址。不仅如此,一些寄存器还必须使用依赖于CPU体系结构的特殊指令进行操作,而这也只有在机器语言中才可能实现。

我不太明白用c和c++等高级语言编写的操作系统是如何获得这种内存管理功能的。

如上所述,根据体系结构,这可以通过具有管理MMU、TLB等的特殊指令来实现。INVLPG是x86体系结构中此类指令的一个示例。请注意,拥有一条需要内核权限的特殊指令可能是以安全的方式在硬件中实现此类功能的最简单方法,因为检查CPU是否处于内核模式就足够了,以确定该指令是否可以执行。

编译器为您将高级语言转换为asm/machine代码,因此您不必自己编写asm。你选择了一个编译器,它可以按照你希望操作系统的方式处理内存;例如,使用调用堆栈进行自动存储,而不是隐式调用malloc/free(因为这些在内核中不存在)。

要将编译后的C/C++链接到内核中,您通常必须更多地了解它所针对的ABI,以及工具链,尤其是链接器。

ISO C标准将实现细节视为一个黑盒。但是,人们用于低级别内容的真正编译器以内核程序员所依赖的众所周知的方式工作(即做出预期/有用的实现选择),将代码和静态数据编译成可以链接到单个内核可执行文件中的连续块,这些可执行文件可以作为一个块加载。


至于实际管理系统内存,您可以自己编写代码来实现这一点,并在其他答案提到的invlpg等特殊指令所需的地方使用一些内联asm。

入口点(执行开始的地方)通常用纯asm编写,以设置一个调用堆栈,堆栈指针寄存器指向它。并设置虚拟内存等,使代码可执行,数据可读/写,只读数据可读。在跳转到任何已编译的C代码之前完成所有这些。您跳转到的第一个C可能是更多的内核初始化代码,例如初始化分配器的数据结构,以管理静态代码/数据尚未使用的所有内存。

创建堆栈并将代码/数据映射到内存是操作系统在启动用户空间程序时通常执行的设置。编译器发出的asm将假定代码、静态数据和堆栈都已经存在。

最新更新