linux简单模块分析

来源:互联网 发布:vb mscomctl.ocx 编辑:程序博客网 时间:2024/05/22 06:45

“hello world”模块:

#include <linux/init.h>#include <linux/module.h>MODULE_LICENSE("Dual BSD/GPL");static int hello_init(void){printk(KERN_ALERT "Hello, world\n");return 0;}static void hello_exit(void){printk(KERN_ALERT "Goodbye, cruel world\n");}module_init(hello_init);module_exit(hello_exit);

一个在模块加载到内核时被调用( hello_init )以及一个在模块被去除时被调用( hello_exit ). moudle_init 和 module_exit 这几行使用了特别的内核宏来指出这两个函数的角色. 另一个特别的宏(MODULE_LICENSE) 是用来告知内核, 该模块带有一个自由的许可证; 没有这样的说明, 在模块加载时内核会抱怨.

sudo makeroot# insmod ./hello.ko //加载模块root# rmmod hello   //卸载模块

makefile (/usr/src/)
如果你从一个终端模拟器或者在窗口系统中运行 insmod 和 rmmod,你不会在你的屏幕上看到任何东西. 消息进入了其中一个系统日志文件中, 例如/var/log/messages

内核模块相比于应用程序,一个模块在内核空间运行, 而应用程序在用户空间运行.

下面的语句打印了当前进程的进程 ID 和命令名称, 通过存取结构 task_struct 中的某些字段.

printk(KERN_INFO "The process is \"%s\" (pid %i)\n", current->comm, current->pid);

表明有一个模块要从目标文件 hello.o 建立. 在从目标文件建立后结果模块命名为 hello.

obj-m := hello.o

有一个模块名为 module.ko, 是来自 2 个源文件( 姑且称之为, file1.c 和file2.c ), 正确的书写应当是:

obj-m := module.o
module-objs := file1.o file2.o

makefile:# If KERNELRELEASE is defined, we've been invoked from the# kernel build system and can use its language.ifneq ($(KERNELRELEASE),)obj-m := hello.o# Otherwise we were called directly from the command# line; invoke the kernel build system.elseKERNELDIR ?= /lib/modules/$(shell uname -r)/buildPWD := $(shell pwd)default:$(MAKE) -C $(KERNELDIR) M=$(PWD) modulesendif

这个 makefile 在一次典型的建立中要被读 2 次. 当从命令行中调用这个 makefile , 它注意到KERNELRELEASE 变量没有设置. 它利用这样一个事实来定位内核源码目录, 即已安装模块目录中的符号连接指回内核建立树. 如果你实际上没有运行你在为其而建立的内核, 你可以在命令行提供一个KERNELDIR= 选项, 设置 KERNELDIR 环境变量, 或者重写 makefile 中设置 KERNELDIR 的那一行. 一旦发现内核源码树, makefile 调用 default: 目标, 来运行第 2 个 make 命
令( 在 makefile 里参数化成 $(MAKE))象前面描述过的一样来调用内核建立系统. 在第 2次读, makefile 设置 obj-m, 并且内核的 makefile 文件完成实际的建立模块工作
/inmod /remod /lsmod

/sys/module 是一个 sysfs 目录层次, 包含当前加载模块的信息.
/proc/moudles是旧式的, 那种信息的单个文件版本. 其中的条目包含了模块名, 每个模块占用的内存数量, 以及使用计数. 另外的字串追加到每行的末尾来指定标志, 对这个模块当前是活动的.

0 0
原创粉丝点击