Linux内核模块
来源:互联网 发布:mysql 查询一年内 编辑:程序博客网 时间:2024/06/05 19:13
1、内核模块(2.6及以后版本为例)
1.1、概念
内核模块是Linux内核向外部提供的一个接口,其全称为动态可加载内核模块(Loadable Kernel Module,LKM),简称为模块。
简单说就是linux内核是一个单内核(monolithic kernel),即内核是一个程序,这样内核运行的效率比较高。内核模块是内核这个程序中的一部分。linux内核允许模块在内核运行起来后,再加载进内核。
这样设计的好处是,可以先运行起来具有基本系统功能的内核,然后再根据需要添加需要的模块,则内核就不会很大。内核是一个程序,不可能预先把所有的功能模块都编译进内核。
1.2、三个基本组成部分(2.6及以后版本为例)
A、两个函数
初始化函数:模块加载进内核的时候做一些初始化工作
注销函数:模块从内核卸载的时候做一些回收工作
B、注册两个函数给内核
把初始化及注销函数注册给内核
(注册的意义:内核不仅仅是先编译好的,而且运行起来了,后编译运行的内核模块的函数要提供给内核回调,从语法的角度看,内核不知道。从运行的角度看这个问题,模块函数加载到内存哪里,内核是不知道的。把模块函数登记到内核指定的位置,内核就可以回调到。)
C、授权声明
linux内核是开源的,可以免费使用,但是使用时候是有协议的,一定要遵循。授权协议有几个版本,到内核官网就可以查询到。
1.3、范例
#include <linux/module.h>
#include <linux/kernel.h>
/*初始化函数*/
static int __init demo_init(void)
{
return 0;
}
/*注销函数*/
static void __exit demo_exit(void)
{
}
/*授权声明*/
MODULE_LICENSE("Dual BSD/GPL");
/*注册初始化函数*/
module_init(demo_init);
/*注册注销函数*/
module_exit(demo_exit);
2、编译环境
2.1、编译模块必须使用编译出内核的内核源码目录树来编译内核
linux内核是一个整体,模块只是其中一部分,所以模块的编译依赖内核。主要需要使用到的是:
A、编译系统
内核使用一个编译系统编译出来的,模块是其的一部分,所以这样编译系统要一致才不会出现问题。
B、内核函数符号表
内核编译出来后会形成一个函数符号与所在地址的一个对应表,这个就是符号表。模块会使用到内核提供的一些函数或是数据,就是根据这个表格来找到内核提供的这些代码或是数据。
C、头文件支持
C语法有声明的概念,就是说编译在编译的时候可以帮我们检查,模块代码中使用的函数原型或是数据类型对不对。
2.2、范例
1
ifneq ($(KERNELRELEASE),)
2
obj-m := demo.o
3
else
4
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
5
PWD := $(shell pwd)
6
modules:
7
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
8
endif
9
clean:
10
rm -rf *.o *.symvers *.order *.ko *.mod.c *.markers
第1行:检查变量KERNELRELEASE(内核源码顶层目录下Makefile中定义)是否存在,不存在则走else项
第2行:定义要编译的模块demo.o表示要编译的模块源码文件是demo.c
第3行:ifneq ($(KERNELRELEASE),)不成功则则else下的执行
第4行:定义一个变量KERNELDIR,指定内核源码目录树,这里的是PC下的内核源码目录树路径
第5行:定义一个变量PWD,指定模块源码所在路径
第6行:定义一个伪目标modules
第7行:伪目标modules下的命令行。
$(MAKE)是Makefile默认变量即指定工具make
-C是make 的参数,表示要切换目录
$(KERNELDIR)是变量引用,即内核源码目录树
M=$(PWD)是传递参数,传递的是$(PWD)指定的模块源码路径
modules是目标名
这句命令行的意思:切换到内核源码目录树下,执行其Makefile中的modules目标,并把模块源码路径传递给内核源码目录下的Makefile
第8行:endif,ifneq ($(KERNELRELEASE),)的结束语法
第9行:定义一个伪目标clean
第10行:伪目标clean的命令行,用来删除编译模块源码产生的过程文件。
这个简单范例反应了模块源码编译的大概过程如下:
先从模块源码所在路径下执行make,然后根据模块源码所在路径下的Makefile的定义转到内核源码目录树所在目录,并执行其Makefile,并把模块的路径传递给这个Makefile。内核源码目录下的Makefile会根据传递去的模块源码目录,再切换回来模块源码,得到要编译的模块源文件,再执行编译。
3、操作模块
这里假定模块文件名xxx.ko(2.6及以后内核编译出来的模块的文件名称的扩展名都是.ko)
模块名,在2中的Makefile范例中“obj-m := demo.o”,demo就是模块名
3.1、加载模块
在终端下执行
#insmod 模块文件名
3.2、卸载模块
#rmmod 模块名
3.3、查看模块
# lsmod
# cat /proc/modules
3.4、查看模块输出信息
#demsg
#cat /proc/kmsg
- Linux内核模块:模块参数
- Linux 内核模块
- linux内核模块加载
- Linux内核模块
- Linux内核模块编程
- Linux内核模块编程
- Linux内核模块使用指南
- linux内核模块解析
- Linux内核驱动模块
- linux内核模块编译
- linux 添加内核模块
- linux内核模块解析
- linux内核模块常用命令
- Linux内核模块编程
- linux内核模块编程
- linux 内核模块
- Linux 内核模块编程
- Linux内核模块概述
- << Oracle高可用>>部分书面作业 - 第九课 RAC+DG技术的应用
- matlab 下读取文件夹中的图片
- java修饰符
- 多线程死锁问题
- << Oracle高可用>>部分书面作业 - 第十课 Oracle Golden gate 概念和机制
- Linux内核模块
- << Oracle高可用>>部分书面作业 - 第十一课 Oracle Golden gate 设计及应用
- 数据中死锁那些事
- 数组首元素地址和数组地址、int *ptr=(int *)(&a+1)问题的探讨
- ssh
- vs2008+ddkwizard+wdk基于xp环境
- 对 SQL*Plus 会话自动设置 sqlprompt
- << Oracle高可用>>部分书面作业 - 第十二课 Oracle 流技术(streams)
- 字符设备驱动