内核模块开发(笔记)
来源:互联网 发布:pptv聚力网络电视 编辑:程序博客网 时间:2024/05/08 14:01
调试方法
kernel oops messages
内核模块简单介绍
最简单的内核模块
注:如果是 redhat 安装的话,需要安装 kernel-devel 才能写内核模块,如果是自己编译内核,记的不要删除源码,不然没法开发模块.
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
/* __init 的标记是内核模块的入口,这个函数加载完后就会释放内存空间 */
static
int
__init hello_init(
void
)
{
printk(KERN_INFO
"Hello world"
);
/* 打印的信息会出现在 dmesg 中 释放*/
return
0;
/* 返回 0 是正常 */
}
/* __exit 的标记是退出内核模块,当这个模块卸载时会执行 */
static
void
__exit hello_exit(
void
)
{
printk(KERN_INFO
"Goodbye world"
);
}
/* 下面这二个是宏,初始化和消除函数时使用和上面的装载卸载模块没关系. */
module_init(hello_init);
module_exit(hello_exit);
放个编译上面模块的 Makefile
obj-m := hello.o
all:
make
-C
/lib/modules/$(shell uname
-r
)/build M=$(shell pwd) modules
clean:
make
-C
/lib/modules/$(shell uname
-r
)/build M=$(shell pwd) clean
给 Makefile 放到上面 hello.c 的相同的目录中(如果上面写的模块代码叫 hello.c 的话).然后使用 make 就能编译了.
insmod lsmod rmmod
调用 insmod 时会给需要的模块加载进内核,会给 ko 的文件以目标代码加载.装载时会调用 module_init 指定的函数.退出也调用相应的 module_exit.
lsmod 可以显示你写的模块,其实是读 /proc/modules .接下来我写写怎么样自己通过内核来建 proc 文件.
模块加载参数
如果在模块加载时,想指定参数,也提供了相应的头文件
#include <linux/moduleparam.h>
static
int
test;
module_param(test,
int
, 0644);
这样以后,直接在内核模块内使用 test 的变量就行了.
模块的信息
在程序中可以为模块加一些描述,发行版权声明,和作者.
MODULE_LICENSE(
"GPL"
);
MODULE_DESCRIPTION(
"Test"
);
MODULE_AUTHOR(
"xxx"
);
模块的符号导出
在 Perl 中,模块是可以导出变量和方法到其它的模块中的.在 Linux 内核中也有这样的方法.
EXPORT_SYMBOL(name);
EXPORT_SYMBOL_GPL(name);
这二个可以导出指定的全局变量,也可以是方法.这个要加载 <linux/module.h> 的头文件,不要忘记了.
其它的模块要使用这个,直接使用 extern void name(void); 就可以使用了.这些导出的函数只能内核和内核模块使用.不能用户调用,可以由 /proc/kallsyms 来查看导出的变量和方法
实例
写个内核模块,通过 proc 可以见到一些信息,通过 proc 的读和写的功能.来实现设置和读取信息.
proc 介绍
proc 是一个非常方便的用来动态的向 Linux 内核加入和禁用代码的一个方法.
proc/sys 中是用来配置内核的参数,可以通过 sysctl -w key=value
象普通文件可以支持 open,read,write,close
例如
读
cat /proc/cpuinfo
写
echofukei-name > /proc/sys/kernel/hostname
proc 的功能实现
proc 在 c 中是一个结构体来实现的,是 struct proc_dir_entry .它可以给读写绑定到特定的函数上.然后通过别人对 proc 中文件的操作来触发和回调相应的绑定的函数.
read_proc 和 write_proc 是这个结构体的成员,也是一种结构体.函数就注册在这个上面.有兴趣的同学可以看看 include/linux/proc_fs.h 中的 read_proc_t 和 write_proc_t 的定义.
实现起来也简单.
struct
proc_dir_entry *proc_entry = create_proc_entery(....);
int
my_read_proc()
{
}
proc_entry->read_proc = my_read_proc();
在这的 create_proc_entery 会返回一个 proc_dir_entry 的结构体的引用.失败就是 NULL .
这样,当用户空间进行 read 的系统调用时,如使用 cat proc 中的内容时.内核会调用注册到 read_proc 上的这个 my_read_proc 来实现的.
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/sched.h>
#include <linux/mm.h>
#define MODULE_NAME "Memory"
int
my_read_proc(
char
*page,
char
**start, off_t off,
int
count,
int
*eof,
void
*data)
{
struct
task_struct *tsk = current;
int
len;
len =
sprintf
( page,
"This module info: task %s pid %d\n"
,tsk->comm, tsk->pid );
return
len;
}
struct
proc_dir_entry *proc_entry;
int
init_module(
void
)
{
proc_entry= create_proc_entry(MODULE_NAME, 0644, NULL);
if
(proc_entry==NULL){
remove_proc_entry(MODULE_NAME, NULL);
}
proc_entry->read_proc = my_read_proc;
return
0;
}
void
cleanup_module(
void
)
{
remove_proc_entry(MODULE_NAME, NULL);
// 退出和出错记的删除
}
MODULE_LICENSE(
"GPL"
);
- 内核模块开发(笔记)
- linux内核模块开发笔记
- linux内核模块开发笔记一
- 工作笔记 内核模块
- 内核模块笔记
- linux内核模块笔记
- Linux内核模块--笔记
- Linux设备驱动开发详解--笔记4--Linux内核模块
- Linux 驱动开发-内核模块设计笔记 0
- Linux内核模块开发
- freeswitch 内核模块开发
- freeswitch内核模块开发
- Linux内核模块开发
- 内核模块开发基础
- linux内核模块开发
- 内核模块开发基础
- Linux内核模块开发
- Eclipse开发内核模块
- CodeForces 23C Oranges and Apples
- 求整形数组中最大递增序列的长度
- zoj 3820 Building Fire Stations (树的直径)
- 学习struts2的笔记
- iOS的完整学习路线图
- 内核模块开发(笔记)
- Android 性能测试初探
- 服务器进程为何通常fork两次(转)
- 2014ACM/ICPC亚洲区域赛牡丹江站总结
- Android手机智能定位并在地图上显示地址
- 猜数
- 记一次vos3000的安装全过程+安装的所有工具包-有图有文字只要跟着我一步一步的做一定成功
- 动态+静态链接库
- 【OJ】1.6.7将军(Check the Check)UVa 10196 // PC 1101017 // acmclub.com 25177