现在的位置: 首页 > 综合 > 正文

Linux 内核开发-笔记

2013年10月11日 ⁄ 综合 ⁄ 共 1499字 ⁄ 字号 评论关闭

操作系统课程作业要求,针对linux 2.6的内核(kernel)进行开发,详细的要求和材料可以参照课程连接:

CS3 OPERATING SYSTEMS, PRACTICAL EXERCISE

PHASE 1 PHASE 2 主要为如何在DICE机上使用VB和linux内核排程器(scheduler)的背景知识阅读, PHASE 3 是正式的开发,课程评分也只参考这一环节,而这一环节也分为三个小部分,简单概括:1.简单的编译与载入、卸载内核模块;2.解决SMP的Lost Wake-up问题;3.编写一个副排程器以缓解CPU和I/O的速度冲突。

Part1:

首先将现成的.c文件编译成.ko文件。

获得ko文件后,比较常用的指令:

-insmod worker.ko 加载某一模块

-lsmod 显示当前运作的模块

-rmmod worker 某一模块


课程提供的worker.c编译加载后会运行一个内核例程(kernel routine),每10秒输出一条命令。在卸载时会调用clean_up函数,并在内核例程结束后,clean_up才结束。简单修改worker.c,如加一点有个性化的输入,形成worker1.c模块,即可提交,30分到手。

Part2:

这次提供的是stuckworker.c,与worker.c不同的是,clean_up函数中,先指示例程结束,然后等了12秒,clean_up才进入sleep的状态,此时已错过了例程的wake_up,简单概括就是一个lost wake-up Problem,在UP中不会出现,但在SMP中有可能出现并造成严重的问题。也不难,课程提供的一个提示是使用wait_even函数,避免了没人唤醒的问题。

Part3:

这一部分挑战最大,主要解决CPU运行速度和I/O运行速度不一致的问题。在读取外设的时候大量的系统资源会被占用,要求开发一个内核,使得在有键盘活动时,读取外设的进程暂停60秒。其中滤出这些占用资源过多的原则是:

1.进程内核运行时间是否大于1秒;

2.进程内核运行时间是否超过总运行时间10%;

struct task_struct *p;

for_each_process(p){

if(cputime_to_secs(p->stime)>limit_time_in_kernel/*此处为1秒*/){//进程内核运行时间
ktime_get_ts(&c_t);//获取当前时间
s_t=(c_t.tv_sec)-(p->start_time.tv_sec);//获取运行时间
if(cputime_to_secs(p->stime)*limit_for_occupy_time/*此处为10*/>s_t){...}//判断进程内核运行时间是否超过总运行时间10%

}

若满足以上两个原则,则暂停进程60秒。寻找这个进程可能不难,但是如何停止,然后恢复却不那么容易,有很多种看似可行的办法。Julian多次发群邮提醒,别想复杂,不用从底层去做,不用通过设置位去完成,从userspace就可以完成。一般而言,在terminal暂停一个进程的指令是kill,那么kill在内核里对应调用的函数为:send_sig(SIGSTOP,,);,相应的恢复运行函数为send_sig(SIGCONT,,);,但在这里内核出了一点小差错,原因尚不明了,可以用kill_pid(task_pid(p,
SIGCONT, 1);
代替。仅仅这两句代码的正确选择,耗费掉了整个作业的大概80%以上时间。完成正常的停止与恢复后,其他一些附加的小功能也就水到渠成了。

很值得一提的是,OS Lecturer Julian还自己开发了一个麻将游戏!

抱歉!评论已关闭.