如何在旧台式计算机上构建小型操作系统?[关闭]


111

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

  • 我不希望构建下一个Linux或Windows。

  • 我知道这将是可怕的,有故障的,并且无法正常工作,但这很好。

我想用AssemblyC和(某些)C ++自己编写所有内容。

这是一个未来的项目,因为我目前正忙于其他事情,没有时间,但我想现在就问一下,也许我可以获得很多答案,并且可以建立并成为这种方法的有用资源(我所看到的所有其他内容都涉及建立minix,使用现有的bootloader,在虚拟启动程序中构建它等)。

我想用显示器,键盘和鼠标设置一个较旧的台式机,然后开始在空白硬盘驱动器上工作。

我想学习如何编写自己的引导加载程序(我已经找到了很多相关的资源,但是为了完整起见,请仍然添加一些不错的资源),我自己的USB驱动程序(如果需要),CD驱动程序(如果需要) )等所有内容,从头开始。

  • 如何将代码放入计算机?最好用软盘来做吗?大多数计算机可以通过USB记忆棒来做到吗?

  • 我需要什么驱动程序,您可以建议任何有关构建这些驱动程序的参考吗?

  • 在启动序列之后-那么呢?我如何进入保护模式等

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

  • 我无疑会遇到什么使我感到困惑?

  • 如何使其成为命令行操作系统和图形操作系统?

  • 什么是图形化的操作系统?就像,我该如何做,例如命令行,字体和顶部的图片?

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

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

相信我,我知道这是一个非常复杂的项目,并且我可能永远也无法完成或编写任何有用的内容。

我还没有提到很多其他内容,如果您有任何想法,也可以随意添加。

请为每个答案输入一个“主题”,例如USB驱动程序,然后列出资源,需要注意的事项等。

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

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


14
这是我最大的目标。我想写一个如此糟糕的操作系统,只是为了好玩和学习它。。。过去几年来,我只是没有时间来浪费时间。如果你曾经找人帮忙,或只是通过谈话事情,你可以在schmeling88在gmail.com电子邮件我
马克斯·施梅林

2
@Max和@Tom,我也遇到了错误。我实际上正准备开始这段时间:)
Giovanni Galbo,2009年

2
只是现在不考虑图形。Unix从未直接支持图形,而且还算不错。:-)但是,基本上没有简单易行的方法可以超越800x600 IIRC。
巴斯蒂安·莱纳德(BastienLéonard)2009年


1
为什么?这个问题是古老的,不再产生任何活动。谁在乎?
卡森·迈尔斯2015年

Answers:


51

首先是第一件事。阅读,阅读,阅读,阅读,阅读。在希望实现自己的操作系统之前,您需要对操作系统的工作方式有深刻的了解。

抓住Andrew Tanenbaum关于操作系统的书之一。这是我们在大学操作系统课程中使用的一种:

现代操作系统PDF

亚马逊上的现代操作系统

尽管有荒谬的封面,但它的读物很棒,尤其是对于教科书而言。Tanenbaum确实是该领域的专家,他对操作系统如何在引擎盖下工作的解释清晰易懂。这本书主要是理论性的,但是我相信他也有一本书讨论了更多的实现。不过,我从未阅读过,因此无法对此发表评论。

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

阅读x86组件(假设您正在为x86机器设计它)。关于在处理器工作模式之间切换,这应该回答您的很多问题。

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

嵌入式设备的好处之一还在于,您可以避免长时间编写VGA驱动程序。就我而言,Digilent开发板具有板载UART,因此我可以有效地将串行输出用作控制台,以使整个过程顺利进行并引导至命令行。

只要确保您选择的目标对象都有易于使用且经过测试的编译器即可。你希望被写操作系统,并在同一时间的编译器。


2
+1,但我更喜欢Tanenbaum Minix的书(该书更着重于实现),实际上没有必要只关注理论。无论如何,他不会尝试编写操作系统。他将首先编写一个引导加载程序,然后切换到保护模式,然后处理I / O,依此类推。
巴斯蒂安·莱昂纳德(BastienLéonard),2009年

2
+1用于编写嵌入式芯片的OS。最终,您会感到自己做了一些独特的事情,这比为x86编写一个简单得多,同时又保留了相同的核心概念。以TinyOS为例(例如,尽管不是技术上的OS,但也有诸如调度程序和任务模块之类的东西。)
Kristopher Micinski 2012年

29

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

欢迎来到OS开发世界。

另请参见SO的其他x86文档链接 tag wiki:Intel和AMD手册,编译器/汇编器文档以及各种指南。

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



不要忘记forums.osdever.net :)
布伦登

6
我知道这些都是有用的资源,但是我想如果您提供一些上下文而不是一组没有解释的链接,可能对将来的读者更有帮助。
icktoofay 2014年

