原文链接:https://wiki.osdev.org/Beginner_Mistakes
主页:https://blog.csdn.net/qq_37422196/article/details/122591214
下面的链接如果指向原网站的话,大概是还没有翻译
在赶了在赶了……
“编写自己的操作系统”的想法把你带到了这里。本Wiki旨在为你的操作系统开发提供帮助、指导和参考
然而,新手犯某些错误或对该主题所涉及的内容有共同的误解是很常见的。这不算什么坏事——许多人以前也犯过这些初学者易犯错误,而且很多人将来也会犯。这篇文章旨在确保你在深入了解所提供的信息之前知道自己在做什么
这个Wiki不是
这可能看起来像是一组可以直接复制和粘贴的教程,外加一个在你遇到困难时提出问题的论坛。事实并非如此。在开始编写自己的操作系统之前,我们非常希望你能知道自己的水平,并先做一名经验丰富的用户空间应用程序程序员。我们还希望你阅读过有关操作系统设计的信息,并且已经研究过你所选择的平台的相关文档。不要指望这个Wiki或者论坛会成为自己编写的操作系统的完整指南,更不用说一般的编程技能指南了
你在这里找到的是前人留下的文档,他们通过阅读技术文档、可用源代码和论坛帖子以及试错编程发现了这些内容。其中一些是为了让自己以后可以再次浏览它而编写的,其中一些是为了让其可以直接为本Wiki所用,而无需让我们重新再写一遍
你在这里找到的一些小提示和指南可能会帮助你的操作系统开发,但这不是也不应该是一个完整详细的教程
即使你还不知道堆栈是什么,或者如何使用调试器,我们也不会特意向你解释。访问这两个页面,你会看到它们在操作系统处理的主要细节,而不是对该主题的一般介绍。这不是缺陷,而是设计使然。如果你正在寻找通用编程启蒙,您应该访问诸如StackOverflow之类的通用编程站点,并在立志成为操作系统开发人员之前先成为一名开发人员
本 Wiki 不会扩展为初学者手册,因为这不是它的目的。它是为了回答当人们觉得他们已经准备好进入内核空间编程时出现的高级问题
一个令人伤心的事实
如果不是在多种语言和环境方面拥有多年经验的开发人员,甚至都不应该考虑操作系统开发。十年的编程经验,包括几年的汇编语言和/或C等系统语言的低级编码,几乎是充分理解该主题以在其中工作的最低要求
而且,随着不同“标准”、计算机和移动设备型号、外围设备和设计概念的数量不断增加,这一点越来越正确
对于像Dennis Ritchie、Richard Greenblatt、Gary Kildall或Steve Wozniak这样的人来说,为硬件编写一个简单的操作系统是比较简单的,因为他们的硬件与现在的相比相对简单,而且他们对其非常熟悉且没有标准规范来要求他们保留一些糟糕的设计以保证向后兼容。这对于现在的硬件已不再适用。而且,他们每个人当时都已经是一位经验丰富的工程师,已经做了多年的系统编程。即便如此,它们也只是为系统提供了基础;大部分工作是在系统核心——现代术语中的内核——完成后,由一小群从属开发人员完成的
这条规则有例外,但并不多。不要指望自己是那千分之一。如果你认为你是,请阅读邓宁-克鲁格效应后再作考虑
哦,顺便一提,Linus Torvalds并不属于那千分之一——他在编写Linux内核时还是一名研究生,并且多年来一直使用C进行编程。虽然他编程确实远不及十年,但作为一个将自己的爱好变成了硕士论文的研究生,他比大多数人有着更多的时间来从事这个项目。无论如何,他在1991年发布到USENET的著名的“Linux 0.0.1”版本只不过是一个循环调度程序,远不及一个完整的操作系统。让其变为完整的操作系统,他又花了一年的时间
虽然这个wiki的大多数贡献者的确在编程不到十年时就开始参与操作系统开发,但对于我们中的大多数人而言,这是由于缺乏经验而做出的错误选择。我们大多数先驱者当时都不知道即使是一个小型操作系统项目也是规模巨大且十分复杂,也不知道操作系统开发究竟做什么。这是一个惨痛的教训,尤其是在像这个Wiki一样的资源还并不广泛可用之时。我们不能强迫你从我们的错误中吸取教训,但至少我们可以想你发出这个警告
现在,您不应该对此感到过于沮丧;关键不是你做不到,而是——如果你和我们大多数人刚开始时一样——你可能暂时还做不到。要启动这么大的项目,耐心是一种美德
有没有关于…的教程?
因为这个地方不能也不会迎合初学者,所以经常有人会问到其他地方哪里有教程、好的代码解释或易于理解的文章。但是,这些东西都不存在。难的东西不能用简单的文章来讲清,就像有太多复杂的东西猴子学不会一样。如果您在阅读官方文档时遇到困难,这将是练习的好时机
初学者须知
时间
无论是为大学学业/论文、业余爱好还是商业用途而开发操作系统,其都需要时间。Linux内核用了一年多的时间,投入大量精力才获得表面上的实用性,而Linus Torvalds所做的只是模仿现有的和有据可查的操作来让已经存在的用户空间在其系统上运行。此外,对于每一个像Linux一样成功的项目,实际上有数百个项目花费了一个人年或更多的时间,却也没有达到拥有功能性shell的程度
因此,为你想要完成的工作,做一个合理的计划。不要假设在3个月内你的操作系统会有GUI和语音识别,因为操作系统开发根本不包含任何RAD工具
确定最终目标
在开始一个项目时,你应该估计你的最终目标、您的最终用户、项目的开发目的等。操作系统开发与此没有什么不同。对你的目标有一个粗略的想法会给你提供动力,指明前进的方向。但是,当你有更好的想法时,不要拘泥于最初的最终目标上
不幸的是,许多操作系统开发人员并没有估计他们最终的操作系统会是什么样子。因此,他们不知道该往怎么做,只好问:“接下来怎么办呢?”
然而,值得一提的是,要估计您的最终目标,您应该了解现有操作系统如何工作的整个(技术)概念
商业操作系统开发
不要以为构建出色的操作系统会让您变得富有。相反,历史告诉我们最好的操作系统永远不会获得任何商业上的成功,而那些几乎完全缺乏设计和灵感的操作系统却在商业上成功了,因为聪明的商业行动和在正确的时间出现在正确的地方,有正确的掩饰
尽管如此,尽管论坛的"商用"部分相对空白,但一些独立开发者的操作系统已经取得了一定商业上的成功,比如01000101的“Drop-in Network Security”(DiNS),这是一种旨在充当专门的深度数据包分析器的操作系统。请注意,它专用于特定应用程序。要以这种方式推销您的操作系统,您需要像了解操作系统开发一样了解应用程序,甚至是更了解,并且您需要非常擅长两者的编码。你的客户会期望你非常专业
另一种可能性是将您的操作系统推销给目前使用MS-DOS进行过程控制的公司。这似乎更容易,因为您不对用户应用负责,但您需要专业并能回答客户的问题和请求。他们可能需要长期支持,而且他们可能不喜欢你真正想要实现的功能
假设不会有人用它
与上述相反,有些人认为没有人会用他们的操作系统。因此,他们的项目代码丑陋,没有考虑到重要的方面,并且通常依赖于丑陋的特性。最糟糕的是,他们不会考虑可用性和可扩展性。这样,他们的假设就变成了一个自动实现的预言
实际上,虽然让您的操作系统在您的测试机器以外的地方运行的机会很低,但有足够多的高级操作系统项目是从这个社区开始的
避免无知
初学者经常问“做 X 最简单的方法是什么?”而不是“做X的最好的、合适、正确的方法是什么?”这是十分危险的,因为新手不会花时间去理解实现某些东西的好方法,而是选择从教程中复制那些概念上更简单的方法。事实上,较简单的路线往往过于简单,从长远来看最终会导致更多问题,因为初学者不知道更好的选择,也不知道什么时候该用哪种方法。走更难一些的路线有什么不好呢?
常见的例子包括懒得使用交叉编译器,不了解实模式、Unreal Mode(Big Real Mode)、保护模式和Long Mode,在没有首先了解如何收集所有重要配置和充分使用它的所有功能(特别是在启动和初始化期间使用BIOS检测基本功能)的情况下过快地从一个模式跳到另一个模式,依赖于非标准的BIOS调用,图方便不学习在自己的操作系统中编写硬件驱动程序而在Windows和Linux下完成,全局暴露测试功能,使用原始二进制文件而不是ELF,不学习可执行、归档、图形、文档等文件格式和压缩算法等等。有经验的开发人员使用更好的替代方案是有原因的,你可能还不明白。有经验的开发者在某些情况下会选择使用劣质的方法,但那是因为他们可以仔细分析是否合适,并且知道何时不合适使用它。作为初学者或中级开发人员,您可能不太了解这些方法和技术,无法判断劣质解决方案是否适合您。请记住,如果您反对一种方法,您应该对它足够了解,以了解它的所有错误(和正确)。无论哪种方式,懒惰和无知只会导致麻烦。如有疑问,请选择看似保守的选择,而不是更简单的选择
设计
GUI设计
如果从头开始,你可能需要几年时间才能真正做任何与GUI相关的事情。GUI的外观充其量是次要的,因为它们可以很容易地追溯更改。真正决定 GUI 可用性的是功能,而这并没有在模型图形中表达。如果您的目标是创建更好的外观而不是更好的操作系统,请考虑实现X窗口管理器而不是整个操作系统
流行程度
我的操作系统会比Windows、Mac OS和Linux更受欢迎!
这是极不可能的。要做到这一点,需要大量的时间、金钱和知识。不是每个人都会下载您的操作系统,因为:
- 他们可能不知道操作系统是什么以及如何安装
- 你的操作系统存在安全风险
- 你的操作系统支持较少的应用程序
- 你的操作系统功能不全(最小的命令行界面或糟糕的GUI)
如果有几个人使用你的操作系统,那可就算很幸运的了。今天流行的操作系统流行的唯一原因是因为它们在几十年前就已经可用并满足了需求,而且当时替代品较少
内存占用
我想让我的操作系统只占用几KB的内存!
对不起,这大概率是不可能的。使用如此少内存的操作系统几乎无法使用。忘记文件系统驱动程序、磁盘驱动程序、USB驱动程序等,如果你想开发一些小东西,只需制作一个简单的引导加载程序,而不是操作系统
你可以试试原生的Forth,它就像一个小操作系统,内核、命令解释器和汇编器都在一个很小的二进制文件中!内核的某些部分甚至可以编写脚本。你甚至不需要文件系统,许多Forth直接编辑和加载磁盘扇区。但其有一个很大的问题:Forth在技巧上并不简单。编写好的Forth可能比写操作系统更难。你需要了解许多底层基础知识才能做到。令人惊讶的是,一些Forth爱好者擅长编写Forth解释器,但却不擅长用Forth编程。您需要成为一名优秀的Forth程序员才能将OS设计概念与Forth相匹配,或者弄清楚哪些概念是不需要的。如果你做不到,你的操作系统将比 Forth 大得多
弄清楚如何减少代码大小可能需要花费大量时间和思考。Forth的发明者Charles Moore编写了一个CAD程序,它只有5行代码。当被问到写这5行需要多长时间时,他回答道:“哦,大约2年!”
操作系统模拟
我的操作系统将能够运行来自Windows、Mac OS、Linux甚至PDP-11的程序!!!
我很抱歉打破你的美梦,但它不大可能成真。即使只是模拟单个系统也需要多年的工作,尤其是当它是专有系统时,例如Windows或Mac OS(Linux可能是这四个系统中模拟起来最简单的)。Wine尽管从1993年就开始开发并且是在用户空间中编写的,但仍然对于许多程序存在问题
因此,与其专注于模拟其他系统,不如专注于自己的系统。设计它,开发它,并与它成为朋友
编程语言
有些语言非常适合编写内核,有些则不太适合。阅读使用C以外的其他语言
内核镜像
引导问题
特别是在早期阶段和使用自制的引导加载程序时,产生引导问题的原因通常是从磁盘获取的扇区太少。要么调整从磁盘获取的扇区数量,要么让引导加载程序/第二阶段加载程序解析文件系统
故障排除/寻求帮助
在论坛或IRC上寻求帮助之前,你应该尽可能自己诊断问题的性质。对于像三重错误或“随机”异常这样的问题,一个常见的错误是对产生问题的原因做出假设。使用调试器或打印语句来定位发生异常的确切位置。使用模拟器和调试器(例如GDB和Bochs/QEMU)将帮助你定位难以追踪的问题。如果你提供一些关于问题的观点和你已经采取的解决问题的举措,人们将能够更好地帮助你(即使你的观点不正确,它至少能让人们了解你对问题的看法,你可能已经尝试过的策略,以及你可能错过的策略)
一般来说,在向他人寻求帮助之前,请尽可能地自己解决问题。在发帖之前,问问自己:“我是否已尽我所能地诊断和解决这个问题?” 通常你会在这个过程中学到很多东西,而且你将来很可能能够自己解决问题(以及类似的问题),而不需要他人的帮助。这是一件好事。当您寻求帮助时,请提供与您的问题相关的代码。但是,问题可能出在其他地方,因此请让其他人也可以查看代码的其他部分(如果您使用的是 GitHub 或 Bitbucket 之类的东西,这会稍微容易一些,但肯定还有很多其他方法)
关于论坛,请阅读论坛规则。它们是必读的,阅读这些规则将提高你的帖子的质量,并使人们更有可能帮助您。在IRC频道上,如果您提出问题,不要期望在10秒甚至5分钟内得到答复。其他人也有自己的事。如果您需要离开去做其他事并想检查是否遗漏了任何内容,则可以查看日志。有关这些,请参阅IRC主题中的链接
有关如何在寻求帮助时成为优秀社区成员的深入指南,请参阅提问的艺术,这是一本很棒的书。理想情况下,您应该在任何地方寻求帮助之前阅读整本书(它不是那么长,而且非常值得一读)
进阶
命名
命名通常是要解决的最后一个问题,即使我们都希望为我们的酷概念起一个酷名称。由于名称的“酷”是一种品味问题,因此我们无法帮助你找到一个很酷的名称。此外,如果你将项目名称与某个功能联系起来,你可能会发现没有一个概念是完美的,并且你想要更改你最初认为的关键功能。没有什么比仅仅因为你“想坚持一个名字”而不进化更愚蠢的了……
在这个帖子中可以找到很多关于命名的好信息。简而言之,将你的操作系统命名为<name>OS(JackOS、FredOS 等)似乎是个好主意,如果你的项目不会有第二个成员。一个好主意(由Solar提供)是选择一个代号(如Longhorn、Chicago等),然后在更接近发布时间的时候编一个更好的名称
项目网站
许多操作系统开发的新手在网站上有任何值得展示的东西之前就创建了项目网站。在你了解项目的发展方向或有任何代码、屏幕截图或下载以展示你已经制作的内容之前,创建一个网站对您的项目的未来计划大做宣传是没有价值的。这样的网站看起来已经死了,并造成了不好的声誉。宣发您的网站(例如在OSDev.org论坛上的Announcements论坛中)或在你的签名中链接到它,而上面只有“欢迎来到<在此处插入花哨的项目名称>”的消息只会让人们在你开始你的项目之前就失去兴趣,并且如果/当你最终产生了值得炫耀的东西,你不得不面对那已经非常糟糕,难以挽回的声誉
团队协作
在公告论坛中可以看到最常见的初学者错误。它通常以两种形式之一出现,尽管这些形式有很多重叠:
社区项目
不要高估让人们对你的项目感兴趣的可能性。即使是更成功的项目,通常也只有一个,也许是两个真正在编写代码的人,而这并不是因为人们不需要。
布鲁克斯定律指出,参与项目的人越多,项目所需的时间就越长。解决此问题的唯一方法是将项目拆分,让每个人只用完成自己的部分。祝你好运
招募人力
有一些事情需要你抓住机会(并避免被痛苦地告知你是一个失败者):
- 如果你没有已建立的代码库,人们不会加入并期望项目失败,因为他们可以看到你缺乏经验
- 如果你缺乏(已制定的)设计,人们将不会加入你的行列,因为他们看不到你的操作系统比他们自己的设计更有趣
- 如果你的名声不足,尤其是更有经验的人会非常警惕你,因不信任而不会加入
- 如果您没有项目管理技能,那么少数加入的人很快就会退出,因为他们正在讨论一些事情并且不会编写代码。
尽管如此,加入项目的人通常是比以上的人更差的程序员