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

Unix/Linux
查看linux 下已经安装的软件包信息
linux 系统中软件raid 配置方法
linux 下MySQL服务器的启动与停止
linux 系统下FTP服务器配置方法
Linux系统下如何挂载U盘,硬盘,光驱
linux 系统下DHCP服务器 配置方法
Linux系统下软件的安装与卸载
在Fedora 9中启用ext4文件系统的方法
linux下挂载(mount)光盘镜像文件、移动硬盘、U盘、Windows网络共享和NFS网络共享
Linux查看文件夹大小的命令
LINUX系统grub常见错误分析
llinux fdisk分区工具 使用方法
linux 系统telnet乱码
rhythmbox 乱码的解决方法
linux单网卡绑定多ip
tar.gz 和tar.bz2 详细解释
linux学习笔记
linux系统rpm安装包详解
linux 服务器常用维护命令
出现The file /boot/grub/stage1 not read cor 解决办法

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-11-01   浏览: 181 ::
收藏到网摘: 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语言和数据结构上下一点功夫.其他的模块,我想也是大同小异, 不过,也修补会这么简单.如内存管理中用到了好多平衡二叉树的排序,遍历等等.但总的结构时不变的.只要可以通栏全局,在不开定义的情况下,可以读懂全局变量的意思(其实,猜个八九不成问题),看懂是不成问题的.起码我是信心十足.

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