【问题标题】:How can I build a small operating system on an old desktop computer? [closed]如何在旧台式计算机上构建小型操作系统? [关闭]
【发布时间】:2010-11-16 12:19:15
【问题描述】:

这可能是徒劳的,因为我知道编写操作系统非常复杂(尤其是自己编写)。

  • 我不希望构建下一个 linux 或 windows。

  • 我知道这会很糟糕,而且有问题,而且不会工作,但没关系。

我想自己编写所有东西,用 AssemblyC 和(一些)C++

这是一个未来的项目,因为我现在正忙于其他事情,没有时间,但我想我现在会问它,所以也许我可以得到很多答案,它可以构建并成为这种方法的有用资源(我所看到的所有其他事情都涉及构建 minix、使用现有的引导加载程序、在虚拟引导程序中构建它等等)。

我想用显示器、键盘和鼠标设置我的一台旧台式机,然后开始使用空白硬盘。

我想学习如何编写自己的引导加载程序(我找到了很多关于这方面的资源,但为了完整起见,仍然请添加一些好的),我自己的 USB 驱动程序(如果有必要的话),CD 驱动程序(如果有必要)等等。一切,从头开始。

  • 如何将代码放到计算机上?最好用软盘来做吗?大多数计算机都可以通过 U 盘进行操作吗?

  • 我需要哪些驱动程序,您能否提供构建这些驱动程序的参考?

  • 在引导序列之后——然后呢?如何进入保护模式等。

  • 如何在没有操作系统帮助的情况下管理内存?我只是使用我想要的任何地址吗?不需要初始化?

  • 毫无疑问,我会遇到什么让我感到困惑的事情?

  • 如何让它既是命令行操作系统,又是图形操作系统?

  • 什么是图形操作系统?比如,我将如何做一个命令行、字体和顶部的图片?

  • 在哪里可以阅读有关设置多任务环境的信息? (即,有两个类似图形的命令行并排运行)。

  • 如何设置一种窗口系统?设置简单的多任务处理后,如何在屏幕上显示图形?

相信我,我知道这是一个非常复杂的项目,我可能永远不会完成它或在上面写任何有用的东西。

还有很多我没有提到的其他部分,如果您想到任何,也请随时添加。

请为每个答案添加一个“主题”——例如,USB 驱动程序,然后可能是资源列表、需要注意的事项等。

另外,请不要建议构建另一个操作系统或预先存在的代码。我知道我会阅读很多预先存在的代码(例如 linux 内核、示例资源、现有驱动程序等),但最终我想自己完成所有的编写工作。我知道我应该建立在其他东西的基础上,如果我改变主意并走那条路,我可以阅读关于 SO 的许多其他问题。但这就是从头开始做整个事情。

关于如何获得图形化的任何建议?不同的视频模式以及如何使用它们等?

【问题讨论】:

  • 这是我最大的目标。我非常想写一个操作系统,只是为了好玩和学习……这几年我一直没能抽出时间。如果你想找人帮忙或者只是和你谈谈,你可以通过 gmail.com 的 schmeling88 给我发电子邮件
  • @Max 和@Tom,我也遇到了这个错误。我实际上正准备开始这一次:)
  • 现在别想图形了。 Unix 从不直接支持图形,而且还不错。 :-) 但基本上没有简单便携的方法可以超越 800x600 IIRC。
  • 为什么?这个问题很古老,不再产生任何活动。谁在乎?

标签: c operating-system bootstrapping osdev assembly


【解决方案1】:

首先要做的事情。读,读,读,读,读。在您希望实现自己的操作系统之前,您需要对操作系统的工作原理有一个深刻的了解。

阅读 Andrew Tanenbaum 的一本关于操作系统的书籍。这是我们在大学操作系统课上使用的:

Modern Operating Systems PDF

Modern Operating Systems on Amazon

