深入理解计算机操作系统(一)

目录

1.1 信息就是位加上下文

1.2 程序被其他程序翻译成不同的格式

1.3 了解编译系统如何工作是大有益处的

1.4 处理器读并解释储存在内存中的指令

1.4.1系统的硬件组成

1.4.2 运行hello程序

1.5 高速缓存至关重要 

1.6 存储设备形成层次结构

1.7 操作系统管理硬件

1.7.1 进程

1.7.2 线程

1.7.3 虚拟内存

1.7.4 文件

1.8 系统之间利用网络通信

1.9 重要主题


1.1 信息就是位加上下文

计算机系统是由硬件和软件组成的,它们共同工作来运行应用程序

源程序实际上就是一个由0和1组成的位(又称为比特),8个位被组织成一组,称为字节.每个字节表示程序中的某些文本字符.

大部分的现代计算机系统都使用ASCLL标准来表示文本字符

hello.c是以字节序列的方式存储在文件中,每个字节都有一个整数值,对应于某些字符.

系统中所有的信息包括磁盘文件,内存中的程序,内存中存放的用户数据以及网络上传送的数据,都是由一串比特表示的.

区分不同数据对象的唯一方法是我们读到这些数据对象时的上下文.比如,在不同的上下文中,一个同样的字节序列可能表示一个整数,浮点数,字符串或者机器指令.

C标准库就是ISO定义C语言和一系列函数库

1.2 程序被其他程序翻译成不同的格式

  1. hello程序的生命周期是从一个高级C语言程序开始的,因为这种形式能够被人读懂
  2. 为了在系统上运行hello.c程序,每条C语言都必须被其他程序转化为一系列的低级机器机器语言指令
  3. 这些指令按照一种称为可执行目标程序的格式打好包,并以二进制磁盘文件的形式存放起来.

目标程序也称为可执行目标文件

在Unix系统上,从源文件到目标文件的转化是由编译器驱动程序完成的

linux>gcc -o hello hello.c

在这里,gcc编译器驱动程序读取源程序文件hello.c分为以下4个阶段

•预处理阶段  预处理器(cpp)根据以字符#开头的命令,修改原始的C程序。
比如hello.c中第一行#include <stdio.h>命令告诉预处理器读取系统头文件stdio.h的内容,并把它直接插入到程序文本中。结果就得到另一个C程序,通常以.i作为文件扩展名。
•编译阶段  编译器(ccl)将文本文件hello.i翻译成文本文件hello.s,它包含一个汇编语言程序。汇编语言程序中的每条语句都以标准的文本格式确切地描述了一条低级机器语言指令。汇编语言为不同高级语言的不同编译器提供了通用的输出语言。
•汇编阶段  接下来,汇编器(as)将hello.s翻译成机器语言指令,把这些指令打包成一种可重定位目标程序(relocatable object program)的格式,并将结果保存在目标文件hello.o中。
hello.o是一个二进制文件,它的字节编码是机器语言指令而不是字符。如果我们在文本编辑器中打开hello.o文件,看到的是乱码。
•链接阶段  hello程序在这里调用了printf函数,这是每个C编译器都会提供的标准C库中的一个函数。printf函数存在于一个名为printf.o的单独的预编译好了的目标文件中,而这个文件必须以某种方式合并到我们的hello.o程序中。链接器(ld)就负责处理这种合并。结果就得到hello文件,它是一个可执行目标文件,可以被加载到内存中,由系统执行。

1.3 了解编译系统如何工作是大有益处的

  • 优化程序性能
  • 理解链接时出现的错误
  • 避免安全漏洞(缓冲溢出错误)

1.4 处理器读并解释储存在内存中的指令

linux>./hello

hello,world

linux>

shell是一个命令行解释器(也是应用程序)

如果该命令行的第一个单词不是一个内置的shell命令,那么shell就会假设这是有一个可执行文件的命令

1.4.1系统的硬件组成

1.总线

总线就是贯穿整个系统的一组电子管道,她携带信息字节并负责在各个部件间传递

就是定长的字节块      通常总线被设计成传送定长的字节块

字长就是自重的字节数

2.I/O设备

I/O设备是系统与外部世界的联系通道.例如键盘鼠标显示器和磁盘驱动器(磁盘)

每个I/O设备都通过一个控制器或者适配器与I/O总线相连

控制器和适配器之间的区别主要在于他们的封装方式

