Operating System Basic Notes
OS Definition
操作系统是一个大型的程序系统, 它负责(处理机管理, 存储管理, 设备管理, 文件系统):
- 计算机系统软、硬件资源的分配和使用
- 控制和协调并发活动
- 提供用户接口, 使用户获得良好的工作环境
GCC 内联汇编
asm ( assembler template // assembly language
:=output operands // 约定输出
:input operands // 约定输入
:clobbers // 约定插入
);
constraints:
- m/v/o = memory
- r = register
- Q = ea/b/c/dx
- a = eax
- b = ebx
- c = ecx
- d = edx
- D = edi
- S = esi
- 0/n = first/nth constraints
基本概念
操作系统的特性
- 并发性 : 能处理多个同时性活动的能力
- 共享性 : 多个计算任务对系统资源的共同享用
- 不确定性: 操作系统能处理随机发生的多个事件 - 程序运行次序的不确定性, 程序运行时间的不确定性
操作系统的资源管理功能
处理器调度
- 确定进程调度策略
- 给出进程调度算法
- 进行处理机的分派
存储器管理
- 存储分配与存储无关性
为用户提供逻辑地址, 解决主存分配问题
- 存储保护
实现系统程序与用户程序之间的隔离, 实现不同用户程序之间的隔离
- 存储扩充
虚拟内存管理: 主存+磁盘, 为每个进程管理一个虚拟内存映射链表
设备管理
- 设备无关性
用户向系统申请和使用的设备无关实际操作的设备, 操作系统为用户提供统一的逻辑设备(名)
- 设备分配(独享分配/共享分配/虚拟分配)
- 设备的传输控制(设备启动处理, 设备中断处理, 设备结束处理)
组织设备完成 I/O 操作, 并正确处理中断
文件资源管理
为用户提供一种简便、统一的存取和管理信息的方法, 解决信息的共享/数据的存取控制/数据的保密等问题:
- 实现用户的信息组织
- 提供存取方法
- 实现文件共享
- 保证文件安全
- 保证文件完整性
- 完成磁盘空间分配
操作系统的演变
- 单用户系统(45-55) -> 批处理系统(55-65) -> 多道系统(65-80) -> 分时系统(70-) -> 分布式系 统
- 手工系统 -人机矛盾-> 联机批处理系统 -CPU I/O 矛盾 -> 脱机批处理系统 -响应能力-> 执行系统(中断/通道) -并行-> 多道批处理系统(粗粒度) -> 分时系统(细粒度) -> 实时系统 -> 个人/网络/分布式系统
批处理系统
作业成批送入计算机, 然后由作业调度程序自动选择作业, 在系统内(多道)运行
- 系统吞吐率高: 脱机/多道运行
- 作业周转时间长, 用户使用不方便, 缺少交互性
分时系统
采用时间片(time slice)轮转(round robin)的方法, 使计算机同时为多个终端用户服务, 保证对每个用户都有足够快的响应时间, 并提供交互会话功能
- 并行性
- 独占性
- 交互性
单处理器系统: 处理器与设备/处理器与通道/通道与通道/设备与设备可以同时刻并行(真正意义上的同时进行)
实时系统
实时系统对外部输入的信息, 能够在规定时间内处理完毕并作出反应(实时控制/实时信息处理) e.g 嵌入式操作系统
- 可靠性
- 安全性
- 及时响应
操作系统虚拟机
- 在裸机上配置了操作系统后便构成了操作系统虚拟机
- 裸机的指令系统: 机器指令; 操作系统虚拟机的指令系统: 系统调用
用户接口
- 操作/命令接口(操作命令): 作业控制语言/键盘命令(CLI)/图形化用户界面(GUI)
- 程序接口(系统功能调用): 在用户程序中可以直接使用系统功能调用(system call)请求操作系统提供的服务
操作系统的组织结构
- 一体化结构
- 模块化结构
- 可扩展内核(微内核)结构
- 层次化结构
并发
Concurrent
程序并发的特点
- 程序执行的间断性
- 相互通信的可能性
- 资源分配的动态性
启动
BIOS
- 基本输入输出程序
- 系统设置信息
- 开机后自检程序
- 系统自启动程序
启动顺序
寄存器
- CF: 初值 F000H
- EIP: 初值 FFF0H
(FFF)F0000H+FFF0H = FFFFFFF0H,
BIOS 的 EPROM(Erasable Programmable Read Only Memory) 处
加电后第一条指令一般是 ljmp(实模式下, 内存 !MB), 跳转地址为 CF<<4+EIP
,
跳转至 BIOS 例行程序起始点.
BIOS Config
BIOS 根据设置(硬盘/U 盘/网络启动), 加载存储设备的主引导扇区(Master Boot Record)(第一个扇区)的 512 字节至内存 0x7c00 处, 开始执行第一条指令(Boot Loader)
Boot Loader
实模式与保护模式带来的问题:
- 在实模式的寻址模式中, 令物理地址为 16 位段寄存器左移 4 位加 16 位逻辑地址的偏移所得的 20 位地址
- 若要访问 1MB 之后的内存, 则必须开启 A20 Line 开关(关闭 wrap around), 将 32 位地址总线打开, 并进入保护模式(Protect Mode)
- 在实模式中, 0~4KB 为中断向量表保留, 640KB ~ 1MB 为显存与 BIOS 保留, 实际可用的内存只有 636KB
- 考虑到日后 内核镜像的体积有超过 1MB 的可能, 所以将其装载到物理地址 1MB(0x100000) 之后连续的一块内存中更好.
- 若要装载内核到物理地址 1MB 之后(实模式下无法访问), 可在实模式中暂时将其装载到一个临时位置, 待进入保护模式之后再移动至合适位置
解决方案:
- 将内核镜像装入内存临时地址
- 开启保护模式
- 移动内核镜像至 1MB 之后合适位置
- 跳转至内核入口(
jmp addr
用以修改 cs:eip)
标志
lab1/tools/sign.c:
- 有效字节小于 510 bytes
- 结尾为 0x55aa
- 总计字节小于 512 bytes
基本功能
- 切换到保护模式, 启动段机制
- 通过 8042 键盘控制器的端口, 开启 A20, 关闭 memory wrap around, 获取足够内存空间
; 键盘控制器的命令
; 0xD0 Read Output Port
; 0xD1 Write Output Port
; 0xDD Enable A20 Address Line
; 0xDF Disable A20 Address Line
; 0x60 - 数据端口, 0x64 - 命令端口
call empty_8042
mov al,0xd1
out 0x64,al
call empty_8042
mov al,0xdf
out 0x60,al
call empty_8042
empty_8042:
dw 00ebh, 00ebh
in al,64h
test al,2
jnz empty_8042
ret
-
置 cr0 保护模式标志位(bit0) 为 1
-
加载全局描述符表
-
设置各个通用寄存器与段寄存器
-
从硬盘上加载 某种(kernel in ELF) 格式的 os kernel(在硬盘中紧邻 MBR) 至内存的固定区域
-
跳转到 os kernel 的入口点(entry point), 转移控制权至 os
保护模式与段机制
- CS -> 全局描述符表(其起始地址与表大小位于 gdt 寄存器中)某项(每项存有 base/limit 等信息) -> 局部描述符表 -> 段选择子(段的基本信息) -> 基址+EIP -> 线性地址 ---页机制---> 物理地址
- 将 cr0 寄存器 bit0 置为 1, 表示进入了保护模式, 段机制开始起作用
物理内存管理
Boot Loader 探测机器内存分布
为内存管理模块提供基础: 在进入实模式前, 调用 int 15h(88h, e801h, e820h), 借助 BIOS 中断获取内存信息
Boot Loader 基本概念
Boot Loader 基本目标
- 抽象: 逻辑地址空间(线性物理地址映射)
- 保护: 独立地址空间(进程间互不影响)
- 共享: 访问相同内存(内核空间与共享库)
- 虚拟化: 独占内存空间假象
基本管理方式
- 重定位(relocation)
- 分段(segmentation): 代码段/数据段
- 分页(paging)
- 虚拟存储(virtual memory): 内存视作硬盘的缓存, 硬盘视作虚拟内存
地址生成
地址生成时机
- 编译时
- 链接时
- 加载时
- 执行时(相对寻址)
地址映射
软硬件结合:
逻辑地址 ---> 物理地址
- 硬件(CPU/MMU)完成映射地址
- 操作系统建立映射规则(页表)
地址检查
软硬件结合:
- 操作系统设置的段机制和段长度
- 硬件(CPU/MMU)根据段信息进行地址检查(内存访问是否异常)
连续内存分配
- malloc
- free
内存碎片
- 外部碎片: 已分配单元间无法利用空闲单元(请求内存单元过大)
- 内部碎片: 已分配单元内空闲单元
动态分配策略
- Fist-fit(最先匹配): 使用第一个可利用空闲块 - 容易产生外部碎片, 分配大块效率低
- Best-fit(最佳匹配): 使用利用度最高的空闲块 - 外部碎片过小, 释放时需重新排列空闲块链表(升序)
- Worst-fit(最差匹配): 使用利用度最差的空闲块 - 分配中块效率高, 释放时需重新排列空闲块链表(降序)
碎片整理策略
ucore 实现
- 连续存放 n 个 page 结构, 形式表示内存页, 并在连续内存块的首页(header page)保存此连续块的连续页数目
- 维护一个链表, 链表每项为大块连续内存块的起始页(header page address) 和 连续页数目, 管理分散的连续内存块
紧凑
Compaction, 将不同进程占用内存单元移至较为集中的地方:
- 只可移动 可动态重定位程序
- 只可移动 等待状态进程
分区对换
Swapping In and Swapping Out:
将等待状态进程的分区对换至外存,以增大可用内存单元
e.g Linux Swap 分区: 安装系统时一般切割大小为内存大小的 50%~100% 的外存作为 Swap 分区
Malloc 实现策略
启发式编程
Heuristic Programming:
- 建立已分配 void 指针表,free 函数执行时,只回收表中存在的指针;不存在则报错
- 对 heap 进行分区 - 小/中/大块内存请求,分别从不同区域(8/16/32 最小单位区)分配
- 记录当前堆块的信息,如长度,空闲状态
- 记录周围环境信息,如保留上/下一堆块的指针或记录上/下堆块空闲状态
伙伴系统
Buddy System:
- 可分配内存单元总大小为 2^n
- 总是将大小 小于请求大小的2 倍且为2 的幂次方 的某块内存单元分配出去(大小为 2^(i-1))
合并空闲块
- 空闲块相邻
- 空闲块等大
- 低地址空闲块的 起始地址 必须为 空闲块大小 的 2 的幂次方倍(2 倍以上)
非连续内存分配
- 支持一个程序使用非连续的物理地址空间
- 支持共享代码与数据
- 支持动态加载与动态链接
段式存储管理
将逻辑地址划分, 低位表示段内偏移, 高位(取摸)表示段号(类比缓存中的内存地址)
GDT
typedef struct gdt_ptr {
uint16_t gdt_limit; // gdt_length - 1
uint32_t gdt_base;
} __attribute__((packed)) gdt_ptr_t;
- 用 16 位来表示表的长度(2 ^ 16 = 65532 bytes), 除以每一个描述符的 8 字节, 最多能创建 8192 个描述符
页式存储管理
开启页机制:
- init page directory(首址位于 cr3 寄存器), page table
- update GDT
- update ds,es,ss
- update cs with jmp instruction
- cr0 寄存器 bit31(most bit) 置 1
虚拟地址
TLB (Translation Lookaside Buffer in CPU/PM):
- Virtual Address =
2^(bits of virtual page offset) * virtual page number + virtual page offset
. - VA = VPN (virtual page number point to PPN) + VPO(virtual page offset = PPO).
- 根据 VPN 在页表中找到对应表项(VPN 表示项号), 每项保存着 PPN.
- TLB = TLBT (tag) + TLBI(index) + VPO.
- 因为内存局部性原理, TLB 一般只需要很小 (比如 64 项) 即可达到不错的效果.
物理地址
C(cache) PPO = VPO:
- Page Frame (帧): 高位为帧号, 低位为偏移.
- Physical Address =
2^(bits of phy page offset) * phy page/frame frame number + phy page offset
- PA = PPN (physical page number) + PPO (physical page offset = VPO).
- CA = CT(tag) + CI(index) + CO(offset).
页表
- 页表由操作系统建立, 硬件(CPU/MMU)根据页表信息将虚拟地址映射为物理地址
页表结构
- FN/PPN
- 标志位: resident bit(存在位)/dirty bit(修改位)/reference(clock) bit(引用位)