尽管封面很荒谬,但它是一本很棒的读物,尤其是作为教科书。 Tanenbaum 确实是该领域的专家,他对操作系统如何在底层工作的解释清晰易懂。这本书主要是理论,但我相信他也有一本书讨论了更多的实现。不过,我从未读过它,所以我无法评论它。

这应该可以帮助您了解进程管理、内存管理、文件系统以及您的操作系统内核需要执行的所有其他操作以使其进入可引导状态。从那时起,基本上就是为您需要支持的硬件编写设备驱动程序,并提供 C 库函数的实现以使内核调用诸如打开文件和设备、读取和写入、在进程之间传递消息等.

阅读 x86 程序集(假设您正在为 x86 机器设计此程序)。这应该可以回答您关于在处理器操作模式之间切换的许多问题。

如果您有任何电子知识,那么从为具有大量文档的嵌入式设备编写操作系统开始可能会更容易,因为它通常比 x86 PC 更简单。我也一直想编写自己的操作系统,我从 Digilent 为This Development Board 编写微内核嵌入式操作系统开始。它可以运行 Xilinx 的软核 MicroBlaze 处理器,该处理器具有非常详尽的文档。它还有一些 RAM、闪存数据存储、LED、开关、按钮、VGA 输出等。编写简单的驱动程序可以玩很多东西。

嵌入式设备的好处之一是您可以避免长时间编写 VGA 驱动程序。就我而言,Digilent 开发板有一个板载 UART,因此我可以有效地将串行输出用作我的控制台来启动整个系统并以最小的麻烦启动到命令行。

只要确保您选择的任何目标都具有现成可用且经过良好测试的编译器即可。您确实希望同时编写操作系统和编译器。

【讨论】:

  • +1,但我更喜欢 Tanenbaum Minix 的书(更侧重于实施),而且真的没必要只关注理论。无论如何,他不会在第一次尝试时编写操作系统。他会先编写一个引导加载程序,然后切换到保护模式,然后处理 I/O,等等。
  • +1 用于为嵌入式芯片编写操作系统。在一天结束的时候,你会觉得你做了一些独特的东西,而且它比为(比如)x86 编写一个简单得多,同时保留了相同的核心概念。例如,看看 TinyOS(虽然从技术上讲不是一个操作系统,但它有调度程序和任务模块之类的东西......)
【解决方案2】:

http://www.osdev.org/http://www.osdever.net/

欢迎来到操作系统开发世界。

另请参阅 SO 的 tag wiki 中的其他 x86 文档链接:英特尔和 AMD 手册、编译器/汇编器文档和各种指南。

它还建议使用 BOCHS 或其他虚拟环境进行调试,因为您可以单步执行引导加载程序并检查寄存器。

【讨论】:

  • 尤其是wiki.osdev.org!
  • 别忘了forums.osdever.net :)
  • 我知道这些是有用的资源,但我认为如果您提供一些上下文而不是一组没有解释的链接,它可能对未来的读者更有帮助。
  • @icktoofay 这个问题太宽泛了,我认为无法正确回答。
【解决方案3】:

我建议至少首先在Bochs 或其他虚拟机上工作,原因是您可以随身携带它,调试起来更容易(您可以看到硬件的确切状态),如果您需要外部帮助调试,他们可以使用与您完全相同的“硬件”。

我得到的最有用的建议是让自己进入一个可以尽快运行 C 代码的状态——即启动,设置你的描述符表,然后让自己进入一个可以安全运行编译的状态C. 如果您想保持理智并继续努力,大多数(如果不是全部)内核都应该在 C 中。虽然在某些地方需要组装,但它很繁琐,而且往往难以调试。

