计算机硬件基础

计算机发展史

  从古至今,如何精确的进行计算一直是人们关注的重点。从中国古代最早的结绳记事再到后来的祖冲之使用算筹推算出圆周率等等事迹可以看出,人们在对于追求数据的长期存储与精确计算这条路上一直在不懈努力着,而推动科学发展最快的因素之一就是战争。

  所以,在二战时期,美国陆军军械部在马里兰州的阿伯丁设立了"弹道研究实验室"用于研制和开发新型的大炮和导弹,很快的世界上第一台"通用计算机"埃尼阿克(ENIAC - Electronic Numerical Integrator And Computer)于1946年2月14日诞生了

  在此前很长一段时间中,教材上依旧写着世界上第一台计算机是ENIAC,但是这其实是错误的。我们来看百度百科给出的说法:

img

  ENIAC是一个庞然大物。它长30.48米,宽6米,高2.4米,采用了17468根电子管,但是庞大的体型也带来了高性能的收益,它的计算速度能够进行每秒5000次加法运算或者400次乘法运算,这是手工计算的20万倍,比当时已有的计算机装置快1000多倍,从此。一个新时代来临了

ENIAC一角展示

img

  在ENIAC诞生后到1958年之间,这是被称为第一代计算机的时代。而第一代计算机的缺点十分的显而易见,体积庞大,运算速度缓慢,内存容量较小,并且是使用机器语言和汇编语言编写程序,这很令人头疼和麻烦,所以随着时间的推移,这些大家伙们终究是要被时代淘汰的。因此第一代计算机是属于电子管计算机时代(1946-1958)

  第二代计算机是采用晶体管制造的,时间约为1958-1964年。并且软件方面已是使用了"面向过程"的程序设计语言,相比于第一代计算机,第二代计算机的体积更小,计算能力更强。就比如于1967年诞生的中国第一台晶体管计算机,它的运算速度约为每秒5万次!

  那么二代计算机为何就比一代计算机强这么多呢?其实归根结底还是因为使用的元件不同。晶体管不仅能够实现电子管的所有功能并且晶体管在尺寸,重量,寿命,效率,发热,功耗上面都是电子管所无法比拟的。

  第二代计算机的主存储器此时已经是开始采用磁芯(内存),而外存储器开始使用磁盘并且整个软件环境也一片大好,出现了各种各样的高级语言以及编译程序,此外还出现了以批处理为主的操作系统,并且第二代计算机开始应用于工业控制。

第二代计算机

img

  第三代计算机的时间为1964-1970年,并且其元件已是采用了中小规模的集成电路了。主存器采用半导体存储器,运算速度可达到每秒几十几百万次的基本运算,并且出现了真正意义上的操作系统。

  第三代计算机相比于第二代计算机的提升最主要还得归功于德州仪器工程师 Jack Kilby。这个人发明了集成电路,而集成电路相较于晶体管简直是一个天上一个地下,并且此时的计算机在程序的控制协调下已经能同时运行很多不同的任务了。

第三代计算机

img

  第四代计算机是从1970年到如今,随着集成电路的不断发展。渐渐涌现了大规模的集成电路和超大规模的集成电路,让计算机的性能越来越强,体积越来越小,功耗越来越低,在第四代计算机之前所有的计算机都是以存储器为中心,而1971年的时候intel公司发布了世界上第一款微型处理器4004,至此计算机开始将硬件中心点转为CPU,而后的1978年里intel再次发布出一颗划时代的CPU,型号为8086,暂时先不论,这个在后面会详细介绍。

8086CPU核心

img

  未来的计算机发展势必是向微型化,智能化的方向发展,随着科技的进步我们相信那一天是会迟早来到我们身边的,至此计算机发展史简单介绍完毕。

