操作系统是管理计算机硬件和软件资源,并且提供用户交互的软件系统

常见操作系统有Windows,Linux,Android

操作系统具备管理计算机资源的功能,具备抽象计算机资源的能力,能和用户进行交互

操作系统实质上是一个很复杂的控制软件,可以管理应用,资源管理,管理外设等等

操作系统的架构的层次是在硬件之上,应用之下

OS Kernel:可并发(同时存在多个运行的应用)。可共享,可虚拟,可异步

微内核:尽可能将内核功能移植到用户空间,缺点就是性能低

外核和内核:一个负责硬件,一个负责软件

DISK(硬盘存储):存储OS

BIOS:基本I/O处理系统(加载外设以及加载软件来运行OS) (basic I/O system)

BootLoader:加载OS

POST(加电自检,查找显卡和执行BIOS)

系统调度:来源于“合法”的应用向系统发出服务请求的(同步或者异布)

异常:来源于“不良”的应用非法指令(或者应用意想不到的请求,应用无法获得资源需求)(同步)

中断:来源于外设对于硬件设备和网络中断(异步)

逻辑化地址空间,独立地址空间,可访问相同内存,更多内存空间(虚拟化)

物理地址空间:硬件支持的地址空间

逻辑地址空间:应用程序拥有的内存范围

操作系统为了运行多个程序,进行了内存地址的隔离(分配独立的虚拟内存地址),虚拟内存地址和物理内存地址是映射关系

应用逻辑地址映射到物理地址

CPU需要逻辑地址上的内存内容(ALU),内存管理单元(MMU)寻找逻辑地址和物理地址之间的映射,控制器将从总线发送物理地址的内存内容的请求

内存发送物理地址内存内容给CPU(告诉CPU,物理地址找到了),建立逻辑地址和物理地址之间的映射(确保应用互不干扰)

虚拟地址和物理地址的映射关系管理

内存分段(内存被看成一组不同长度的段)

内存分段下的虚拟地址分为段选择⼦和段内偏移量

段选择⼦保存在段寄存器中,段选择⼦其中的段号被用于段表的索引,段表中保存的是这个段的基地址和段界限等等

而段内偏移量是位于0和段界限之间的,如果段内偏移量合法,那么段内偏移量加段的基地址得到物理内存地址

分段的内存碎片问题,如果某个程序占用了128mb内存,然后该程序被关闭了,释放128mb内存,如果这个128mb内存不是连续的,而是被分段了,这将导致没有内存空间打开另一个内存占用128mb的程序

内存分页(将物理内存和虚拟内存切成一段段固定大小的内存空间)

内存分页解决了内存分段的内存碎片问题,其释放内存是以页为单位释放的,当内存空间不够,会释放其他正在运行的进程的没使用的内存页面

内存分页下的虚拟地址被分为页号和页内偏移,页好为页表的索引,页表保存着物理页的所在物理内存的基地址,基地址和页内偏移组成物理内存地址

内存分页的缺点就是在运行多线程时,页表会非常大,所以出现了多级⻚表(将页表分成一级一级的)

段⻚式内存管理(内存分段和内存分页的结合体)

先将内存分为多个段,再将每个端分为多个页,地址通过段号,段内⻚号和⻚内位移组成

连续性内存管理(内存碎片和分区的动态分配)

外部碎片:在分配单元间的未使用内存

内部碎片:在分配单元中的未使用内存

当一个应用被批准运行在内存中时,分配一个连续的区间,来给运行的应用访问数据

动态分配的策略:当想分配某字节,先从低地址找,找到第一个被某字节大的空闲块,就使用它

动态分配的缺点就是外部碎片严重

非连续内存分配

分段Segmentation:

逻辑地址空间连续,物理地址离散

一个段表示一个内存块,一个逻辑地址空间,应用访问内存地址的时候,需要个二维的二元组

虚拟内存:

早期内存不够应用消耗,应用的规模比存储器的容器大

当应用太大,超出内存,可采用手动的覆盖(overlay) 技术,只把需要的指令和数据保存在内存中

