模块
在开篇处还是先为你放上这次模块的全部代码:
<code>// traverse.c
#include <linux>
#include <linux>
#include <linux>
#include <linux>
#include <linux>
#include <linux>
static int traverse_init(void)
{
struct task_struct *task;
printk(KERN_INFO "Hello, world. \\n");
for_each_process(task)
printk(KERN_INFO "%s[%d]\\n", task->comm, task->pid);
return 0;
}
static void traverse_exit(void)
{
printk(KERN_INFO "Finish.\\n");
}
module_init(traverse_init);
module_exit(traverse_exit);/<linux>/<linux>/<linux>/<linux>/<linux>/<linux>/<code>
嘿,就只有这么点。这里既保留了先写 Hello, world 的传统,又对我们的内核进程进行了遍历。
在阅读完上面的代码之后,你会发现这与你之前所学的 C 语言有那么几处不同。
- 头文件不同,连之前最常用的 stdio.h 都没有。
- 输出不是 printf 而是 printk。
- 没有 main 函数,取而代之的却是 __init, __exit 这种东西。
再加上一个 Makefile 文件:
<code>obj-m:=traverse.o
all:
\tmake -C /usr/src/linux-headers-$(shell uname -r) M=$(shell pwd) modules
clean:
\tmake -C /usr/src/linux-headers-$(shell uname -r) M=$(shell pwd) clean
/<code>
此时你就可以开心地为你的内核编译模块了。
<code>make/<code>
如果你编译成功了的话,在当前目录下进行 ls 操作,会发现多了很多新文件,其中对我们最重要的就是 traverse.ko 文件了。
<code>sudo insmod traverse.ko/<code>
这里并没有任何输出信息,就代表着你已成功地将模块插入到了内核中。
是时候看看输出结果了,但是 prink 并不会将内容输出至屏幕,它是对内核信息的一种记录。就跟你传给它的参数 KERN_INFO 的意思一样,是你在告诉内核,这有警告信息,请你记录下来。
接下来从内核中将刚刚的模块删除了吧:
<code>sudo rmmod traverse/<code>
同样执行这一步时,你在终端上并不能看到提示信息。
<code>dmesg/<code>
操作后,你就能一览你刚刚编写的模块的结果了。
省略部分
从开头的 Hello, world 到各个进程的相关信息,以及最后你执行删除操作时所留下的自定义 Finish 信息,你期待的全部都在这里了。
进程
至于模块就先说那么多,毕竟这一片还是以说内核链表在内核中的应用为主,那当然就需要告诉你,进程描述符的作用了。
task_struct 类型的进程描述符中包含着一个进程的所有信息:
<code>struct task_struct {
\t// ...
\tpid_t pid;
\tchar comm[TASK_COMM_LEN];
\tstruct list_head tasks;
\t// ...
};/<code>
内核源码文件为 include/linux/sched.h,你可以在其中找到 task_struct 的完整超长定义。其中此次你将要用到的字段有 pid,进程号;comm,进程名;还有内嵌其中的 task,链表结构。
再加上一个,进行便利操作,又是对 list_entry 进行了封装的宏:
<code>#define for_each_process(p) \\
\tfor (p = &init_task ; (p = list_entry_rcu((p)->tasks.next, \\
struct task_struct, tasks) \\
\t) != &init_task ; )/<code>
本文只是一次对内核链表,在内核中应用的简单体验,希望对你理解内核链表有帮助。
参考
[1]Peter Jay Salzman; Michael Burian; Ori Pomerantz.The Linux Kernel Module Programming Guide[EB/OL].https://blog.csdn.net/yeshennet/article/details/82315604,2007-05-18
[2]Bovet, D. P.; Cesati, M…深入理解Linux内核[M].中国电力出版社:北京,2007:85.
[3]Love, R…Linux内核设计与实现[M].机械工业出版社:北京,2011.6:21.
閱讀更多 一棟人 的文章