Linux入门篇(一)——建立方法
Linux入门篇(二)——操作系统之哲学原理
Linux入门篇(三)——操作系统之进程原理
Linux入门篇(四)——操作系统之内存原理
Linux入门篇(五)——操作系统之文件原理
Linux入门篇(六)——操作系统之I/O原理
Linux入门篇(七)——操作系统之多核原理
本节内容为《计算机的心智操作系统之哲学原理》的总结,由于个人认知有限,可能总结的不够准确,所以建议阅读完整书籍来学习。
学习操作系统需要具备哪些能力?
1.善于观察生活中细节的能力
2.C语言的能力
为什么需要善于观察生活中细节?
操作系统来源于生活,服务于生活。操作系统的大部分设计都是从生活中观察得到的现象进行抽象所获得,所以只需要稍微留意一下生活中的细节,就能具备理解操作系统的能力。
为什么需要C语言?
因为操作系统的代码大部分有C语言所写,作为一个工程师不仅需要明白操作系统的设计原理,还要从代码中理解一个软件系统的真正运行机制,而要想理解一个软件系统的真正运行机制,正如Linux的创始人所说,一定要阅读其源代码(RTFSC-Read The Fucking Source Code)。
学习理论知识的重要性?
非科班出身的程序员,大多善于在实战中总结经验。但是对于如今庞大的操作系统来说,我们如果还是直接从实战开始,就犹如盲人摸象,始终不得要领。所以对于操作系统来说,学习理论知识就变得尤为重要,先居高临下,高屋建瓴的窥探全貌后,才能做到心中有数,学起来心领神会。
这个世界上的所有东西都可以分为两类,一类是本来就存在于自然中,人类所做的只不过是发现;另一类是本来并不存在,人类所做的是发明。而操作系统就是人造系统。
人造的特点:
操作系统英文名称为:Operating System 意味着掌控一切的系统。操作系统是掌控计算机上所有事情的软件系统,
从这个定义可以引申出操作系统的功能包括:
从以上功能再进行提升,就可以得出操作系统所扮演的两个根本角色:魔幻家和管理者。
操作系统可以把差的东西变好(多进程),把少的东西变多(虚拟内存),把复杂的东西变容易(复杂的东西由操作系统实现),就像一个魔幻家一样。
操作系统对CPU、内存、I/O、磁盘等的管理,可以使不同的用户之间或者同一用户的不同程序之间可以安全有序的共享这些硬件资源。
根据管理的资源不同,具体功能包括:
操作系统一个是软件,用户程序也是个软件,那么操作系统软件和用户程序软件是什么样的一个关系?
很显然,操作系统为用户程序提供了一个虚拟机器的界面,而用户程序运行在这个界面之上,这是一个比较抽象的理解。通俗一点的理解就是调用与被调用的关系。
从用户的角度看,是用户程序调用操作系统提供的服务,操作系统完成用户调用的服务后再返回给用户。这个时候用户程序是主程序,操作系统是子程序。
从操作系统的角度看,计算机启动之后最先运行的实操系统程序,在次之后,操作系统不断的调用用户程序。这个时候操作系统是主程序,用户程序是子程序。
实际上,也可以看作操作系统和用户程序是互相调用的动态关系,每个角度都对。
驱动操作系统演变的量大因素:
操作系统的演变就是一个我们对计算机硬件进行粉饰的过程,以下从时间先后顺序介绍演变出的各种操作系统。
计算机硬件结构可以简单概括为:各种硬件设备挂在总线上,这些设备都有一个控制器,外部设备都由这些控制器与CPU通信。
为了提高计算机效率,人们设计除了流水线结构,将计算机的功能部件分为多个梯级,每条计算机指令同样分拆成多个步骤,每条指令在流水线上流动,到流水线最后一个梯级时执行完毕。
为了进一步提供效率,又发明了多流水线、超标量计算和超长指令字等多指令发射机制。
除了指令单元,计算机的另一个重要部件是指令的存放单元,成为存储架构。
操作系统提供的是一个抽象。抽象来源于具体,但又超越具体。例如具体的计算机硬件,CPU、内存、I/O设备等,但又超过这些现实,使人和应用软件感觉到更多、更好的硬件存在。
不仅如此,操作系统内部也分为不同的的功能块,而不同的功能块之间互相提供的也是抽象。
运行在内核态的程序可以访问的资源更多,单可靠性、安全性要求高,维护管理都较复杂;用户态程序访问资源受限,但可靠性、安全性要求低。一个程序到底应该运行在内核态还是用户态取决于其对资源和效率的需求。
态势的识别
计算机可以通过CPU状态字里边的一个字位来判断正在运转的程序是在内核态还是用户态。
内核态与用户态的实现
为了给内核态程序赋予访问所有资源的特权,限制用户态程序访问资源的权限,可以通过对虚拟地址翻译的控制,就可以控制程序对资源的访问。
操作系统的结构类似与政府的行政机构,每一层的功能各不相同,且下面一层只对上面一层负责,上面的层通常也只对其直属下层进行直接控制。
微内核结构
从上图可以看出操作系统的所有功能都在内核态运行,因为内核态程序可以访问所有资源,所以安全性和可靠性要求十分高,在操作系统很小时,其设计的可靠和安全还不是特别困难,但是随着操作系统越来越大,破坏者水平越来越高,操作系统的可靠性和安全性就变得很难达到。
因此,就有了微内核的结构,即将操作系统中的核心放在内核态运行,其他功能都移到用户态。这样就提高了安全性。
凡事有利必有弊,微内核频繁的进出内核态和用户态,又会带来效率上的损失。但是当前的趋势正是这种微内核的操作系统结构,至于这个微内核有多“微”,则是仁者见仁智者见智。
进程是操作系统里边的核心概念。它指的是一个进展中的程序。操作系统对进程的管理通过进程表来实现。进程表里存放的有关于进程的一起信息。在任何一个时候,进程所占有的全部资源,包括分配给该进程的内存、内核数据结构和软资源形成一个进程核(Core)。核快照(Core Image)代表的是进程在某个特定时刻的状态。
内存是操作系统里边的另一个核心概念。它是进程的存放场所。内存管理就是使的数据的读写具有高效率、高安全、高空间利用率和位置透明的特性。
文件是操作系统提供的外部存储设备的抽象,它是程序和数据的最终存放地点。
系统调用就是操作系统提供的应用程序界面(API)。用户程序通过调用这些API获取操作系统的服务。
系统调用按照功能可以划分为六类:
用户程序通过调用操作系统提供的系统API来获得操作系统的各种服务。但使用API需要编程,为这些不编程的用户,操作系统提供了一个壳(sheel),来与用户交互。这个壳是覆盖在操作系统服务上面的一个用户界面,既可以是图形界面,也可以是文本界面。
实际上,用户输入的命令是不能直接操作系统服务的,而是通过C语言提供的库函数来解决这个问题。
一个壳的具体功能包括如下几项:
操作系统的层次架构类似与人类社会的层次架构,比如政府的行政机构,每一层的功能各不相同,且下面一层只对上面一层负责,上面的层通常也只对其直属下层进行直接控制。
人类的社会制度发生过多次变化。即使现在,世界上也存在多种设计制度或形态。但不管社会制度和意识形态如何,我们都能和平相处。可见,社会形态本身并无对错之分,只有好坏之分。
放在操作系统里,这条原则同样适用。就像我们不能说windows是对的,linux是错的。
懒人哲学的合理性在于提前将事情做掉也许是一种浪费。因为没有人能够遇见未来会发生什么事情,而情况的变化有可能造成前面所做事情毫无意义。例如,系统在fork时,只创建一个空的子进程,而不进行父子进程地址空间的复制,这样,如果将来要运行新的程序,我们没有做任何无用功。
最典型如对死锁的处理,虽然现代操作系统采取了部分措施来降低死锁的概率,但是都不能完全避免死锁的发生。这种不愿意花费力气进行死锁的避免,却把死锁可能留给用户的做饭就是典型的让困于人,即让用户来承担困难。
后续文章会专门讲解死锁产生的原因,及应对方法。
俗话说,不可将事情做绝。操作系统的设计处处都存在这保留空间,就是为了方便以后对系统的改善。
这正是操作系统的最大角色:魔术师。例如,在操作系统里面,用户看到的内存是一个非常简单、具有线性美的一维数组。这个数组无限大(实际上与磁盘一样的),速度无限快(实际上与缓存一样快)。单实际上我们的物理内存只有几个G (肯定没有磁盘大),速度也只有缓存的十分之一。
时间和空间的转换。例如页表的实现(后续文章后续会专门探讨)。
裁判和运动员不能是同一个人。在操作系统里,策略可以由用户指定,操作系统则是执行机制。所以有了所谓的调度算法参数化,算法在内核里,参数可以用户指定。由于策机分离,操作系统在实现调度算法
越简单的架构效率越高。
简单不等于过于简单。例如爱心斯坦说过一句话“一切都应该尽可能简单,但没有更简单”,这就给追求简单界定了限制。