【讨论】:

  • 我现在会研究 Bochs 来玩玩,但我最终只想在某些 PC 上构建它
  • 如果它在 BOCHS 中工作,它通常在真正的 PC 上工作,在他们的 BIOS 中取模差异。您的大多数错误可能是影响 BOCHS 和实际硬件的事情,但不同的是,当您的代码在 BOCHS 中陷入无限循环时,您可以使用 BOCHS 的内置调试器查找位置,并单步查找如何/为什么。在真实硬件上,您所能做的就是添加调试打印。使用调试器可以节省数小时甚至数天的时间。
【解决方案4】:

在其最低级别,操作系统需要能够做的最低限度是以某种方式驱动系统的硬件并以某种方式加载执行某种“用户代码”。如果您要从 PC 开始,那么您需要编写可以从某些设备或其他设备加载的代码。较旧的 PC 在固件中有一个 BIOS,它决定了硬件如何执行某些初始化(至少是视频、键盘和某种形式的存储或引导加载程序)。 (2017 年 10 月更新:较新的 PC 具有 EFI 或 UEFI 固件……这在很大程度上是一种迂腐的区别;本次讨论的目的相同)。

因此,首先要了解如何在目标系统上使用 BIOS 或其他固件的底层细节。也就是说,学习如何编写 BIOS 可以加载和执行的程序。这最终会变成你的引导加载程序。从小处着手。只需从固件启动过程中直接获取一个打印:“Hello,Linus”的程序(在软盘或 USB 拇指驱动器上,将是一个好的开始......如果你愿意,也可以在硬盘驱动器上)。

我建议从那里编写一个非常简单的串行驱动程序...更新您的引导加载程序以初始化一些串行端口,然后从那里开始下载。然后它可以执行它拉过的代码。从那里编写一些可以写入另一组块的引导程序(我们还没有实现文件系统......甚至没有分区表解析;所以我们首先只处理磁盘上的原始块范围)。

此时,您的引导加载程序应该能够通过串行线路拉取新代码,将其转储到一个分区中(是的,实现某种分区表处理......它是否符合标准 PC 约定取决于您此时),并执行它。

从那里您应该能够处理更复杂的功能。在这个基础上,您可以编写和编译一个新的“内核”......重新启动您的测试平台,并将新内核部署到它。

(您的引导加载程序应该接收一些信号,例如串行握手线路上的 BREAK 作为跳过下载并仅引导现有映像的命令;它也应该以这种方式处理一些超时)。

从那里写一个非常简单的终端层和命令shell?文件系统?执行命令以下载除内核之外的新可执行内容(某种文件或对象)。以此类推。

当然,您可以从使用 PC 键盘和视频的控制台驱动程序开始(如果我没记错的话,分别是 BIOS INT 0x16h 和 INT 0x10H 的东西)。但是,我建议从串行驱动程序开始,因为您可以从任何其他现有(功能)系统自动执行构建/部署/测试周期。由于您的新操作系统将作为一个交叉编译项目开始,因此您必须采用一种简化的方式来处理它。

我不知道你想把你的项目走多远。一个相当令人印象深刻的目标是实现“自我托管”。如果您可以创建一个简单的汇编器/编译器,允许您使用新操作系统来(重新)构建、链接和引导到新操作系统的工作版本……那么您已经实现了这个目标。 (请注意,这不是必需的。许多嵌入式系统永远不会是自托管的,这并没有错)。

【讨论】:

  • 在现代硬件上,让串行驱动程序工作可能比编写控制台(视频/键盘)驱动程序更难。自从我写这篇文章以来的几年里,普通的老式串行连接器在现代台式机和笔记本电脑上几乎不存在。一些嵌入式和“爱好者”硬件仍然具有老式的 RS-232C 接口,无需通过 USB 仿真。例如:mpl.ch/t2600.html 好像有。
【解决方案5】:

如果您不介意使用硬件虚拟化,可以选择“从 Nand 到俄罗斯方块”的课程(书籍 + 讲座 + 软件)。您完全自己创建一个完整的计算机系统,从(为了这些目的是原子的,给定的)电子与非门,一直到构建操作系统、一种语言,最后在您的个人机器上编写一个简单的游戏。