当应用太多,超出内存,可采用自动的交换(swapping) 技术,把暂时不能执行的程序送到外存(磁盘)中

进程和线程:

进程状态(state),线程(thread),进程间通信(inter-process communication),进程互斥与同步,死锁(deadlock)

进程包含正在运行的应用的全部状态信息

进程可动态化创建,结束进程,可以被独立调度并占用处理,不同的进程互不影响,可访问共享数据或者资源

进程控制块(process control block, PCB):进程的数据结构,操作系统管理控制进程运行所用的信息集合,操作系统为每一个进程都维护了一个PCB,用来存储保存和该进程有关的状态信息

进程是操作系统最小可调度的资源单位

多个程序运行在单核心CPU服务器上,实质就是在共享时间片(时间片,操作系统将某个程序分配到某段CPU时间上,单核是无法同时运行多个程序的,只能共享时间片,而进程就是因此而生)

进程状态有3种,分别是运行,阻塞以及就绪

运行和就绪可互相转换,运行状态就是CPU指令在读取运行进程中的程序段,而就绪就是该进程在等待调用

运行可切换到阻塞状态

阻塞就是进程在等待信号(依赖的资源没有就位),阻塞状态结束后会切换到就绪状态

进程状态的切换可理解为接力赛跑,运行状态就是正在跑的运动员,而就绪状态就是在等待接力棒的运动员,而阻塞状态就是运动员需要补充休息,暂时不跑了

进程发生阻塞时,该进程将放弃CPU使用权,CPU会执行下一个就绪状态的进程

中断和中断向量

当程序发生中断(CPU暂时中断当前正在运行的程序),CPU转去处理其他的程序(也可能是处理内存的数据),当CPU处理完毕,CPU可恢复到之前被暂时中断当前正在运行的程序的状态,这个过程叫中断

中断向量就是中断程序的入口地址

中断发生时,该进程会第一时间保存被中断程序的状态,会将相关数据保存到寄存器,当CPU通过中断向量,跳转到处理中断程序中去,并且执行中断程序,然后决定下一个执行哪个程序,如果这个程序正好是之前被中断的,会从寄存器中读取相关数据。恢复到之前中断的执行状态

任何进程都需要排队等待

进程中断和进程阻塞的区别:中断是由于一些优先级比较高的需要CPU处理而被迫中断执行,而阻塞是因为进程需要一些依赖,但是依赖没有就位,需要等待就位,该进程就会进入到阻塞队列中,当依赖就位,就恢复到就绪状态,等待进程调度系统分配CPU执行权

进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源的分配和调度的基本单位,每个进程都拥有一个自己的地址空间,进程至少有5种基本状态,分别是:初始状态,执行状态,等待状态,就绪状态,终止状态

线程(Thread)是进程的执行实例,是程序执行的最小单位,是操作系统能够进行运算调度的最小单位,一个进程可以创建多个线程,同一个进程的线程共享进程的内存信息,同一个进程的多个可以并发执行,一个线程要执行,必须至少有一个进程

并发和并行的区别

并发:指一个时间段中有多个线程(程序)被快速的轮换执行(处于启动运行到运行完毕之间),在一个时间段中只有一个线程(程序)在执行,在宏观上感觉是多个线程同时被处理,如果多线程操作在一个cpu上,操作系统将cpu运行时间分隔为若干个时间段,将时间段分配给各个线程执行,在一个时间段的线程执行时,其他线程将处于挂起状态,这就叫并发

并行:当系统拥有多个cpu(1个以上)时,一个cpu执行一个线程,另一个线程执行另一个线程,同时进行处理,这就叫并行

并发和并行的区别:并发一个时间段只能执行一个线程(多个线程需要排队执行),并行可以在一个时间段中同时执行多个线程

当多线程程序在单核CPU上执行时,就是并发,在多核CPU执行时,就是并行,当线程数大于CPU核数,那么既有并行又有并发

进程调度的性能消耗太大,因为进程调度会导致进程中断,不但需要将数据保存在寄存器中,恢复进程还需要从寄存器中读取数据,而调度线程的性能消耗就很小,线程是进程的执行单元,一个进程中最少存在一个线程

