想写好操作系统,必须得先学明白从计算机中一些不得不会的基础知识
计算机基础知识:不得不会的基础知识
1. 存储单元、存储器、内存、外存
A. 存储单元、存储器
存储单元
是存储数据的单元,一般一个存储单元
能够存储8位二进制的数据也,就是一个字节。存储单元
一般应具有存储数据和读写数据的功能。
而存储器
可以视为由一个个存储单元
组成的有序集合。当然,存储器
在物理上是由时序逻辑电路去实现的,有具体的、物理上的电路实现。在原理上,存储器
是利用半导体、磁性介质等技术制成的储存资料的电子装置。其电子电路中的资料以二进制方式储存,不同存储器产品中基本单元的名称也不一样。
而由于存储器
中有很多存储单元,因此为了能够使用这些存储单元,我们需要去区分每个存储单元。区分每个存储单元的方法,就给给每个单元一个地址
。地址
之间是互不相同的。因此,通过地址
,我们可以实现向指定的存储单元中写入数据、从某个指定的存储单元中读取数据等等操作,从而实现最大化的利用存储单元
地址
本身其实是一个整数,描述了当前存储单元
在存储器
中的编号,本质上地址
就是序号。既然地址
是整数,那么我们可以使用二进制去表示,也可以使用十进制去表示,也可以是八进制、十六进制。当然,一般我们都是用十六进制去表示地址
的。
用去地址
这个序号去在存储器
这个有序集合中索引存储单元
,类似于我们使用下标
/索引
/index
在数组
这个顺序集合中索引元素。因此在逻辑上,在逻辑上,或者说我们在使用的时候,可以将存储器
视为由存储单元
组成的数组,而地址
就是下标
。
我们写的程序中会有很多变量,而这些变量都是存储在存储单元
中的。我们给变量赋值,实际上就是将数据存入对应的存储单元
,而使用变量进行计算,实际上就是将数据从存储单元
中读取出来,然后进行计算。
存储单元
和地址
是一一对应的,因此后面有时候会把存储单元的地址
简称为地址
。
B. 外存、内存
存储器
实际上分为内存
与外存
。内存
指的是计算机的内部储存器
,而外存
指的是计算机的外部存储器
。内存和外存是两个相对的概念。
内存
,或者说内部存储器
指的是计算机内部的存储器。
外存
,或者说外部存储器
指的是除计算机内存及CPU缓存以外的储存器,此类储存器一般断电后仍然能保存数据。常见的外存储器有硬盘、软盘、光盘、U盘等。
外存,不严格的理解就是我们能够手动添加到当前计算机系统上的存储器,例如:硬盘、U盘、光碟等等。而不能手动添加的存储器就是内存了,包括:RAM
、ROM
。当然,这里说的手动指定就是手动的插拔,如果要用热风器吹那内存也能换。而且现在的RAM不少都是可插拔式的。
我们通常说的内存,由两部分组成:
- 第一部分:
Random-Access Memory
(RAM
) ,随机存取存储器,对于CPU来说,RAM是主要存放数据和程序的地方,所以也叫做主存
,而对用户来说,既能读取数据,也能写入数据,因此RAM
也就是我们平常说的内存条
,一旦断电数据就丢失了 - 第二部分:
Read-Only Memory
(ROM
),只读存储器,对于用户来说,它只能读取数据,不能写入信息,断电也没有关系,放ROM的数据一辈子都不会变
而外存的种类就多了,什么光盘、U盘、硬盘都是外存,每种具体的设备存储信息的物理原理不同,有可能未来还会出现什么量子盘啥啥的,但是他们共同的特性就是数据写入其中后不会丢失。
所以,用一张图来描述计算机的内存和外存:
2. CPU访问存储单元、寻址、寻址空间
A. CPU访问存储单元、寻址
我们上面说到了每个存储单元
都有自己的地址。我们接下来讲讲CPU
是如何访问存储单元的。下面这张图表示了CPU
是如何访问存储单元的:
暂时忽略掉上图中CPU
内部的TLB
、MMU
、Virtual Address
什么的,那些是内存分页的相关内容,我们后面会讲解他们名,但是这里他们不是我们关注的重点,所以我们先不讲他们。
上面这张图中,我们需要关注的是下面的Physical Address
和Bus
。在CPU
的内存有一个地址总线
(Bus
),当CPU
想要访问某个内存单元的时候,CPU只需要把要访问的存储单元的地址
(我们后面就简称地址
了)提交到地址总线上,而后地址总线上的硬件电路就会自动根据地址
去查找对应的存储单元
,并将该存储单元
中的内容再传输给CPU
。
上面所介绍的,CPU
借助地址总线
去获取指定地址
的存储单元
的值的过程,称为寻址
B. 寻址能力
寻址
本身指是CPU
访问存储单元
获取其中的值的过程。那么这就涉及到了一个问题,CPU
的寻址能力到底如何,或者说,CPU
到底能访问到多少存储单元
?回顾CPU
寻址的过程,CPU
将要访问的存储单元
的地址通过地址总线
送出去,而后地址总线
上的硬件电路再去访问内存单元。所以影响CPU
寻址能力的最重要的因素就是地址总线
的宽度(处理器的地址总线
的位数)。
如果地址总线
的宽度是16位的话,那么地址总线
上的地址范围就是0x0000~0xFFFF
(一个十六进制位等于四个二进制位),如果CPU给了一个20位的地址0x1FFFF
,那么多出来的位数据总线
也没有办法传输。
CPU
中地址总线
的宽度是由硬件决定的,所以在设计的时候,CPU
中地址总线
的宽度就已经决定了:
Intel
公司早期的CPU
,例如8086
、8088
的地址总线
的宽度是20
位,即CPU
的寻址能力为$2^{20}字节=1024\times1024字节=1024K字节=1M字节$Intel 80286 CPU
的地址总线
的宽度为24
位,所以80286 CPU
的寻址能力为$2^{24}字节=2^{20}\times2^4字节=16\times1M字节=16M字节$Intel 80386
及80386
以上的CPU
的地址总线
的宽度为32位,CPU
的寻址能力为$2^{32}字节=2^{24}字节\times2^{8}=16M字节\times256=4G字节$
也就是说,我们通常理解的是内存越大,机器性能就越好,但是如果机器的CPU
过早,总线宽度优先,无法访问所有的存储单元
,那么即使有很大的内存也不能得到利用。
所以,限制CPU
寻址能力的首先因素是CPU
内地址总线
的宽度,然后才是内存大小。对于现在的CPU
,地址总线
的宽度是64
位的,能够访问到$2^{64}字节=2097152T字节$,这样的寻址能力
已远远超过目前的内存容量,所以现在的问题主要就是内存做不大,而不是地址总线位数不够。
C. 寻址空间
我们上面介绍了CPU
的寻址能力
,到最后我们介绍了现在的CPU
的地址总线
基本都是64位的了,那么就存在一个问题,地址总线上所能够描述的存储单元
,已经比真实地的物理的储存单元
要多了。
因此,我们将CPU
的地址总线
上能够描述的所有存储单元
称为寻址空间
,而寻址空间
中只有一部分对应到了真实地物理内存中,访问这些地址,将会直接访问真实物理内存。
因此,CPU
直接访问的实际上是寻址空间
,而非真实的物理地址,由地址总线
上的决定何时将寻址空间映射为物理地址
3. CPU控制物理设备、内存映射IO、内存布局
A. CPU控制物理设备
首先,我们需要扫清一个误区,就是存储单元
的范围。我们可能直接认为存储单元
指的就是内存中的一个个存储单元
。可是,内存中的一个个单元的名字是内存单元
,而内存单元
只是存储单元
的一种。
事实上,存储单元
不仅仅包括内存单元
,在其他的物理设备上也都存在有存储单元
,例如显卡、键盘、鼠标,以及ROM
等等。因为这些物理设备也都是要或多或少存储一些数据的,例如:
- 键盘:在我们按下键之后要过大概10毫秒操作系统才会读取到我们按下的键,那么在这之前就是键盘中的
存储单元
保存着我们按下的键,而后操作系统再去读取键盘的存储单元
,从而知道我们按下了那个键。 - 鼠标:和键盘同理,只不过存储的不是按下的键,而是鼠标在水平和竖直方向上的位移数据。
- 屏幕(显卡):屏幕实际上是显存映像。如果显卡工作在
图像模式
,那么我们把要显示的图片写入到显卡的存储单元
(一般称为显存
),而后显卡就会在屏幕上绘制出来图像。如果显卡工作在文本模式
,那么我们把要输出的字符写入到显卡的存储单元
,而后显卡就会在屏幕上输出要显示的字符
所以,任何设备都是有存储单元
的,而CPU
想要去使用其他设备,本质上都是去读写设备的存储单元。
B. 内存映射IO
我们上面讲到,CPU
直接访问的对象实际上是寻址空间
,而非物理内存。并且寻址空间
中只有一部分映射到了物理内存中,那么我们就会有一个问题,寻址空间
中剩下来的那部分空间怎么办?寻址空间
只是一个概念,真正的数据还是储存在物理硬件上的,因此剩下的寻址空间
由于没有对应的储存单元,因此没有办法用于储存数据。那这部分剩余的寻址空间
怎么办?
我们上面讲到,CPU
控制物理设备本质上是通过读写物理设备上的存储器实现的,例如我们要读写硬盘,就把读取指令
/写入指令
写入硬盘的存储单元
中,然后再把要读取的文件写入到硬盘的另外一个存储单元
中,然后当硬盘完成读取后,会在把文件的内容存入到硬盘专门存放文件的存储单元
中,而后CPU
读取硬盘存放文件的存储单元
就可以读取到文件的内容。
所以,还有一个问题就是,CPU
如何访问这些非内存的存储单元
呢?
我们前面说给物理内存
会映射到寻址空间
,那么其实我们也可以把一部分寻址空间用于映射物理设备上的存储单元
。因为物理设备上的存储单元
和内存中的存储单元
是一样的,都支持读取或者写入。因此,对于CPU
来说,这个时候想要访问设备,那么只需要读取或者写入映射到物理设备上存储单元
的这部分寻址空间
即可。
所以对于CPU
来说,此时访问物理设备就和读写内存一样了。而这种操纵物理设备的方式,称为内存映射IO
。之所以称为IO
,因为物理设备一般都是输入(Input
)或者输出(Output
)设备,例如屏幕是输出设备,鼠标和键盘都是输入设备,而硬盘既是输入设备也是输出设备。
内存实际上也是物理设备中的一种,因此,把内存映射到寻址空间实际上也是内存映射IO
的一种
此外,ROM
也是内存的一种,因此也可以通过内存映射IO的方式去访问。