我认为这是一个好主意,而且我完全打算很快就投入其中。这本书非常便宜,我相信这门课程是在麻省理工学院教授的。我能想象没有比完全了解您自己从头开始构建的整个系统更棒的感觉了。

链接:http://www1.idc.ac.il/tecs/

【讨论】:

  • 我认为这个链接已经失效。有谁知道任何其他访问方式?
  • @KorayTugay nand2tetris.org
【解决方案6】:

我会从小处着手,购买 8086 嵌入式开发套件,然后在其上开发多任务操作系统。一旦您拥有了内核并熟悉了在硬件级别上的工作,您就可以准备好做一些更具挑战性的事情了。

甚至构建一个 VGA 显示器的 DOS 克隆也是一件相当具有挑战性的事情。细节是巨大的。 :-)

具体主题。

如何将代码放到计算机上?最好用软盘来做吗?大多数计算机都可以通过 U 盘进行操作吗?

BIOS 将进行基本引导。


我需要什么驱动程序,您能推荐任何构建这些驱动程序的参考吗?

任何不是直接 CPU/内存操作的东西。任何不在 CPU 参考手册中的内容。


在启动序列之后——然后呢?如何进入保护模式等。

保护模式将成为引导顺序的一部分。

然后你开始多任务处理并弄清楚如何启动进程。


如何在没有操作系统帮助的情况下管理内存?我只是使用我想要的任何地址吗?不需要初始化?

正确。您最终可能会想要整理出一个虚拟内存系统。


毫无疑问,我会遇到什么让我感到困惑的事情?

没有调试工具,没有IO


如何让它既是命令行操作系统,又是图形操作系统?

带着悲伤。查找 Windows 3.1 和 Linux,尤其是 X windows。


什么是图形操作系统?比如,我将如何做一个命令行、字体和顶部的图片?

查找 X 窗口。


最后的建议:学习 linux/x windows。它并不完美,但它提供了对 one 方法的理解。还要研究嵌入式系统。

【讨论】:

  • 很好的答案,我已经有了方便的 linux 内核,我肯定会研究 windows 3.1。
【解决方案7】:

我看到很多关于操作系统开发网站的优秀参考资料,所以我将描述一种不同的方法:

如果您想体验从裸机实现操作系统的体验,有比旧 PC 更好的硬件选择。使用 PC 架构,您将花费大量时间围绕其 30 年设计历史中无趣的工件进行编码。例如,仅项目的引导加载程序部分可能已经烧毁了许多勇敢的程序员。

例如,您需要一组驱动程序来从磁盘和/或网络中读取内核。然后你需要代码才能进入保护模式。那时,您需要另一组驱动程序!在那之后,您为使芯片进入保护模式所做的工作很少可以转移。您想在另一台 PC 上运行它 +- 4 年,您还需要另一套驱动程序。

研究如何引导 ARM 或其他 32 位“嵌入式”芯片。提供廉价的开发板,或者您可以自己焊接!有些有内置的以太网和USB。我认为你会在一个理智的、非硬壳的架构上工作更有趣,并且可能最终获得一些可重用的技能。

【讨论】:

  • 不完全是我所要求的,但 +1 让我在阅读的切线上发送我
  • Marsh 给了你很好的建议。 x86/BIOS 体系结构的底层细节很复杂。您可能会陷入这些细节的困境,从而无法专注于内存管理和进程调度等更大的问题。选择带有串行端口的“更清洁”架构。从长远来看,你会更快乐。
【解决方案8】:

