内核(以及一般的操作系统)是如何用 C 语言编写的?

How are kernels (and operating systems in general) written in C?

我想了解你是如何着手用 C 语言编写 OS 的。

我一直使用 C 编写应用程序 - 使用 mallocfork 等命令从 OS 请求东西。如果在编写 OS 本身(或者特别是内核)时这些方法不存在,您将如何编写它们?

您如何实现内存和进程管理等,特别是哪些功能可用以及公开哪些功能可以让您在 C 而不是汇编程序中执行此操作? (内存/设备/中断交互叫什么?)

我可以想象这不是一个小问题,所以我很高兴得到一个包括一些进一步阅读的答案,但如果你能够总结与每个问题相关的要点,那将是对我来说超级方便!

提前致谢!

编辑 (8/3/20):

这个相关问题附有一些很好的资源,有助于回答问题:

What are some resources for getting started in operating system development?

How do you implement memory

编写自己的分配器是一项常见的系统编程练习。您唯一需要从“外部”获得的是要管理的内存区域。如果您正在对裸机进行编程,您可能会有一个可用的内存映射,它描述了哪些区域是 RAM。这些你可以用 malloc 管理。

and process management

现代 OS 的流程有很多。它们通常有自己的页表、上下文(进程挂起时保存的寄存器)和许多其他特定于进程的数据结构。

您可以在 C 中设置的数据结构,但它们的“激活”(切换页表,saving/restoring 上下文)通常超出可移植 C 中的可能范围。对于那些您有汇编例程或一些内联汇编与 C 代码交错。

and so on, specifically what functions are available and what is exposed to allows you to do this in C instead of assembler?

有托管和独立的 C 实现。如果您自己编写 OS,您通常处于独立的 C 环境中,并且没有标准库提供的函数供您使用。您依靠自己的代码、编写汇编例程或使用编译器内部函数。

what do you call to interact with memory

您可以将整数转换为指针并操纵指针。 volatile 允许您告诉编译器您绝对想按照编写的顺序执行 reads/writes。

devices

许多设备是内存映射的,这意味着您可以像 reading/writing 内存一样进行通信(简化;缓存可以使这有点棘手)。其他设备可通过专用 I/O 端口寻址。这些需要特殊指令,编译器具有内部函数或者您需要在汇编中实现(您可以从 C 调用)。

interrupts?

同上。 enabling/disabling 中断等部分可能需要专门的指令。设置中断处理程序可能只是将函数指针写入正确地址的问题。

I'm more than happy for an answer that includes some further reading but if you'd be able to summarise the main points related to each question that would be super handy for me!

我的建议是给自己买一个 ARM Cortex-M 并开始使用它。评论中提到的 osdev 也是一个非常好的资源。