花了一周多时间把操作系统的课程看了一遍,晚上结课的时候尝试性地想看着笔记的标题回忆一下内容,发现……嗯……一片混沌……,趁热打铁做个总结吧,辅以uCoreLab上的coding!一个走!
1 操作系统的启动
- 未启动前,os和Bootloader都存放在disk中;
- BIOS(basic I/O system)基本的I/O处理系统,开机之后会检测到外设(Bootlaoder),就将Bootloader从磁盘的磁盘引导扇区加载到它的起始地址中
- Bootloader到内存后将操作系统的代码和数据加载到内存中,跳转到它的起始地址,此时所有的硬件就都在OS管理下了,即操作系统已经启动
- 应用程序要访问硬件就需要通过OS
2 为什么应用程序要通过OS访问外设?
- 因为在计算机运行中,内核是被信任的第三方,有些应用程序时是不安全的
- 至于内核才可以执行特权指令
- 也是方便应用程序,不用去管底层
3 中断,异常,系统调用
中断由于外设;异常来源于不良的应用程序,非法指令或其他处理状态如内存出错,是CPU事件;系统调用是应用程序主动向操作系统发出服务请求
3.1 中断处理机制
- 硬件会将内部/外部事件设置中断标记,并记录中断事件的ID,即中断向量地址
- 软件首先保存当前处理状态,做中断服务程序处理,处理好之后清楚中断标记,最后恢复之前保存的处理状态
- 中断服务程序处理:收到中断,查中断表,找到中断服务例程的起始地址,直接跳到那儿执行
3.2 异常处理机制
- 保存现场,异常处理,恢复现场
- 异常处理:杀死异常程序或者重新执行异常指令
3.3 系统调用
程序访问主要通过高层次的API接口而不是直接进行系统调用,一条指令就会触发一个系统调用
- 通常情况下,存在与每个系统调用相关的序号,系统调用接口根据这些序号来维护表的索引
- 系统调用接口调用内核态中预期的系统调用,并返回系统调用的状态和其他任何返回值
- 用户不需要知道系统调用是如何实现的,只需要获取API和了解OS将什么作为返回结果,OS接口的细节大部分隐藏在API中,并通过运行程序支持的库来管理
内核态与用户态
- 用户态: 应用程序在执行的过程中,CPU执行的特权级的状态很低,不能访问特殊机器指令和IO
- 内核态: 应用程序在执行的过程中,CPU的特权级状态很高,OS可以执行CPU任何一条指令
- 系统调用时涉及到特权级从用户态到内核态的转换,应用程序和操作系统有各自的堆栈,这个变化比函数调用的开销更大,但更安全和可靠///程序调用是在一个栈空间实现参数的调用和返回
跨越操作系统边界开销
跨越边界的开销在执行时间上超过程序调用
开销包括
- 建立中断/异常/系统调用号 与对应服务例程映射关系的初始化开销
- 建立内核堆栈(操作系统和应用程序的堆栈不一样
- 验证参数(操作系统会检查参数
- 内核态映射到用户态的地址空间,更新页面映射权限
- 内核态独立地址空间TLB
MMU, TLB
- mmu: memory management unit 存储器管理单元,
是CPU中用来管理虚拟内存器,物理存储器的控制线路,同时也负责虚拟地址映射为物理地址,以及提供硬件机制的内存访问授权 - tlb Translation lookaside buffer 传输后备缓冲器是一个内存管理单元用于改进虚拟地址到物理地址转换速度的缓存。TLB是一个小的,虚拟寻址的缓存,如果没有TLB,则每次取数据都需要两次访问内存,即查页表获得物理地址和取数据
参考资料
https://www.bilibili.com/video/av6538245?from=search&seid=436175425155932048
实验部分:lab0- start coding
1. 了解gcc :
2. gcc常用选项
这边-g是方便gdb调试
3.尝试用gdb调试程序,断点的应用
- 作业:
1.1. 按提示输入gcc -g之后会生成a.out文件,若要运行代码则./a.out
1.2. 尝试在gdb环境下调试代码,gdb a.out,就进入gdb环境
1.3. 输入l查看源代码
1.4. 用break 加数字的指令对相应的行添加断点,可用info breakpointers查看断点情况
1.5.可以用gdb指令对程序进行调试,如r,s,c分别表示run,step,continue进行调试 -
gdb指令整理
list :简记为 l ,其作用就是列出程序的源代码,默认每次显示10行;
break n (简写b n):在第n行处设置断点;
delete 断点号n:删除第n个断点;
disable 断点号n:暂停第n个断点;
enable 断点号n:开启第n个断点;
clear 行号n:清除第n行的断点;
info b (info breakpoints) :显示当前程序的断点设置情况;
delete breakpoints:清除所有断点;“”《》、
continue(简写 c): 继续执行程序,直到下一个断点或者结束;
next(简写 n ):单步执行程序,但是遇到函数时会直接跳过函数,不进入函数;
step(简写 s) :单步执行程序,但是遇到函数会进入函数;
until:当你厌倦了在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体;
until+行号: 运行至某行,不仅仅用来跳出循环;
finish: 运行程序,直到当前函数完成返回,并打印函数返回时的堆栈地址和返回值及参数值等信息;
call 函数(参数):调用程序中可见的函数,并传递“参数”,如:call gdb_test(55);
info program: 来查看程序的是否在运行,进程号,被暂停的原因;
quit:简记为 q ,退出gdb;
where:查出程序出错的地方
4. 5. 相关的C编程
根据指令进行编译修改, ok