进程的竞争和临界区

临界区:指的是共享内存中的程序片段

当两个进程同时访问了临界区,而临界区中的数据正好不能被同时访问,例如进程A读取了临界区中的某个内存,并且修改了这个内存,但是进程B正好在读取该临界区的这个内存,导致读取的数据是错的,而解决这个问题的最简单方法就是互斥,当一个进程在该临界区中时,其他进程不能进入,需要排队等待,而且不能过于长时间的占用临界区,临界区外的进程不影响到临界区内的进程

死锁:当多个进程因为竞争资源或者进程通信而导致的阻塞现象,进程在互相等待,无法进行下一步操作

严格轮换法,Peterson算法

严格轮换法简单来说就是声明一个状态,某个进程进入临界区时,状态为1,出来的时候状态为0,当其他进程看到状态为1时,等待该进程出来,看到状态为0时,进入临界区

Peterson算法是严格轮换法的优化版,实现了互斥的同时又避免的死锁

Peterson算法的思路是声明2个状态(一个是正在使用临界区的状态,另一个是想进入临界区的状态),当一个进程想进入临界区时,会检查一下其他进程是否想进入临界区,如果存在其他进程想进入临界区,则等待


FHS规范(3.0),全称Filesystem Hierarchy Standard,中文翻译为文件系统层次结构标准,用于定义根目录以及一级子目录的规范,大多数Linux版本使用该标准来定义文件系统(并不一定完全符合规范,只是大概上符合)

FHS规范定义了系统各个目录应该要放什么文件数据,以及所需要的文件和目录

例如:规范某一些文件或者目录可以分享或者不可以分享给给其他人使用

FHS规范了根目录(/),以及根目录的子目录etc(配置文件),bin(必要软件或者命令),usr(二级目录),home(当前用户的家目录),var(动态数据)

Linux文件系统—VFS(虚拟文件系统)(Linux下一切都是文件)

VFS不需要考虑不同文件系统和存储介质的差异,因为其内核抽象出了通用的文件系统接口,只要符合接口标准,一些文件或者比较特殊的文件系统都是可以兼容

VFS抽象对象,超级块:文件系统,目录项:文件的路径,索引节点:具体文件(操作文件的具体信息),文件:进程打开的文件。都有自己的接口来操作

XFS(高性能64位日志文件系统),带有日志功能防丢数据,原生提供备份工具(xfsdump/sfsrestore)


图灵机和冯诺依曼模型

图灵机实质就是机器模拟人类在纸上进行数学运算,先将数值写到一个纸带的小方格中,再通过读写头来读取小方格里面的信息

这个读写头具备存储,运算,控制功能。存储读取的数据以及运算出来的数据,可执行运算指令,可识别数据是运算指令(例如加号,减号等等运算符号)还是数字

冯诺依曼模型(约定使用二进制来存储和计算数据,并且定义计算机基本结构,CPU,内存,输入设备,输出设备,总线,具备这5个部分的计算机就是冯诺依曼模型)

CPU:中央处理器,64位处理器(64位指的CPU的位宽,位宽决定了处理器一次可以计算处理多少字节的数据,64位处理器可以一次计算8个字节)

CPU内部还有寄存器(存储CPU计算时的数据),运算单元(负责计算),控制单元(控制CPU工作)

常见的寄存器有:通用寄存器(存储需要进行计算的数据),程序计数器(存储CPU要执行下一个指令的内存地址),指令寄存器(存储程序计数器指向的指令)

总线(CPU和其他设备之间的通信,总线被分为3种,地址总线(传送外部存储器(内存)的地址),控制总线(用来传输和接收控制信号),数据总线(传送内存的数据信息,数据总线又分单向传输,双向传输))

输入输出设备(输入设备通过控制总线和CPU通信,CPU处理后,将数据输出给输出设备)

线路传输:通过电压来传输数据,低电压表示0,高电压表示1,一条线路可传输1bit的数据(二进制,0或1)

32位处理器的最大寻址空间为2的32次方(4294967296,大概4GB左右),所以32位CPU(或者操作系统)只能操作4G内存(而64位理论上寻址范围高达2的64次方)

