Skip to content

Latest commit

 

History

History
243 lines (120 loc) · 24.7 KB

1.1_20161226_计算机基础.md

File metadata and controls

243 lines (120 loc) · 24.7 KB

计算机基础和linux操作系统的历史

本节主要描述了冯·诺伊曼体系计算机的各组成部分,和简单的计算机原理以及linux操作系统的历史

简单理解计算机冯·诺依曼体系计算机

一台计算机由硬件和软件组成,根据冯·诺依曼体系架构,计算机由5部分组成,分别为运算器,控制器,存储器,输入和输出设备。

运算器用来运算,控制器负责程序执行控制和各硬件之间的协调,运算器和控制器合在一起称中央处理单元,就是我们常听到的CPU。存储器用来存储数据的。

问题空间和解空间以及编程

CPU执行运算要从存储器读取数据,运算后把结果存回存储器。那么CPU是怎么运算的?

CPU是通过指令进行运算的。

简单的讲就是CPU内部为实现计算功能而设计的电路逻辑,这些用于实现计算功能的电路逻辑被称为该CPU的指令集

很明显,不同的厂商设计的CPU或同厂商设计的不同型号的CPU计算功能一样但内部的电路逻辑不一定相同,所有他们使用的指令集就不相同。

要想让CPU执行计算,只能计算指令集支持的计算。

那么我们拿到一颗芯片,到底怎样才能让CPU进行我们想要的计算呢?

要解决的问题或需求叫问题空间,CPU能完成的所有操作叫做解空间

举个例子,我们想要计算2乘以3,CPU支持加法运算,我们知道乘法运算是可以转换成加法运算的,那么计算结果就可以通过转换运算出来了。

把问题空间的问题映射到解空间中所能够执行的指令集完成计算,这个过程实际上就是编程

一个程序能在两个不同型号或厂商上的CPU运行,这个程序就是跨平台的程序,一个程序在一个CPU上能运行,在另一个CPU上不能运行,修改了部分让它能执行,这个过程叫移植

芯片在生产完成之后,能够支持的操作叫做指令,支持操作的集合叫指令集,而这些指令集还支持一些内生的逻辑,这种编程机制叫做微码编程,利用指令集进行问题空间映射解空间过程叫做微码编程,也叫做汇编编程

编址的存储单元

运算器如何正确读取到在存储器中存储的数据?存储器通过对每一个存储单元进行编址让CPU可以正确的识别,地址表示也只能是二进制

CPU想要到一个固定的位置取数据,cpu就要知道到哪个地址去取数据,所有cpu需要一个地址总线来连接运算器和存储器

假如有地址总线中有4个针脚将运算器和存储器相连,最多可以表示2^4个不同的变化,也就是说cpu最多可以找16个存储单元,如果编址单元的变化超过了这16种,cpu就找不到地址了,4个针脚无法表示出来。如果有32根针脚相连,就是2^32也就是4亿多个存储单元,转换成存储空间就是4G,也就说明了为什么32位的CPU最大支持4G内存。

内存内部由RAMROM组成

内存控制器

假如cpu的针脚数和存储器的针脚数不一致,就需要通过内存控制器来进行连接,内存控制器还可以控制CPU中的程序对内存的操作,因为从内存中读操作和写操作的危险程度是不一样的,为了包含内存中的数据不被恶意修改,要引入内存保护,要内存控制器的参与

为什么还需要输入输出设备

内存是一种易失性的存储,取一次数据后必须马上充电才能保持原来的数据,存储单元存储的数据是0和1,内存判定数据是0还是1的时候 是看数据是否有电荷,有电荷代表1,没有代表0。但时间一长,2个电荷就会相互的吸收电荷,这时候就要刷新,刷新的时候,内存会把大于1/2的电荷冲满电成为数据1,没有的放电成为数据0,这样防止时间长了数据数据丢失。

因为是易失性的存储,所以就需要I/O设备来保存程序

基本的I/O有,鼠标,键盘,硬盘,显示器

轮询和中断