@icktoofay,我想这个问题太广泛了,无法正确回答。
user253751

15

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

我最有用的建议是让自己尽快进入运行C代码的状态-即启动,设置描述符表,并使自己处于可以安全运行编译C的地步。如果不是所有内核都应该使用C,那么您要保持头脑清醒并继续努力。虽然在某些地方需要进行组装,但是这很繁琐,并且往往难以调试。


我现在考虑让Bochs玩一下,但是我最终还是想在某些PC上构建它
Carson Myers 2009年

如果它可以在BOCHS中运行,通常可以在真实的PC上运行,并且其BIOS的模数有所不同。您的大多数错误都可能会影响BOCHS和实际硬件,但不同之处在于,当您的代码陷入BOCHS的无限循环中时,您可以使用BOCHS的内置调试器找出位置,并一步一步找到知道如何/为什么。在真实的硬件上,您所能做的就是添加调试打印。使用调试器将节省大量时间和时间。
彼得·科德斯

14

在最低层次上,操作系统所需要做的最低工作是以某种方式驱动系统的硬件,并以某种方式加载执行某种“用户代码”。如果要开始使用PC,则需要编写可从某些设备或其他设备加载的代码。较旧的PC在固件中具有BIOS,该BIOS确定硬件如何执行一些初始化(至少是视频,键盘以及某种形式的存储或引导加载程序)。(2017年10月更新:较新的PC具有EFI或UEFI固件...这在很大程度上有明显的区别;在此讨论中它们具有相同的目的)。

因此,首先了解目标系统上如何使用BIOS或其他固件的低级详细信息。即,学习如何编写BIOS可以加载和执行的程序。最终它将变成您的引导加载程序。从小开始。只需直接从固件引导过程中获得一个打印程序:“ Hello,Linus”(在软盘或USB拇指驱动器上,是一个不错的开始……或者在硬盘上,如果您愿意的话)。

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

那时,您的引导加载程序应该能够在串行线上拉出新代码,将其转储到分区中(是的,实施某种形式的分区表处理……是否符合标准PC约定由您决定) ),然后执行它。

从那里,您应该能够使用更复杂的功能。在此基础上,您可以编写和编译新的“内核” ...重新启动测试平台,并在其上部署新内核。

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

从那里编写一个非常简单的终端层和命令外壳?文件系统?实施命令以下载内核以外的新的可执行内容(文件或某种对象)。等等。

当然,您可能已经开始使用PC键盘和视频使用控制台驱动程序(如果我没记错的话,分别是BIOS INT 0x16h和INT 0x10H)。但是,我建议从串行驱动程序开始,因为您可以从任何其他现有(功能)系统中自动进行构建/部署/测试周期。由于您的新操作系统将以交叉编译项目的形式开始,因此,对于您而言,拥有一种精简的处理方式至关重要。

我不知道你想把你的项目走多远。一个相当可观的目标是实现“自我托管”。如果您可以创建一个简单的汇编程序/编译器,使您可以使用新的OS来(重新)构建,链接和引导到新OS的工作版本中,那么您就可以实现该目标。(请注意,这不是必须的。许多嵌入式系统永远都不会成为自我托管的对象,这没有什么错)。


在现代硬件上,使串行驱动程序工作可能比编写控制台(视频/键盘)驱动程序更加困难。自从我撰写本文以来的几年中,普通的旧串行连接器在现代台式机和笔记本电脑上已几乎不存在。一些嵌入式和“爱好者”硬件仍具有老式的RS-232C接口,而无需通过USB仿真。例如:mpl.ch/t2600.html似乎有它。
Jim Dennis

12

如果您不介意使用硬件虚拟化,那么有一门课程(书本+讲座+软件)将带您“从Nand到Tetris”。您可以完全(从原子的和给定的)电子NAND门创建您自己的完整计算机系统,直到构建操作系统,语言,最后在您的个人计算机上编写一个简单的游戏。

我认为这是个好主意,也是我完全打算很快加入的一个想法。这本书非常便宜,我相信这门课程是在麻省理工学院教授的。我可以想象得到的感觉,莫过于拥有从头开始构建的整个系统的完整,完整的知识。

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


我认为此链接已失效。有人知道有其他方法可以访问吗?
Koray Tugay,2015年


10

我将从小处着手,购买8086嵌入式开发套件,然后在其上开发多任务OS。一旦有了内核并熟悉硬件级别的工作,便可以准备进行更具挑战性的工作。

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

具体主题。

如何将代码放入计算机?最好用软盘来做吗?大多数计算机可以通过USB记忆棒来做到吗?

BIOS将执行基本引导。


我需要什么驱动程序,您可以建议任何有关构建这些驱动程序的参考吗?

