之前逼逼了那么多,都是口水,现在来电干货。其实也不是我原创的,我只是知识的搬运工和一个不合格的消化者,但是是一个好的传播者。
书,教材
前人经验
操作系统实验
学习目标
简单操作系统的代码阅读
30天自制操作系统
文献
课外阅读
各个大学的实验,讲义等
推荐《Linux内核完全剖析》,书的内容以Linux0.11为基础,嗯,对,你没看错,是long long ago的版本,这个版本的代码是相当于目前较新Linux的精简版本,麻雀虽小,五脏俱全啊,比较适合接触Linux不久的。很多操作系统概念的具体实现你都可以在书中找到源码,而且代码不是很长,在真刀真枪的实践中比较能体会到操作系统的真正精髓所在。因此建议先看完这本书后再去看较新版本的(Linux2.6千万级的代码量啊)。
当你看完此书,并且能在此版本中能够很轻松的添加个系统调用,记录下系统进程的切换日志,实现下内核级线程神马的,甚至实现网络功能还有新的文件系统的话,LZ的操作系统课程就完全可以打满分了,而且是当之无愧的满分,完爆那些靠背诵得高分的。
并且,以后LZ逢人便可说,哥当年也是搞过Linux内核的!
UNIX操作系统设计
Linus Torvalds 看了这本书之后写出了最初的Linux:
操作系统概念,已经到第七版了。Abraham Silberschatz等著。不过如书名一样,这本只是一本操作系统入门级的教材,介绍一般性的概念,范围比较全面。这本里Windows,Linux,Solaris都会举例到。
个人推荐《操作系统真象还原》,从零实现一个操作系统,讲解相当精彩。
莱昂氏unix源码分析是经典之作,MIT现在也出了一本小册子,类似与莱昂氏的书籍,作为课程教学使用。
mit的操作系统源码分析中文翻译地址:deyuhua/xv6-book
类似涉嫌被抄袭的教材还有:
WilliamStalling的《操作系统内核与设计原理》(清华大社学出版1998年版)、
Peterson的 《操作系统概念》(高等教育出版社2003年版)、
Solomon 的《Windows2000 技术内幕》(北京大学出版社2000年版)、
屠立德等编写的《操作系统基础》(清华大学出版社2000年版)、
王素华《操作系统教程》(人民邮电出版社 1995年版)、
谭耀铭《操作系统》(中国人民大学出版社1999年版)、
冯耀霖《操作系统》(西安电子科技大学出版社1989年版)等。
孟女士原是一名大学教师,现在以*撰稿人身份从事计算机教材写作。1997年11月,她根据自己的备课笔记,编著完成《计算机操作系统》一书(以下简称“孟书”),由中国人民大学出版社出版发行。
Tanenbaum的《现代操作系统》、
Peterson的《操作系统概念》、
William Stalling的《操作系统——精髓与设计原理》。
csapp不用说了,读过的都知道
光看书不动手很容易出现这种情况...
我推荐 6.828 / Fall 2014,往年的视频也很容易找到。这门课会接触到两个小的操作系统: xv6 和 jOS。课堂上主要讲xv6, 一个小的unix操作系统;而课程Lab分6~7个阶段让你填写jOS的关键代码。
这门课的好处就是理论加实践,而且课程节奏很好。
比如讲完系统调用,你就可以试着给xv6加个timer调用;讲完threads,你就可以试着给xv6加个系统调用,然后让这个系统支持线程...
Lab实现的jOS和xv6有很多设计决策不同,对比它们你可以更好的理解什么是操作系统;当然能自己亲手写一些代码感觉会很不一样(理论怎么转换到实践)
几点体会:
- homework也许比Lab更有启发性(我是这么认为的);
- 如果看过CSAPP就最好了,汇编都不用学了,shell也会写了,memory也了解了。
- 6.828有个作业提交系统,只要邮箱就能注册了,然后可以互评Lab...
有了一些自己的体验后,然后结合书看也许就完全不一样了。
作者:gashero
链接:https://www.zhihu.com/question/27871198/answer/38460394
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
书籍上讲的多是理论,可以自己再去找个开源的嵌入式OS,一起看着代码实现,就会好的多了。比如FreeRTOS,可以也买本书,学会编译,并在电脑里当成个应用跑起来,学会自己创建进程、协程后,进入对应的API实现看看。内核的调度、优先级、内存管理、资源管理、抢占式任务切换等等。
选择嵌入式OS是因为足够小,毕竟要为这个事情读Linux源码就是个大坑。FreeRTOS拥有大部分现代OS的各种核心功能,用来学习真是个好的例子。我也是学了FreeRTOS后,才逐渐让数年前操作系统的知识变得灵活起来了。
举几个例子,在FreeRTOS中的实现:
1. 线程管理:
给每个线程建立个私有的堆栈,每次在线程里调用任何的函数,所需的参数传递、本地变量等都是放在线程私有堆栈里的。这样各个线程之间不会发生混乱。该堆栈的建立一般还有个最大长度值,以免浪费内存过多,同时也限制了递归过深的情况。需要OS应用一开始就进行一个估算,调用栈会有多深。
2. 内存管理:
一般是先从物理内存里申请一大块内存,建立针对这块内存的分配表,每当有申请内存就记录一条,释放内存就选择时机将剩余内存合并。分配策略有多种,比如按照顺序,或者优先选择符合条件的最小空闲段。每个线程都建立自己的堆,有助于提高内存分配效率。
3. 进程/线程切换:
使用系统硬件上的定时器,每隔一定时间就发生一次硬件中断,此时当前进程/线程被停止,所有寄存器被保存到进程私有栈里。两次中断之间实际执行任务代码的部分,就叫做一个时间片。然后调用中断处理函数。这个中断处理函数就是OS内核里的任务切换功能,会重新选择处于就绪(ready)状态的各个任务中优先级最高的那个来运行。所以,理解并实现这个中断处理函数,就是理解任务切换的关键。放心代码不长。
4. OS内核调用:
现代的CPU,包括一些嵌入式MCU,都会严格区分user space和kernel space。两者的各种资源相对独立,甚至堆栈都不同。当user application需要调用内核提供的服务时,往往是将自己要调用的内核调用符号、参数、返回值放到内存中指定位置,然后触发一个软件中断。比如Cortex-M系列的SVCall,或者DOS的80中断。此时就切换到了kernel mode。此模式下的中断处理函数会根据系统调用内容分发调用请求,执行结束后,再根据返回地址跳转回去。
6.828 / Fall 2014
xv6的链接。Learn by doing。
先看这个
看了很多回答,感觉有些同学的建议简直太离谱了。
先说鸟哥linux私房菜,楼主可以到鸟哥网站上先看看。他的风格是告诉你怎么做,不告诉你为什么,很杂很乱。
还有Linux系统编程手册这种手册书都拿出来,不是误人子弟吗?
再说深入理解计算机系统,这本书是好书,需要耐心和精力,不过不推荐初学者学习。因为你会因为里面复杂的细节丧失很多兴趣。
最后有推荐6.828这个网络课程,有些靠谱,我先去看看然后回头补充答案。
视频:推荐北京大学操作系统原理公开课(2015年)(free,需注册账号)
Coursera - Free Online Courses From Top Universities
书籍:赵迥的《linux内核完全剖析》
这两个讲得都是很实际的操作系统知识,不会给你一种空中楼阁的感觉。
1.于渊的《自己动手写操作系统》,这本书从零开始实现一个小的操作系统内核,看完之后可以对操作系统最基本的原理有比较好的理解。
2.网易云课堂李治军老师的操作系统课程,讲的通俗易懂,用的是linux0.11的源码,真的很好。
3.Linux内核完全剖析(linux0.12),很全面。
深度探索嵌入式操作系统:从零开始设计、架构和开发
为什么没人推荐这个 Operating Systems: Three Easy Pieces
骚年,来一条龙啊
xv6+深入理解操作系统+unix环境高级编程+c程序设计语言
推荐两本适合入门和建立基本概念的书,都是以linux0.1x版本为范例来讲解的:
<linux内核设计的艺术>,书中有非常多的图解,比起单纯的文字描述更容易接受和理解;
<linux内核完全剖析>,还有赵炯的其它几本书;
上面两本看完了可以看下面这本:
<深入理解Linux内核>,对应的英文版"Understanding The Linux Kernel",中文版的翻译不是很令人满意,很多专业名词一旦翻译成中文反而更难理解,建议直接看英文版.
《Freebsd操作系统设计与实现》《深入Linux内核架构》。前者纯理论,后者偏实现,有中文版,翻译的也不错。
若是想写个操作系统的话 推荐你看《操作系统真象还原》
目前可以公开的情报:需要动手做实验。一学期写几千行弄个完整的mini OS大概比较困难,但是可以阅读类似的mini OS源代码(比如MIT的xv6,6.828 / Fall 2014),自己架设虚拟机和编译/调试用的工具链,改一改,调一调。有的OS课程实验设计就是给一个mini OS,然后从其中抠掉一些代码,要求学生在掌握OS知识和熟悉mini OS架构的基础上,自己补完代码,且能通过测试。
有两门近期将开课/已经开课的国内OS公开课可以关注一下:
Coursera - Free Online Courses From Top Universities,北京大学《操作系统原理》
操作系统-学堂在线慕课(MOOC)平台,清华大学《操作系统》
作为CS三剑课(数据结构,算法,操作系统)中的capstone和终极大Boss,OS的独特魅力在于:你不但能学到所有你想知道的,而且还*着去了解所有你不想知道的(夸张了点,但就那意思…
所以,学好这门课无非就两点:
1. 熟练掌握你想知道的
2. 适度理解你不想知道的
OSTEP
假如你是自己认真看书,然后独立完成大二小学期用 VHDL 模拟后刻在板子上的 CPU,大三上继续认真看书,搞清楚那些点,独立完成那8个实验。
如果学好的标准是考试拿高分,那死记硬背就好了,操作系统比文科还需要死记硬背。
但是如果你想真正弄懂,那需要看的东西太多了
我个人感觉,搞清楚计算机启动的整个过程,比如加电置全1,扇区引导,实模式进入保护模式....
操作系统就已经能明白一半了
操作系统怎么学,首先要想操作系统是怎么来的,在没有操作系统的年代里,人们是怎么编程的。这是首要的问题。不知道有没有人看过INTEL官方的CPU文档,总是分为应用级编程、系统级编程、指令集这三块。其中系统级编程这一块最复杂,我不说内容,就单从文件的大小来看,IA-64编程手册的应用级编程卷是2MB,系统卷却有6MB。就连IA-32编程手册上的系统卷部分也远比应用卷的要多。当然这些内容我还没有看,不过从目录当中,觉得有很多相似的地方,比如CPU内存寻址、虚拟存储器管理、中断与保护等等,可以从INTEL的CPU文档上看出,各种CPU或机器虽然各有各的不同,各有各的特点,但是目前的CPU要解决的核心问题就是那么几块,要解决的就是象如何寻址内存,如何管理虚拟存储,如何实现中断,如何保护资源等等。
各位编程的同仁想必都很清楚,计算机的操作系统就是在为应用级编程提供服务,提供什么服务,就是提供象诸如如何内存寻址,如何管理虚拟存储器、如何进行中断,如何管理磁盘,如何。。。。等等。操作系统为我们做掉了系统级编程中最繁重的一块,所以我们在用应用级编程比如用C++编程的时候才会那么舒服,用int分配一个变量这内存地址就来了,某个函数要调用另一个函数执行的时候这执行行程就能跳到那个函数,内存不够了,没有关系,操作系统自动启动虚拟存储器(只不过慢了些),所以应用级编程是最舒服的,操作系统级编程比较难,而直接做单片机可能就是最难的了。因为即使就是操作系统级编程,可能很多有关CPU底层的东西也已经做掉了,你要做的可能就是要了解的你的操作系统做掉了哪些功能,如何调用。而单片机就没有那么好玩了,单片机我没有做过,我想可能就是直接对着一个CPU用汇编来编程,而且很可能是在没有操作系统的情况下,这样一来,操作系统要承担的诸如内存管理,中断,过程跳转等这些复杂繁重的工作就得程序员自己来承担,那程序员的负担就比目前应用级编程大得多了。
我猜想,可能在没有操作系统的时候,每个计算机程序员的日子可不会象现在的那么好过,因为做每个程序,都需要你自己去分配管理内存,你不但要考虑如何高效的管理内存,还要知道如何进行过程跳转等等这一大堆的的细活,而这些细活在不同的CPU上的实现方式也是不同的,直到把这些问题都解决了以后,你才开始真正考虑你的应用方面的程序逻辑如何去编的问题。当然了,虽然有关CPU底层的系统级实现细节不一样,但是大至CPU系统级这一部分要解决哪几块问题这是一样的,所以在INTEL的官方文档上,无论是IA-32还是IA-64这两个编程手册的系统卷上,都是那么几块内容。
既然系统级要解决的几个任务都是相同的,每个程序员在编程的时候都要考虑这几方面的内容,那么可能就会想,为什么不把这些程序要解决的相同的任务给提取出来呢,这就形成了操作系统,操作系统的内核的任务,就是专门负责解决早期计算机程序员每次编程都必须要解决的几项系统级任务,这样一来,留给应用级的担子就非常的轻了,忘记在哪里看过,好像以前的数据库系统是属于应用软件的,可能同样是因为每个应用软件连同操作系统都需要一个数据库,所以就把数据库系统给单独提了出来做为系统软件了。有一点不明白为什么目前的操作系统要用文件系统,直接用数据库系统不更好些吗,既对用户服务,又为系统服务!
我觉得,如果大家有要学操作系统原理的,根本就不必要去看所谓什么操作系统原理这一类的书,连外文的书籍也没有必要去看,因为目前国际CPU制造商提供的CPU文档的系统级编程卷才是真正的,原汁原味最好的教材,你要编写的操作系统从大部分任务就是解决系统卷里的任务的。有一次在QQ上和一个做单片机的家伙聊天,那人比我小一点,我当时说目前操作系统底层好难,他就说这有什么难的,他马上就能做一个操作系统,就连编译器也能做,我当时被吓了一大跳,小小年纪就这么厉害,现在我懂了,做单片机的,大概都会做操作系统,因为单片机的每次编程就是和系统底层打交道的,所以做单片机程序的自然对一个操作系统内核会比较了解了。
在此建议和我一样的对操作系统原理感兴趣,对系统底层的感兴趣的人,直接去看INTEL的官方材料吧,操作系统原理有哪几条,要解决哪些任务,通过查看不同CPU的系统卷编程手册,找出其中相同的任务和逻辑去自己总结操作系统是如何做,无疑这种方法学到会是最多的了,而且理解起来可能会比一般的学习方法来得更深刻。
学习应用软件的朋友,我也劝你们看看操作系统,内核等这些系统底层的东西。看过了以后,你会觉得看应用级编程会更流畅,学起来也会更简单。我就是这样学的,学MFC,后来开始学INTEL CPU的应用级编程,现在我决定开始从系统级学起。目前我也会上MSDN英文网站看看有关MFC的东西,但我看MFC倒不是主要因为去编写MFC应用程序,而是想看看微软是用系统为所有的应用级编程提供服务的,这整个一套结构是如何构造出来的,ORACLE数据库是我继INTEL文档的下一波目标,我也是想看看,一个数据库体系结构是什么样的,可不可以嵌到操作系统里去。
操作系统是一个庞大的软件,涉及到方方面面,如果你想透彻了解操作系统,那么你必须要写一个操作系统,并不需要写个windos or linux那样的操作系统,写个几千行的到1万多行的玩具就可以了。
独立写一个操作系统需要很广的知识面, 《深入理解计算机系统》着本书你总得看吧,怎么也得稍微有一点系统开发的经验吧(windos or linux都行),推荐看《UNIX环境高级编程》,当然这都不是必须的.
1、随便看一本关于操作系统理论的书,国内国外教材都可,推荐《操作系统:精髓与设计原理》
2、看《x86汇编语言:从实模式到保护模式》,动手照着书上写代码
3、跟着MIT 的操作系统的实验 6.828 / Fall 2014,全程把这个实验做完
完成以上三点,你基本就可以写出一个完整的、可在真机上运行的操作系统了,在这期间你需要很强的毅力,善于自己解决问题。
4、看《深入理解Linux内核》与《x86/x64体系探索及编程》,对照着《深入理解Linux内核》上讲的Linux内核的各种系统(eg. 虚拟文件系统、slub内存分配系统、伙伴系统),再看看Linux内核的源码,再与自己的思维融合一下下,就可以开始动手写一个自己的操作系统了。
我就是按照以上四个步骤写了一个操作系统 GitHub - Zhang626/fuckOS
在这期间需要查阅非常非常多的资料,大部分资料都列在MIT 6.828 的实验上了。
推荐一个外国的关于开发操作系统的论坛,上面有很多牛人OSDev.org • Index page 与 Expanded Main Page
还有一本很屌的书叫:《Linux From Scratch》
在本地用virtualbox架设一个汇编环境,用来做开发测试的沙盒
选书如 Operating System Concepts
汇编的教程网上与很多,可以自己找。
uc/os给我的感觉不错。虽说这是个嵌入式系统,但是用来了解任务调度和进程同步的细节还是非常好的,结构设计也非常有层次感。作为一个RTOS,它每一个函数都能设计好有一个确定的执行时间,感觉还是很神奇的。
最重要的是,它是免费的!免费获取源码,注释也很清晰。除了缺少系统的内存管理和文件系统之外,还是非常不错的一个用来学习的系统。
推荐MIT-6.828 :6.828 / Fall 2014
这是他们的schedule,按照上面的课程好好上完,把pre的paper好好读读,lab全部做完,基本你就对操作系统有了全新的认识了。
要是嫌mit的英文看的太累的话,也可以试试清华的,lab都差不多,不过清华的pre paper好像没有。
玩具还是不要搞了吧。可以看xv6,或者看赵炯博士的0.12版linux分析,或者读freebsd或者illumos这种注释很清楚的源代码
我给出的建议是:莫要贪心,想要一口吃个胖子。OS是个工程性很强的技术活儿,初学者最好不要把目标定为“深入学习”(在我看来深入学习的意思有两种可能:读源码分析其实现,或者学习分布式系统),“了解原理”应该是更切实的目标。
如果你还是在校学生,只看现代操作系统那本书就够了,多读几遍,一遍肯定很多地方读不懂,这基本上就会用掉半年的时间。如果读完之后还有很浓厚的兴趣想了解OS的实现,那就读读xv6(xv6有本xv6-book的电子书,必读,读完它再去看源代码),或者赵炯博士那本。上学期间读这些就够了,花更多时间学学web开发技术更有钱途。
如果已经工作,那只能读Linux或者FreeBSD、illumos这种久经考验的操作系统。FreeBSD和illumos的优点是代码结构清晰,有前面那些基础很容易读进去,读完能学到很多知识;缺点是用户群小(和Linux相比)。Linux代码虽然乱些,但分析源码的书更多,遇到难点也许更容易克服。
长远看,未来是属于Linux,所以建议先从Linux学起,我个人推崇的linux的入门书是robert love的linux kernel development。我对Linux没有深入了解,唯一认真度过的是linux device driver,但这本书比较难啃,但值得推荐。
我上操作系统课的时候用的是Nachos,可以看一下Nachos
我在读大学的时候是努力试图学习过linux源码的,在机房里打印出厚厚一叠纸,闷在计算机旁边猛看了好几天,饭也没好好吃,那些纸的质量不太好,有股怪味,空着肚子钻研,到后来闻那股味道,差点呕吐,于是放弃,出去大吃了一顿。
这是上世纪末的事情了,那时其实水平还没到,心里好奇,完全是赖蛤蟆想吃天鹅肉。学习这个事情,还是得循序渐进的。
要想学深入学习操作系统,推荐从这本书开始: Operatiing Systmes, Design and Implementation (by Tanenbaum, Woodhull),里面有个用于教学的操作系统Minix。Linux的某些方面,现在还可以找到Minix的影子。
我手里的这本书,是第二版,现在书最新版是第三版。Minix 3.0,也已经有点难度了, X Window System都有了。http://www.minix3.org/
要是觉得还是太复杂,还有个更简单的GeekOS,http://geekos.sourceforge.net/
OS的设计是受限于硬件的,尤其是CPU。当代OS的不同进程之间的内存保护,虚拟地址,都要通过硬件。所以对一个CPU的深刻了解,必不可少。对于Intel的CPU,应该读下面三本:
1. Intel Architecture Software Developer's Manual, Volume 1: Basic Architecture http://www.intel.com/design/PentiumII/manuals/243190.htm
2. Intel Architecture Software Developer's Manual, Volume 2: Instruction Set Reference Manual http://www.intel.com/design/PentiumII/manuals/243191.htm
3. Intel Architecture Software Developer’s Manual Volume 3: System Programming http://www.intel.com/design/PentiumII/manuals/243192.htm
尤其是第三本,编OS必看,虚拟内存,内存保护的东西全在里面。
操作系统里面代码最多的,实际是IO部分,理论不多,可事关重要。Mindshare出了一系列书,写的非常深入详细。http://www.mindshare.com/
学汇编开始直接学CISC的指令集太费劲了,推荐先从RISC汇编开始,西方大学计算机专业走的也是这条路。可以看的一本书是Introduction to RISC Assembly Language Programming,by John Waldron。里面用的处理器MIPS,可以下载个SPIM Simulator,在PC上跑。http://www.cs.wisc.edu/~larus/spim.html
Knuth老先生在The Art of Computer Programming一书里的例子,都是汇编,现在用的虚拟机是访RISC设计的,叫做MMIX,Knuth写了本书,叫做MMIXware, A RISC Computer for the Third Millennium, 呵呵,口气好大啊。
讲计算机架构的两本计算机学科经典书,是Patterson和Hennessy合写的两本:Computer Organization and Design: The Hardware/Software Interface 3rd edition,以及Computer Architecture, Fourth Edition: A Quantitative Approach
学汇编要注意一点,每个汇编器,其语法都不一样。在Windows下面写汇编,微软的Macro Assembler不是很合适,里面的Macro太多,都赶上高级语言了。有个开源的Netwide Assembler, http://sourceforge.net/projects/nasm, 倒是挺不错,推荐使用。
关于学习操作系统内核,如果不是非抱着Linux的话,BSD是个挺好的选择。代码的结构可能还清晰些。我有一台FreeBSD服务器,基本非常满意,有两点不足,MySQL是针对Linux优化的,在FreeBSD下性能不够好,但是根据Yahoo的人说(Yahoo用FreeBSD),FreeBSD最新版下用MySQL threading library重新编译性能可以接受了。Java也不尽如意,Sun 现在提供Java 5的binary给FreeBSD。但我在FreeBSD如果启动Tomcat开的内存太大,启动会失败。
想看看FreeBSD的源码,可以看看这里:http://www.leidinger.net/FreeBSD/src_docs/,里面列的都是内核各个部分的Code Reference Manual。里面那个讲kernel的文件有23M,共2205页,可见钻研这些是件极为费时费力的事情。
http://www.chinaunix.net/也有很多BSD的资料。
现在主流操作系统,就两大家了,一边是微软的以NT为内核的Win2k/XP/2003/Vista,另一边是以UNIX为根基的Linux/BSD/Solaris等等.
Tanenbaum说过这么一句话,操作系统是什么呢,就是操作系统定义的API。
学习Windows下的API,容易许多,资料全,另外Jeffrey Richter的Programming Application for MS Windows那本书写的太好了,Process, Job, Thread, Fiber, Critical Section, Event, Waitable Timer, Semaphore, Mutex,Virtual Memory, IO,写的非常详尽清楚。要是Linux/BSD下面也有这么一本书,该有多好啊。Linux, BSD里面的线程,家家各有不同,把人搞得糊里糊涂。
如果从研究操作系统是怎么实现的,那么正好反过来,Linxu/BSD/Solaris简单明了多了.除了代码公开,他们内部结构没有Windows那么复杂。Windows的源码,要是成为微软的MVP,也是可以看到的。Windows 2000的大部分源码,还泄露出来了,在网上流传了一阵子。
我个人觉得搞应用的去学习编译器回报可能更大,首先就是对语言了解很深入,写码,读码容易。如果会了编译器前台技术,可以自己写个分析代码的程序啊,那么读别人的码不久容易很多。现在虽然有现成的源码分析器,但是想想你有个数据库,一种是只能使用别人写好的界面,一种是可以用SQL*查找,哪个好?如果学会了编译器后台技术,恭喜你,写任何一行代码都知道在计算机里怎么执行的,这是一种多么*自在的境界啊。