写一个操作系统内核有多难?大概的内容、步骤是什么?
写一个 Demo 级别的不是太难,关键还是需要兴趣和耐心,
如果你真的想刨根问底,没什么能挡住你。
最基本的有几个部分:
1 bootloader, 你是用个现成的grub还是自己写,很多人就倒在这一步了。
2 内存管理
3 进程管理
4 中断和系统调用
5 文件系统
当然可以折腾的很多,但最好还是先把这些弄出来,才可称之为一个操作系统。
资料都有,你可以参考:
Expanded Main Page JamesM's kernel development tutorials
xv6的代码也不错,文档齐全,Xv6, a simple Unix-like teaching operating system
Orange'S:一个操作系统的实现 (豆瓣) 可以参考,只是有很多部分其实可以不用汇编写了。
James的那个教程还是入门最好的。
在Github无数个人在折腾自己的Hobby OS:Open Source Operating Systems
SamyPesse/How-to-Make-a-Computer-Operating-System。
比如我当年的小项目: chenyukang/Panda,
有的完成度还是比较高的,比如klange/toaruos总共花了六年时间才做出一个基本可用的有图形界面和网络的 OS。redox-os/redox是一个 Rust 写的微内核的 OS。
你要做的就是准备好时间,做,看,做,看...
我的建议是可以自己花些时间做一个简单的 OS,哪怕是拼凑出来也好,就是为了体会一下编程的石器时代,而后还是选择自己感兴趣的模块,看看成熟的操作系统是如何做的,毕竟人的精力和时间是有限的。
写个玩具内核不难,固然学习与理解需要花费比较长的时间,但总体而言本科硕士的知识面已经足够了。关于内容和大体步骤,当时写了一点东西,如果感兴趣可以作为参考:基于 Bochs 的操作系统内核实现写个玩玩还是挺超值的,对得起上学没处打发的时间。
ps: Linus 可比一般的喷子脑残之流凭他们可怜的想象力所沾到的影子牛逼多了。现在不少人都在通过自己写内核来学习操作系统,网上还有专门的课程(6.828 / Fall 2011 / Schedule),按照这个课程,几个月就可以完成一个功能还算完备的内核.
但是这些人可以自己用几个月的时间写个内核,建立在当下相关资料特别丰富,而且虚拟机调试特别方便的基础上的.用bochs(虽然我自己从来都没有整好过),qemu,可以轻松进行汇编级调试,qemu还可以利用gdb remote debug来进行源码级调试.
但是倒退到Linus那个时代,一个人写内核的,绝对是绝顶高手,因为当初没有什么相关资料,大概就几本书可以参考,MINIX那本,UNIX内核设计与实现等.而且调试非常不便,只能靠自己把代码写对,非常非常的不容易.
尽管上面很多人说写一个操作系统内核是比较简单地事情,但是,如果你只有一点点软件和一点点硬件基础,那么我可以放心地告诉你,这绝对不是一件很简单的事。除非你指的操作系统就是一个稍微能控制一下资源或者稍微能运行几个进程的简单东西而已。
在写操作系统之前,你就清晰地明白操作系统是要干什么用的。操作系统对应用程序提供了硬件层面的抽象;负责管理包括CPU,内存,磁盘,IO等硬件资源,以及进程表,文件打开表,页表等软件资源;负责提供应用程序可用的API和系统调用;负责保护硬件资源和软件资源的访问安全和隔离性;以及提供多用户支持等等功能。那么在写一个操作系统之前,你就得保证你所写的操作系统满足必须满足的要求:鲁棒性,可扩展性,高效性,丰富性,安全性。先不说后几条要求,仅仅鲁棒性一点要求,都能把一个程序员折腾很久(呃,我这个菜鸟程序猿就被折腾了很久)。
当你明白了理论上的代码要求,你可以开始琢磨写一个简单的操作系统内核。至于你说要分为那几步。我的拙见是,在你动手写之前,你又必须给自己一个规划,这个规划就是:从实模式到保护模式一步一步的推进,从微内核到单内核的推进,从实验到简易实用的推进…
当你开始写实模式的操作系统内核时,你得要会一下这些必须知道的知识:(哪怕一点点)
- 操作系统启动原理,也就是bootloader的作用,包括魔数,MBR等等
- Intel 汇编或者AT&T 汇编或者嵌入汇编。这里面需要使用到int中断,简单的算术操作指令,跳转指令,开关中断指令(你只需要知道一点点,完全不用看intel手稿)
- DS,ES,SS,BS,SI,DI,AX,BX等等寄存器的使用和工作原理,这是实模式下唯一需要了解的一点点微机原理知识。
- 信号量,消息同步以及中断屏蔽的知识。这一部分会让你更加清楚地了解到Linux单内核的NB之处。
- 系统调用,进程切换,内存分配,磁盘访问布局,文件系统。系统调用包括read,write,fork,exec,wait,exit这些最基本的系统调用(甚至不用去看dup,dup2,wait2等等暂时无用的),进程切换了解pcb管理,内存就了解最简单的分配方式,文件系统就是inode节点结构(甚至不需要考虑超级块等等)。
当你进步到保护模式的时候,你就得额外学习其他的知识了,这些知识包括但不限于:
- 地址转换的概念,段页的概念,页表访问,MMU,TLB等原理。
- 什么是内核模式,什么是用户模式,ring0~3是怎么具体保证的的
- EAX,EBX,ECX等等通用寄存器以及控制寄存器,GDT,LDT的概念
- 更高级的内存分配模式,例如slab或者懒惰伙伴分配等等。
- 更高级文件系统,ext3,ext4等等。
当你又从微内核进步到单内核的时候,你需要考虑:
- 微内核中一些模块如进程分配服务,内存分配服务,文件管理服务,设备驱动服务如何集成到内核,哪些可以集成到内核,哪些不能。
- 自旋锁,信号量,消息同步的有什么区别,如何避免死锁。
- 单内核的系统调用和微内核系统调用的区别等等。
当你从实验进步到简易实用(只是简易而已,暂时还不包括网络资源管理,这一部分涉及到TCP/IP协议栈,更加复杂)的时候,你需要考虑:
- 操作系统效率以及安全性问题,这里面涉及到进程调度,内存管理算法,磁盘调度算法等等方面。
- 系统调用的丰富性问题,是不是支持大部分的系统调用。
- 基本应用程序的支持性问题,例如shell,cat,wc,cd,ls这些简单的总要支持。
- POSIX标准的支持问题,能不能支持编译运行一些原始版本的程序。
总而言之,对我这样的不是研究系统架构的人来说,写一个操作系统内核也并不是一个非常简单的事情(尽管我们在大二的时候就已经写过了)。我仍然需要花很多的时间查资料,看文章,仍然能够从中学习到很多很多以前没有学习到的知识。
所以,写一个操作系统并没有很多人说的那么简单,当然这样的说法有点冒犯了上面一些说比较简单的大神们,还请包涵。
厚脸皮推荐自己基于《JamesM's kernel development tutorials》写的中文文档,如果你只有基本的C语言和汇编基础以及一点点操作系统理论的话,这是起点很低的入门读物了。
项目地址:Hurlex-doc by hurley25
PDF 文档以及对应的 Latex 源文件(那会只是刚开始学着用Latex,不规范的地方请见谅)也在git仓库里一并提供(可以免费复制传播,请不要用于商业用途)。git仓库里甚至按照章节的形式提供了每章节结束后代码的样子(文档里不是全部代码都贴),以供参考。
懒得下载可以看在线版: x86架构操作系统内核的实现
在线版是markdown格式转换的,遗憾的是markdown格式的源文件被我搞丢了。。
补充一下文档目录:
- 项目概述和开发环境配置
- 计算机启动过程、GRUB 以及 multiboot 标准
- 裸机上运行的 Hello OS Kernel
- 字符模式下的显卡驱动
- 相关库函数和调试打印函数
- 添加全局段描述符表
- 添加中断描述符表
- 完成中断请求和定时器中断
- 物理内存管理的实现
- 虚拟内存管理的实现
- 内核堆管理的实现
- 内核线程的创建与切换
- 接下来如何继续学习
这个东西很难被称为“内核”,甚至说它是“玩具内核”都是缪赞了。这只是一个看起来能运行的原理示范性质的小程序。不过不可否认,按照文档来,你可以写出一个看起来挺好玩的东西并学到一些基础知识。
虽然一个真正的内核很难很复杂,但是一个简单的Demo并不是遥不可及。即使有兴趣,学习的过程中也需要乐趣和不断获得的成就感,不是吗?
祝你玩的愉快~
------------------------------------------
第二版的代码地址:
hurley25/Hurlex-II · GitHub
第二版在硬件机制上没有增加多少东西(简单的忙等待的IDE驱动,简单的键盘驱动),主要是策略上和代码上做了一点点优化,参考了Linux内核的一些命名和代码(比如2.6内核的伙伴算法简化后添加进来)。
我认为,某些专业的合格硕士生建造一个 Karl Benz 时代的汽车也并不难。但是我不知道这么做有什么实际意义。我还看到有人说:「初学者千万不要看 Linux 代码」「可能一辈子都看不完」。这是最最误导初学者的言论。学汽车难道不去看真正的发动机,去看 Karl Benz 的古董?去看标准模型做的玩具?一个 Audi 的 TFSI 发动机的细节,研究十年不一定能穷尽。但是那不意味着这台发动机的知识是不分层次的。组织合理的话,你在这台发动机上花的实践可以和得到的知识成正比。
另一件值得注意的事情是,软件在构建过程中的样子,未必就是最终 deliver 的样子。和建筑一样,软件在构建过程中也要搭脚手架。很多代码是构建过程中不得不用但是 deliver 之前又不得不删除或者 disable 的。刚刚开始写程序,甚至写过几年 app 的人,都不见得知道如何去运用这种 scaffold code。OS 内核恰恰是需要 scaffold code 非常多的领域。我认为,随着软件系统越来越复杂,真的没有必要每一代人都重复体验如何构建某个领域的 scaffold code。初学者更应该从成型的软件中学习知识。
题外话:拿 Linus 开涮的人我都绕着走 —— 当经理的肯定不是好鸟,做技术的早晚摔跟头。
这个不难。写个小内核的,仅有有限的任务调度功能的操作系统,读完CS专业大学三年级的课程即可。目标平台可以是真实的,也可以运行在Windows Console下。这种操作系统有很多,比如ucOS,rex,FREERTOS,等等。
最初程序员们都是纸带机啥的上面写点0和1。后来写写汇编,都是针对硬件直接编程。也不区分什么内核应用什么的,都是一个线串下来。
硬件遵循摩尔定律发展了一阵儿之后一根筋的程序里面就得弄一大堆中断响应。也就是说程序执行的过程中,需要让CPU停下来干别的更重要的事儿的情况多了起来。慢慢的程序结构复杂了起来,人们觉得需要做点基础工作让写代码的时候不必关注多中断调度啥的。还有就是一次要干的事儿多了,几个事儿不能光靠外部中断进行切换,得让它们有个内在的秩序。于是就有了任务调度。
再后来大家觉得光有任务调度的代码还不够。最好内存管理也能简单点。还有存储设备,一个劲儿的对一个块读完了擦,擦完了写,特定的块会挂掉。诸如此类的需求不断出现。于是就有了内存管理和设备驱动。
慢慢的发展下来大家觉得这部分代码是非常重要的。要区别于它们所服务的代码。就有了内核和应用的区分。早期的应用和内核是在一起编译的,后来有了可执行文件这样的设计,就可以分开了。
上面的例子可能不够准确。大家轻拍。
回到正题。操作系统是为了解决计算机科学技术发展中遇到的实际问题。分几个步骤,要看题主想解决几个问题,也就是有什么样的目标。
一般计算机的本科生(大一的会点C语言,有点耐心,3个月)就可以了。。。
有一本日本人写的书叫《30天自制操作系统》一步一步带你写出一个操作系统内核(可以写到光盘上,从光盘启动,第一节就叫你如何实现一个“hello,world”),一般计算机的本科生(就是会一点点C语言的那种理工科生),有点耐心的话,每天2~3小时,三个月基本能够看完,跟着撸出一个操作系统内核。根本不需要什么硕士水平。不需要前面说的各种文档。事实上作者的目标甚至是中学生也能看得懂,感觉基本做到了(最后也就几十k的代码)。写完之后会很有成就感。
我的第一本计算机厚书就是《30天自制操作系统》。写出来有什么鼠标键盘输入,汉字显示(书中是日文显示,由于日文中有汉字,所以其实可以算汉字显示),多进程(多任务),段页式内存管理,各种驱动,定时器,文件系统(读硬盘,文件目录和内容读取等),窗口,音乐播放,内核保护,api,小游戏,图片播放,应有尽有。。。如果大学能够跟着写完,绝对,毕业面试的时候能吹嘘一下。。。当然里面的c语言编译器不是自己写的(编译器工作量真不小)。。。
我当初就是看不惯国内那些书在那里装比,没有真正的拿得出手的科研成果,然后在那里装比的各种著作。然后人家这本,哈哈,真的就能够跟着撸出一个操作系统内核,而且,绝对是效率不错,结构可以的东西。。。而且人家通俗易懂,很有诚意,比起那些复制粘贴强行装B的书不知道要强多少倍。。。跟着做完内核保护和api的话,还能加深理解。
我的意思是,你完全可以自己快乐地把一个操作系统内核给读懂,在半参与的状态下做出来,玩一玩,不用一开始就想的那么高深和神圣。。最后跟着一起写api,玩游戏,理论+实践,轻松+愉快。。以后如果有兴趣可以去读linux的东西,去搞点其他的。。。愉快的成长
而不是一本厚书接着一本厚书地啃,啃了半年也看不到一个hello,world和桌面,最后感叹一句放弃。那样很无趣,很苦逼。
----------------------------------------------------补充分割线------------------------------------------------------
本书的某些代码的确不算完美,有些地方甚至比较幼稚,作者为了照顾初学者,会故意不用某些高级的成熟的开发技巧。。。这是本书的缺点,也是本书的优点。因为本书的定位就是那些没啥基础却又好学的新手。
最后如果你在读那本书,请一定要看第18页,不要去买软盘(我当初就TM没细看,去买了软盘还有软盘读盘的那种古董级别的东西,结果看到第18页吐血了,葵花宝典:第一页:“欲练此功 必先自宫”,某人狠下心,咔,第二页“若不自宫,也能成功”,连想艹都不能)。。。
----------------------------------------------------补充分割线------------------------------------------------------
我的文章受众是普普通通的计算机专业的本科生(我也是计算机本科生毕业)(各位研究生大大们,见谅)。。。希望哪怕有一个人能够通过这本书,开始写一点代码。我读大学的时候见过太多人,张口闭口比尔盖茨,扎克伯格,却不知他们的偶像还写过不少代码。。。他们没事情会去看“烫烫烫,屯屯屯”的由来,也不愿意去写几行C语言代码。他们会去看各种Linux的花边故事,也不愿意自己看看操作系统的基本结构。。。学校里也是,你还没弄个网站就有一堆教授跟你说:三大框架,并发优化,精品佛一开始弄,就要弄到标准,弄到一个水平。。。
我只希望,有人能够去踏踏实实地去看点书,去写点代码,而不是看了知乎的“写一个操作系统内核有多难”之后,记住几个名词然后回去吹牛,我希望,他们能够自己开始动手去看,去跟着写,去发现,去收获。
写于2015年2月1日
-----------------------------再次补充分割线-----------------
最近有人点赞,然后回头看自己四年前的回答,看着真是应了那句话“好为人师”,自己都没搞明白,然后还强行热血。
或许如果是现在的我,更愿意让当时的我去买个按小时付费的云服务器,看一下linux入门,学着搭个小网站,grep下日志,vim,诊断工具,git什么的学一学,也还容易找工作。
想听实话吗?玩具内核中学生受过训练都能写.
写代码,的确是世界上最简单的事.写操作系统内核,甚至连高等数学都不需要会,也没有特别难的算法和数据结构,算是最简单的一类程序,仅仅比脚本复杂一点.
/////////////////////////////////////////分割线//////////////////////////////
有人要说了:答主你这么强行xx真的好吗?
真的好.下面总结下写一个操作系统内核需要具备的知识:
t1.(知乎这个居然不能加制表符,我手动t了,你们就当成有制表符看吧吧)一门能操作底层的编程语言,汇编的一点基础必须有(至少得知道代码段数据段栈段这类的,还有函数调用的约定,如果你用C内嵌汇编的话),C语言最好熟练掌握.如果要编写的平台上有成型的C++编译器,也可以利用.但没有new基本上类是废的,就当成有构造函数的结构体就行了....
t2.计算机组成原理的理解.这个只要知道点汇编基础基本上都能有.
t3.操作系统原理的理解,包括操作系统内核的几大功能,还有一些操作系统中用到的数据结构.
t4.程序调试经验.
t5.耐心.
////////////////////////////////////////分割线////////////////////////////
需求:既然是玩具内核,那就应该忽略一些仅仅靠时间堆砌就能完成的部分.因此文件系统就没必要实现了.嵌入式环境是一个比较理想的环境.
要实现基本的任务按优先级调度和优先级内部轮转调度,内存动态分配回收,消息机制,锁机制等等.
如果感兴趣可以研究保护模式,分页机制,不过嵌入式环境没这个条件.保护模式的精髓就在于利用分页寄存器实现了地址空间变换,提供了内核空间和用户态空间两套地址空间.
那么怎么规划开发流程呢?我的思路是:(可供参考不一定最好)
首先要实现高可扩展性,就必须先动态分配和回收内存.因此先造个malloc和free.声明一个大数组,让你的malloc()在这个数组里分配空间给各个进程以供使用.这块内存里构造出内存控制块结构,记录内存的分配和回收情况.这个可以参考UnixV6.
然后,要构造出抽象的各个概念的管理结构.
进程要被操作系统接管,因此进程控制块(TaskControlBlock,TCB)是一个重要结构.里面至少要记录进程的一些基本信息(已用时间,优先级,资源列表,函数指针,栈区空间等).
消息结构也很必要.可以实现简单的邮槽机制,进程接收消息构造成先进先出的队列比较符合一般的思维习惯.
定时器结构,里面放一个函数指针之类的,这都是可以的.
中断管理块,如果你考虑未来这方面的深入的话.
如果你想做的复杂一些,加上一点文件系统和输出之类的,那就还得加上文件控制块结构,并且接触更底层的操作,用中断直接控制处理器与外设交互.这个有资料可以查,但我没实现过.
然后就是一些关键的函数.因为C没有类,结构体刚构造出来的时候是一团乱糟糟的东西在里面.因此上面的各个结构都需要有"构造函数".有了malloc,要new也不难.
然后就是控制各种结构的行为.比如进程的调度需要上调度器锁,寄存器压栈,栈区空间的切换,寄存器弹栈,优先级更改,时间片计数,卸调度器锁等等操作.这个自由度比较大,有一定发挥的空间.比如可以做成实时操作系统,类似uC_OS2,也可以做成类似linux那种,有个prio和一个nice值在里面,有个红黑树之类的.不过一般嵌入式空间不允许你这么折腾...然后还有定时器调度,进程的启动与终止资源回收之类的.反正有了malloc和free,,这些都是时间问题.
为了保证可移植性,最好把和CPU相关的代码单独拿出来放到一个头文件里去.
对了,前面忘了说了,这些结构和函数摆放的顺序也是有讲究的,然后呢,不同的编译器对宏的支持和一些细节的语法要求也不太一样,不同的工作环境栈区增长方向不一定一样,这个都得试一试.
其实写操作系统真不算难的,这种玩具内核连个复杂点的数据结构都没有.写数据库起码还得有个B树呢,写浏览器还有个http协议,图形,html读取的问题在里面,写编译器有文法分析什么的,相比之下操作系统内核真心不算难了.
///////////////////////////////////////最后一个分割线//////////////////////////////////
当然了,你要是不做玩具内核,而是做真正能用的商业内核,那可难了.这种难度主要是软件工程方面的.上千万行的代码需要许多人分工协作,开发用的东西比较底层,debug也不是很方便.因此难度很高.有了内核还不算,还要有优良的生态系统.因此与其从头写一个,不如用现成的linux内核,成熟稳定.连嵌入式平台都有用Linux的.借这个问题,正好把自己以前走过的总结下。
zero to one
大学的时候,一心热血,想着写个自己的简单操作系统,刚开始也是一脸茫然,首先接触的也是这份文档《JamesM's kernel development tutorials》JamesM's kernel development tutorials,对着作者的blog,特别有意思,很多概念都不是很清楚,慢慢查,在学习完之后,对操作系统简单的有了轮廓,bootload, GDT IDT, 内存管理,文件系统等等。
microkernel vs monolithic
随后认识了有一种更新的理念(当然现在不新了,对当时对我),微内核,发现内核OS,原来还能有另一种(非Linux宏内核的)设计,我们看的很多教程,多少天写操作系统,包括前面的JamesM's kernel development tutorials,都是类unix实现,本质上设计的思路和框架都类似。微内核则是把很多原来集成到kernel的模块,通过IPC的方式,变成一个个services跑在用户模式下面,这样大大增强了可扩展性和内核的稳定性。
在接触Linux的时候,曾经看到的有关Linus和Minix作者关于微内核和宏内核的争论,让我首先接触到Minix,但是水平不够,读起来比较吃力。
后来发现了FreeNOS,用C++写的基于微内核的操作系统,通过学习这个项目,又对操作系统,软件设计,设计模式等等大开脑洞。
FreeNOS
lordsergioinspa/FreeNOS · GitHub
这是一个用C++实现的微内核的操作系统,各种宏内核中的服务作为一个独立的services在微内核中,基于消息的通信方式,这点其实跟Mac内核中的mach那部分机制相似。
除了是一个操作系统的实现,另外从中也能很好的学习到OOP的设计方式,整个代码风格特别好,完全基于面相对象,还有一些常见的设计模式,在接触了这个开源项目之后,才了解,代码风格,注释,doxygen,scons,设计模式。
不仅涵盖了所有的操作系统的设计,学习,更接地气的包括了各种优美设计。
Exokernel微内核
http://pdos.csail.mit.edu/6.828/2005/readings/engler95exokernel.pdf
新一代的微内核,MIT出品。
Exokernel微内核的核心观点是:只要内核还提供对系统资源的抽象,就不能实现性能的最大优化 -- 内核应该支持一个最小的、高度优化的原语集,而不是提供对系统资源的抽象。从这个观点上来说,IPC也是一个太高级的抽象因而不能达到最高的性能。Exokernel微内核的核心是支持一个高度优化的原语名叫保护控制转移(protected control transfer, PCT)。PCT是一个不带参数的跨地址空间的过程调用,其功能类似于一个硬件中断。在PCT的基础上,可以实现高级的IPC抽象如RPC。在MIPS R3000处理器上,一个基于PCT的RPC实现了仅10μs的开销,而在同一硬件上运行的Mach RPC为95μs。对磁盘的处理,跟微内核的比较
坚持成长,更多的不在于结果,关乎过程。共勉~内核不难,但要让大厂商为你的内核写驱动比登天还难。
写文章不难,但要让大网站把你放首页很难。我觉得李纳斯的牛逼之处在于,他在他当时的时代能写出来牛逼的内核。
好比,你问说,现在制造喷气式飞机很牛逼么?现在不牛逼,但在螺旋桨时代出现喷气式就是很牛逼!
李写内核0.1是在90年代初,那时还没有win95吧?你在那时写出一个win nt内核你就也牛逼了!最新回复
当时我感冒了,回家呆了半天,然后写了这些东西。
当时2013、2014年完成了一些技术攻关,2014、2015年一直到广东省科技创新大赛前基本都还在做,省赛意外失利后就没继续做了,所以到写这些东西的时候,已经过去了将近一年,每个功能具体入微的实现、当时对其他系统的研究、一些设备的支持啥的这些细节都已经忘得差不多了,只剩下那个时候开发的整体印象。所以这篇文章没有给大家带来更多的知识真是不好意思。
我的博客http://hwj.me我其实蛮少用的,最近才想再次去使用它,所以那里也没有太多的东西给大家。
有人说PS的,我也表示理解,毕竟就一个图放在这,喜欢搞大新闻的人也蛮多。这里就放一个视频表示真实性吧。
鬼鸟操作系统的简单演示(for 知乎)
鬼鸟操作系统的简单演示(for 知乎)—在线播放—优酷网,视频高清在线观看http://v.youku.com/v_show/id_XMTYzOTk3NTc4NA==.html
至于有人说那个按钮的单词打错了,这个好像当时也有人说过,忘记改了……当时我的英语水平刚刚从不及格到及格,这种错误犯了不止一次,包括在一些函数中。
有人还说这些东西不牛x,我说真心话这的确不牛x,这篇文章也并非炫耀。只是解答上面这个人的问题罢了。希望更多人能够到达自己要到达的山峰。
目前高考结束了,我最近在试图去研究AI,这个操作系统(包括内核)也会进行不断的更新。
-------------------------------------------历史分割-------------------------------------
我很想回答这个问题。 我是一个高中生,自初中开始就想做一个操作系统,并付诸于行动。 我们制作的操作系统 鬼鸟操作系统,使用自己实现的 探索者操作系统内核,已经完成了基本的功能,外加一个不错的图形用户界面。
类似这样的基本功必不可少,我可以用汇编实现整套操作系统,但是考虑到可移植性,后续维护,我们到后期还是用了汇编和C混编的方案。除此之外,因为操作系统运行环境和应用程序运行环境着实不同,这些基本功对于我们进行操作系统设计,调试都是极其重要的。
除此之外,毕竟操作系统是个大工程,在做这个东西的时候,我们力量小,这时就需要我们有聪明的开发策略。打个比方,现在商业级操作系统的文件系统部分所占代码量可能就已经超越众多小型操作系统总代码量了,个人或者小团体开发的操作系统,真的不能过多关注单一的功能,人家的东西是按商业化考虑的,你就按照实现的角度考虑就行了,哪怕你的一些做法功能不会像人家那么好,一些优化算法不如人家那么有效,但是到真正的需要你考虑其效能问题的时候,你们的操作系统已经非常大了,那时候进行商业性的设计,比现在的更方便。
做操作系统,最关键的是,要在大的功能上均有所实现,在人少力量弱的情况下,小功能不要追求完整。只要能够支撑下个功能的实现就行了。例如,实现内核模块动态链接功能,至少需要在文件系统方面实现文件读取,能读取文件才能支持后面对elf格式分析,重定位等一堆功能实现。但是这并不意味着你需要在百忙中追求文件系统中长文件名的读取这类只有用户才介意的功能。
操作系统包含的功能面多,对于我们而言,不可能一开始就学完所需要的各个知识,各种标准规范协议,实际上大多数情况下,你需要边学习,边借鉴,边设计,边研发。在这个情况下,你需要清晰的知道自己需要完成哪些功能,对于这些功能,你要有清晰的了解,然后以这些功能实现为主线,博览群书,看看民间的方案,linux和Windows的方案,然后再设计自己的方案。我接触过的很多人,边看30天自制操作系统边做,或者Orangs 一个操作系统的实现 ,哪怕是一些更加专业的书籍,也会有一些不足和局限,如果对自己做的功能不了解,只能深陷于这些书的坑。
就说这么多吧,我的qq 2322869088,个人网站胡文杰的小站,时间不早了,还有80多天就高考了,希望这篇文章能给大家说明一些事情。还有,对于985 211院校,凭着操作系统参加自主招生容不容易一本线录取?
稍后这个文章会被复制到知乎其他文章中。邀请 @于仲智 来回答。
折腾了半个学期 + 4个人能搞出来,还带了一个基本的 GUI。
光在 GUI 里显示鼠标就直播 coding 了 7 个小时……
Rendering mouse ...
GitHub - TakefiveInteractive/TedkOS: Operating System仅用有无独创的内核,这个标准来评价一个程序员,是比较片面的。
如果题主的目的是为了兴趣,那么有不少教程可以读一读,例如于渊的《自己动手编写操作系统》就是我入门时看的…然而大部分书只能带你入门,之后要学东西靠得是实验和读手册(例如Intel IA-32 Software Developer Manual)
如果题主更多的是为了积攒经验方便以后工作,则只需要稍微了解系统原理,多注重如何使用现有API。因为人们对这类经验看中的是你学没学会一种思想,能不能知道商用系统中怎么利用,很少有需要你自己重造轮子的。
要记住的是,一般没人会只因为你做了一个操作系统就给你工作。这也是我忘了操作系统只是兴趣后,才体验到的教训…希望能帮上一些人的忙…
感谢@Suji Yan邀请难度在 没有时间https://github.com/aducode/DiyOS
还在填坑。求不鄙视不难,会C语言,学过操作系统原理,自己慢慢摸索,总能写出来的……表示大二下的时候,旁听计算机的嵌入式操作系统课,然后写过一个基于优先级调度的RTOS,跑在STM32上,没发现了什么bug,但是问题在于并没什么卵用,只是为了好玩而已。当时如果真的深入进去,花大时间去写个跑在x86上的,估计也是行的,但是还是没什么卵用……这些写操作系统的也仅仅是为了练练手,熟悉熟悉理论而已,花的时间多,还没意义。你要知道,嵌入式RTOS到处都有,freeRTOS,ucos等等,完善的一比,要你写的干嘛?像linux这样强大的,还要你写的系统?有时间去学学java,web,找份互联网的工作比在那花时间写操作系统这类扯淡的事实在有意义的多……
如果只是个玩具操作系统,那么可能不会太难,就好比一些教学操作系统,但是如果需要考虑
支持不同的硬件架构(x86, MIPS, PPC, ARM)?
支持多处理器。
高性能(高效的内存管理,进程调度,中断处理,文件系统,IO)。
稳定性(进程地址空间隔离,保护)
灵活可扩展的驱动框架。
那还是蛮难的。
甚至有些人说操作系统里边没啥算法,如果是玩具操作系统,那么可能的确不需要什么算法,因为算法本来就是为了满足性能,效率等需求而产生的。但是,商业的操作系统里边,肯定是有很多算法的,别说内存分配,进程调度,或者文件系统了。就算是最基本的自旋锁,都有好几种算法。