任何不直接执行cpu /内存操作的内容。CPU参考手册中未直接提及的所有内容。


在启动序列之后-那么呢?我如何进入保护模式等

保护模式将成为启动顺序的一部分。

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


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

正确。您可能最终希望整理出一个虚拟内存系统。


我无疑会遇到什么使我感到困惑?

没有调试工具,没有IO


如何使其成为命令行操作系统和图形操作系统?

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


什么是图形化的操作系统?就像,我该如何做,例如命令行,字体和顶部的图片?

查找X窗口。


最终建议:研究linux / x Windows。它不是完美的,但是它提供了一种方法的理解。还研究嵌入式系统。


很好的答案,我已经可以使用Linux内核了,我肯定会研究Windows 3.1。
卡森·迈尔斯,

8

我看到了很多有关OS开发站点的很好的参考,因此我将介绍一种不同的方法:

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

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

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


并非完全符合我的要求,但让+1送给我阅读的切线
卡森·迈尔斯

沼泽给您很好的建议。x86 / BIOS体系结构的底层细节很复杂。您可能会陷入这些细节的泥潭,无法专注于内存管理和进程调度等更大的问题。选择带有串行端口的“更清洁”的体系结构。从长远来看,你会更快乐。
巴里·布朗

8

最重要的是,如果您希望它在真实的硬件上运行,则绝对需要处理器手册的副本。英特尔手册(http://www.intel.com/products/processor/manuals/)是无价的。它们涵盖了从切换模式(实模式/受保护模式)到虚拟内存管理(如果您选择更远的范围)到进行系统调用(如果您进入用户模式)的所有内容。 最重要的是,它们详尽地解释了一些必须设置的功能才能起作用,例如TSS和段寄存器,大多数OS文本没有讨论,因为它们比处理器更关注高级概念,具体细节。


您可以通过英特尔免费获得纸质副本。
马修·伊瑟林


8

尝试阅读小型的基本开源OS(例如MikeOS)的代码。

另外,我建议执行以下步骤(应该很有趣!):

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

上面的步骤对于编写一个简单的OS似乎有点愚蠢,但是,嘿,这太有趣了。


6

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

编辑MenuetOS是图形的。它也写的是纯汇编,但是比MikeOS更复杂


6

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

大多数结构化方法(教科书或大学课程)将引导您完成此过程,但它们提供了许多精妙的代码,可以掩盖所选平台的神秘细节,并让您专注于全局构想:进程调度,内存管理,防止死锁,I / O等。

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

什么是操作系统?

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

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

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

在“干净的”架构上执行此操作,例如具有64K左右内存的嵌入式ARM处理器。在花了几天时间了解ARM的知识之后,您可以在汇编中对此进行编码。和瞧!,您将拥有一个操作系统。

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

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

这为您提供了一个构建基块。您现在有很多选择。其中之一可能是允许将两个程序加载到内存中,然后让用户决定下一步运行哪个程序。

或者,您可以让用户挂起一个程序的执行,切换到另一个程序,挂起,然后再切回。这是基本的多任务处理,即使它完全是手动的。

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

如果您的视野不太高,那就很有趣!



4

许多学校开设的OS课能满足您的描述。我的学校(CMU)用C语言教OS,我们编写了内核,文件系统和Shell,并提供了用于引导加载程序的代码。

不幸的是,我无法在网上找到该课程的任何确切资源(15-412),并且该资源随着时间的推移而不断发展。但是也许人们可以在资源丰富的网络上发布指向学校资源和作业的链接。


3

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

祝好运。


1
拥有如此深入的教程虽然很棒,但其中有很多错误,供初学者不断遇到。当且仅当您愿意还打开英特尔手册之类的内容并考虑您正在做的事情(即不要复制和粘贴!)时,本教程才是不错的选择。
马修·伊瑟林

3

研究A2系统(以前称为Oberon系统)以获取可以窃取的想法。它是仅由两个人构建的图形操作系统,尽管公认的一个是Niklaus Wirth。速度大约在1990年左右发布,而且速度惊人。古特内希特有一本书。


3

关于低级图形编程,这将为您提供许多信息:http : //www.osdever.net/FreeVGA/home.htm。(对于文本模式也非常有趣。)

我无疑会遇到什么使我感到困惑?

您将意识到,在PC上还有很多东西尚不清楚:x86指令集本身很复杂,并且当您直接访问硬件时,要了解如何在屏幕上编写单个字符可能要花费相当长的时间。 。

不用担心软盘之类的问题,大多数时候,您会使用Bochs或QEmu之类的仿真器。




1

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

BIOS将第一个扇区加载到硬盘驱动器上,并从那里开始执行代码,因此,必须将第一条指令与OS一起放置在硬盘驱动器的第一个扇区中。

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.