从一个简单的mykernel来分析Linux系统工作过程

刘文 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
我们本次分析一个精简过的内核代码mykernel,配合kernel3.9.4使用,该代码来自https://github.com/mengning/mykernel;孟宁老师在课程公告中指出:“理解和运行mykernel,它是提供初始化好的CPU从my_start_kernel开始执行,并提供了时钟中断机制周期性执行my_time_handler中断处理程序,执行完后中断返回总是可以回到my_start_kernel中断的位置继续执行。当然中断保存现场恢复现场的细节都处理好了,mykernel就是一个逻辑上的硬件平台,具体怎么做到的一般不必深究。”“难点是理解基于mykernel实现的时间片轮转调度代码。”那么我们就主要分析一下mymain.c和myinterrut.c中的关键代码在kernel启动中是如何工作的,分析其执行过程和工作原理,从而理解Linux系统的工作原理。
我们首先看一下自定义的头文件mypcb.h:

该头文件中定义了两个结构体,第一个是struct Thread,它用来存储线程的ip和sp。另外一个是PCB(进程控制块),这是操作系统中一个很重要的数据结构,所有关于进程的信息都存储在PCB中。这里代码中简化了PCB的结构,只给出了一些最基本的信息,如Pid(进程号),state(进程状态),程序入口地址,内核堆栈,线程信息等。有了PCB这个数据结构,我们就可以用它来创建进程或者在进行进程间切换时保存信息,方便在mymain.c中和myinterrupt.c中利用。
再来看一下mymain.c:
首先定义了一些包含的头文件,其中包括我们刚刚自定义的头文件”mypcb.h”,同时创建了线程的基本信息。而代码开始时kernel是从my_start_kernel开始执行的,我们看一下它的内容。首先是一段初始化进程的代码:
每次创建新的进程时,都将新创建的进程插入到进程队列的最后一个位置,然后将新进程的next指向第一个进程,这样就会形成了一个环形的进程队列,可以实现进程的环形循环调度。之后是一段很重要的嵌入式汇编代码:
代码首先将PCB中的sp信息放入esp寄存器,然后将ebp压栈(因为此时进程堆栈为空栈,所以压入esp相当于ebp),第三第四句我们将eip压栈然后ret(即pop eip),下一条指令就会跳转到0号进程的第一条指令开始执行,在这里就是my_process()。下面我们看一下my_process()函数的内容:
my_process()函数做的事情很简单,就是循环等待并打印一下当前进程的id,然后观察变量my_need_sched是否为1,如果是则进入调度函数my_schedule开始执行。这个函数在myinterrupt.c的文件中,在分析调度函数之前我们先分析一下这个文件中的my_timer_handler()函数:

这个函数是由mykernel提供的时钟中断机制的一部分,周期性执行my_time_handler()中断处理程序,那么函数定时观察my_need_sched是否不等于1,如果是则将其置为1,使myprocess()执行my_schedule()。这时我们分析一下my_schedule():
该函数在PCB环形队列中选择下一个进程进行执行。如果即将进入CPU的进程之前已经运行过(即state为0),我们保存当前进程的信息,然后把下一个进程的信息写入到寄存器中,执行ret使下一个进程开始执行。而假如该进程之前没有在运行态过(state不为0),我们先将其设置为运行态,我们这里需要初始化其ebp,因为该进程的堆栈是空栈esp=ebp。

至此,该精简过的内核代码mykernel就分析完毕了。
总结:
这次的实验即基于mykernel实现的时间片轮转调度代码的理解是很有挑战的,它本身就是由Linux内核精简而来的,所以其实理解起来很有难度。mykernel是提供初始化好的CPU,从my_start_kernel开始执行,并提供了时钟中断机制周期性执行my_time_handler中断处理程序,执行完后中断返回总是可以回到my_start_kernel中断的位置继续执行。难点是理解基于mykernel实现的时间片轮转调度代码。自己写一个时间片轮转调度内核还是很难的,幸好可以利用孟宁老师的资源,只需到mykernel的github版本库找到代码复制过来重新编译Linux3.9.4的源代码就可以了。通过这段时间对Linux内核部分的理解,大体上理解了Linux系统的工作原理,理解了进程上下文的保存和恢复。最近感觉收获很多,但是仍然需要努力,希望可以在孟宁老师的教导下学到更多的东西。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值