计算机五大元件

  上面说过,在四代计算机之前。所有的计算机都是依存储器为整个硬件核心,而四代计算机开始后则由CPU担任整个硬件的核心,那么计算机内部到底最主要的部件有那些呢?不要着急,我们慢慢向下看。

  继续回到ENIAC的话题上,其实ENIAC是没有存储单元的。它是用布线接板对机器进行控制的(类似于现在的鼠标键盘),所以操作十分繁琐。ENIAC研究组中的一个天才感觉到了这些缺点,他的名字叫做 冯·诺依曼。(请记住这个人,因为他被称之为:计算机之父

  所以,冯·诺依曼还在EDVAC方案中(ENIAC的改进版计算机)提出了计算机核心的五大元件的概念和他们各自的职责以及相互之间的关系,五大元件分别是:

  1. 运算器

  2. 控制器

  3. 存储器

  4. 输入设备

  5. 输出设备

  并且在EDVAC方案中冯·诺依曼还提出:新的EDVAC机应采用二进制(ENIAC未采用二进制),不光数据采用二进制。连指令都应该采用二进制

  此后,在1946年7,8月的时间中,冯·诺依曼为普林斯顿大学高级研究所开始研究具有"存储程序"的计算机(IAS计算机),而后,存储器一直被当做计算机的中心点。它的工作方式为:

任何要计算机完成的工作都要先被编写成程序,然后将程序和原始数据送入主存(内存)并启动执行。一旦程序被启动,计算机应能在不需操作人员干预的情况下,自动完成逐条取出指令和执行指令的操作。

  具有这种结构的计算机,被称为冯诺依曼机。很明显,ENIAC并不属于真正意义上的冯诺依曼机,但是现在的所有计算机却都是属于冯诺依曼机的范畴。

  我们接下来看一张图,以便能够更好的理解冯诺依曼机的结构:

冯诺依曼结构图

img

  冯·诺依曼结构的主要思想:

  • 计算机应由运算器、控制器、存储器、输入设备和输出设备 五个基本部件组成。  

  • 各基本部件的功能是:内部以二进制表示指令和数据。每条指令由操作码和地址码 两部分组成。操作码指出操作类型,地址码指出操作数的地址。由一串指令组成程序。

  • 存储器不仅能存放数据,而且也能存放指令,形式上两者没有区别,但计算机应能区分数据还是指令;

  • 控制器应能自动取出指令来执行;

  • 运算器应能进行加/减/乘/除四种基本算术运算,并且也能进行一些逻辑运算和附加运算;

  • 操作人员可以通过输入设备、输出设备和主机进行通信。

  • 采用“存储程序”工作方式。

  至此,计算机五大元件简单介绍完毕。如想更深层次了解这些,我会在博客下方放入文献参考。

进制之间的转换

  上面简单介绍了一下冯诺依曼在EDVAC方案中的核心思想,其中有一点便是EDVAC机应采用二进制,那么什么是二进制?与我们学过的十进制又有什么区别呢?

  二进制说白了很简单,就只有0和1这两个数字,十进制是逢十进一,那么二进制就是逢二进一。这里有个疑问点,计算机为何要采用二进制而不采用十进制呢?

  二进制不难看出它只有2个状态,而我们的计算机又是通过电来工作。电有一个特性就是高电平和低电平,这2个电平刚好可以对应0和1这两个数字。这也是最直接简便的方法,所以计算机内部的所有数据均采用二进制来记录。(数据本身不具有意义,必须分配相应的规则,具有规则的数据才会被人读出意义)

  除了二进制之外,还有八进制(0-8)与十六进制(0-9和A-F,英文不区分大小写)。这里也统一的列一下,通常它们的区分方式为:

进制与符号表示
进制表示符号
二进制 0b
八进制 0o
十六进制 0x

  那么接下来介绍它们的转换方式:

  二进制转换十进制按照位权进行转换,位权(从右往左数第几位数然后-1次方),示例如下:

转换数字计算方法最终结果
0b 10 1*2(2-1次方)+0*2(1-1次方) 3 - 1 = 2
0b 10101 1*2(5-1次方)+1*2(3-1次方)+1*2(1-1次方) 16 + 4 + 1 = 21

  十进制转换二进制按照除2取余法,然后从右往左将余数组合,示例如下:

转换数字计算方法最终结果
173 173 / 2 = 86(1) 86 / 2 = 43(0) 43 / 2 = 21(1) 21 / 2 = 10(1) 10 / 2 = 5(0) 5 / 2 = 2(1) 2 / 2 = 1(0) 2 / 1 = (1) 从右往左反向取余:0b 10101101
13 13 / 2 = 6(1) 6 / 2 = 3(0) 3 / 2 = 1(1) 1 / 2 = 0 (1) 从右往左反向取余:0b 1101

   八进制转换十进制按照位权进行转换,位权(从右往左数第几位数然后-1次方),示例如下:

转换数字计算方法最终结果
0o 10 1*8(2-1次方)+0*8(1-1次方) 8 + 0 = 8
0o 10101 1*8(5-1次方)+1*8(3-1次方)+1*8(1-1次方) 4096 + 64 + 8 = 4168

   二进制转八进制采用三位一组进行计算,示例如下:

转换数字计算方法最终结果
0b 11 101 010. 010 110 110 三位一组 0o 352 . 266

  注意:从右往左将二进制数分成三位一组进行除二取余运算,转换后的数字对应八进制的一位数。

   十六进制转二进制采用四位一分:

转换数字计算方法最终结果
0x 4AF8B 四位一分 0b 0100 1010 1111 1000 1011

  注意:这样来算,从右往左推,B对应11,除二取余得出1011以此类推。

  二进制转十六进制采用四位一合:

转换数字计算方法最终结果
0b 0001 1101 0110 四位一分 0x 1d6

计算机内部实现四则运算基本原理

  我们现在已经知道了为何冯·诺依曼在EDVAC方案中提出计算机为何要采用二进制存储数据以及指令,并且还学会了进制之间的互相转换。那么计算机内部对二进制数是如何划分相应的规定,并对它们进行四则运算呢?

  这里引入新的概念,机器数与真值

  首要规则:计算机中二进制数被划分为8位为一组。(1位代表一个0或者1)

  机器数(计算机存储的二进制数。8个0或者1):

  一个数在计算机中的二进制表示形式,叫做这个数的机器数。机器数是带符号的,在计算机用个数的最高位存放符号,正数为0,负数为1。

  比如十进制中的 +3 转换为二进制就是用的八位来存 00000011 而十进制中的 -3 转换为二进制就应该是 10000011 。所以,这里00000011 与 10000011 就是机器数了。

  

  真值(用来表示真正的值):

  因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数10000011,最高位1代表的是负。真正的数值是 -3 而不是形势值 131(0b 10000011的十进制直接转换)。所以为了区别起见,将带符号位的机器数对应的真正数值称为计算机的真值(即剩下的后7位)。

  因为人脑可以知道第一位是符号位,在计算的时候我们会根据符号位,选择对真值区域的加减。但是对于计算机,加减乘除已经是最基础的运算,要设计的尽量简单,计算机辨别 "符号位" 显然会让计算机的基础电路设计的十分复杂。于是人们想到了将符号位也参与运算的方法,我们知道根据运算法则减去一个正数等于加上一个负数。

即:(1-1 = +1+-1)

  所以机器可以设计成只有加法而没有减法,这样计算机运算的设计就更加简单了。

  于是人们将符号位参与运算,并且只保留加法,这样做简化了计算机的运算,但还是不够。所以除此之外还发明了原码,反码还有补码。他们都是有符号的用二进制表示数的方法,均由符号位(第1位)和数值位(后7位)构成。请注意,此时只是一种方案思想,还没有进行真正的往计算机内部执行。计算机内部真正执行还是靠的原码,反码,补码。

  原码(符号位+真值,区分正负数)

  原码是符号位加上真值的绝对值,即用第一位表示符号,其余表示值。比如如果是8位二进制。

[+1]原码的表现形式为:0000 0001

[-1]原码的表现形式为:1000 0001

  第一位是符号位,剩下七位都是数值位。因为第一位是符号位,所以 8 位二进制数的取值范围就是 [1111 1111 , 0111 1111](不算第一位)

     即:[-127 , 127 ]

  原码是人脑最容易理解和计算的表示方式。

  

  反码(原码基础上做的一次操作,以便进行二进制运算)

  反码的表示方式是:

    正数的反码是原码其本身。

    负数的反码是在其原码的基础上,符号位不变。其余各个位取反。

[+1] = [ 00000001 ]原码 = [ 00000001 ]反码

[-1] = [ 10000001 ]原码 = [ 11111110 ]反码

  如果一个值是负数,反码表示方式是人脑无法直观看出其数值的,通常要转换成原码计算。

  

  补码(对负数再做一次操作,用于达到能够有加减的目的。巧夺天工的设计,也是计算机内部真正存放的数字)

  补码的表示方式是:

    正数的补码就是其本身。

    负数的补码是在其原码的基础上,符号位不变,其余各取反,最后+1。( 即在原码基础上+1 )

[+1] = [ 00000001 ]原码 = [ 00000001 ]反码 = [ 00000001 ]补码

[-1] = [ 10000001 ]原码 = [ 11111110 ]反码 = [ 11111111 ]补码

  对于负数,补码表示方式也是人脑无法直观看出其数值的,通常也需要转换成原码再计算其数值。在计算机系统中,数值一律用补码来表示(存储)。主要原因是使用补码,可以将符号位和其他位统一处理。同时减法也可以按加法处理,另外,两个用补码表示的数值相加的时候,如果最高的符号位有九位,则第九位会被舍弃。补码和原码的转换过程基本相同的。比如 1 - 1 可以理解为 + 1 + - 1 通过二进制补码转换就是:

00000001 表示 +1

00000001 表示 +1

11111111 表示 -1

200000000 从右往左数舍弃第9位

  二进制 -1 加上一个 二进制 +1 第九位变成2并舍弃 其余位全部变成0; 00000000 1 - 1 = +1 + -1 = 0

计算机系统构成

  对于计算机系统构成大体可分为2部分,分别为硬件系统和软件系统

  冯·诺依曼提出的五大元件全部属于硬件系统,可以做个很形象的比喻。计算机的硬件系统就像人类的身躯,而计算机的软件系统就像人类的灵魂。

  硬件系统这一方面想必前面介绍了这么多应该是比较熟悉了,那么接下来详细介绍软件系统。

  软件系统可分为:

  1. 系统软件(操作系统)

  2. 应用软件

  在计算机发展史中可以看见,早期的计算机是没有操作系统的。直到第二代计算机的时候出现了批操作系统,但是批操作系统并不是真正意义上的操作系统。这个先不急后面会讲到,我们先来看看为什么要有操作系统这个东西。

  如果没有操作系统那么开发人员想开发一款拍照软件,他得研究关于计算机上摄像头的组成原理,得了解整个系统的指令分发,得自己写一个让五大元件协同工作的程序,那么在这些都完成后才能开始开发一款拍照软件,无疑这是绝对不可能完成的事情。(想起来以前贴吧上有个梗挺火的,家里电脑坏了请了个高手修电脑,单纯用电话机敲2进制敲出了windows操作系统,这种情况只存在于段子,可以肯定的说目前世界上没有人能做到。)

  那么另一个程序员想开发一款聊天软件,他也要先去研究关于计算机上网卡收发数据的原理,也要自己写一个程序让五大元件协同工作,这不就是白费工作了吗?所以在这个时候有一些公司站出来了说道:"各位大佬你们安心开发你们的程序,关于底层这一块我们公司来给你们大家做!"

  因为都是重复的功能,大家都会需要五大元件协同工作。所以这些代码完全可以整合出来,那么这些跟底层硬件打交道的代码整合体就被称为操作系统。

   操作系统 --> 操纵硬件,操作系统是基于硬件工作的,并且职责为应用软件提供服务。

  好了,现在有了操作系统了,大家都能够开心的在操作系统的层面上来安安心心的做自己想做的事。想用相机这个硬件?没问题,操作系统给你提供接口,你只需要按照规定合理使用接口即可,不必关心操作系统内部是怎么做到让硬件听话的。想调用网卡让网卡工作?没问题,操作系统为你提供接口,放心用吧!

   应用软件 --> 基于操作系统,用于完成特定的功能,为人类用户提供服务。

CPU分类与指令集

  五大元件中,CPU就是控制器和运算器。如果将电脑比作人,CPU比作人的大脑。那么CPU指令集就相当于这个人诞生时就拥有的一些意识,各式各样的应用程序的最终目标都是为了操纵计算机的硬件为我们做事。但是如何具体操纵计算机硬件却是由CPU来控制的,这一点可以这么理解。小A让小B去跑腿买东西,小B买完了就回来了。同理,程序员A让电脑打开摄像头拍张照,那么这个指令一定会被CPU所接收,其中,CPU如何令摄像头打开就属于指令集的工作了。

  每一块CPU在诞生时都会被嵌入一段指令集,用于操纵其他硬件。就如同你的母亲大人把你生下来后你自带的就能通过脑子控制自个儿的嘴巴吃饭和控制自个儿的小手打人一样

  关于CPU分类:CPU分类如果按照指令集来分的话可分为复杂指令集和简单指令集2种。对于稳定的系统如大型服务器,银行等服务器基本都是采用简单指令集,而个人PC更多采用的是复杂指令集。

  它们的区别在于简单指令集的指令集精简,每个指令的运行时间都很短,完成的动作也很单纯,指令的执行效能较佳;但是若要做复杂的事情,就要由多个指令来完成。复杂指令集的每个小指令可以执行一些较低阶的硬件操作,指令数目多而且复杂,每条指令的长度并不相同。因为指令执行较为复杂所以每条指令花费的时间较长,但每条指令可以处理的工作较为丰富。

指令集图示

img

  一句话总结:所有对底层硬件的操作必须通过CPU的指令集进行控制

X86_64是什么意思

  在我们下载软件的时候有时候可能碰到什么32位的软件或者64位的软件。这是什么意思呢?且听我慢慢道来。先看一下这张图,再回忆下之前提到的intel发布的8086处理器。

示例

img

  基于X64的处理器,其实完整的话语应该是基于X86架构的64位处理器,当我们点击任何应用程序执行任何操作实际上都是通过CPU在向底层的其他硬件发号施令。而CPU向其他硬件发号施令的方式就是通过指令集,指令集本身就是一组组的二进制数组成

  我们编写的应用程序是存在于硬盘上的,当双击打开它运行时会将该应用程序加载至内存中(速度快),而CPU则需要将该应用程序存在于内存中的二进制指令源源不断的取出来并交由底层硬件去实现。这一读取的过程有一个性能上的差异,目前大多数CPU都是一次性能够读取64位二进制指令的。而32位则代表最大只能从内存中一次性读取32位二进制指令。(注意:64位CPU能够支持32位应用程序运行,代表向下兼容性)

  关于X86其实是CPU架构的一种统称,并且目前的CPU基本都是采用的X86架构,因为最早intel的CPU代号为8086,并且在这颗8086的基础上又开发出了80285,80386等等等等CPU,因此这种架构的CPU就统称为X86架构了。并且由于现在大多数的CPU都是64位与X86架构,所以X86_64即可简称为X64。

指令流程图

img

寄存器与CPU工作状态

  实存储设备除了内存,硬盘外还有个叫寄存器的东西。它是与CPU一体的,其目的就是为了能够更加快速的(比内存还快许多倍,几乎与CPU同步)向CPU提供重要信息。因此它的容量也是非常的小只有寥寥数位而已... 但是它的作用却不容忽视。

  我们以为内存很快,其实如果没有寄存器的存在而让CPU的所有数据都单纯的在内存中去取那么这种速度是非常慢的,所以在此产生了寄存器。

寄存器

img

  指令计数器

  它保存了将要取出的下一条指令的内存地址。在指令取出后,该计数器便会更新以方便执行后期的指令(继续存下一条指令内存地址)

  指令寄存器

  将从内存中拿到的指令存放在指令寄存器中方便CPU随时直接通过寄存器取出指令(存指令的地儿)

  运算单元 / 存储单元

  运算单元是拿到指令寄存器中的指令并且解决该条指令是想控制哪一个底层硬件,或者说硬件拿到的数据该如何处理并返回交由那个应用程序。存储单元则是为了临时的存储数据以便后面放入内存中(当然临时存储的数据也有可能返回给运算单元)

  数据段

  指代码段在运行中产生的新的数据

用户态与内核态

  用户态和内核态是CPU的2种工作状态,内核态下运行的必然是操作系统相关的代码。它允许直接操作硬件,而用户态下运行的必然是应用程序相关的代码。用户态下不可以直接操纵底层硬件而必须通过操作系统调用才能间接的使用底层硬件,而应用程序的运行必然是要操纵底层硬件的,所以就必须让CPU不断的做2种状态的切换才行。

  那么如何区分用户态和内核态呢?这里要说到上面寄存器的概念,有一个psw寄存器。详细关于用户态与内核态的知识会在并发编程中讲到,到时候会详细介绍该知识点。

  现在只需要理解这幅图即可:

内核态与用户态

img

  主要知识点:应用软件只能通过操作系统来调用硬件资源,CPU具有内核态和用户态的2种工作模式

多线程与多核芯片介绍

  当我们查看CPU信息时常常会看到XX核XX线程这样的数据。那么核心和线程是什么意思呢?其实这也是因为早期CPU制作工艺不成熟导致性能不足,而慢慢的随着科技的发展CPU的制作工艺越来越强大,此时为了提高CPU的性能有了以下方面的增强:

  1.在CPU芯片中放入更大的缓存(缓存的概念下面一节会提到)

  2.在CPU中增多处理逻辑,并且由intel公司提出。称之为多线程或者超线程技术,对于用户来讲一个有2个线程的CPU(物理是1个)就相当于是有2个虚拟CPU。(多线程运行可以让CPU保持2个不同的线程状态,可以在纳秒级的时间内进行切换,但是多线程并不提供真正的并行处理,一个CPU同一时刻只能处理一个进程)

  3.增加多个CPU芯片,即是CPU核心数

  2核心 4线程(1个物理CPU看做2个虚拟CPU) = 伪 4核CPU

  4核心 8线程(1个物理CPU看做2个虚拟CPU,8除以4等于2,所以看做2个) = 伪 8核CPU

  另外再简单介绍一下目前生产CPU的厂商有2家:intel,AMD,它们2家厂商在多线程的处理上就有截然不同的做法。

img

img

存储器介绍

  存储器是计算机组成元件中非常重要的部分,而且存储器的速度快慢往往是决定计算机速度快慢的根本。因为CPU的处理速度是非常快的,如果存储器的性能更不上会导致CPU长时间处于等待状态,所以运行时间慢是因为这些时间都浪费在了数据传输上。

  下图来了解一下存储器的速度与容量大小吧。

存储器相关图示

img

  寄存器

  寄存器存在于CPU之上,也被称为L1缓存。它的速度与CPU的速度保持一致。用于存放非常重要的一些数据,比如即将执行的指令,当前CPU工作状态(内核态,用户态)等等。

  高速缓存

  高速缓存也称为L2缓存,它常常存放一些CPU经常要用到的数据(在CPU上面)。当有的数据可能会被CPU经常用到的时候变将这些数据存储在L2缓存之中,这也节省了CPU再重新到内存里面读取信息的步骤(内存的访问速度比高速缓存的访问速度要慢)。当CPU需要用到数据时会先检查高速缓存中是否存在该数据,如果是则表示高速缓存命中,直接用就好。如果不存在就表示高速缓存未命中,还需要通过总线到内存中去取一遍数据。(Linux磁盘管理中会详解这一块)

  内存

  内存也被称为主存,它的容量也在不断的提升,当数据不存于L2缓存时便会到内存中来取数据,但是它的数据是易失性的。也就是说当断电后数据全部都不存在了,所以它的英文简写是RAM。(随机存储器

  硬盘

  ROM为(只读存储器),它的速度同RAM一样。但是只能读不能写,并且断电后数据依旧保留,计算机ROM中的数据常常在出厂前就被编程完毕然后再也不能被修改,那么计算机启动的引导加载模块存放在ROM之中是十分明智的选择。

  EEPROM(闪存),它是非易失性的,速度介于磁盘与RAM之间。常常被应用于固态硬盘,但与磁盘不同。闪存擦除的次数如果过多,就会被磨损。

  CMOS芯片

  CMOS(BIOS)芯片,很多计算机利用CMOS存储器来保持当前时间和日期的数据,并且还保存BIOS程序中的设置项(启动顺序等等)。它有一小块电池支持并被该电池长期供电,当断电后该芯片中存储的数据将会丢失。

磁盘与虚拟内存以及磁带介绍

  磁盘即我们所说的硬盘,它是属于外存储设备。硬盘包括但不限于磁盘,还有EEPROM也就是基于电工作的固态硬盘(SSD),固态硬盘由于是具有损耗性的特征所以一般不用于大型服务器部署中,当然它的价格也是十分昂贵的。

  所以在这里我们着重介绍一下磁盘,首先最重要的一个概念,磁盘是基于磁信号的方式工作相比于使用电信号的SSD来说它的数据存取是较慢的。我们先来看一下磁盘的大体样式图解:

真实的机械磁盘

img

  接下来再看一张图,以便能够好理解磁盘的工作原理

磁盘结构图解

img

  这里我们看到的这个磁头就是机械臂的前端,磁盘在工作时机械臂会伸出来沿着磁道读取上面的磁信号,磁信号对应二进制数,这样就能存储到信息了。

  值得注意的一点是一张盘片的正反面都是具有磁道的,也就是说一张盘片的双面都能存取数据。

  而扇区这个概念是对于磁盘本身来说操作系统要向磁盘写入数据时一次性要求被最小写入的数据量(512Bytes),所以一个扇区的大小就是512Bytes。那么说到了这里就不得不提一下关于存储容量之间的关系,磁盘存储的全是二进制数,按理说应该按bit(二进制单位)来进行标识,为何生活中不是这样表示的呢

原来是因为使用bit进行标识是极为不方便的,所以一般采用GB进行标识。关于他们之间的转换关系如下:

  1 bit = 1 位 (一个0或者一个1,注意是小写b)

   8 bit = 1 Bytes (注意是大写B,Bytes --> 字节) 

  1024 Bytes = 1 KBytes (简称 1KB)

  1024 KBytes = 1 MBytes (简称 1MB) 

  1024 Mbytes = 1 GBytes (简称 1GB) 

  1024 GBytes = 1 TBytes (简称 1TB)

  这里需要注意 1MB 与 1Mb 的区别,前者是容量单位,后者是带宽单位不可混淆。这里有人可能会发现新买的硬盘是512GB结果到手后发现没有真正的512GB是什么原因呢?这是属于正常现象,原因是硬盘厂商在对硬盘容量标识时不是采用1024为进制单位而是采用1000,所以会造成认知上的差异。

  好了,我们继续回到扇区的概念上来,刚刚细心的朋友可能会发现扇区这个单位是对于硬盘来讲操作系统一次性最小写入的数据量单位(512Bytes),那么对于操作系统来说它其实不是按照扇区来发送数据给硬盘的而是按照block块(虚拟概念,Windows中也被称为簇),一个block块默认相当于8个扇区也就是4096个字节,当操作系统准备向磁盘写入数据时会攒够一个block块的大小后再将整个block块的数据打包发送给磁盘,磁盘再将block块的数据拆分为8个扇区的数据后进行写入。

  补充:4096被称为4K对齐,当对磁盘采用格式化的时候Windows会默认指定block块大小为4096Bytes,block块越大代表浪费的存储空间越多但是读写性能会越高。操作系统向硬盘写入数据是需要让内存来做的,因为操作系统的数据全部存在与内存中,而内存速度又比磁盘快太多,所以频繁的对硬盘进行操作会让整个系统运行速度变得更慢,当磁盘空间足够大的时候分区时应该采取较大的block块来提升性能,一句话总结,减少与硬盘打交道的次数

block块与buffer缓存区

img

  接下来讲解关于柱面的概念,首先一块磁盘肯定不止一张盘片,而是很多张盘片,上下一串盘片中,相同半径的磁道所组成的一个圆柱型的环壁,就称为柱面。从这意义上说,柱面,其实是个“虚”的东西!它是分开的。物理上不是一体的。只是在空间上,它类似于一个桶的桶壁一样。

  解密磁盘慢的真正原因

  好了,在上面我们已经大致的了解到了磁盘的工作方式。当磁盘运行时中心轴会开始带动盘片转动并且机械手臂也会开始运动,我们说过磁盘的数据是存在于磁道上,那么如何的取出具体的数据就完全是看运气了。

  这里有一个非常至关重要的因素就是磁盘转速(常见有7200转/分钟与5400转/分钟),当磁盘开始工作时机械手臂会在一个范围内不停的做机械运动而盘片也在不停地旋转。我们看一下下面这张图就大概能理解

IO延迟图解

img

  关于第1条:机械手臂转到数据所在磁道上花费的时间叫做平均寻道时间,受限于物理工艺水平目前大约能达到5毫秒左右,这个没办法让用户做任何选择。

  关于第2条:机械手臂磁头到了蓝色磁道上,但是没在红色磁道范围,这个值我们可以求一个平均值,按照7200转磁盘的速度来算这个平均值应该是4ms,即转半圈的速度(半圈很大概率到达红色磁道),这个时间叫做平均延迟时间。

  第1条和第2条花费的时间有一个非常重要的名称,叫做IO延迟。即IO延迟 = 平均寻道时间 + 平均延迟时间

  那么这就是磁盘速度真正慢的原因,都花在了找数据上面。故对开发人员而言,程序尽量减少与磁盘打交道的机会就是直观的提升执行效率!

  虚拟内存

  虚拟内存这个东西其实说白了就是当物理内存不够用的时候,系统会将硬盘的一部分化作一块假的内存空间,故被称为虚拟内存,它能够保证程序的正常运行,但是程序的运行速度也会被硬盘的速度拖慢了。系统会将当前运行程序的一部分不重要的数据放入虚拟内存中,并且交由CPU中的一个部件负责,称为存储器管理单元即MMU

  磁带

  磁带价格低廉,且易于携带,因此常常被作为备份数据的存储介质。在某些突发情况下磁带的便携性以及其便于拆卸的特点都保障了该种存储介质在很长一段时间内都不至于被淘汰。所以它作为备份的存储介质是十分明智的选择,并且这常常体现在大型数据库系统中。

I/O设备简介

  I/O设备其实就是输入/输出设备(input/output),我们的鼠标键盘是属于输入设备,显示器音箱等等则属于输出设备。它有一个明确的划分标准:

  输入设备

  输入设备的任务是把人们编好的程序和原始数据送到计算机中去,并且将他们转换成计算机内存所能识别和接受的信息方式。按输入信息的形态可分为字符(包括汉字)输入、图形输入、图像输入及语音输入等等。目前,常见的输入设备有:键盘、鼠标、扫描仪等。辅助存储器(磁盘、磁带)也可以看作输入设备。

  输出设备

  输出设备的任务是将计算机的处理结果以人或其他设备所能接受的形式送出计算机。目前最常用的输出设备是打印机和显示器。除此之外,I/O设备还包含另外两个部分:设备控制器和设备本身

  • 控制器:是查找主板上的一块芯片或一组芯片(硬盘,网卡,声卡等都需要插到一个口上,这个口连接的便是控制器),控制器负责控制连接的设备,它从操作系统接收命令,比如读硬盘数据,然后就对硬盘设备发起读的请求来读出内容。

  • 控制器的功能:通常情况下对设备的控制是非常复杂及具体的,控制器的任务就是为操作系统屏蔽这些复杂而具体的工作,提供给操作系统一个简单而清晰的接口。

  • 设备本身:有相对简单且标准的接口后,大家都可以为其编写驱动程序了。要想调用设备,必须根据该接口编写具体的程序,再由控制器提供设备驱动接口给操作系统。故必须把设备驱动程序安装到操作系统中。

BIOS简介

  BIOS是"Basic Input Output System"的缩写,它是一组固化到计算机内主板上ROM芯片中的程序,它保存着计算机最重要的基本输入输出程序、开机后自检程序和系统自启动程序,它可从CMOS芯片(也称BIOS芯片)中读写系统设置的具体信息。

  这里注意一下:BIOS程序代码存在于主板ROM芯片中,但是由于ROM芯片不能写入则将所有计算机的重要信息(如:时间,启动顺序)存在于CMOS芯片中,而COMS芯片需要由主板电池长期供电来保存这些重要的信息,一旦主板电池电量耗尽则意味着自定义的所有BIOS设定将会丢失恢复为原始状态。(代码放在一个地儿,不能被修改。存储的数据放在另一个地儿由电池供着电。)

  BIOS也可以认为是一个微型的系统,早期的BIOS是不支持鼠标操纵的但是近年来越来越多的BIOS开始支持鼠标操纵,这其实也是取决于电脑主板生产厂商的考虑,对于熟悉超频的DIY玩家来说BIOS绝对是他们的亲切伙伴,使用BIOS对CPU进行性能的压榨是DIY玩家们的乐趣所在,为此,网上还有一些关于刷BIOS的技术文章等等... 当然这些都是做一个了解,感兴趣的朋友可以自行搜索一下。

原始的BIOS看起来十分简陋

img

微星主板的BIOS

img

总线与主板

  总线(BUS)是计算机内部各个组件之间传递信息的公共干线,是由导线组成的传输线束。总共可分为三个大类,分别是:

  1. 数据总线

  2. 地址总线

  3. 控制总线

  对于内部设备(CPU,内存,硬盘等等)总线将它们相互链接,而对于外部设备(鼠标,键盘,打印机等等)则通过接口电路再与总线链接,可以这么说,计算机硬件系统的总线就如同人体身上的血管一样。

  在早期的计算机中都是通过单总线进行控制,但是随着处理器和存储器的速度越来越快,单总线的数据传输量已经满足不了需求了,故出现了多总线模式并且一直沿用至今。

总线图示

img

  主板是搭载所有计算机元件的核心,相当于人的肉体一样。而各大元件代表内脏,主板上可以装载电源,因为计算机是通过电力驱动的所以电源就对应人类的心脏。除此之外主板上还有两个芯片非常重要,一个叫北桥芯片(PCI),一个叫南桥芯片(ISA)。总线路过这两个芯片并且这两个芯片掌管不同的设备。

  一般来说,北桥芯片掌管的都是高速率传输设备,如显卡,CPU,内存等。而南桥芯片则掌管低速率传输设备,如硬盘,鼠标键盘等设备。

主板图示

img

操作系统安装原理与操作系统启动流程

  注意:以下内容均为 BIOS+MBR分区模式的启动流程。如果是 UEFI+GPT分区模式的启动流程则不适用于以下文字。

  在一台刚刚出厂后的计算机上并没有安装任何操作系统而只有BIOS系统,无论是通过光驱,U盘,移动硬盘等等为该机器装载操作系统实际上都是将一段代码程序放入这台计算机的硬盘中。我们来看一下它底层到底是怎么做的:

  1. 首先,新机器硬盘是空的。

  2. 开机,BIOS开始运行,检测硬件:CPU,内存,硬盘等。

  3. 进入BIOS之后设置启动项(假设U盘安装,设置U盘为第一启动项)

  4. 重启,重新经历步骤1,2后BIOS读取CMOS芯片中的配置,并将U盘作为启动项开始启动

  5. 读取U盘上第1个扇区的内容(MBR主引导记录共计512Bytes【一个扇区】,前446Bytes为引导信息,后64Bytes为分区信息,最后2Bytes为标志位)。

  6. 根据分区信息读入bootloader启动装载模块,运行U盘中的程序代码。

  7. 将装载于U盘中的微型操作系统(WinPE)载入于计算机内存中,此时BIOS移交硬件权限,BIOS工作已经完成。

  8. 安装真正的操作系统(如Win10),将真正需要安装的操作系统代码全部写入硬盘中

  9. 安装完成,重启计算机

  现在的这台机器已经存在了操作系统。我们再看一下启动该机器后会发生什么事情:

  1. 首先,该机器硬盘已经存有操作系统的代码

  2. 开机,BIOS开始运行,检测硬件:CPU,内存,硬盘等。

  3. BIOS读取CMOS芯片中的配置,找到第一启动项开始启动。

  4. 读取启动设备的第1个扇区内容(MBR)。

  5. 根据分区信息读入bootloader启动装载模块,启动操作系统。

  6. 操作系统与BIOS交接工作,获得配置信息,检查驱动是否正常,如全部正常则将它们调入内核,初始化相关表格(如进程表)等,执行操作系统登录程序代码。

  知乎:GPT+UEIF启动流程与MBR+BIOS启动流程对比

  附:应用软件启动流程

  应用软件的启动流程其实也十分的简单:

  当我们鼠标点击应用软件的exe快捷方式(软连接)的时候,操作系统会根据文件路径找到exe程序在硬盘的位置,并且将其加载至内存中,随后CPU会从内存中读取应用软件的代码。至此应用软件启动完成。

密码破解与安全相关

  现在,我们已经捋清了操作系统的安装流程与启动顺序。所以,当我们操作系统的密码忘记之后可以这么做:

  1. 操作系统本身就是一些代码程序,所以存储的密码也是一段二进制数据

  2. 用U盘制作一个WinPE微型操作系统

  3. 修改BIOS启动项为U盘启动

  4. 使用WinPE微型操作系统查看存有原操作系统密码的文件(存在于硬盘上)

  5. 删除其原操作系统存有密码文件中存储的密码(具体文件是哪个还得问度娘)

  这里看似差不多了,但是别忘了BIOS也能设置启动密码。对于一些BIOS设置了密码的机器我们根据BIOS的配置信息全部存在于CMOS芯片上这个原理可以选择将其机箱拆卸扣掉主板电池让其CMOS芯片上存储的BIOS配置信息全部擦除就好。(有些鸡肋)

posted @ 2020-04-25 13:13  云崖先生  阅读(2001)  评论(1编辑  收藏  举报