操作系统-基础

Posted by 小拳头 on Friday, October 2, 2020

操作系统的课程来自哈工大的李志军老师, 视频和课件可以在B站找到, 配套的实验在蓝桥可以找到. 课程分为四个部分: 操作系统基础, 进程与线程, 内存管理, 设备驱动与文件系统. 视频部分有22小时.

操作系统发展

从图灵机到通用图灵机, 增加了控制器动作和状态, 控制器就可以通过不同的逻辑来操作数据.

冯·诺依曼存储程序思想可以概括为取址执行: 将程序和数据存放到计算机内存中,计算机在程序的控制下一步一步进行处理, 执行一条指令的过程可参考<汇编语言第三版>P26. 简单的汇编介绍: 汇编语言入门教程.

这里我想提一个小的知识点: 内存本身是不分段的, 段的划分来自CPU, 如8086中物理地址 = 基础(段)地址 * 16 + 偏移地址, 其中基础地址对应的一段区间就是连续的地址, 我们就可以把它看作是一个段. 这里的*16相当于把16进制数左移一位.

CPU中的CS是代码段寄存器, IP是指令指针寄存器, 任意时刻, CPU将CS:IP指向的内容当做指令执行. 我们把CS就看做基础地址, IP看做偏移地址. 读取一条指令后(指令到达了指令缓冲器), IP中的值会自动增加, 使CPU可以读取下一条指令. 有时候CS:IP也叫PC(program counter), 很容易让人联想到JVM中的PC寄存器.

操作系统启动(todo)

暂跳过.

操作系统接口

应用软件和操作系统交互主要通过命令行过着图形界面. 命令行就是命令程序, 图形界面就是消息框架程序+消息处理程序, 实际上也是调用了一些函数. 而这些系统调用的函数就是操作系统的接口. POSIX(Portable Operating System Interface of Unix)定义了一些接口, 举例如下图, 我们对此可以有一个大致的印象, 如果系统调用不变, 那么一个代码就可以在不同的操作系统运行.

系统调用

程序不能直接从内核调用数据, 不能jmp, 也不能mov. 如果可以调用, root的密码也就可以轻易地得到了, 而且程序也可以轻易地修改内核数据, 这显然是不安全的. 所以处理器在硬件设计上把内存被分为了内核段用户段.

能否调用某一部分的数据需要就检查段寄存器中的特权级. 有两个重要的段寄存器: CPL(当前特权级)和DPL(目标内存段特权级). 其中0对应内核态, 3对应用户态, 而只有当CPL<=DPL时, 命令才能执行. 在初始化的时候, DPL就被初始化好了, DPL存在在GDT的表项中. 而CPL对应的是CS的最后两位.

那系统调用是如何实现的呢? 其实中断是唯一能进入内核的方法, 系统调用的核心有三步:

  1. 用户程序中包含一段包含int 0x80指令的代码.
  2. 操作系统写中断处理, 获取想调程序的编号
  3. 操作系统根据编号执行相应代码

下图是直观的例子, 左图直接调用是不行的, 因为CPL=3, DPL=0. 右图中, 首先设置了系统调用号eax=72, 告诉操作系统我们想调用哪个函数, 再通过int 0x80把DPL执为3(通过_set_gate), 所以指令才能穿过接口. 然后将CPL执为0, 进入内核态, 进行sys_write调用.

参考

  1. 操作系统-李志军
  2. 配套实验
  3. 汇编语言-王爽

comments powered by Disqus