所有的设备都要和CPU相连,那CPU如何正确响应各个组件呢?

cpu实时监听每一个设备,叫做轮询(pull),这样非常浪费计算资源,那么cpu进行正常计算,有事件发生时打断cpu让他来处理叫做中断(interrupt)

I/O设备通过中断控制器连接到CPU,每个I/O设备在中断控制器上注册一个针脚使用,每个I/O设备和注册针脚相对相应,cpu通过中断控制器和每I/O设备进行交互。此时只是传输了中断信号,通知cpu有中断事件发生,并没有传输I/O所发送的具体数据

I/O设备向总线注册了I/O端口,cpu接到中断信号后在注册的I/O接收数据然后存到存储器

编程语言

低级语言运行速度快,但开发维护难度高,高级语言易于人类理解,需要翻译转换成计算机能理解的语言。

翻译有两种:一种是边翻译边执行叫做解释,一种是先解释后执行叫做编译

通常情况下编译型语言的执行速度快一点

批处理作业

早些时候计算机的处理速度是高于I/O设备的,计算机通过I/O设备输入输出执行一次作业(job),此时内存中只有一个程序在cpu执行,当执行完毕时,计算机再进行下一次的I/O和计算,这种情况下cpu很多时候是空闲的,后来出现了批处理作业,在磁带上按顺序放置多个作业,执行完作业一执行作业二,效率虽然提高但cpu利用率仍然很低

内核和多任务

因为批处理作业cpu利用率还是很低,所以人们想到在内存中同时运行多个程序,但每个程序的开发者在开发程序时并不会考虑其他内存的程序,两个程序都认为自己是内存中唯一的程序,所以需要一个监控程序来安排各个程序,并且必须由这个监控程序来管理分配程序和内存空间,应用程序由直接和硬件接触改为和监控程序接触。

监控程序向应用程序隐藏了底层的复杂度,同时还要将底层所具有的功能提供出来,是一个硬件的包装程序,负责直接管理硬件并负责在各个作业之间分配硬件资源(cpu时间片和内存段),应用程序也无法绕过监控程序操作硬件的,实际上这个监控程序就是操作系统

CPU指令级别和系统调用

程序最后还是要到cpu中运行,如何防止程序做了本不允许做的事情呢?

Intel的CPU将特权级别分为4个级别:RING0(特权环),RING1,RING2,RING3

CPU运行时只允许内核运行环0中的指令,程序只能运行环3中的普通指令,程序要使用一些必须的特权指令,就由内核提供的系统调用来实现

只有内核可以执行的操作会通过封装成接口的形式提供出来,这些接口就叫做系统调用

系统调用是一些低级的操作,离用户远,操作也不具体。把系统调用继续封装成更高级的,离用户更近更简单和具体的接口,二次封装的接口叫做

API和ABI

在64位cpu上使用C内核编译的C语言二进制文件能在32位cpu上使用C内核上运行么?

编程时调用的接口一样,但内部实现可能不同

API:应用编程接口

ABI:应用二进制接口

实际上在遵循美国国家标准委员会指定的ANSI的编译环境,在win上开发,在linux编译,在linux是可以运行的。而在win上开发和编译,在linux上是无法运行的。

编译之前使的是API,编译之后使用的是ABI

常见的cpu芯片

X86

X86-64

Power

PowerPc

Alpha

安腾(IA)

Ultrasparc

ARM

MIPS

M68k

人机交互接口:shell

并非操作系统启动后所有的程序都马上运行,需要时启动即可,所以有一个特殊的程序让用户来操作程序,叫shell

人机交互接口shell有两种,一种是图形用户界面,另外一种是命令行界面

GUI:Graphic User Interface

windows

IOS,Android

X-Windows(Gnome,KDE,Xfce)

CLI:Command Line Interface

PowerShell

bsh

csh

tcsh

ksh

bash

zsh

进程--程序的实例

运行一个程序时在主机上称为作业,但在多任务的操作系统中,程序不再称为是作业,而叫做进程(process)

进程是程序的实例,是程序的子集,进程有生命周期

