期中总结
计算机是如何工作的http://www.cnblogs.com/L20135304/p/5215409.html
操作系统是如何工作的http://www.cnblogs.com/L20135304/p/5246820.html
构建一个简单的Linux系统 MenuOs http://www.cnblogs.com/L20135304/p/5272481.html
扒开系统调用的三层皮http://www.cnblogs.com/L20135304/p/5299761.html
扒开系统调用的三层皮(下)http://www.cnblogs.com/L20135304/p/5326881.html
进程描述和创建http://www.cnblogs.com/L20135304/p/5350527.html
可执行程序的装载http://www.cnblogs.com/L20135304/p/5375698.html
进程的切换和系统的一般执行过程http://www.cnblogs.com/L20135304/p/5402218.html
一、计算机是如何工作的
1.冯 诺依曼体系结构是指具有存储程序的计算机系统
-
硬件:CPU与内存通过主线连接;CPU上有一块寄存器叫做IP,该寄存器相当于指针,总是指向内存的代码段;CPU总是执行IP指向的指令然后IP自加一
-
软件(计算机如何识别指令):通过ABI(程序与计算机的接口界面
2.常见的寻址方式
- 寄存器寻址(操作的都是寄存器):将eax的值直接赋值给edx;
- 立即数寻址:将十六进制的数值123(这个立即数)直接放到edx中(和内存也没有关系);
- 直接寻址:将0x123这个地址所指向的内存数据放到寄存器edx中;
- 间接寻址:将ebx的值作为一个内存地址,这个地址所存储的数据放到edx中;
- 变址寻址:与间接寻址类似,是把ebx的值加上4作为地址
二、操作系统是如何工作的
1.计算机是如何工作的?(总结)——三个法宝
-
存储程序计算机工作模型,计算机系统最最基础性的逻辑结构;
-
函数调用堆栈,高级语言得以运行的基础,只有机器语言和汇编语言的时候堆栈机制对于计算机来说并不那么重要,但有了高级语言及函数,堆栈成为了计算机的基础功能;函数参数传递机制和局部变量存储
-
中断,多道程序操作系统的基点,没有中断机制程序只能从头一直运行结束才有可能开始运行其他程序。
2.操作系统两把利剑
- 进程切换
- 中断上下文
三、构造一个简单的Linux系统MenuOS
1.创建及调试步骤:
-
下载安装完后,启动并使它一开始就停止:
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
-
然后启动gdb调试,设置断点,单步运行等,这个在后面的学习过程中都会经常使用
2.分析这个内核的启动过程
-
x86 CPU启动的第一个动作CS:EIP=FFFF:0000H(换算为物理地址为000FFFF0H,因为16位CPU有20根地址线),即BIOS程序的位置;
-
BIOS例行程序检测完硬件并完成相应的初始化之后就会寻找可引导介质,找到后把引导程序加载到指定内存区域后,就把控制权交给了引导程序;
-
引导程序BootLoader开始负责操作系统初始化,然后启动操作系统。启动操作系统时一般会指定kernel、initrd和root所在的分区和目录;
-
内核启动过程包括start_kernel之前和之后,之前全部是做初始化的汇编指令,之后开始C代码的操作系统初始化,最后执行第一个用户态进程init(这里和讲解中以及实际的代码main.c是一致的);
-
一般分两阶段启动,先是利用initrd的内存文件系统,然后切换到硬盘文件系统继续启动。initrd文件的功能主要有两个:
(1)提供开机必需的但kernel文件(即vmlinuz)没有提供的驱动模块(modules)
(2)负责加载硬盘上的根文件系统并执行其中的/sbin/init程序进而将开机过程持续下去
3.init进程的解析——“道生一,一生二”
- start_kernel创建了cpu_idle,即0号进程
- 0号进程又创建了两个线程kernel_init和kthreadd
- kernel_init即1号进程,这个进程最终启动了用户态
4.扒开系统调用的三层皮(上)
- 用户态、内核态和中断处理过程
- 系统调用概括
- 使用库函数API获取系统当前时间
-
使用C代码中嵌入汇编代码触发系统调用获取系统当前时间
5.扒开应用系统的三层皮(下)
- 给MenuOS增加time和time-asm命令
- 使用gdb跟踪系统调用内核函数sys_time
-
系统调用在内核代码中的工作机制和初始化
系统调用在内核代码中的工作机制和初始化,简化后便于理解的system_call伪代码,简单浏览system_call和iret之间的主要代码。
6.进程的描述和进程的创建
- 进程的描述
-
进程的创建
进程的创建概览及fork一个进程的用户态代码 理解进程创建过程复杂代码的方法 浏览进程创建过程相关的关键代码 使用gdb跟踪创建新进程的过程
7.可执行程序的装载
```javascript
(一)预处理、编译、链接和目标文件的格式
1.可执行程序是怎么得来的
2.目标文件的格式ELF
3.静态链接的ELF可执行文件和进程的地址空间
(二)可执行程序、共享库和动态加载
1.装载可执行程序之前的工作
2.装载时动态链接和运行时动态链接应用举例
(三)可执行程序的装载
1.可执行程序的装载相关关键问题分析
2.sys_execve的内部处理过程
3.使用gdb跟踪sys_execve内核函数的处理过程
4.可执行程序的装载与庄生梦蝶的故事
5.浅析动态链接的可执行程序的装载##8.进程的切换和系统的一般执行过程
javascript
(一)进程切换的关键代码switch_to分析
1.进程进度与进程调度的时机分析
2.进程上下文切换相关代码分析
(二)Linux系统的一般执行过程
1.Linux系统的一般执行过程分析
2.Linux系统执行过程中的几个特殊情况
(三)Linux系统架构和执行过程概览
1.Linux操作系统架构概览
2.最简单也是最复杂的操作——执行ls操作
3.从CPU和内存的角度看Linux系统的执行
心得体会
通过这几周的学习,使我对操作系统有了更加深入的了解。尤其是进程切换的堆栈变化让我印象深刻。系统调用的学习让我对内核的运行机制有了更深的了解与掌握,也认识到了linux与windows的众多不同,受益匪浅。
遗憾之处在于每次实验或者视频,老师都会讲到一些比较高深的东西,这些东西不理解,或者说在百度上也没有明确解释的时候,往往就不了了之,没有想办法再去深究,这也是我以后需要加强的地方。