Linux内核分析——操作系统是如何工作的
马悦+原创作品转载请注明出处+《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
一、计算机是如何工作的(总结)
1、三个法宝:
存储程序计算机
函数调用堆栈
中断机制
二、深入理解函数调用堆栈
1、堆栈是c语言程序运行时必须的一个记录调用路径和参数的空间。
函数调用框架
传递参数
保存返回地址
提供局部变量空间
2、了解堆栈存在的目的和编译器对堆栈使用的规则是理解操作系统一些关键性代码的基础
3、堆栈相关的寄存器
esp 堆栈指针
ebp 基址指针(在C语言中用作记录当前函数调用基址)
4、操作
push 栈顶地址减少4个字节(32位)
pop 栈顶地址增加4个字节
4.其他关键寄存器
cs:eip 总是指向下一条的指令地址
顺序执行:总是指向地址连续的下一条的指令地址;
跳转/分支:执行这样的指令的时候,cs:eip的值会根据程序需要被修改;
call:将当前cs:eip的值压入栈顶,cs:eip指向被调用函数的入口地址。
ret:从栈顶弹出原来保存在这里的cs:eip的值,放入cs:eip中。
5、深入理解函数调用堆栈的工作机制
6、函数调用时堆栈的变化
三、参数传递与局部变量
举例分析函数调用堆栈:
首先使用gcc -g生成test.c的可执行文件test,然后使用objdump -S获得test的反汇编文件。
四、C代码中嵌入汇编代码
1、内嵌汇编语法
五、mykernel实验
mymain.c
【89行】每循环十万次打印一次mykernel
myinterrupt.c
每次时钟中断都调用一次printk,并输出
六、进程分析
在mykernel基础上构造的简单的操作系统内核
1、mypcb.h
1、本文件中定义了Thread结构体,用于存储当前进程中正在执行的线程的eip和esp。
2、pid:进程号
thread:当前正在执行的线程信息
task_entry:进程入口函数
next:指向下一个PCB(模拟系统中所有的PCB是以链表的形式组织起来的)。
my_schedule:调度器。
2、mymain.c
内核初始化和0号进程启动
1、函数my_start_kernel完成了0号进程的初始化和启动(入口是myprocess)。
2、进程刚启动时next指向自己。
3、创建了其它的多个进程,在初始化这些进程的时候可以直接利用0号进程的代码。
4、循环1000万次判断一次是否需要调度。
3、myinterrupt.c
1、my_timer_handler 函数每调用1000次,把 my_need_sched的值修改为1,通知正在执行的进程执行调度程序my_schedule。
2、操作系统“两剑”:中断上下文、进程上下文的切换。
七、学习总结
本周对上一周计算机是如何工作的进行了总结,并就操作系统是如何工作的进行了学习,其中有函数调用堆栈、参数传递与局部变量、利用mykernel实验模拟计算机硬件平台、C代码中嵌入汇编代码的写法等课程。
老师通过举例,让我们更加清楚、深入地了解了堆栈的变化。既巩固了旧知识,又学习了新知识。