概念 缩写
GDT 操作系统的内存映射表 全局描述表(GDT Global Descriptor Table):在保护模式下一个重要的数据结构。 GDT可以被放在内存的任何位置,那么当程序员通过段寄存器来引用一个段描述符时,CPU必须知道GDT的入口,也就是基地址放在哪里,所以Intel的设计者门提供了一个寄存器GDTR用来存放GDT的入口地址,程序员将GDT设定在内存中某个位置之后,可以通过LGDT指令将GDT的入口地址装入此寄存器,从此以后,CPU就根据此寄存器中的内容作为GDT的入口来访问GDT了。 LDT(Local Descriptor Table) 进程的内存映射表,GDT表是操作系统的段表 GDT表是操作系统的段表,LDT每个进程的段表
cs查 gtd 查 内核段
PCB process control block TCB thread control block
在CPU中,CS的全拼为“Code Segment”,翻译为“代码段寄存器”,对应于内存中的存放代码的内存区域,用来存放内存代码段区域的入口地址(段基址)。 在CPU执行指令时,通过代码段寄存器(CS,Code Segment)和指令指针寄存器(IP,Instruction Pointer)来确定要执行的下一条指令的内存地址。 在CPU中类似的寄存器有: DS:是 Data Segment 的缩写,翻译为“数据段寄存器”; SS:是 Stack Segment 的缩写,翻译为“堆栈段寄存器”; ES:是 Extra Segment 的缩写,翻译为“附加段寄存器”。
PC(Program Counter,PC)用来存放当前欲执行指令的地址,它与主存的MAR之间有一条直接通路,且具有自加1的功能,即可形成下一条指令的地址。 程序计数器是用于存放下一条指令所在单元的地址的地方。 为了保证程序(在操作系统中理解为进程)能够连续地执行下去,CPU必须具有某些手段来确定下一条指令的地址。而程序计数器正是起到这种作用,所以通常又称为指令计数器。在程序开始执行前,必须将它的起始地址,即程序的一条指令所在的内存单元地址送入PC,因此程序计数器(PC)的内容即是从内存提取的第一条指令的地址。当执行指令时,CPU将自动修改PC的内容,即每执行一条指令PC增加一个量,这个量等于指令所含的字节数,以便使其保持的总是将要执行的下一条指令的地址。由于大多数指令都是按顺序来执行的,所以修改的过程通常只是简单的对PC加1。PC的维数一般和存储器地址寄存器MAR的维数一样。 当程序转移时,转移指令执行的最终结果就是要改变PC的值,此PC值就是转去的地址,以此实现转移。有些机器中也称PC为指令指针IP(Instruction Pointer)。
进程线程
进程,通俗来讲就是运行的程序。其由代码段,数据段和PCB(进程控制块)三部分构成
现代os都将线程作为最小调度单位,进程作为资源分配的最小单位。
线程的上下文切换只需要保存线程的一些运行时的数据,比如线程的id、寄存器中的值、栈数据。
而不需要像进程上下文切换那样要保存页表、文件描述符表、信号控制数据和进程信息等数据
go中的协程,轻量级线程,是用户级线程,只有用户栈,没有内核栈,不由内核调用
cpu管理 调度策略
- FCFS(first come, first served)–周转时间大(吞吐量)不行 (吞吐量 单位时间执行任务个数)
- SJF 短作业优先–长作业的响应时间不行
- 按时间片来轮转调度—->提高响应时间(时间片大响应时间长,时间片小吞吐量小)
Linux0.11的schedule函数
c(0) = p;
c(t) = c(t-1)/2 + p;
counter最大就是优先级调度,counter本身也是时间片,
执行IO阻塞进程完后,进入就绪队列的时候优先级升高
等比数列,响应时间有界
内存管理
分段:根据程序分成程序段 数据段等放在不同物理内存上
分页:内存每一页4k一个单位,将程序分配再多个4k上
分段+分页将程序分段,映射在虚拟内存上(程序员角度),虚拟内存再映射实际内存页上(操作系统角度)
问题:
每一页4k,4G/4k=2^20,页表太大–>多级页表(虚拟再虚拟)但是查询时间变慢–>快表 放在cpu内部寄存器,保存最近经常访问的页表
32位操作系统 虚拟内存都是4g,然而实际内存可以小于4G,使用换入换出来实现1G内存看似有4G内存
每个进程都有4GB的虚拟地址空间
这4GB分3部分
(1)一部分映射物理内存
(2)一部分映射硬盘上的交换文件
(3)一部分什么也不做
文件系统
磁盘基本概念 cyl柱面,head磁头(磁道),sec扇区

获取三个值,如第2个柱面,第3个磁道,第4个扇区,就可以开始读数据了
第一层抽象:三个参数太多,引入盘块号,将三维信息编址到一维信息
磁盘访问时间 = 写入控制器时间 + 寻道时间 + 旋转时间 + 传输时间
写入控制器时间:系统总线给磁盘发起命令的时间
寻道时间 + 旋转时间:移动磁头的时间,旋转柱面,这个时间最长
传输时间:读到后给系统总线
磁盘读取数据是以盘块(block)为基本单位的。位于同一盘块中的所有数据都能被一次性全部读取出来。而磁盘IO代价主要花费在查找时间Ts上。因此我们应该尽量将相关信息存放在同一盘块,同一磁道中。或者至少放在同一柱面或相邻柱面上,以求在读/写信息时尽量减少磁头来回移动的次数,避免过多的查找时间Ts。
所以,在大规模数据存储方面,大量数据存储在外存磁盘中,而在外存磁盘中读取/写入块(block)中某数据时,首先需要定位到磁盘中的某块,如何有效地查找磁盘中的数据,需要一种合理高效的外存数据结构,B树 B+树
第二层抽象:通过队列访问磁盘,由磁盘驱动调度(电梯算法,从一端到另一端,圆形循环)

第三层抽象:文件 写入的抽象接口:
///将修改的信息放入电梯队列
//inode 用来找到写入磁盘的盘快号
//file 文件流读写的区间
//buf 内容
//count 数量
file_write(struct inode *inode, struct file *file, char *buf, int count)
具体实现则由不同文件实现,如磁盘文件、设备文件等
第四层抽象:文件系统
文件视图

常见的系统调用
