2018-2019-1 20189213 《Linux内核原理与分析》第三周作业
《Linux内核原理与分析》第三周学习总结
无论是视频资源还是《庖丁解牛Linux 》第2章,主要讲述的都是操作系统是如何工作的,并介绍了如何在mykernel基础上构造一个简单的操作系统内核。
1.函数调用堆栈:
堆栈的由来:堆栈并不是一开始就有的,计算机没有高级语言的时候,只有机器语言时候,因为汇编可以跳转,没有太多函数的概念,有了高级语言,有了函数,就要借助堆栈了。
堆栈是c语言程序运行时必须的一个记录调用路径和参数的空间 ,具体作用有:记录函数调用框架、传递函数参数、保存返回地址、提供函数内部局部变量的存储空间等等。
堆栈相关的寄存器:
esp—堆栈指针 (stack pointer)
ebp—基址指针 (base pointer)— ebp在c语言中用作记录当前函数调用基址
堆栈操作:
push—栈顶地址减少4个字节
pop—栈顶地址增加4个字节
其他关键寄存器 :
cs:eip总是指向下一条的指令地址 ;
顺序执行:总是指向地址连续的下一条指令。
跳转/分支:执行这样的指令的时候,cs:eip的值会根据程序被修改。
call:将当前的cs:eip的值压入栈顶,cs:eip指向被调用函数的入口地址。
ret:从栈顶弹出原来的保存在这里的cd:eip的值,放入cs:eip中。
2.C代码中嵌入汇编代码的写法:
寄存器前有两个% 例如:movl $3,%%ebp;
%加数字,代表代码末的输出或输入 例子:addl %1,%%eax;
其中:"d"(val2) /d代表edx寄存器/ "c"(val1) /c代表ecx寄存器/
即%eax+=val1,由于%eax清0,其实就是把val1赋给eax。
3.mykernel实验指导及过程:
首先使用实验楼的虚拟机打开shell,在终端上输入如下命令:
其中make编译内核阶段比较漫长,截了一段过程:
在QEMU窗口,不停的输出字符串:
源代码中的mymain.c:
在mymain.c的my_start_kernel函数中有一个循环,会不停的输出my_start_kernel here;
源代码中的myinterrupt.c:
在myinterrupt.c中,可以看到一个会被时钟中断周期调用的函数my_timer_handler ,在这个函数里,输出>>>>>my_timer_handler here <<<<<;
即:mykernel系统启动后,调用my_start_kernel函数,周期性的调用my_timer_handler函数,它们分别完成了系统进程的初始化和进程的轮转调度,这就是一个简单的操作系统模拟。
4.完成一个简单的时间片轮转多道程序内核代码及详细代码分析:
这里首先我参考了mykernel在自己的虚拟机上搭建环境,搭建成功后主要分析实验中需要改写的三个文件,其作用简述如下:
mypcb.h : 进程控制块PCB结构体定义。
mymain.c: 初始化各个进程并启动0号进程。
myinterrupt.c:时钟中断处理和进程调度算法。
mypcb. h:
在代码中有函数的声明my_schedule:调度器。它在my_interrupt.c中实现,在mymain.c中的各个进程函数会根据一个全局变量的状态来决定是否调用它,从而实现主动调度。
mymain.c:
myinterrupt.c:
myinterrupt.c包含my_timer_handler和my_schedule两个函数。 my_timer_handler每隔100次将my_need_sched赋值为1,等待mymain.c中my_process函数的主动调度。my_schedule保存恢复进程上下文。
总结:
操作系统是连接软硬件的桥梁:
一方面它管理硬件资源(配置内存,控制输入输出设备,操作网络与文件系统),最大限度地发挥计算机资源;
另一方面,他负责进程调度和作业管理,为软件运行提供库支持,屏蔽硬件的不同。通过中断对外界做出反映,通过进程切换使CPU时间合理分配,保证计算机的性能发挥。
遇到的问题:
1.在看书过程中,一开始对书中的C代码中嵌入汇编代码实例中的“%加一个数字则表示第二部分输出、第三部分输入以及第四部分破坏描述(没有破坏则可省略)的编号”这句话并没有很好的理解,后面再仔细看了书中详细具体实例解释后,有了一丝的了解,但还是不太懂。
2.做一个简单的时间片轮转多道程序时,用了自己的虚拟机重新搭建了环境,搭建环境由于网速等原因导致特别的慢,期间也出现了很多的问题,经过查阅资料与询问同学,有了一些了解,但还是好多不懂,希望在下周老师的课上能认真学习这些知识。
3.对mykernel中的mymain.c与myinterrupt.c也没有完全的读懂,还需要继续深入学习。