【笔记】计算机操作系统-李治军

前言

在这里插入图片描述
这是计算机裸机,如何方便的使用这些硬件,就是操作系统要做的事情。
在这里插入图片描述
操作系统是计算机硬件和应用之间的一层软件,方便我们使用硬件,高效的使用硬件。它管理着CPU、内存、终端、磁盘、文件、网络、电源等放个方面。

  • 向下操作硬件,向上提供接口

Open the OS

发展:

  • 图灵机(只能做一件事) - > 通用图灵机(能做很多事)- > 计算机(冯诺依曼存储程序思想)
  • 冯诺依曼思想:(存储程序的主要思想:)讲程序和数据存放到计算机存储器中,计算机在程序的控制下一步一步进行处理;
  • 过程:将程序放在存储区中,用PC指针指向在运行的指令,然后取值执行;(在运算器、控制器中执行)

在这里插入图片描述
计算机上电过程(取值执行、读入内存、初始化):

  1. BIOS:检查硬件、将引导扇区 读入0x7c00 处512字节,然后跳转执行;

  2. OS引导扇区BOOT(bootsect.s) :(将OS 从磁盘读出)

    • 将0x7c00 处代码移动到0x9000位置(为了给后面OS 代码留出空间)然后跳转执行(实际上是顺序执行,但是因为移动了代码,所以是跳转执行);
    • 将setup的四个扇区代码读入内存、
    • 打印logo;
    • 以及os的后面部分从硬盘引导到内存中;(包括了显式字符的bios 中断)
    • 跳转到set up继续执行
  3. 引导 setup扇区 (setup.s) :(获得一些参数,启动保护模式,完成OS 启动前的设置)

    • 读取扩展内存大小(默认1M ,以外的都是扩展内存)等其他硬件;形成很多 数据结构,来管理这些硬件;
    • 开始接管硬件、初始化;
    • 将OS代码,0x9000开始的代码移动到0地址;(之前boot 就是空出了这块空间)
    • 初始化 gdt表项
    • 从16位启动模式,进入32位的保护模式;jmpi 0 ,8 其实是跳转到0地址开始执行(根据表项映射的地址)跳转到system 的head.s 执行(寄存器cr0)
  4. system 模块( os 代码)

    • head.s :初始化一些gdt、页表;跳到main;
    • 进入main;初始化内存、中断、设备、始终、CPU 等内容;
      等…
  • 每次转换所有权,都需要修改 CS + PC 指针来跳转到对应段;
  • 系统启动后,OS 相关代码已经被拷贝到了0地址处;(上面还有GDT表、IDT表)
  • 同时初始化了mem_map 位图;就知道了有多少内存还可使用;
  • mem_map 位图:以4K的页为单位;

OS Interface

接口:用于连接两个东西、信号转换、屏蔽细节;

例如 fork、exec、write、pthread_create、open、…(printf这种底层就是调用的write)

而图形界面基于的是一种消息机制;(信号与槽也是)硬件中断产生了消息,在内核中是消息队列形式产生,应用层需要 getmessage 来获取消息,然后会执行不同进程/线程;所以: 操作系统提供 重要的函数(接口),称之为系统调用;能够进入到内核中;

所以有个统一的接口很重要:POSIX(Portable Operating System Interface 可移植操作系统接口)IEEE 制定的一个标准族;
在这里插入图片描述

标志含义全称
CPL当前进程的权限级别Current Privilege Level
RPL进程对段访问的请求权限Request Privilege Level
DPL存储在段描述符中,规定访问该段的权限级别Descriptor Privilege Level

系统调用的实现

为什么用户程序不能访问硬件(为什么不能进内核态)

  • 函数调用和系统调用的区别:
  • 为了保护、安全、限制;
  • 系统调用可以操作内存中的数据、操作应将;
  • 这样就区分开了用户态和内核态;

为何区分用户态、内核态(怎么不让进内核态的)

  • 当前程序在哪里执行,由CS:IP(两个合起来就是PC指针)来确定当前指令;而CS 的低两位用来表示:0 内核,3 用户态;
  • 每次访问的内存段,都有个特权级,跟当前指令的特权级相比较,就能知道能不能访问;
  • 内核态能访问任何数据,用户态不能访问内核数据;对于指令跳转也一样,实现了隔离;
    在这里插入图片描述

硬件提供了“主动进入内核 的方法)(如何进内核态)

  • intel X86 提供了中断指令 int:讲CS 中的CPL (Current Privilege Level) 改成 0,进入内核;

  • 这是用户程序发起调用内核代码的唯一方式;

系统调用的核心

  • 用户程序中包含一段包含 int 指令的代码;
  • 然后操作系统写中断处理处理函数,获取想调程序的编号;
  • 操作系统会根据编号执行响应代码;

