当前位置: 首页 > 图文教程 > 操作系统 > Unix/Linux > 读核日记(四)

Unix/Linux
Linux 备份 恢复方法
Linux玩CS反恐精英的方法
在一个ISO镜像中集成多个不同的linux发行版,可刻盘,可引导
Linux 快捷键使用
Linux DHCP 服务器配置方法介绍
Linux 22端口的修改方法
Linux 记录会话过程的命令
Linux 后台执行程序如何操作?
linux Wget命令来浏览网页的方法
Linux tail命令的巧妙应用
Wine 中文存在很多的乱码怎么解决方法
linux 新手教程之创建锁文件的方法
配置Linux 保证其系统的安全
Linux DHCP协议实现过程
Linux系统下破解SAM密码
linux/unix vi 编辑器用法详解
Linux 误删文件的解决方法
Linux系统下的历史记录删除方法
Red Hat Linux 安全设置指南
Linux基本命令-注销、关机、重启

Unix/Linux 中的 读核日记(四)


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-11-01   浏览: 35 ::
收藏到网摘: n/a

 

这几天身体不太好,进展不快.有时候突然发现在拼命的读代码的间隙里,停一会想一想,收获会更大.特别是对于这种非常庞大的系统来说.把握整体的意义尤其重要.随着对linux整体的拆解,我对于整个系统,已经不想开始是那么模糊.好像已经度过了那个极点.不过我也应做好准备,因为一但我对整个细节解读时,肯定也会有同样的经历.

整个linux内核之所以这样艰涩,难懂就在于它的整体性.想我们这样很少写万行以上程序的人来说,它就好像一个庞大的肉球.让你不知道如何下嘴.不过一但咬破.就非常香美了.毕竟,读这么优秀的代码也是一种享受.

我个人认为linux 的内核难在这几点:1,系统庞大,太多的变量,结构, 以及typedef定义的东西不容易找到.2,作为操作系统,它的函数调用时动态的,读不懂大量的makefile 你根本就不知道这50 M的东西是怎么组织起来的,况且,你绝对不可以像跟踪程序一样用debug走一下.3, 庞大的数据结构,可能是比较简单的运算变得不容易读.

因此在读核的初级阶段.我们应该善于想象,善于将不容易理解的部分用伪码的理解方式走过,当我们对大局把握好了,将整个结构拆解清楚了,在读不迟.况且,虽内核本身来说,它所涉及到的运算,结构. 本质上和课本上的没有差别.(可惜我不是计算机系毕业的).只不过是内容多了一些罢了.

比如说进程调度这一部分,说白了,就是在调用fork()的时候,就产生一task_strut 类型的指针,它包含进程调度所用到的一切信息.然后将这个指针插到队列中去就行了,然后cpu 一次总队类中取出指针,分配给他们时间片.

而这个指针如何插入呢?说白了就是看它的weight,weight 的计算方法,有根据进程类型的不同由不同的算法(实时进程,内核进程,普通进程).好了,这样我们想一下<<数据结构中>>关于队列的操作,插入,删除,插到队头,置于队尾.再想一下,这些操作如何同操作系统的应用结合在一块.例如;好队进程正在运行,突然,由于一硬件中断.产生一进程,它必须马上处理.系统应把它插入到队头.

好了.你可以读一下/usr./src/linux/kenrel/sched.c,不要过那么多全局变量,现在数据结构上走过去,如下面的代码:

 

static inline void move_last_runqueue(struct task_struct * p)

{

struct task_struct *next = p->next_run;

struct task_struct *prev = p->prev_run;

 

/* remove from list */

next->prev_run = prev;

prev->next_run = next;

/* add back to list */

p->next_run = &init_task;

prev = init_task.prev_run;

init_task.prev_run = p;

p->prev_run = prev;

prev->next_run = p;

}

 

static inline void move_first_runqueue(struct task_struct * p)

{

struct task_struct *next = p->next_run;

struct task_struct *prev = p->prev_run;

 

/* remove from list */

next->prev_run = prev;

prev->next_run = next;

/* add back to list */

p->prev_run = &init_task;

next = init_task.next_run;

init_task.next_run = p;

p->next_run = next;

next->prev_run = p;

}

如果你还不懂,你可能要先,在c语言和数据结构上下一点功夫.其他的模块,我想也是大同小异, 不过,也修补会这么简单.如内存管理中用到了好多平衡二叉树的排序,遍历等等.但总的结构时不变的.只要可以通栏全局,在不开定义的情况下,可以读懂全局变量的意思(其实,猜个八九不成问题),看懂是不成问题的.起码我是信心十足.

我应该在熟悉一下,计算机专业的软件基础课!!