内核模块开发 初步
2017-06-19 22:10
337 查看
LINUX内核模块基础
什么是内核模块:Linux内核的整体结构非常庞大,其包含的组件也非常多,如何使用这些组件呢,有一种方法是:把所有的组件都编译进内核文件,即:zImage或bzImage,但这样会导致一个问题:占用内存过多。
应当采用一种机制能让内核文件本身并不包含某组件,而是在该组件需要被使用的时候,动态地添加到正在运行的内核中。
内核模块具有如下特点:
• 模块本身并不被编译进内核文件(zImage或者bzImage)。
• 可以根据需求,在内核运行期间动态的安装或卸载。
安装与卸载内核模块:
安装 insmod
例:insmod /home/dnw_usb.ko
卸载 rmmod
例:rmmod dnw_usb
查看 lsmod
例:lsmod
内核模块设计
内核模块C程序代码举例://Linux内核模块的三要素:头文件、加载函数、卸载函数 #include <linux/init.h> #include <linux/module.h> //加载和卸载函数都要加上static静态函数 //在内核中打印不能使用 printf ,要使用 printk 函数 static int hello_init() { printk(KERN_WARNING"Hello world!\n");//没有逗号,KERN_WARNING 是优先级 return 0; } static void hello_exit() { printk(KERN_WARNING"hello exit!\n"); } module_init(hello_init); //加载函数,insmod命令之后自动开始执行括号内的函数 module_exit(hello_exit); //卸载函数,rmmod命令之后自动开始执行括号内的函数
makefile文件编写:
obj-m := helloworld.o #helloworld.o是最终生成的内核模块的名字,上面是单个文件的写法 #多个文件的写法: #obj-m := hello.o #hello-objs := file1.o file2.o file3.o KDIR := /home/ARM_Linux/system2/season4/First/part3/linux-ok6410 #开发板上运行的内核代码的路径,编译内核需要依赖于内核路径,注意斜线方向 all: make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm # -C 表示进入后面的路径中,因此还需要加上内核模块代码的路径 # pwd 是内核模块代码的路径 clean: rm -f *.o *.ko *.order *.symvers *.bak *.mod.c
对代码进行编译,可以得到 .ko 文件,将 .ko 文件拷贝到嵌入式系统的根文件系统中。
在嵌入式系统上,用insmod命令加载模块和用rmmod命令写在模块,都可以看到程序的运行效果。
内核模块可选信息
该部分是模块中可选的信息,可有也可以没有。模块申明:
加入下面的宏,声明相应的信息:
1、MODULE_LICENSE(“遵守的协议”);
申明该模块遵守的许可证协议,如:GPL、GPL v2等
2、MODULE_AUTHOR(“作者”);
申明模块的作者
3、MODULE_DESCRIPTION(“模块的功能描述”);
申明模块的功能
4、MODULE_VERSION(“V1.0”);
申明模块的版本
模块参数:
在应用程序中:
int main(int argc, char** argv)
argc表示命令行输入的参数个数,argv中保存输入的参数。
内核模块中可以通过命令行输入参数,例如:
insmod xx.ko 某个变量=某个值(该变量必须在程序中用宏指定)
但是,必须先通过宏module_param指定保存模块参数的变量。模块参数用于在加载模块时传递参数给模块。
module_param(name, type, perm);
name:变量的名称
type:变量类型,bool:布尔型,int:整型,charp:字符串型。
perm:是访问权限。 S_ IRUGO:读权限,S_IWUSR:写权限。
例程,传入两个参数:
int a = 3; char *st; module_param(a,int, S_IRUGO|S_IWUSR); module_param(st,charp, S_IRUGO|S_IWUSR); insmod xx.ko a=xx st=xx
符号导出:
一个模块的数据给其他模块使用必须要进行符号导出。
内核符号的导出使用宏
EXPORT_SYMBOL(符号名); EXPORT_SYMBOL_GPL(符号名); //符号名可以是变量,可以是函数名 //调用该符号的文件要使用extern声明该符号 //同时还要注意不同内核的安装顺序
说明:
其中EXPORT_ SYMBOL_GPL只能用于包含GPL许可证的模块。
相关文章推荐
- ubuntu11.10下为android模拟器编译内核到为android开发内核模块(.ko文件)全过程纪实
- Linux-内核模块开发
- Linux 驱动开发之内核模块开发(四)—— 符号表的导出
- linux、内核源码、内核编译与配置、内核模块开发、内核启动流程
- Linux 驱动开发之内核模块开发(四)—— 符号表的导出
- Linux 驱动开发-内核模块设计笔记 0
- UBuntu8.10 开发第一个基本Linux 驱动内核模块
- Linux驱动程序开发基础, -->内核模块编程,内核的调试方法
- [树莓派内核学习]内核模块开发
- raspberry内核编译和模块开发
- 内核模块开发基础
- Linux 下内核模块的开发方式的记录 及问题解决(入门的Helloworld)
- linux、内核源码、内核编译与配置、内核模块开发、内核启动流程
- freeswitch 内核模块开发
- Linux操作系统下 内核模块开发详细解析
- Linux驱动开发1--内核入门之hello模块
- linux 学习- 编程基础之内核模块开发
- Linux2.6下开发简单的可加载内核模块
- Android内核开发 adb远程调试内核模块
- Android内核开发 Linux C编程调用内核模块设备驱动