第二周 操作系统是如何工作的
一.函数调用堆栈
l 计算机是如何工作的?(总结)——三个法宝
- 存储程序计算机工作模型,计算机系统最最基础性的逻辑结构;
- 函数调用堆栈,高级语言得以运行的基础,只有机器语言和汇编语言的时候堆栈机制对于计算机来说并不那么重要,但有了高级语言及函数,堆栈成为了计算机的基础功能;
- enter
- pushl %ebp
- movl %esp,%ebp
- leave
- movl %ebp,%esp
- popl %ebp
- 函数参数传递机制和局部变量存储
- 中断机制,多道程序操作系统的基点,没有中断机制程序只能从头一直运行结束才有可能开始运行其他程序。
l 堆栈
esp:堆栈指针
ebp:基址指针,在C语言中用作记录当前函数调用基址
CS:eip:总是指向下一条的指令地址
call xxx
执行call之前
执行call时,cs : eip原来的值指向call下一条指令,该值被保存到栈顶,然后cs : eip的值指向xxx的入口地址
进入xxx
第一条指令: pushl %ebp
第二条指令: movl %esp, %ebp
函数体中的常规操作,可能会压栈、出栈
退出xxx
movl %ebp,%esp
popl %ebp
ret
二.借助Linux内核部分源代码模拟存储程序计算机工作机制及时钟中断
l mykernel实验指导
虚拟机打开shell
- cd LinuxKernel/linux-3.9.4
- qemu -kernel arch/x86/boot/bzImage
然后cd mykernel ,可以看到qemu窗口输出的内容的代码mymain.c和myinterrupt.c
mymain.c代码
myinterrupt.c代码
三.实验:完成一个简单的时间片轮转多道程序内核代码
首先,解读一下程序的中心代码
void __init my_start_kernel(void)
{
int i = 0;
while(1)
{
i++;
if(i%100000 == 0)
printk(KERN_NOTICE "my_start_kernel here %d n",i);
}
}
这是内核代码的启动函数,C言语编写,循环局部是每执行100000次,输出一条语句。
void my_timer_handler(void)
{
printk(KERN_NOTICE "n>>>>>>>>>>>>>>>>>my_timer_handler here<<<<<<<<<<<<<<<<<<="" pre="">
这段代码是被时间中缀时调用,每次被调用的时分输出一条语句。
然后对编写的代码停止整合,然后整合到Linux Kernel-3.9.4中。
然后下载linux kernel-3.9.4,下载完成后解压。
进入解压后的文件夹:
cd linux-3.9.4 把本人的代码编译到linux-3.9.4中
patch -p1 < ../mykernel_for_linux3.9.4sc.patch
make allnoconfig
make 最后安装QEMU,运转kernel。
最后,运转内核,效果如下图:
四.总结
实验中,在上述函数的作用下,成功地实现了时间片轮转的中断处理内核的功能。通过分析源码,我们了解到时间片轮转算法的具体方法,即每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。如果在时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。如果进程在时间片结束前阻塞或结束,则CPU当即进行切换。调度程序所要做的就是维护一张就绪进程列表,当进程用完它的时间片后,它被移到队列的末尾。这是一种最古老,最简单,最公平且使用最广的算法。