程序在没有载入到内存时,并不使用cpu,只有程序被载入内存的时候才会分配内存和cpu,以我们熟悉的word为例,当打开word程序时,并不是word所有的功能都被启用了,而且我们也可以打开多个文档,所以进程是程序的实例,是程序的子集

在多任务的操作系统中,cpu被划分成时间片分配给多个进程,在特定的时间内只有一个进程在使用cpu,多个进程轮流使用cpu,这种进程的切换叫做上下文切换

在上下文切换时,被暂停的进程要保存现场,被运行的进程可能要恢复现场

进程的切换也要由内核来控制(进程切换过快,时间浪费在保存和恢复现场,进程切换慢,对用户体验不好)

共享库

程序在编译的过程中,在链接这一环节中,将所用到的库调用通过链接的方式载入内存,如果另外一个进程同样也需要相同的库调用,就不用重复调用,而直接使用内存中的库,这种库叫做共享库,在win中表现为dll,在linux表现为so。

如果直接编译的库,只能进程自己使用,是静态库

进程的元数据

内核为了管理和追踪进程,为进程建立了元数据,在内核内部建立一个查找表来追踪每一个进程的属性信息,在linux中称为任务结构

启动一个进程内核如何快速建立进程的任务结构?一般来说任何进程都是由父进程fork自身而来,这一过程由父进程申请,内核生成结构描述完成的

再谈跨平台

平台分为硬件平台和os平台,当用汇编语言在一个硬件平台上编译的二进制文件在另外一个不同的硬件平台上是不能运行的,当使用高级的标准C开发时,在两个硬件平台上分别编译同一个C文件时,就实现了跨平台,当然两个硬件平台都要支持C所需要的库

文件系统

文件系统是用来管理文件的,格式化这一操作就是建立文件系统,文件系统将硬盘分为元数据区和数据区,数据区分为多个数据块,一个数据块包含多个扇区,一个文件可能存在多个数据块。文件系统存在与内核中,也有用户空间的文件系统比如分布式。

文件系统还提供了权限控制

总结一下内核通常要包括的功能有:文件系统、网络协议栈、进程管理、加密/解密、驱动程序

shell环境

shell的环境是由shell的环境变量决定的,而环境变量可以保存在配置文件中。环境变量一般来讲只对当前进程有效,如果想持久生效,通常需要把它保存在系统进程能读取到的配置文件中

linux内核

当系统启动时,内核启动后,shell也是一个程序,要从init这个进程fork

linux内核有版本号,shell也有版本号

主流的linux的发行版有redhat,suse和debian,发行版也有版本号

linux的历史

在上世纪60年代,虽然此时第一台电子计算机问世不久(1946年2月14日在费城开始运行的ENIAC计算机),但是电子计算机的超强计算能力给当时社会所带来的影响却是十分广泛的。在那个年代,一台计算机的价格昂贵,并且体积庞大,在普通民众群体中是十分稀有的资源。后来麻省理工学院(MIT)开发了分时操作系统,也就是一个大型主机提供多个终端机链接,实现多个用户在某个时间段内分别使用主机的CPU资源。当然,这种方式在CPU频率很高的前提下并不会给用户带来为了使用计算机排队的感觉。不过这种终端机只能是个IO设备,并且限于硬件和技术的发展水平,在当时一个比较先进的主机最多也就能支持30台左右的终端机。

为了充分利用主机资源,实现一个主机同时支持300终端机工作的这么一个目的,在1965年,贝尔实验室(Bell)、麻省理工学院(MIT)和通用电气公司(GE)三家巨头公司共同发起了一个名为Multics的项目,这在当时是如此兴师动众的一个工程,三家巨头各自出动了一批优秀的年轻人才。经过几年的努力,Multics的基本功能实现了,可以支持多程序、多用户,不过就算在大型机上面运行,性能仍然不怎么样。在基本功能完成后,三家都没有停止这个项目的意思,继续在为Multics延展一些功能。又过了一段时期,失去目标的Multics项目不再一如当前的吸引人,所以GE、BELL相继退出,只剩了MIT仍然在继续。不过Multics仍然是成功了的,据说福特公司使用曾购买使用Multics,一直运行到2000年以后才下线。

