Linux 内核开发-笔记
2012-11-12 03:04
295 查看
操作系统课程作业要求,针对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还自己开发了一个麻将游戏!
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还自己开发了一个麻将游戏!
相关文章推荐
- linux驱动开发学习--对中断和内核定时器的学习笔记
- 国嵌视频学习笔记---linux内核开发1
- Linux 驱动开发-内核模块设计笔记 0
- Linux内核分析笔记 与Linux内核开发理论
- linux驱动开发笔记--2.3内核模块相比于应用程序
- Linux设备驱动开发详解--笔记3--Linux内核及内核编程
- linux内核开发基础学习笔记
- Linux设备驱动开发详解--笔记3--Linux内核及内核编程
- linux 设备驱动开发学习笔记(一):最简单的内核模块
- linux内核开发基础学习笔记
- 嵌入式软件开发培训笔记——嵌入式linux内核与文件系统移植与分析
- 浅谈 Linux 内核开发之网络设备驱动
- 使用 u-boot 烧写内核——韦东山嵌入式Linux学习笔记10
- Linux开发心得总结20 - 内核编程中的全局变量使用(EXPORT_SYMBOL())
- 中国LINUX内核开发大会 ppt演讲资料 与 会议视频
- linux驱动开发笔记2
- Linux内核与驱动开发学习总结:内核初始化宏__init(十二)
- 深入理解Linux内核之内存寻址笔记-2
- Linux开发基础(2010.7.11-2010.7.14)——学习笔记
- Linux内核开发之将驱动程序添加到内核