mykernel实验指导(操作系统是如何工作的)

来源:互联网 发布:乌海四中网络选课系统 编辑:程序博客网 时间:2024/06/15 15:28

康鹏 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 


1. 代码下载地址(由孟老师提供):https://github.com/mengning/mykernel。

2. 按照要求,输入如下命令:

cd LinuxKernel/linux-3.9.4qemu -kernel arch/x86/boot/bzImage
cd mykernel


输入vi mymain.c,可以看到有如下两个函数:

void __init my_start_kernel(void); // 初始化进程0,并用for循环创建更多的进程(1~n),汇编代码启动进程0void my_process(void); // 每10000000次进行一次判断:如果需要调度,则调用my_schedule()。并输出相应提示语句
输入vi mymain.c,可以看到有如下两个函数:

void my_timer_handler(void); // 周期性执行该时钟中断处理程序,设置时间片大小,时间片用完时设置一下调度标志void my_schedule(void); // if两个正在运行的进程之间做进程上下文切换,else切换到一个新进程的方法

3. 执行程序截图



mymain.c的分析:

1.#include "mypcb.h"2.申明了一个PCBtask数组,当前task的一个指针,是否需要调度(标识)3 **怎样标识初始化**   (1)从my_start_kernel(void)开始,初始化当前0号进程,pid=0,状态是正在运行,入口是my_process(实际上是my_start_kernel,只是在这初始化一下)   (2)堆栈的栈顶定义了一个stack    (3)next指向它自己,启动时,整个系统只有0号进程   (4)创建更多的进程for(i=1;i<MAX_TASK_NUM;i++),       用memcpy()把进程初始状态复制过来;状态,用自己的堆栈,每个进程都有自己的堆栈,      task[i].next=task[i-1].next;指向下一个进程,      task[i-1].next=&task[i];将新创建的进程加入进程链表的尾部,创建多个进程(MAX_STASK_NUM个)   (5)start process 0 by task[0],0号进程开始执行   (6)图:汇编代码----%1表示ESP C----表示ECX  建立环境,从0号进程的堆栈与入口,构建CPU的构建环境,此时内核初始化完成,0号进程也启动。   (7)my_process()所有进程都用这个,10000000万次,打印,调度一次(**my_schedule()**),切换,主动调度的机制。

myinterrupt.c的分析:

1.#include "mypcb.h" , extern一些全局的东西。time_count计数

2.设置时间片的大小,时间片用完时,设置一下调度标识。 if(timecount%1000==0&&myneedsched!=1) 当进程执行到的时候,发现needsched==1,就执行myschedule

3.myschedule() *prev---当前进程 将当前进程赋给next 情况一:如果下一个进程的状态是0的话,正在执行的话,用图进行切换两个正在运行的进程上下文切换 $1f接下来的标号1:的位置


最后总结部分:

通过内核源代码了解,从环境搭建起来,mystartkernerl开始初始化至完成,启动0号进程,利用时间片,每个进程每隔1000万次,判断是否需要调度,调度使用myshedule()进行调度.设置时间片的大小,时间片用完时,设置一下调度标识。 if(timecount%1000==0&&myneedsched!=1) 当进程执行到的时候,发现needsched==1,就执行myschedule,调度分两种情况,一种是下一个进程正在进行的,另一种是从未调度过的,进程从未执行过,执行起来特殊点,将状态转成运行时状态,作为当前执行的进程,esp,ebp指向同一位置两种汇编代码略有不同,是关键。

0 0
原创粉丝点击