在这里插入图片描述

  • 通过一个int 0x80内嵌汇编进入内核;通过不同的系统调用号,区分函数(系统调用好就是一个函数表的索引)
  • 简化就是:将一个系统调用号置给eax,然后调用int 0x80,然后就进入内核了 。

int 0x80如何实现进入内核态

  • GTD (全局描述表、Global Descriptor Table)表用于查询需要jmp 到哪里;

  • IDT(中断描述符表、Interrupt Descriptor Table)表用于int 查询jmp 到哪个中断处理函数中去;

  1. 所以 int 0x80 就是去IDT表查询处理system_call 中断的位置;
  2. 然后还会设置CPL = 0;内核中处理中断函数;
  3. 然后根据 sys_call_table( %eax,4) 根据传进来的系统调用号,来跳转;
  4. sys_call_table是个全局函数数组,其中可以看到第四个就是write 接口;
  • 这些都是深入内核,后面就是调用对应IO的驱动了;(文件系统)

在这里插入图片描述
在这里插入图片描述

总结

  1. 设置系统调用号(选择write 、fork…之类的)
  2. 通过 int 0x80 指令穿过接口,到达接口;
  3. 接口首先将DPL 设置为3 ;然后穿过,穿过后CPL 修改为了0;然后执行了system_call;
  4. system_call中通过移动查表,调用对应的真正的内核代码;这会就真正进入了内核态;可以任意访问内存了;

操作系统历史

IBSYS - > OS/360 - > MULTICS - > Unix - >Linux

  • 需要让计算机干很多任务 -> 多道程序设计的出现;
  • 作业之间的切换和调度成为了核心;既要有IO 任务,又要有计算任务;
  • 分时系统的产生(核心仍然是任务切换,资源复用思想很重要,虚拟内存也是一种复用);直到迎来了 UNIX ;慢慢由MINIX 到 了Linux;
  • 多进程结构是操作系统基本图谱;

DOS

  • QDOS以CP/M 为基础,将BASIC 和FAT 包含进入;(文件管理+编程环境)

  • MS- DOS 有了磁盘、文件、命令;使其更易使用;

  • 后来的Windows ;主要是文件、开发环境、图形界面对OS 的重要性的体现;

Mac OS 与IOS

  • Mac OS 核心是UNIX ,专注于界面、文件、媒体等和用户有关的内容;

总结

  • 核心技术仍然是程序执行、多进程、程序执行带动其他设备使用的基本结构;
  • 用户使用感受更加被重视;

CPU管理

  • 操作系统主要分为进程视图(CPU、MEM)、文件视图(磁盘、设备);

如何使用CPU

  • 取址 执行

存在的问题。以及如何管理

  • 单纯的取址 执行,导致CPU 利用率很低,大部分时间在等待IO ;
  • 所以需要在IO的时候,调度即可;这就是多道程序设计;这也是CPU 管理的核心;
  • 核心在于PC指针的切换;记录切出的时候的PC、各种寄存器(ax、bx…);每个程序有一个存放信息的数据结构: PCB;
  • 操作系统感知进程与组织进程,都是靠PCB ;

进程的引出

  • 也引出个概念:运行(执行)中的程序(进程),是为了和静态的程序进行区分;
  • 进程有开始、结束,程序没有;进程会走走停停,程序不会;进程需要记录ax、bx,程序不需要;…
  • 多个进程交替跑起来就是对CPU 的很好的管理;这其中PCB 就很重要,记录了各种状态和信息;

一个CPU上交替的执行多个程序:并发

进程、线程、及其调度

多进程图像

  • 启动了的程序就是进程;所以是多个进程推进;
  • 操作系统要做的是:将这些进程记录好,按照合理的次序进行推进**(资源分配、调度)**

在这里插入图片描述

  • main 中的fork 创建了第一个进程;init 进程 执行了shell/ Windows桌面

进程映像

  • 就绪队列、阻塞队列、

在这里插入图片描述
在这里插入图片描述

多进程如何组织,OS 如何交替多个进程

  • PCB 放在不同队列中,用状态来推进多个进程,进行状态转化;

  • 交替多进程:

    1. 进程进行IO 读写;PCB状态转换为 “W ”;将PCB 放进阻塞队列中
    2. 开始 schedule(); 函数;
    3. schedule(); :
      • 就绪队列中获取下一个进程PCB(调度);
      • 切换当前进程和下一个进程(用PCB实现)(保存当前现场,恢复下一个现场)

交替的三个部分:队列操作 + 调度 + 切换

在这里插入图片描述

多进程调度如何相互影响

  1. 内存影响:通过虚拟内存映射解决;
  2. 多进程互斥影响:同步、互斥;

进程管理+内存管理 = 多进程图像;