控制器是I/O设备本身或者系统的主印制电路板(通常称作主板)上的芯片组

适配器则是一块插在主板插槽上的卡 

无论如何,它们的功能都是在I/O总线和I/O设备之间传递信息

3.主存

主存就是用来存放程序和程序处理数据

从物理上说,主存是由一组动态随机存取存储器(DRAM)芯片组成

从逻辑上说,存储器是一个线性的字节数组,每个字都有其唯一的地址(数组索引),这些地址是从零开始的

4.处理器

中央处理单元(CPU)简称处理器,是解释(或者执行)存储在主存中指令的引擎,

处理器的核心是一个大小为一个字的存储设备(或寄存器),称为程序计数器(PC)

在任何时刻,PC都指向主存中的某条机器语言指令(既含有该条指令的地址)

从系统通电开始,直到系统断电,处理器一直在不断的执行程序计数器指向的指令,再更新程序计数器,使其执行下一条指令

处理器是按照一个指令执行模型来操作的,这个模型是由指令集架构决定的

处理器从程序计数器指向的内存处读取指令,解释指令中的位,执行该指令指示的简单操作,然后更新PC,使其指向下一条指令,而这条指令并不一定和内存中刚刚执行的指令相邻

寄存器文件是一个小的存储设备,由一些单个字长的寄存器组成,每个寄存器都有唯一的名字

指令集架构是每条机器代码指令的效果

微体系接收是处理器世纪上是如何实现的

寄存器是中央处理器内的组成部分。寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令数据地址。在中央处理器的控制部件中,包含的寄存器有指令寄存器(IR)和程序计数器(PC)

1.4.2 运行hello程序

当我们在键盘上输入字符串“./hello"后,shell程序将字符逐一读入寄存器,再把它存放到存储器中。

当我们在键盘上敲回车时,shell程序就知道我们结束了命令的输入。然后shell执行一系列指令来加载可执行的hello文件,将hello目标文件中的代码和数据从磁盘复制到主存。数据包括最终会被输出的字符串”hello world\n"。

一旦目标文件hello中的代码和数据被加载到主存,处理器就开始执行hello程序的main程序中的机器语言指令。这些指令将“hello,world\n"字符串中的字节从主存复制到寄存器文件,再从寄存器文件中复制到显示设备,最终显示在屏幕上。

1.5 高速缓存至关重要 

处理器从寄存器文件读取数据比从主存中读取的开销快100倍,针对这种处理器和主存之间的差异,系统设计者采用了更小更快的存储设备,称为高速缓存存储器(cache memory 简称cache或高速缓存),作为展示的集结区域,存放处理器近期可能需要的信息

1.6 存储设备形成层次结构

1.7 操作系统管理硬件

操作系统可以看成是应用程序和硬件之间插入的一层软件

操作系统有两个基本功能

  1. 防止硬件被失控的应用程序滥用
  2. 向应用程序提供简单一致的机制来控制复杂而又通常大不相同的低级硬件设备

文件是对I/O设备的抽象表示;虚拟内存是对主存和磁盘I/O设备的抽象表示;进程则是对处理器,主存和I/O设备的抽象表示

1.7.1 进程

进程是操作系统对一个正在运行的程序的一种抽象.

无论实在单核还是多核系统中,一个CPU看上去都像是在并发的执行多个进程,这是通过处理器在进程间切换来实现的,操作系统实现这种交错执行的机制称为上下文切换

操作系统保持跟踪进程运行所需的所有状态信息.这种状态,也就是上下文,包括许多信息,比如PC和寄存器文件的当前值,以及主存的内容

在任何时刻,单处理器系统都只能执行一个进程的代码

从一个进程到另一个进程的转换是由操作系统内核管理的,内核是操作系统代码常驻主存的部分

注意,内核不是一个独立的进程.相反,他是系统管理全部进程所用代码和数据结构的集合

1.7.2 线程

在现代系统中,一个进程实际上可以由多个称为线程的执行单元组成,每个线程都运行在进程的上下文中,并享有同样的代码和全局数据.

多线程比多进程更容易共享数据

1.7.3 虚拟内存

虚拟内存是一个抽象的概念,它为每个进程提供了一个假象,即每个进程都在独占的使用主存

每个进程看到的内存都是一致的,称为虚拟地址空间

在Linux中,地址空间最上面的区域是为操作系统中的代码和数据保留的,对于所有进程来说都一样。地址空间的底部区域存放用户进程定义的代码和数据。图中的地址是从下往上增大的。

