前面说到模块是一些内核的组件,因为对系统启动的紧迫性没有那么急所以放在外存中,等系统启动之后由内核调度出来。一般内核加载一个模块的命令为insmod 模块文件名, 卸载模块的命令为rmmod 模块名。编译一个模块需要两个部分,一个是主程序文件,另一个是控制编译的Makefile文件。其实LINUX内核编译的时候也是通过一系列的Makefile调用来构建整个系统的,所以我们参照linux内核中的内核编译makefile编写我们的makefile,内容如下


ifneq ($(KERNELRELEASE),)
param-objs := new.o new.o
obj-m := new.o
else
KDIR := /lib/modules/`uname -r`/build [这里要替换成你自己的源码根目录路径]
all:
make -C $(KDIR) M=$(PWD) modules
clean:
rm -f *.ko *.o *.mod.o *.mod.c *.symvers

endif


保存为Makefile, 这个的内容主要是分为两部分
直接执行make时会跳到内核的源码目录,然后执行模块编译。执行make clean的时候会清理掉生成的临时文件。

然后就是主程序的编写了 new.c


#include #include #include #include

MODULE_AUTHOR("Hakurei");
MODULE_LICENSE("GPL");

static int __init _init(void)
{
struct task_struct *task;
struct list_head *list;
char* status;
printk(KERN_ALERT " %-16s%-8s%-13s%-5s\n", "name", "pid", "state", "normal_prio");
for(list=(&(current->tasks))->next; list!=¤t->tasks; list=list->next)
{
task=list_entry(list, struct task_struct, tasks);
if(task->mm==NULL) {
if(task->state>0) status = "Stopped";
else if (task->state==0) status = "Runnable";
else if (task->state==-1) status = "UnRunnable";
else status = "Unknown";
printk(KERN_ALERT " %-16s%-8d%-13s%-5d\n", task->comm, task->pid,
status, task->normal_prio);
}
}

return 0;
}

static void __exit _exit(void)
{
printk(KERN_INFO " mModule has been unregistered\n");
}

module_init(_init);
module_exit(_exit);

这个程序的作用是输出所有内核线程的一些详细内容到内核日志中, module_init module_exit 两个函数是用来注册模块被安装和卸载的时候所执行的函数内容的。上面的MODULE_AUTHOR等是一系列宏,用来指定模块的作者和协议等信息,可以在模块编译完之后用modinfo命令查看。

然后把这个文件和makefile放在同一个目录下,执行make命令,生成的一个.ko后缀名的文件就是我们要的模块文件了。之后就可以使用


sudo insmod new.ko

来装载模块了。

分类:

发表评论

电子邮件地址不会被公开。