总结

  • 如何形成多进程图像:
  1. 读写PCB ;
  2. 操作寄存器完成切换
  3. 调度程序;
  4. 进程同步、合作(上锁)
  5. 地址映射

用户级线程

  • 进程的切换不仅要切换指令。虚拟内存的映射表也需要切换;
  • 进程 = 资源 + 指令执行序列;

能不能将资源 和 指令执行分开;

  • 能不能一个资源 + 读个指令执行序列;

  • 使得既有多段程序交替执行,又避免了进程切换的代价; – (线程)

  • 线程切换PC和少量寄存器就行;下面可得到,资源都不需要切换;

  • 而进程的切换就包括了:指令执行的切换 + 内存映射表和资源的切换;

在这里插入图片描述
TCB 与线程

  • TCB 和PCB一样,同样是为了保存线程的各种状态,比如栈顶指针esp;
  • 而线程栈,同样重要,里面保存了返回后的PC指针等…;
  • 其中ThreadCreate负责了: 申请栈、申请TCB、函数指针压栈、关联TCB与栈…

用户级线程

  • 以上的实现,都是可以用户自己实现的;自己实现申请与切换即可;(搜狗等浏览器都有用户级线程的支持)
  • 但是因为用户级线程TCB 在用户态;无法让OS 来调度,一个阻塞了,全都会阻塞掉;

内核级线程

  • 进程的切换分为了指令切换、资源切换;指令切换就是线程切换;
  • 进程是在内核中的,没有用户级进程一说;所以进程切换是内核级线程的切换;
  • 因为进程是要分配资源的,所以只能由内核分配,也就不存在用户级进程;

核心级线程

  • 多核处理器和多处理器又区别;(多核共享cache、MMU(内存映射))
  • 所以要有核心级线程的支持;只有支持核心级线程,多核处理器才有用;
  • 核心级线程,不单有自己的用户栈,还有自己的内核栈;

用户栈和内核栈

  • 线程中断后进入内核态;用户栈切换到了内核栈;
  • 同时内核栈中保存了用户栈的基、顶指针;以及PC 等指针;
  • 内核中可能阻塞,然后就切换TCB ,然后切换了线程栈,到了另一个线程的内核栈;
  • 然后再回到另一个线程的用户栈;

在这里插入图片描述
内核线程 switch_to 的五段论

  • 用户栈-> 内核栈 ->走到TCB -> TCB切换 -> 找到内核栈 -> 用户态
  • 用户角度只能看到用户栈切到另一个用户栈的过程;
  1. 中断产生,进入内核;(切换到了内核栈)
  2. 中断处理,可能引发切换
  3. 找到下一个线程的TCB;
  4. 内核栈的切换、内核线程的切换;
  5. 退出中断;另一个线程由用户态切换到用户态,由用户栈切换到用户栈;

如果涉及到进程切换,需要有地址的切换;(地址映射表的切换)

内核线程 创建

  • Thread_create 包括了用户栈、内核栈、TCB 的创建;
  • 并完成了内核栈与TCB 的关联;并于用户栈的关联;

在这里插入图片描述

内核级线程实现(不懂)

在这里插入图片描述

  • 内核线程的实现:主要在于两套栈的切换;

系统调用引起中断

  • 进入内核态,内核栈保存了用户栈的信息。
  • 用户栈保存了当前现场,以备后面恢复现场;

调度

  • 根据阻塞状态、时间片来判断调度;

switch_to TSS

  • TSS(task state segment)切换;就是任务的切换;

  • TSS描述符表,它记录了一个TSS的信息,同时还有一个TR寄存器,它指向当前任务的TSS。任务切换的时候,CPU会将原寄存器的内容写出到相应的TSS,同时将新TSS的内容填到寄存器中,这样就实现了任务的切换。

  • TSS在任务切换过程中起着重要作用,通过它实现任务的挂起和恢复。所谓任务切换是指挂起当前正在执行的任务,恢复或启动执行另一个任务。Linux任务切换是通过switch_to这个宏来实现的,它利用长跳指令,当长跳指令的操作数是TSS描述符的时候,就会引起CPU的任务的切换,此时,CPU将所有寄存器的状态保存到当前任务寄存器TR所指向的TSS段中,然后利用长跳指令的操作数(TSS描述符)找到新任务的TSS段,并将其中的内容填写到各个寄存器中,最后,将新任务的TSS选择符更新到TR中。这样系统就开始运行新切换的任务了。由此可见,通过在TSS中保存任务现场各寄存器状态的完整映象,实现了任务的切换。 task_struct中的tss成员就是记录TSS段内容的。当进程被切换前,该进程用tss_struct保存处理器的所有寄存器的当前值。当进程重新执行时,CPU利用tss恢复寄存器状态。