每个进程看到的虚拟地址空间由大量准确定义的区构成,每个区都有专门的功能。

1.程序代码和数据
 对于所有进程来说,代码是从同一固定地址开始,紧接着的是C全局变量相对应的数据位置。代码和数据区是直接按照可执行目标文件的内容初始化的,在示例中就是可执行文件hello。

2.堆
代码和数据区后紧随着的是运行时堆。代码和数据区是在进程一开始运行时就被规定了大小,与此不同,当调用如malloc和free这样的C标准库函数时,堆可以在运行时动态地扩张和收缩。

3.共享库
大约在地址空间的中间部分是一块用来存放像C标准库和数学库这样共享库的代码和数据的区域。

4.栈
位于用户虚拟地址空间顶部的是用户栈,编译器用它来实现函数调用。和堆一样,用户栈在程序执行期间可以动态地扩展和收缩。特别是每次我们调用一个函数时,栈就会增长;从一个函数返回时,栈就会收缩。

5.内核虚拟存储器
内核总是驻留在内存中,是操作系统的一部分。地址空间顶部的区域是为内核保留的,不允许应用程序读写这个区域的内容或者直接调用内核代码定义的函数。

1.7.4 文件

文件就是字节序列,仅此而已.每个I/O设备,包括磁盘,键盘,显示器,甚至网络都可以看成是文件

1.8 系统之间利用网络通信

当系统从主存复制一串字节到网络适配器是,数据流经过网络到达另一台机器,而不是比如说到达本地磁盘驱动器

当我们在tenlnet客户端键入"hello"字符串并敲下回车键后,客户端软件就会将这个字符串发送到telnet的服务器.

tenlent服务器从网络上接收到这个字符串后,会把他传递给远程shell程序

远程shell运行hello程序,并将输出行返回给telnet服务器

最后,telnet服务器通过网络把输出串转发给telnet客户端,客户端就将输出串输出到我们的本地终端上

1.9 重要主题

系统是硬件和系统软件相互交织的集合体,它们必须共同协作以达到运行应用程序的最终目的

1.9.1 Amdahl定律

Amdahl定律的主要思想是当我们对系统的某个部分加速时,其对系统整体性能的影响取决于该部分的重要性和加速程度

若系统执行某应用程序需要的时间为Told.假设系统某部分所需执行的时间与该时间的比例为a,,而该部分性能提升比例为k

加速比S = Told/Tnew

                S = 1/( (1-a) + (a/k))

用后缀"X"表示比例,因此"2.2X读作"2.2倍"

1.9.2 并发和并行

并发是指一个同时具有多个活动的系统

并行是指用并发来使一个系统运行的更快

超线程,有时称为同时多线程,是一项允许一个CPU执行多个控制流的技术

1.9.3 计算机系统中抽象的重要性

程序员无需了解它内部的工作便可以使用这些代码

机器代码程序表现的就好像运行在一个一次只执行一条指令的处理器上

虚拟机,它提供对整个计算机的抽象

1.10 小结

计算机系统是由硬件和系统软件组成的,它们共同协作以运行应用程序。

计算机内部的信息被表示为一组组的位,它们依据上下文有不同的解释方式。

程序被其他程序翻译成不同的形式,开始时是ASCII文本,然后被编译器和链接器翻译成二进制可执行文件。 处理器读取并解释存在主存里的二进制指令。

 

因为计算机花费了大量的时间在内存、I/O设备和CPU寄存器之间复制数据,所以将系统中的存储设备划分层次结构——CPU寄存器在顶部,接着是多层硬件的告诉缓存存储器,DRAM主存和磁盘存储器。

在层次模型中,位于更高层的存储设备比低层的存储设备要更快,单位比特造价也更高。层次结构中较高层次的存储设备可以作为较低层次设备的告诉缓存。通过理解和运用这种存储层次结构的知识,程序员可以优化C程序性能。

操作系统内核是应用程序和硬件之间的媒介,他提供三个基本的抽象:1)文件是对I/O设备的抽象;2)虚拟内存是对主存和磁盘的抽象;3)进程是处理器、主存和I/O设备的抽象。

 

最后,网络提供了计算机系统之间通信的手段,从特殊系统的角度来看,网络就是一种I/O设备。 -

猜你喜欢

转载自blog.csdn.net/kevlin_V/article/details/82805533