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

Car*_*ers 110 c assembly bootstrapping operating-system osdev

这可能是徒劳的,因为我知道编写一个操作系统是无法忍受的复杂(尤其是自己).

  • 我不希望构建下一个linux或Windows.

  • 我知道这将是可怕的,而且越野车,并且不会起作用,但那很好.

我想在Assembly,C和(某些)C++中自己编写所有内容.

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

我想用显示器,键盘和鼠标设置一个旧的桌面,然后开始使用空白硬盘.

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

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

  • 我需要哪些司机,你能建议任何建议吗?

  • 启动序列之后 - 然后是什么?我如何进入保护模式等

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

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

  • 我怎样才能使命令行O/S和图形命令行?

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

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

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

相信我,我知道这是一个非常复杂的项目,我可能永远无法完成它或在任何用途上写任何东西.

还有很多其他的部分我还没有提到过,如果你想到的话,也可以自由添加.

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

此外,请不要建议建立另一个操作系统或预先存在的代码.我知道我将阅读许多预先存在的代码(例如Linux内核,或示例资源,现有驱动程序等),但最终我想自己完成所有的写作.我知道我应该建立其他的东西,而且还有很多其他的问题,如果我改变主意并走那条路,我就可以读到这些问题.但这一切都是关于从头开始做整件事.

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

Bob*_*ers 49

首先要做的事情.读,读,读,读,读.在希望实现自己的操作系统之前,您需要牢固了解操作系统的工作原理.

抓住Andrew Tanenbaum关于操作系统的书籍之一.这是我在大学的OS课程中使用的那个:

现代操作系统PDF

亚马逊上的现代操作系统

尽管有荒谬的封面,但这是一本精彩的阅读,特别是对于一本教科书.Tanenbaum真的是这方面的专家,他对操作系统如何工作的解释清晰易懂.这本书主要是理论,但我相信他还有一本书,讨论了更多的实现.我从来没有看过它,所以我不能评论它.

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

阅读x86程序集(假设你是为x86机器设计的).对于在处理器操作模式之间移动,这应该回答了很多问题.

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

嵌入式设备的一个好处是,您可以避免长时间写入VGA驱动程序.在我的例子中,Digilent开发板有一个板载UART,因此我可以有效地使用串行输出作为我的控制台来完成整个操作并以最小的麻烦启动到命令行.

只要确保您选择的任何目标都有一个随时可用且经过良好测试的编译器.您希望同时编写OS和编译器.

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

小智 28

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

欢迎来到OS开发世界.

另请参阅SO的 标签wiki中的其他x86文档链接:Intel和AMD手册,编译器/汇编器文档以及各种指南.

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

  • 我知道这些是有用的资源,但我认为如果您提供一些上下文而不是一组没有解释的链接,它可能对未来的读者更有帮助. (5认同)

hba*_*bar 15

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

我最有用的建议是让自己进入一个可以尽快运行C代码的状态 - 即启动,设置描述符表,并让自己达到可以安全运行已编译的C的程度.如果不是所有内核都应该在C中,如果你想要保持理智并继续努力.组装虽然在某些地方需要,但是很乏味且往往难以调试.


Jim*_*nis 14

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

首先,在目标系统上学习如何使用BIOS或其他固件的低级细节.也就是说,学习如何编写BIOS可以加载和执行的程序.这最终会变成你的引导装载程序.从小处开始.只需获得一个程序打印:"Hello,Linus"直接来自固件启动过程(在软盘或USB拇指驱动器上,将是一个良好的开端......或者如果您愿意,可以在硬盘驱动器上).

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

此时,您的引导加载程序应该能够在串行线上提取新代码,将其转储到分区中(是的,实现某种类型的分区表处理......此时是否符合标准PC约定由您决定),并执行它.

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

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

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

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

我不知道你想把你的项目带到多远.一个相当令人印象深刻的目标是实现"自我托管".如果你可以创建一个简单的汇编程序/编译器,它可以让你使用你的新操作系统来(重新)构建,链接和启动到新操作系统的工作版本......那么你已经实现了这个目标.(请注意,这不是一个要求.许多嵌入式系统永远不会自我托管,并且没有任何问题).


Sam*_*Sam 12

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