Bell退出之后,当初为Multics招来的许多工程师就空闲了,其中有个叫Ken Thompson的年轻人 ,他曾经负责在Multics上面开发名为Space Travel这么一款游戏。在退出之后,由于无法再免费使用Multics来继续他的游戏开发,他就申请去购买一套Multics装在机器上面。在1972年左右,市面上流行的主机是PDP-11,由DEC公司生产的,是一款小型机,属于VAX系列。当时一台PDP-11数万美元。理所当然,Ken的申请被拒绝了。不过流浪在Bell的期间他发现了一台老旧没人用的PDP-7,虽然跨了四代(跨四代对电脑什么概念不必多言),不过还好能用。但是限于当时的Multics是用汇编语言所写,对硬件的依赖程度还是非常高的,所以Ken必须要自己开发一套内核来跑他的游戏。于是Ken凭借队此前的Multics的记忆,花了四个星期写了一套内核,并且还成功的跑起了他的游戏。Ken就向实验室里的同事炫耀他的游戏,然而没人看好他界面丑陋的游戏,大家倒是对他所开发的那套系统十分感兴趣。那套系统十分小巧,被实验室里的人称为UNICS,后来才改称为UNIX。此后的一年,出色的性能使得UNICS风靡Bell。不过同样的道理,UNICS是用汇编语言开发的,跟硬件平台紧密结合,在不同的硬件架构的电脑之间移植非常困难。为了扭转劣势。这时Bell实验室里的另外一名叫做Dennis M.Ritchis主动找到Ken,表示可以用高级语言重新开发UNICS,这样用编译器在不同的电脑上编译就能实现系统移植。两人不谋而合,立即着手对当时的B语言改进,通过引入静态变量,指针等一堆东西之后,B语言也升级成了赫赫有名的、广为流传的C语言。继而俩人用C语言改写了UNIX,最后发行出了UNIX正式版本。值得一提的是由于高级语言的一些特性(比如通过结合一些额外的机制,弥合多种硬件之间的不同),使得相对于汇编语言执行效率低了大概30%。在硬件速度相对慢的时代,这是非常大胆的举动。不过这也是俩人预见以后硬件速度的提升肯定会日新月异,果不其然,现在的高级语言的效率问题在电脑平台上几乎可以忽略了。

UNIX发行之后,俩人联合署名在在美国计算机通信杂志上面发表了一篇论文,来宣传UNIX。这样一来,很多的高校和科研机构都希望能获得一份源码。由于Bell属于AT&T,在美国反垄断法的规定中,AT&T是不能销售除了电报电话之外的任何产品的,并且在别人需要的时候要无偿提供。这样很多著名的大学包括伯克利分校都获得了UNIX的源码。在有了这么突出的贡献之后,Ken获得了年休的机会,于是借此机会,他在1976年时去伯克利分校任教。在伯克利分校有个很厉害的研究生叫Bill Joy,他成立了一个叫BSRG的团体,专门是改进UNIX,修复bug,加入些新功能之类的。事实上在Ken加入之后,伯克利分校几乎成为UNIX研究领域的领头羊。

随着研究的进行,后来美国军方网络平台需要一套传输数据的报文协议,军方不想在封闭的系统平台上面开发这一套协议,所以就把这个任务交给BSRG团队。BSRG团队在加入包括拥塞控制等一些列机制之后,再柔和进UNIX很多新功能,将研发结果打包发行,并称为BSD(伯克利系统发行版),开始了卖系统。在这之后不久,Bell被卖给另一家公司,看到BSRG卖UNIX挣了很多钱,Bell也迫不及待开始打包发行UNIX,并且以40000美元一个授权的价格,也挣了一大笔钱。后来两家为了UNIX正统之争开始打官司,一打就是十年。导致这段时间UNIX的研究陷入停顿状态。起初的UNIX只能在PDP系列上运行,由于当时PC机上的Inter芯片接口丑陋不堪,性能也不好,所以没人来将UNIX改造使其能运行在PC机上。

