Linux 内核模块
来源:互联网 发布:淘宝最新开店流程 编辑:程序博客网 时间:2024/05/22 06:26
Linux 内核模块
Linux 设备驱动会以内核模块的形式出现,内核模块本身不被编译入内核镜像,从而控制了内核的大小,这样的工作机制也更加灵活.
内核模块程序结构
一个Linux内核模块主要由如下几部分组成
- 模块加载函数
- 模块卸载函数
- 模块许可证声明
- 模块参数(可选)
- 模块导出符号(可选)
- 模块作者等信息声明(可选)
内核模块基础示例
【代码仓库】
hello world
#include <linux/init.h>#include <linux/module.h>static int __init hello_init(void){ printk(KERN_INFO "Hello world enter"); return 0;}module_init(hello_init);static int __exit hello_exit(void){ printk(KERN_INFO "Hello world exit"); return 0;}module_exit(hello_exit);MODULE_LICENSE("Dual BSD/GPL");
Makefile
KERNELDIR = /lib/modules/`uname -r`/build#Kernel modulesobj-m += hello.o#EXTRA_CFLAGS=-g -o0all: $(MAKE) -C $(KERNELDIR) M=$(PWD) modulesclean: $(MAKE) -C $(KERNELDIR) M=$(PWD) clean
验证
$ make$ insmod hello.ko$ modinfo hello.kofilename: /root/share/linux_driver_demo/hello_world/hello.kolicense: Dual BSD/GPLsrcversion: 5A29A82E48CA197252C923Ddepends:vermagic: 4.4.0-31-generic SMP mod_unload modversions$ dmesg | tail -1[22017.025568] Hello world enter$ rmmod hello$ dmesg | tail -1[22225.742975] Hello world exit
相关说明
示例内核模块中只包含了加载函数、卸载函数和对GPL许可权限的声明.
- insmod hello.ko 加载模块
- rmmod hello 卸载模块
- printk 内核打印函数
- modprobe 加载/卸载模块(包括依赖关系)
- modinfo hello.ko 查看模块信息
内核模块符号导出
Linux 的“/proc/kallsyms”文件对应着内核符号表,记录了符号以及符号所在的内存地址.模块可以使用如下宏导出符号到内核符号表中:
- EXPORT_SYMBOL(符号名)
- EXPORT_SYMBOL_GPL(符号名)
导出的符号可以被其他模块使用,只需要在使用前声明一下即可.
符号导出基础示例
export symbol
#include <linux/init.h>#include <linux/module.h>MODULE_LICENSE("Dual BSD/GPL");int add(int a, int b){ return a+b;}int sub(int a, int b){ return a-b;}/* 导出符号 */EXPORT_SYMBOL_GPL(add);EXPORT_SYMBOL_GPL(sub);
Makefile
KERNELDIR = /lib/modules/`uname -r`/build#Kernel modulesobj-m += export.o#EXTRA_CFLAGS=-g -o0all: $(MAKE) -C $(KERNELDIR) M=$(PWD) modulesclean: $(MAKE) -C $(KERNELDIR) M=$(PWD) clean
import symbol
#include <linux/init.h>#include <linux/module.h>/* 使用导出符号函数 */extern int add(int, int);extern int sub(int, int);static int __init import_init(void){ int rc = add(5, 6); printk(KERN_INFO "[import symbol] -> add(5, 6) = %d\n", rc); return 0;}module_init(import_init);static int __exit import_exit(void){ printk(KERN_INFO "import symbol exit\n"); return 0;}module_exit(import_exit);MODULE_LICENSE("Dual BSD/GPL");
Makefile
KERNELDIR = /lib/modules/`uname -r`/build#Kernel modulesobj-m += import.o#EXTRA_CFLAGS=-g -o0all: $(MAKE) -C $(KERNELDIR) M=$(PWD) modulesclean: $(MAKE) -C $(KERNELDIR) M=$(PWD) clean
验证
$ cd export_symbol && make$ cp Module.symvers ../import_symbol$ insmod export.ko$ cd ../import_symbol && make$ insmod import.ko$ dmesg | tail -1[23665.048569] [import symbol] -> add(5, 6) = 11
学习资源
- 《Linux C API 参考手册》
- 《Linux 设备驱动开发详解》
阅读全文
0 0
- Linux内核模块:模块参数
- Linux 内核模块
- linux内核模块加载
- Linux内核模块
- Linux内核模块编程
- Linux内核模块编程
- Linux内核模块使用指南
- linux内核模块解析
- Linux内核驱动模块
- linux内核模块编译
- linux 添加内核模块
- linux内核模块解析
- linux内核模块常用命令
- Linux内核模块编程
- linux内核模块编程
- linux 内核模块
- Linux 内核模块编程
- Linux内核模块概述
- Android-----------OkHttp
- 博客上线
- http://blog.csdn.net/kj_zx19854/article/details/1865337
- ORACLE-024:列行转换、多行合并
- CMarkUp使用简介
- Linux 内核模块
- selector到底是什么
- Charles安装与简单使用
- 云南协和医院好不好?网友举报其为黑心骗子医院
- 二叉树(4)
- Linux下打包语句
- 单例的几种实现方式
- activeMQ(1)
- 从Python对象三要素来看is和==的区别