我认为这是一个好主意,我完全打算很快陷入困境.这本书出奇的便宜,我相信这门课程是在麻省理工学院教授的.我可以想象没有比从头开始构建自己构建的整个系统的完整,完整知识更好的感觉.

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


Pau*_*han 10

我会从小规模开始购买8086嵌入式开发套件,并开发一个多任务操作系统.有了内核并且熟悉硬件级别的工作,您就可以做更具挑战性的事情了.

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

具体主题.

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

BIOS将进行基本自举.


我需要哪些司机,你能建议任何建议吗?

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


启动序列之后 - 然后是什么?我如何进入保护模式等

保护模式将是引导顺序的一部分.

然后你开始多任务处理并找出如何启动流程.


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

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


毫无疑问,我会遇到什么会让我困惑?

没有调试工具,没有IO


我怎样才能使命令行O/S和图形命令行?

带着悲伤.查找Windows 3.1和Linux,特别是X windows.


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

查找X窗口.


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


Mar*_*Ray 8

我看到很多关于OS开发站点的很好的参考,所以我将描述一种不同的方法:

如果您想要从裸机实施操作系统的经验,那么硬件选择的方式比旧PC更好.使用PC架构,您将花费大量时间编写其30年设计历史中不感兴趣的工件.例如,只是项目的引导加载程序部分可能已经烧毁了许多勇敢的程序员.

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

研究一下ARM或其他32位"嵌入式"芯片的自举问题.可以使用廉价的开发板,也可以自己焊接!有些内置以太网和USB.我认为你会在一个理智,非硬度的架构上工作更有乐趣,也许最终会有一些可重复使用的技能.


小智 8

最重要的是,如果您希望在真实硬件上运行,您绝对需要处理器手册的副本.英特尔手册(http://www.intel.com/products/processor/manuals/)非常宝贵.他们讨论从切换模式(真实/受保护)到虚拟内存管理(如果你选择那么远)到制作系统调用(如果你曾经做过用户模式)的所有事情. 最重要的是,他们非常详细地解释了许多必须为功能而设置的东西,比如TSS和段寄存器,大多数操作系统文本都没有讨论,因为他们更关心的是高级概念而不是处理器 -具体细节.


tom*_*mzx 8

操作系统开发系列 @ BrokenThorn你可能会感兴趣.


小智 8

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

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

  1. 编写虚拟机.定义所有处理器指令,以便您了解内部和外部的系统.与SDL接口,用于键盘,鼠标,屏幕,音频访问.保持简单,以便您可以立即适应您的头脑.它不需要是最先进的虚拟机,只需一个可以模拟"真实"计算机功能的虚拟机.
  2. 为虚拟机的处理器编写汇编程序.请记住,这汇编不必写在虚拟机的语言编写的程序,但任何可以汇编语言转换成机器代码.
  3. 定义可执行格式,并编写一个简单的链接器.
  4. 您已经拥有了编写操作系统的所有部件!用汇编语言写它,组装它......等等.你不需要这么复杂的引导加载过程,只需让你的机器先运行你的操作系统.

上面的步骤对于编写一个简单的操作系统来说似乎有点愚蠢,但是嘿,这很有趣.


Ale*_*lex 6

看看MikeOS.它编写的一个相当简单的操作系统是可读的(如在注释中)汇编.即使它相当简单,它确实有一个GUI,并支持一些网络和多媒体.

编辑:MenuetOS是图形化的.它也写得很直接,但它比MikeOS更复杂


Bar*_*own 6

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

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

我的建议是这样:缩减你的期望并从一个基本问题开始.

什么是操作系统?

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

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

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

在"干净"的架构上执行此操作,例如具有64K内存的嵌入式ARM处理器.在了解ARM的详细信息几天后,您可以在汇编中对其进行编码.和瞧!,你有自己的操作系统.

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

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

这为您提供了一个构建块.你现在有很多选择.也许其中一个是允许将两个程序加载到内存中,让用户决定下一个程序运行.

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

你的选择是无限的,但每一个都是你以前的一步.

如果你不把目光放得太高,这很有趣!


Gio*_*lbo 5

我在StackOverflow上维护一个资源列表:如何开始操作系统开发.当你开始冒险时,请为它添加新的资源(我即将开始:))