CPU执行过程:CPU读取程序计数器的值(指令内存地址),控制单元通过地址总线访问到内存,并且通过数据总线获取数据给CPU,CPU接收到数据,将该数据存储在指令寄存器,CPU处理指令寄存器的数据,确定数据的类型,如果是计算类,就交给运算单元处理,如果是存储类,就交给控制单元处理,CPU处理完毕后,程序计数器的值自增(用来表示下一条指令,自增取决于CPU的位宽,如果是64位处理器就是自增8(因为64位一次性处理8个字节数据,一个字节数据需要一个地址来存放))

CPU会不断执行该过程,直到结束(这个过程叫CPU的指令周期)

CPU的执行速度取决于指令的执行速度,而指令的执行速度取决于CPU的时钟频率(Ghz),例如我电脑的CPU是 2.10 GHz的,这个 2.10 GHz指的是1秒内可以产生2.1G次数的脉冲信号,而每一次脉冲信号的高低电平的转换就是时钟周期(振荡周期)

时钟频率越高,时钟周期越低,CPU的处理速度越快


存储器

内存断电,数据会丢失,而硬盘不会,因为硬盘是持久化存储,而且CPU内部也有存储器(只不过其能存储的数据很小)

寄存器处理速度最快,再到CPU Cache(中⽂称为CPU缓存,一般分为L1,L2,L3这样的缓存层,比如我电脑的r5 3550h的一级缓存为384KB,二级缓存为2MB,三级缓存为4MB,二级缓存是一级缓存的缓冲器,三级缓存是二级缓存的缓冲器)

然后再到内存,最后是硬盘

一个主频为2.1Ghz的CPU,表示其1秒内完成2.1x10的9次方个时钟周期

CPU Cachee使用了⼀种叫 静态随机存取存储器(Static Random-Access Memory,SRAM)的存储器,一旦断电就会丢失数据

每个CPU核心都有属于自己的L1缓存和L2缓存,而L3缓存一般是多核心共享的

内存使用的是一种叫动态随机存取存储器(Dynamic Random Access Memory,DRAM)的存储器

SRAM存储1bit的数据,一般情况需要6个晶体管,而DRAM只需要一个晶体管和一个电容

硬盘就是固体硬盘(分为HDD硬盘(Hard Disk Drive)和SSD硬盘(Solid-state disk)),HDD硬盘结构和内存相似,但是和内存,缓存之类的不同的是其断电,数据不会丢失

CPU Cachee的数据是从内存中获取的,通过Cache Line(缓存块)来一块一块获取,L1缓存一般分为数据缓存和指令缓存

补码:将正数的二进制全部取反再加1,补码被用于处理负数

十进制小数转二进制用的是乘2取整法(将小数部分乘以2,作为二进制的一位,一直到不存在小数,整数还是用除2法,再合并就是小数的二进制结果)

不是所有小数都可以乘2取整的,例如0.1就不能取整,无法使用二进制精确表示0.1,只能使用近似值来表示,这将导致精度缺失的情况发生


操作系统内核:连接硬件设备的桥梁,应用只需要和内核交互,无需关注硬件,内核已提供访问硬件的接口

现代操作系统内核支持进程调度,内存管理,硬件通信,提供系统接口等功能

内核权限很高,并且将内存分称2个部分,分别是内核空间(只有内核程序可访问),用户空间(专门提供给应用使用)

当程序在使用用户空间时,那么该程序在用户态执行,如果在使用内核空间,那么该程序在内核态执行

内核一般分为三种,宏内核(Linux为代表,整个内核是一个完整的程序),微内核(具备一个小内核,一些服务或者模块由用户态来管理)以及混合内核(宏内核和微内核的结合体,windows为代表)


计算机的输入,输出,状态转换函数F

状态描述:一切可使用数字描述

输入:晶振(时间输入,CPU周期,时钟驱动CPU工作),外界输入设备

输出:打印机,显示器

机械计算机:差分机(巴贝奇,多项式求值)

图灵机

冯 诺依曼模型


