【Linux系统编程】从冯诺依曼体系结构到操作系统

Content

    • 一、认识冯诺依曼体系
    • 二、操作系统概念与定位
      • 1. 什么是操作系统
      • 2. 为什么要有操作系统
      • 3. 操作系统如何进行管理
        • 管理的本质是对数据进行管理
        • 管理的方法是先描述,再组织
    • 三、系统调用、库函数和用户操作接口

一、认识冯诺依曼体系

【Linux系统编程】从冯诺依曼体系结构到操作系统_第1张图片

冯诺依曼体系结构主要由输入设备、输出设备、运算器、存储器与控制器五部分构成:

  • 其中运算器、控制器,再加上其他的一些寄存器统称为中央处理器 (CPU);
  • 存储器一般指内存,内存掉电易失,只能用作临时存储;
  • 输入设备和输出设备被统称为外设,其中磁盘、网卡等属于输入输出设备,键盘只属于输入设备,显示器只属于输出设备,磁盘是不带电存储的,可以用于永久存储。

[!attention] 注意

  1. 这里的存储器指的是内存
  2. 如果不考虑高速缓存,这里的CPU能且只能对内存进行读写,不能访问外设(输入或输出设备)
  3. 外设(输入或输出设备)要输入或者输出数据,也只能写入内存或者从内存中读取。
  4. 因此,所有设备都只能直接和内存打交道

[!answer] 几个问题

  1. 为什么程序运行必须加载到内存
    CPU需要从程序中读取数据,但是CPU只和内存打交道,而我们的程序是存储在磁盘中的。内存向磁盘读取和写入数据就是IO的过程
  2. 如何理解软件数据流?以发送消息/文件为例。
  • 发送消息 --> 接受消息 的数据流动:A 的键盘 --> A的内存 --> A的CPU (加密) --> A的网卡 --> B的网卡 --> B的内存 --> B的CPU (解密) --> B的显示器;
  • 发送文件 --> 接受文件 的数据流动:A 的磁盘 --> A的内存 --> A的CPU (加密) --> A的网卡 --> B的网卡 --> B的内存 --> B的CPU (解密) --> B的磁盘;

二、操作系统概念与定位

是什么 -> 为什么 -> 怎么样

1. 什么是操作系统

操作系统是一个进行软硬件资源管理的软件,是电脑第一个被加载的软件,操作系统:

  • 对下管理好各种软硬件资源 —— 手段
  • 对上为用户提供良好的 (安全、稳定、高效) 运行环境 —— 目的

【Linux系统编程】从冯诺依曼体系结构到操作系统_第2张图片

操作系统包括:

  1. 内核 kernel(进程管理,内存管理,文件管理,驱动管理)
  2. 用户空间 user space(包括但不限于函数库,shell程序,系统工具,应用程序接口(API))

操作系统的四大软件管理模块:

  • 进程管理
  • 文件系统
  • 内存管理
  • 驱动管理

2. 为什么要有操作系统

操作系统为什么要对这些软硬件进行管理呢?答案是这些软硬件需要我们对其管理才能正常工作。

比如我们程序运行之前需要预先把数据加载到内存当中,那么谁来加载?什么时候加载?一次加载多少呢?CPU为了提高效率把数据写入到内存中,之后再统一刷新,那么谁帮我们刷新?什么时候刷新呢?CPU运算结束后内存中的垃圾数据又由谁来帮我们清理呢?等等问题;这些事情全部都由操作系统来完成。

3. 操作系统如何进行管理

管理的本质是对数据进行管理

拥有对重大事宜的决策权的人被称为管理者,但是决策是要有依据的,而决策的依据就是被管理者的数据;比如你的绩点、综测和各种获奖记录等数据决定你是否能够评优评先、国励、优秀个人等;你期末的挂科门数和日常的违纪次数等数据决定你是否能够升级或者是否会被学校开除;

另一方面,既然管理者不与我们直接交互,那么它如何得到我们的数据呢?答案是由执行者提供 – 执行者通过与被管理者交互得到被管理者的各种数据,管理者通过这些数据对被管理者做出决策,然后执行者再执行这些决策;对应到上面的例子来说,校长通过辅导员 (假设学校只有校长、辅导员、学生三类对象) 获取我们的各种数据,然后做出决策,最后辅导员再对我们执行这些决策;

对于计算机来说,各种硬件对应的驱动就是所谓的执行者,比如网卡有网卡驱动,磁盘有磁盘驱动;操作系统从这些驱动获取硬件数据,然后通过对硬件的数据进行管理实现对硬件的管理;

管理的方法是先描述,再组织
  1. 描述起来,用struct结构体
  2. 组织起来,用链表或其他高效的数据结构

我们知道,一个大学有几万名学生,如果校长对每个学生的数据都独立保存的话,那数据管理的成本势必会非常大;所以,我们可以利用面向对象的思想将学生的数据描述成一个结构体或者一个类,然后每个学生都对应着由这个类/结构体实例化出的一个对象;最后,我们可以使用某一种数据结构 (比如顺序表、链表) 将这些类对象组织起来,形成一个学生信息管理系统;此时,我们对学生数据的管理就转变成了对某一数据结构的增删查改,大大提高了管理的效率。

我们以链表为例对各种硬件设备进行管理,由硬件的各种数据抽象出来的结构体:

  • 由硬件的各种数据抽象出来的结构体:
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 操作系统是托瓦兹大神于1991年使用C语言编写的,而上述的各种系统调用接口又是由操作系统提供的,所以它们也是C式的接口,说白了就是用C语言编写的用于用户调用的各种函数接口。

[!attention] 理解系统调用
系统调用的具体实现代码是在内核中运行的。当一个用户空间的程序发出系统调用请求时,系统会切换到内核模式(或特权模式),在内核空间执行相应的系统调用代码,然后再切换回用户模式,将结果返回给用户空间的程序。


系统调用和库函数

  • 在开发角度,操作系统对外会表现为一个整体,但是会暴露自己的部分接口,供上层开发使用,这部分由操作系统提供的接口,叫做系统调用。
  • 系统调用在使用上,功能比较基础,对用户的要求相对也比较高,所以,有心的开发者可以对部分系统调用进行适度封装,从而形成库,有了库,就很有利于更上层用户或者开发者进行二次开发。

这两部分共同构成了一个完整的操作系统。内核负责底层的硬件交互和资源管理,而其他程序则建立在这些基础服务之上,为用户提供更为丰富的功能。

虽然操作系统为我们提供了各种系统调用接口让我们来访问软硬件,但是这些接口在使用上功能比较基础,对用户的要求也相对较高;于是人们在系统调用接口的基础上开发出了用户操作接口:

  • 比如 Linux 下的外壳程序 shell,各种函数库 (C/C++等);
  • windows 图形化界面 (GUI),以及一些指令 (编译好的可执行程序) 等。

用户通过这些操作接口进行指令操作、开发操作以及管理操作等等,比如:

  • Linux 下外壳程序 bash 提供的 ls,本质上是调用系统接口,将磁盘中文件信息写入到显示器;
  • touch 本质是调用系统接口,在磁盘上创建文件;
  • 又比如 C语言的 scanf/printf 函数,底层都是调用系统调用接口从键盘读入数据/向显示器上打印数据。

文章部分引用自:【Linux】计算机的软硬件体系结构

你可能感兴趣的:(linux,运维,服务器,centos,bash)