前言
本文意在对计算机的软硬件体系结构进行梳理,包括计算机体系结构,什么是操作系统,为什么存在操作系统,操作系统如何进行管理,以及建立在这些软硬件基础上的各种提供给用户进行操作的接口。
本文对于理解操作系统本身以及下一节的进程概念,甚至对整个Linux系统编程的理解都有着至关重要的作用,希望大家能耐心读完。
一、冯洛伊曼体系结构
我们目前使用的计算机,绝大多数都遵守冯洛伊曼体系结构,其具体构成如下:
冯洛伊曼体系结构主要由输入设备、输出设备、运算器、存储器与控制器五部分构成:
- 其中运算器、控制器,再加上其他的一些寄存器统称为中央处理器 (CPU);
- 存储器一般指内存,内存掉电易失,只能用作临时存储;
- 输入设备和输出设备被统称为外设,其中磁盘、网卡等属于输入输出设备,键盘只属于输入设备,显示器只属于输出设备,磁盘是不带电存储的,可以用于永久存储。
我们知道,CPU 是一台计算机的核心,因为它具有很强的运算能力;但是其实CPU是很笨的,它只能被动的接受别人传递过来的数据和指令,然后将运算得到的结果返回;那么这里就会出现两个问题:
1、CPU如何能够识别我们传递给它的数据和指令?
答案是CPU内部有一套自己的指令集,它会把指令对应到指令集,然后完成相应的操作;其中CPU的指令集是二进制的,这就是为什么我们编写的代码需要经过编译链接变成二进制的可执行程序后才能被运行的原因 – CPU需要读懂我们的指令才能完成对应的运算;这也是编译器存在与产生的根本原因。
2、CPU需要的数据从哪里获取?
答案是内存 (此处不考虑缓存);虽然我们的数据是存放在磁盘中的,但是由于磁盘读取与写入数据的速度太慢了 – 可以简单理解为CPU的运算速度以纳秒为单位,内存的运算速度以微秒为单位,而磁盘的运算速度则是以毫秒甚至秒为单位;CPU如果直接从磁盘中读取和写入数据,会有大量的等待时间,所以为了提高计算机的整体效率,CPU只会向内存中读取和写入数据;内存再向磁盘中读取和写入数据;其中,内存向磁盘读取和写入数据就是IO的过程。
经过上面的学习,我们可以得到如下结论:
在数据层面上,CPU不会直接和外设打交道,而只会和内存打交道;同样,所有的外设需要载入数据时,只能载入到内存,内存要写入数据,也只能写入到外设中。
有了上面的知识铺垫后,我们就可以解释为什么 程序运行必须加载到内存 中了 – CPU需要从程序中读取数据,但是CPU只和内存打交道,而我们的程序是存储在磁盘中的。
最后,我们对冯诺依曼的理解,不能停留在概念上,要深入到对软件数据流理解上,以下面这个例子为例:我们在QQ聊天窗口向别人发送一条消息到别人接受消息的过程中,数据的流动过程?如果发送的是文件呢?
发送消息 --> 接受消息 的数据流动:A 的键盘 --> A的内存 --> A的CPU (加密) --> A的网卡 --> B的网卡 --> B的内存 --> B的CPU (解密) --> B的显示器;
发送文件 --> 接受文件 的数据流动:A 的磁盘 --> A的内存 --> A的CPU (加密) --> A的网卡 --> B的网卡 --> B的内存 --> B的CPU (解密) --> B的磁盘;
二、操作系统 (OS)
1、什么是操作系统
操作系统是一个进行软硬件资源管理的软件,它通过对下管理好各种软硬件资源 – 手段,来对上为用户提供良好的 (安全、稳定、高效) 运行环境 – 目的;操作系统有四大软件管理模块 – 进程管理、文件系统、内存管理、操作系统。
2、为什么要有操作系统
我们上面说操作系统是一款对软硬件资源进行管理的软件,那操作系统为什么要对这些软硬件进行管理呢?答案是这些软硬件需要我们对其管理才能正常工作;
比如我们程序运行之前需要预先把数据加载到内存当中,那么谁来加载?什么时候加载?一次加载多少呢?CPU为了提高效率把数据写入到内存中,之后再统一刷新,那么谁帮我们刷新?什么时候刷新呢?CPU运算结束后内存中的垃圾数据又由谁来帮我们清理呢?等等问题;这些事情全部都由操作系统来完成。
3、操作系统如何进行管理
关于操作系统如何管理,我们主要从三个方面进行阐述;
- 管理者不需要与被管理者直接交互,依旧能够很好的将被管理者管理起来;
我们以学校为例,学校的校长并没有直接与我们 (学生) 进行交互,但是他仍然能够很好的将我们管理起来;可能有的同学会说,我们并不是由校长来管理的,而是由辅导员来管理的?但是实际上,辅导员并不算一个管理者;
拥有对重大事宜的决策权的人才是管理者,虽然日常与我们进行交互的入是辅导员,但是辅导员对我们并没有决策权,比如你是否能够升级、是否能够评优评先、是否会别学校开除等等重大事项;
- 管理的本质是对数据进行管理;
我们上面提到,拥有对重大事宜的决策权的人被称为管理者,但是决策是要有依据的,而决策的依据就是被管理者的数据;比如你的绩点、综测和各种获奖记录等数据决定你是否能够评优评先、国励、优秀个人等;你期末的挂科门数和日常的违纪次数等数据决定你是否能够升级或者是否会被学校开除;
另一方面,既然管理者不与我们直接交互,那么它如何得到我们的数据呢?答案是由执行者提供 – 执行者通过与被管理者交互得到被管理者的各种数据,管理者通过这些数据对被管理者做出决策,然后执行者再执行这些决策;对应到上面的例子来说,校长通过辅导员 (假设学校只有校长、辅导员、学生三类对象) 获取我们的各种数据,然后做出决策,最后辅导员再对我们执行这些决策;
对于计算机来说,各种硬件对应的驱动就是所谓的执行者,比如网卡有网卡驱动,磁盘有磁盘驱动;操作系统从这些驱动获取硬件数据,然后通过对硬件的数据进行管理实现对硬件的管理;
- 管理的方法是先描述,再组织;
我们知道,一个大学有几万名学生,如果校长对每个学生的数据都独立保存的话,那数据管理的成本势必会非常大;所以,我们可以利用面向对象的思想将学生的数据描述成一个结构体或者一个类,然后每个学生都对应着由这个类/结构体实例化出的一个对象;最后,我们可以使用某一种数据结构 (比如顺序表、链表) 将这些类对象组织起来,形成一个学生信息管理系统;此时,我们对学生数据的管理就转变成了对某一数据结构的增删查改,大大提高了管理的效率。
我们以链表为例对各种硬件设备进行管理:
由硬件的各种数据抽象出来的结构体:
typedef struct device { int type; //设备类型 int status; //设备状态 ... //其他属性信息 struct device* next; //下一个设备的地址 }Dev;
对设备的数据进行管理转变为了对链表进行增删查改:
list dev_list; struct Dev disk_div; dev_list.insert(disk_div); struct Dev keyBoard_div; dev_list.insert(keyBoard_div); dev_list.erase(display_div); ...
注:我们上面举的都是硬件的例子,但是操作系统不仅能管理硬件,也能管理软件,且对软件的管理和对硬件的管理方法是完全一样的 – 管理软件 --> 管理软件的数据 --> 把软件数据描述成一个结构体 --> 管理用于组织这个结构体的数据结构。
总结 (非常重要 – 贯穿我们Linux学习的整个生命周期)
- 管理的本质是对数据进行管理;
- 管理的方法是先描述,再组织;
三、系统调用与用户操作接口
1、系统调用接口
既然操作系统是管理各种软硬件资源的软件,那么我们能否通过操作系统直接对各种软硬件进行操作呢?比如磁盘、显示器、磁盘驱动等设备;答案是不能,因为操作系统不相信任何用户 – 操作系统不确定我们是否会对各种软硬件进行违法操作,比如删除磁盘驱动、向磁盘中添加恶意数据等等;
但是操作系统又必须给上层用户提供各种服务,比如用户访问软硬件的需求,比如从磁盘中读取与写入数据、向显示器打印数据、通过网卡发送数据等等;针对上述情况,操作系统想了一个完美的方法 – 给用户提供系统调用的接口,即当用户有访问软硬件的需求时,直接调用操作系统提供的接口,然后由操作系统来帮助用户完成对应的工作;这样即满足了用户的需求,又保护了软硬件资源。
注:Linux 操作系统是托瓦兹大神于1991年使用C语言编写的,而上述的各种系统调用接口又是由操作系统提供的,所以它们也是C式的接口,说白了就是 用C语言编写的用于用户调用的各种函数接口。
2、用户操作接口
虽然操作系统为我们提供了各种系统调用接口让我们来访问软硬件,但是这些接口在使用上功能比较基础,对用户的要求也相对较高;于是人们在系统调用接口的基础上开发出了用户操作接口,比如 Linux 下的外壳程序 shell,各种函数库 (C/C++等),windows 图形化界面 (GUI),以及一些指令 (编译好的可执行程序) 等;
用户通过这些操作接口进行指令操作、开发操作以及管理操作等等;比如 Linux 下外壳程序 bash 提供的 ls,本质上是调用系统接口,将磁盘中文件信息写入到显示器;touch 本质是调用系统接口,在磁盘上创建文件;又比如 C语言的 scanf/printf 函数,底层都是调用系统调用接口从键盘读入数据/向显示器上打印数据。
四、计算机的软硬件体系结构
在学习了上面的所有知识以后,我们的计算机软硬件体系结构就搭建起来了:
一方面,操作系统对所有软硬件资源进行管理,同时为用户提供访问软硬件资源的系统调用接口,由操作系统来完成资源的各种访问;另一方面,用户为了降低成本,使用各种用户操作接口来访问软硬件资源,用户操作接口的底层再来调用系统调用接口。所以说,操作系统将硬件、软件和用户有机联系了起来。