后来美国一个教授,开发了CP/M,售价大概两三万美元,当时的PC机也是售价两三万,使得个人能买一台能用的计算机非常昂贵,所以PC机的销量并不好。IBM和当时的康柏公司就迫切一个解决方案。在1981年美国的西雅图,比尔盖茨成立了微软公司,最初公司一共3个人以卖basic编译器和包装发行UNIX为主。公司成立不久之后,在比尔盖茨的好友艾伦的一个好友所在的公司,有一个程序员写了个在PC机上的小系统。于是比尔盖茨非常敏锐的捕捉到这个商机,利用他母亲IBM公司董事会董事的关系,找到IBM董事长沃森,说有这么一个系统可以卖给IBM公司,不过他只是卖给沃森版权,也就是装一个这样的系统只要给比尔盖茨几美元就行了。沃森当即就同意了。比尔盖茨于是让艾伦以50000美元找那个程序员买断了这个系统,再和她一起改造了之后,更换名字为Dos。结果PC机大卖,比尔盖茨也挣了很多钱。不过Dos是单任务、单用户的系统,实际上并不好用。此时又有一家公司成立了,也就是Jobs成立的苹果公司。Jobs目的是生成PC机,并且要生成比IBM的PC兼容机性能强很多的真正的PC机。有趣的是Jobs这个人特别崇拜图灵,不过图灵是个同性恋,被当时的人们关押之后,图灵羞愤之下咬了一口涂了氰化钾的苹果死了,所以苹果的Logo是现在这样咬了一口的苹果。苹果公司所生产的1型PC机是基于UNIX的,卖了很多台。最初苹果电脑的CPU是PowerCPU,不是Inter的。

为了给他的电脑添加一些新的东西,Jobs利用各种关系进入了施乐公司(卖打印机的)的PARK实验室参观,此时实验室里一个人在UNIX系统首先上研究出了世界上第一个鼠标,而且并且出了第一个图形操作界面。但是卖打印机为主的施乐公司领导层并不喜欢这个产品,当Jobs发现这个之后就向施乐公司高价买了一份回去研究。回去之后他就立即着手组织人对这个宝贝进一步研发(Jobs本人并不是程序员)。于是在苹果二代就有了图形操作系统,这使得装Dos系统的PC机销量日下。于是比尔盖茨也很想搞这么一套代码来开发他的系统,比尔盖茨就想方设法去接近Jobs,希望一起研究进一步开发这个图形界面,于是他成功的从Jobs手中骗走了一份源码,并且立即开始了改进他的系统。所以Windows系统就诞生了,但Windows是在Dos基础上研发的,经常蓝屏。

此时的UNIX还在战争期间,当BSD和Bell发现微软和苹果搞得这样火爆时才决定放弃了正统之争。之后BSD研究团队就解散了,但是里面一些人仍然在继续队UNIX的研发,并且开发了第一个可以在PC机上运行的UNIX,名字为FreeBSD。此后还出现了其他可在PC机上跑的UNIX发行版,如OpenBSD、NetBSD等。到现在苹果系统的核心仍然是FreeBSD内核。之前领导BSRG的Bill Joy,随后成立了著名的Sun公司,主要是生成工作站,并且开发了自己的操作系统Sun OS,后来结合UNIX系统改名为Solaris。Bill Joy最突出的贡献是为UNIX添加了一个程序:csh,也就是兼容C语言的shell。

再回到苹果和微软,微软公司的Windows系统一直到Windows95、98版本之后,蓝屏问题仍然没有解决,由于Dos这个基础并没有改变。前面提到生产PDP主机的DEC公司,这家公司生产的机器上装的是自己开发的OpenVMS系统。在DEC公司被收购之后,OpenVMS系统的研发人员就被比尔盖茨接收进微软公司,来改进他的Windows系统。整个OpenVMS研发团队进入微软之后,新版本的Windows系统就在OpenVMS之上修改而成,改名为WindowsNT,此时的内核不再是Dos。之后又发行了WindowsXp,windows2000等等,这些系统的内核都是基于OpenVMS。尽管Windows系统的蓝屏问题解决了,但是界面不如苹果系统,因为不论微软吹嘘得多厉害的技术,基本都是别人几年前就不用的技术,直到现在。不过,苹果强大的界面都是依靠硬件支持,所以现在的图形工作站主机多数都是苹果机。