最重要的是,如果您希望它在真实硬件上运行,您绝对需要一份处理器手册的副本。英特尔手册 (http://www.intel.com/products/processor/manuals/) 非常宝贵。他们涵盖了从切换模式(真实/受保护)到虚拟内存管理(如果您选择走那么远)到进行系统调用(如果您曾经进行过用户模式)的所有内容。 最重要的是他们非常详细地解释了一些必须设置才能正常运行的东西,例如 TSS 和段寄存器,大多数操作系统文本不会讨论这些内容,因为它们更关心比特定于处理器的细节更高级的概念。

【讨论】:

  • 您可以通过英特尔免费获得纸质副本。
【解决方案9】:

OS Development Series@BrokenThorn 可能会让您感兴趣。

【讨论】:

  • 他们的代码被破坏了。但是教程本身很棒。
【解决方案10】:

尝试阅读小型基本开源操作系统的代码,例如 MikeOS。

或者,我建议以下步骤(应该很有趣!):

  1. 写一个虚拟机。定义您的所有处理器指令,以便您从内到外了解您的系统。将其与 SDL 连接以进行键盘、鼠标、屏幕、音频访问。保持简单,以便您可以一次将所有内容都放在脑海中。它不需要是最先进的虚拟机,只要能够模拟“真实”计算机的功能即可。
  2. 为您的虚拟机处理器编写汇编程序。请记住,此汇编程序不必是用虚拟机语言编写的程序,而是可以将您的汇编语言转换为机器代码的任何程序。
  3. 定义可执行格式,并编写一个简单的链接器。
  4. 现在您已经准备好编写操作系统的所有部分了!用汇编语言编写它,组装它......等等......你不需要这么复杂的引导加载过程,只需让你的机器先运行你的操作系统。

上面的步骤对于编写一个简单的操作系统来说可能看起来有点愚蠢,但是,嘿,这太有趣了。

【讨论】:

    【解决方案11】:

    查看MikeOS。它编写的一个相当简单的操作系统是可读的(如注释中的)程序集。尽管它相当简单,但它确实有一个 GUI,并支持一些网络和多媒体。

    编辑MenuetOS 是图形化的。它也是直接写的 asm,但比 MikeOS 更复杂

    【讨论】:

      【解决方案12】:

      你有一个雄心勃勃的目标。但执行是关键。

      大多数结构化方法(教科书或大学课程)将引导您完成整个过程,但它们提供了许多细节代码,掩盖了您选择的平台的晦涩细节,让您专注于大-图片思路:进程调度、内存管理、死锁预防、I/O 等等。

      我的建议是:降低您的期望,从一个基本问题开始。

      什么是操作系统?

      计算机科学家(希望)永远不会说操作系统是图形用户界面、网络浏览器、连接 USB 设备的方式,或者用户实际可以看到或触摸的任何东西。相反,最基本的操作系统就是我上面提到的那些东西。它们都属于一个大保护伞:资源管理。

      操作系统不过是管理计算机硬件资源的程序:内存、CPU 和外围设备。

      这是一个简单的操作系统:程序允许用户使用串行连接输入程序(十六进制或二进制)。一旦程序被输入,它就会运行程序。程序完成后,控制权会返回给用户,用户可以再次运行该程序或键入一个新程序。

      在“干净”的架构上执行此操作,例如具有 64K 内存左右的嵌入式 ARM 处理器。在学习了 ARM 的来龙去脉几天后,您可以在汇编中编写代码。 瞧!,您已经拥有了自己的操作系统。

      它完成了操作系统应该做的所有事情:

      • 它通过不让用户覆盖操作系统本身来管理内存。
      • 它安排单个进程运行。
      • 它处理单个串行外设的 I/O。

      这为您提供了一个开始的基础。你现在有很多选择。也许其中之一是允许将两个程序加载到内存中,并让用户决定下一个运行哪个程序。

      或者您可以让用户暂停执行一个程序,切换到另一个程序,暂停,然后切换回来。这是基本的多任务处理,尽管它完全是手动的。

      您的选择是无限的,但每一个都是您之前的一小步。

      如果你不把目光定得太高,那会很有趣!

      【讨论】:

        【解决方案13】:

        我在 StackOverflow 上维护了一个资源列表:How to get started in operating system development。请在您开始冒险时为其添加新资源(我即将开始:))

        【讨论】:

          【解决方案14】:

          许多学校的操作系统课程与您描述的大部分内容一样。我的学校 (CMU) 用 C 语言教授操作系统,我们编写了内核、文件系统和 shell,并提供了用于引导加载程序的代码。

          很遗憾,我无法在网络上找到本课程 (15-412) 的任何权威资源,而且它随着时间的推移而发展。但也许人们可以为那些在网络上有很好资源的学校发布资源和作业的链接。

          【讨论】:

            【解决方案15】:

            您可能会喜欢名为“滚动您自己的玩具 UNIX 克隆操作系统”的 this 教程,它非常有见地,应该可以帮助您。

            祝你好运。

            【讨论】:

            • 虽然拥有如此深入的教程非常棒,但其中有很多初学者经常遇到的错误。本教程非常棒当且仅当您愿意打开英特尔手册之类的内容并思考您正在做什么(即,不要复制并粘贴!)。
            【解决方案16】:

            研究A2 System(以前称为Oberon 系统)以获取可以窃取的想法。它是一个仅由两个人构建的图形操作系统,尽管公认的是 Niklaus Wirth。 1990 年左右首次发布,速度惊人地好。 Gutknecht 有一本书。

            【讨论】:

              【解决方案17】:

              关于低级图形编程,这里会给你很多信息:http://www.osdever.net/FreeVGA/home.htm。 (文本模式也很有趣。)

              毫无疑问,我会遇到什么让我感到困惑的事情?

              你会发现在 PC 上还有很多不清楚的地方:x86 指令集本身很复杂,当你直接访问硬件时,你可能需要很长时间才能理解如何编写单个指令集屏幕上的字符。

              不用担心软盘之类的,大多数时候你会使用模拟器,比如 Bochs 或 QEmu。

              【讨论】:

                【解决方案18】:

                您可能需要考虑查看Operating Systems Concepts, by Abraham Silberschatz - 了解系统编程概念是一项基本要求,查看操作系统 linux *BSD 和 GNU/Linux 的 F/OSS 内核内部结构,尤其是早期版本,它们是可能有更多记录。

                【讨论】:

                • Silbershatz 确实相当不错,但是非常高级。
                • 同意;但是,我想说它从根本上来说是必不可少的。 Tanenbaum 的 Modern Operating Systems 文档(前面提到过)
                【解决方案19】:

                看看Minix。与“Operating Systems Design and Implementation”一起研究源代码。考虑为项目做出贡献。我认为 Minix 是一个非常好的和有前途的操作系统。这也是一个资金充足的项目。这意味着,您甚至可能会因为您的贡献而获得报酬!

                【讨论】:

                  【解决方案20】:

                  这非常简单,因为 BIOS 已经内置了许多输入/输出功能,用于更改屏幕模式、更改像素颜色、将文本写入屏幕和许多其他事情。但是,它不包括对文件系统的支持,这是您必须在操作系统中加入的极少数内容之一。

                  BIOS 会加载硬盘上的第一个扇区并从那里开始执行代码,因此您的操作系统必须将第一条指令放在硬盘上的第一个扇区中。

                  这篇 Wikipedia 文章应该让您开始了解 BIOS 中断,以便将文本写入屏幕、从键盘接收按键和其他内容。 https://en.wikipedia.org/wiki/BIOS_interrupt_call

                  即使您打算使用 c++,我也强烈建议您阅读汇编编程,因为这对于了解硬件的工作原理至关重要。

                  【讨论】:

                    猜你喜欢
                    • 2012-03-11
                    • 2016-04-13
                    • 1970-01-01
                    • 2012-02-10
                    • 2013-07-29
                    • 1970-01-01
                    • 1970-01-01
                    • 2022-01-05
                    相关资源
                    最近更新 更多