本文为学习李治军老师《操作系统原理、实现与实践》第一章及第二章的总结。
参考资料:
第一章 系统启动
什么是操作系统
- 是计算机硬件和应用之间的一层软件,方便高效使用硬件;
- 操作系统管理以下硬件:CPU管理、内存管理、终端管理、磁盘管理、文件管理等;
- 计算机工作原理:取指-执行。
操作系统核心轮廓
- 多进程视图:CPU + 内存;
- 文件视图:I/O + 磁盘。
操作系统启动过程
-
系统准备
-
读入内核
- 开机后检查硬件情况,BIOS读入磁盘0磁道0扇区(引导扇区)的bootsect.s;
- 执行bootsect.s:读入setup.s、显示系统标识、读入system主体部分;
-
执行setup.s
- 读取内存大小、硬件参数;
- 启动保护模式:
- 从16位转到32位,扩大寻址范围,即从实时模式转到保护模式, 使得寻址方式发生了改变:
实时模式: 地址翻译 CS<<4 + IP
保护模式 :根据CS查GDT表 + IP - 跳转到0x00执行system,即转到head.s;
- 从16位转到32位,扩大寻址范围,即从实时模式转到保护模式, 使得寻址方式发生了改变:
-
启动段页
- 执行head.s: 初始化GDT(查找地址),IDT表(查找中断入口程序)、设置页表;
- 转到main()函数;
-
-
系统初始化
- 执行main()函数:初始化内存mem_init()、初始化其他重要数据结构;
-
系统运转进入shell。
实践项目1
- 控制操作系统启动
第二章 系统接口
操作系统接口
- 操作系统接口:连接上层用户和操作系统软件;
- 操作系统提供这样的接口函数,表现为函数调用,又称为系统调用(system_call)。
基本系统调用及应用
-
和进程有关的系统调用:fork、exec、wait、exit
系统调用 作用 int fork() 创建进程 void exec(const char *filepath, char *arg1, …) 从磁盘上载入并执行某个可执行程序 int wait(int *stat_addr) 等到子进程退出时才继续执行 void exit(int status) 进程退出 -
和文件有关的系统调用:open、read、write
系统调用 作用 open(char *filename, int mode) 打开文件 read(int fd, char *buf, int count) 将fd对应的文件读到内存缓冲区,读入count个字节 write(int fd, char*buf, int count) 将fd对应的文件写入到内存缓冲区 -
printf、scanf
- printf、scanf是用来分别操纵显示器和键盘的函数;
- printf()、scanf()是两个库函数,不是系统调用,真正的实现要调用write和read。
系统调用的实现机理
-
内核态与用户态:
-
为保证操作系统安全,将操作系统代码分为用户态和内核态,通过处理器的“硬件设计”来防止用户访问内核代码,对应的内存中的区域叫用户段和内核段;
-
当前特权级(CPL表示当前执行指令的特权级)、描述符特权级(DPL)表示目标段的特权级,在访问/跳转时进行特权级检查;
-
-
系统调用与int 0x80
-
对于intel x86,中断指令int是用户程序发起的调用内核代码的唯一方式,通过int指令将使CS中的CPL改成0,进入“内核”;
-
系统调用的核心:
-
用户程序包含一段包含int 0x80指令的代码(c语言库函数);
-
操作系统写中断处理,获取想调程序的编号;
-
操作系统根据编号执行相应的代码;
-
-
实践项目2
- 添加系统调用
- 运行bochs会在虚拟软驱上挂在Image,在硬盘上挂载hdc.img;
- 在Linux0.11上访问文件系统,访问的就是hdc.img文件内虚拟的文件系统:在宿主机上通过mount命令访问,访问完后需要通过umount命令退出。