copy_process : 创建栈;

  • 申请内存空间、创建TCB、创建内核栈/用户栈、关联栈和TCB;
    在这里插入图片描述

CPU调度策略

schedule

  • 先来先服务调度算法:FIFO作为队列;

  • SJF 短进程优先调度算法:不利于长作业进程的执行;

  • 高优先权优先调度算法:前台进程优先级高于后台进程;// 可以加上饥饿,一直没被执行的,慢慢增加优先级;然后执行的程序优先级慢慢下降;

  • 时间片轮转调度算法

  • 多级反馈队列调度算法

在低优先级的队列中的进程在运行时,又有新到达的作业,此时须立即把正在运行的进程放回当前队列的队尾,然后把处理机分给高优先级进程。换而言之,任何时刻,只有当第1~i-1队列全部为空时,才会去执行第i队列的进程(抢占式)。特别说明,当再度运行到当前队列的该进程时,仅分配上次还未完成的时间片,不再分配该队列对应的完整时间片。
在这里插入图片描述

schedule实例

在这里插入图片描述

进程同步

进程同步和信号量

  • 同步:多个线程/进程,按照一定顺序向前推进;让进程走走停停,保证多进程合作的合理有序;
  • 信号量 :通过对这个量的访问和修改,让多个进程有序进行;
  • 信号用于通知;表达少量元素;wakeup() 通知sleep();

信号到信号量

  • 信号量可以用于记录阻塞了的线程,用于唤醒时判断
  • P操作: --的时候如果资源小于0了;就睡眠;
  • V操作:++后,如果资源还是小于等于0,说明有资源在等待,就唤醒队列;
    在这里插入图片描述
  • 互斥使用:访问共享内存;P V 成对出现;访问前P,访问后V
  • 同步使用:生产者消费者模型;生产完一个用V ,消费者消费之前P;

信号量实现生产者消费者问题

  • full信号量用于 生产者V 消费者P ;生产者生产一个后V一次;消费者消费前P一次,如果小于0就不消费了,表示没有东西可以消费;初始化为0表示刚开始没有;
  • empty信号量用于 生产者P 消费者V ;生产者生产之前P一次,如果小于0了就不生产了;消费者消费一个后V一次,表示消耗了一个;初始化为BUFFER SIZE表示最多能生产多少个,表示的是缓冲区大小;
  • mutex表示互斥信号量;用于进入临界区的互斥性;初始为1 为互斥信号量;
    在这里插入图片描述

信号量临界区保护

  • 对共享变量(信号量)访问的加锁;

加锁方式

  • 最简单的方法就是关中断;不让调度;(多CPU、多核不好使)
  • 硬件原子指令法;TAS(TestAndSet)

保护原则

  • 互斥进入
  • 有空让进
  • 有限等待

信号量代码实现(不懂)

  • 主要的是一个信号量的value + 一个PCB 的queue(保存阻塞了的进程);
  • 因为用于多个进程使用,所以是在内核空间中的;
  • 所以信号量就是一个大家共同能看到的一个整数,根据这个整数表示当前进程该怎么进行;

信号量实现过程

  • P 的过程:(过程中要加锁)(linux 0.11 只适合单核的时候,通过开关中断实现加锁)

      1. value ;
      1. 判断小于0的话,阻塞自己(通过state);然后把自己加入队列中;
      1. 调度;
  • V 的过程:(过程中要加锁)

      1. ++value ;
      1. 判断大于0的话;从队列中取出一个进程,设置就绪态;
      1. 调度;

在这里插入图片描述

死锁处理

在这里插入图片描述
在这里插入图片描述
死锁解决办法:
在这里插入图片描述

内存

逻辑地址-》物理地址
在这里插入图片描述
分段:若干部分(段)组成,每个段有各自的特点、用途
请添加图片描述
内存分区,供段代码使用
在这里插入图片描述
分页,解决分区内存使用效率问题,即空闲分区(内存碎片)
请添加图片描述
多级页表,解决页表太大造成浪费问题,牺牲部分查找时间来节省空间方式
在这里插入图片描述
快表,提升多级页表查找时间
在这里插入图片描述
段页结合:虚拟内存
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
虚拟内存,换入换出(类似仓库和柜台关系)
在这里插入图片描述
在这里插入图片描述
换出

  • FIFO
  • MIN
  • LRU||LRU近似实现
  • Clock算法(最优)

给进程分配多少页框:求工作集

  • 分配的多,请求调页导致的内存高效利用就没用了!
  • 那分配的太少,“颠簸“

IO设备

IO与显示器

  1. 向控制器发送指令;(发送过程利用的OS提供的文件视图)
  2. 外设控制器完成工作后,向CPU发送中断信号;

操作系统给用户提供了一个简单的视图:文件视图;

在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值