CPU的工作原理(内存,寄存器,ALU(算数逻辑单元))

数据空间地址和指令空间地址


指令

通过指令来控制计算机工作,CPU被时钟驱动,并且不断读取指针指向的指令,从内存读取指令然后执行指令

不同的cpu架构使用不同的指令集,常见的指令集有RISC(Reduced Instruction Set Computing,精简指令集),CISC(Complex Instruction Set Computing,复杂指令集)

RISC中代表的有arm指令集,CISC中代表的有x86指令集

RISC的特点就是CPU单元电路少,面积小,功耗低(只进行二进制处理器指令)

CISC的特定就是CPU单元电路多,面积大,功耗大(进行复杂指令)


寻址模式,浮点数,指令分类

寻址模式(指令集的一部分,表示指令有哪些操作符,地址应该怎么计算)

寄存器寻址,立即寻址,偏移量寻址(基地址,偏移量),PC相对寻址

内存读写(load/store指令),加减乘除(add,sub,div,mult)。


操作系统的并发性(2个事件及2个以上事件在一段时间内发生,就叫并发,并发是单核CPU的知识点),共享性(操作系统的资源可以提供给多个并发程序使用,互斥共享,同时访问(一段时间内并发访问资源)),虚拟性(将物理设备虚拟成多个逻辑实体,虚拟技术有时分复用(分时使用硬件资源,例如虚拟处理器技术,就是将多个程序分时复用处理器资源,虚拟设备技术,就是将物理设备虚拟成多个逻辑设备,一个程序使用一个逻辑设备,通过逻辑设备来并发访问真实的物理设备),空分复用技术(虚拟磁盘技术(将物理磁盘虚拟成多个逻辑盘),虚拟内存技术(可使用比实际内存更大的内存空间))),异步性(允许多进程并发执行)


信号量(semaphore)

信号量是操作系统解决不同进程之间共享资源互斥和同步的原语(原语,控制进程,一个程序段,一旦执行,那么就要执行完毕,过程不可中断,并且常驻内存,并且是原子操作(英文primitive or atomic action,表示该操作的全部动作必须做完或者不做,是不可被分割的)的,在管态(即内核态,处理器可在该下执行指令系统的全集,另外还有目态,即用户态,目态切换管态只能通过中断完成,因为当程序在目态下执行特权指令时,会发生中断,让操作系统来完成,避免用户态程序对系统发生破坏,而管态切换目态只需要修改状态字就可以了)执行)


阻止恶意操作和保护数据使用到了一种叫hierarchical protection domains的机制,中文翻译为分级保护域,这个分级rings特权级分为四个级别,分别是0,1,2,3 0拥有最高权限,3拥有最低的权限,例如在Windows,只使用了两个级别,0和3,Windows下应用程序工作在3级,只能访问3级的数据,而操作系统内核和驱动工作在0级,可访问全部级别的数据 在低权限的级别上工作,想执行特权指令是不行的,只能通过系统内核调用完成(而这个内核调用的过程就是CPU运行级的用户态与内核态的转换),这个机制是为用户程序和服务程序对资源的利用隔离

负级的保护,实际上并没有定义负级的(这个是微软的说法,用于hypervisor层运行),Ring -1的例如有VT-x 与 AMD-V(这两个支持全虚拟化,也就是硬件辅助虚拟化技术(Hardware-assisted Virtualization Machine)),VT-x 与 AMD-V都定义了一个新的保护级,可以让vmm运行在比ring0级别权限更高的级别上(也就是Ring -1)

VT-x将保护级别分为两种操作模式,分别为根操作模式(vmm运行在该模式中,)和非根操作模式(vm机运行在该模式),这两个操作模式都有Ring0到Ring3 的全部指令级别

vm机可以正常运行在Ring 0 级别,因为发出什么级别的指令都会进入到根操作模式的虚拟层中

运行在ring级别越低,行为可见性越低,对ring级别高的程序来说,就是不可见的,比如ring3的应用程序是无法感知内核级别干了什么的,因此当在ring级别低的层级中运行恶意程序,其行为被察觉和查杀将变的更难