再回到UNIX,当UNIX商用之后,很多高校就不能在免费用了。荷兰一个大学里,有个叫安德鲁的教授,此前一直在使用UNIX教学,UNXI商用之后他就自己开发了一个操作系统上课用,叫Minix,也就是和UNIX十分相似的很小的系统。在他去芬兰赫尔辛基大学教学之后,这个系统也被带了过去。由于他是用汇编写的这个系统,所以学生要使用就要自己开发内核。

要再继续讲Linux就得先介绍一个著名的人,麻省理工学院的教授Richard Matthew Stallman。他是一个著名的黑客,认为程序是全人类的,于是举起自由的大旗,成立GNU组织,开始了程序界的共产主义运动,并且草拟了著名的GPL。Stallman开发了很多程序,如Emacs、GNU C(GCC)、GNU C Library(GLIBC)、Bash shell等。在赫尔辛基大学里有个叫Linus的学生,他20岁生日时收到外公的一个礼物——一台80386PC机。在1991年,他自己使用bash、gcc等工具在这台PC机上写了个很小的内核程序,命名为Linux。之后他在电子公告牌上宣布了这个消息,这让很多人感兴趣,并加入了对他写的这个内核的维护中来。此前说的Stallman所开发的程序都是在UNIX上运行的,此时Linux的出现正和GNU组织内核的需求相吻合。但是Linus提供的Linux只是内核,不是程序,没有库,之后Linus在Linux上移植了很多bsh,于是全球黑客开始了Linux编写程序的活动。于是在1994年,Linux1.0诞生,由于所有人都在努力将Linux移植到各种硬件上,所以此时的Linux已经可以跑在很多PC上面上。要再次说明的是Linux只是个内核程序,GNULinux才是个系统。不过两者都是源代码,要运行在PC机上面得先编译。但是不是所有人都会编译,另外由于CPU支持二进制的格式不同,并且ABI(应用二进制接口)不同所以编译要求两台主机完全一样,比如编译后要在x86架构主机上运行,就必须在x86架构主机上编译才行。此时一些第三方组织出现,他们负责编译内核和外围应用程序,并打包发行。著名的包括RedHat、Debian、SUSE,他们不是Linux 的开发者,只是打包发行而已,Linux 的内核由linus和开发团体提供,软件由GNU提供。发行商在其中加入自己的配置文件,使得Linux不同版本之间看起来各不相同。

由于早期的软件都是和内核打包发行,用户不能自己更改。所以后来出现了软件管理器,如Debian的Dpkg,RedHat的RPM,使得软件有安装、卸载、升级等功能。遵循GPL所规定的,发行商发行的源码必须公开。为了盈利,RedHat在发布源程序,但是不发放编译好的二进制文件,而且在软件升级时也不发放二进制升级补丁。这样的情况下出现了另一个组织,CentOS(社区企业操作系统)。每当RedHat发行源码时,CentOS都给搞成二进制代码免费发放,并且和RedH发行的版本完全兼容,不过CentOS不提供后续服务。在RedHat9.0(个人版)发行之后,这个系统基本就十分稳定了,所以后来RedH专注于研发RedHa企业版,个人版的更新在2003年终止,并将个人版捐给Fedora公司。Debian是目前唯一一个不受商业组织支持的UNIX发行者,因为Debian的所有者都是自愿者,所以最先进的Linux发行版是Debian,不过最难使用的也是Debian。之后Debian的二次发行版,如Ubuntu,主要用于PC,界面很漂亮。还要基于Ubuntu的二次发行,Mint。值得说的是现在流行的Andriod系统也是Linux的一个发行版。