本文最后更新于:星期五, 二月 1日 2019, 5:45 下午
最近想研究下linux内核,就开始学习内核模块编程,写篇博客,做下学习笔记。
内核模块编程
模块的定义
内核模块就是具有独立功能的程序,它能被单独编译,但是不能单独运行,它的运行必须被链接到内核作为内核的一部分在内核空间运行。
用户编程和内核模块编程的区别
基本组成
模块通常由一组函数和数据结构组成,用来实现一种文件系统、一个驱动程序或其他内核上层的功能。
内核编程3个必须的头文件
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
必须的两个函数
//模块加载函数
static int __init init_fun(void) //函数名随意,__init和__exit是init.h中定义的宏
{
// 初始化代码
}
//模块卸载函数
static void __exit exit_fun(void)
{
// 释放代码
}
module_init(init_fun); //驱动程序初始化的入口点
module_exit(exit_fun); //对于可加载模块,内核在此处调用module_cleanup()函数,而对于内置的模块,它什么都不做。
一个简单的例子
// 基于 Linux 2.6的内核
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
static int __init init_fun( void )
{
printk(“<1>Hello,World! from the kernel space…\n”);
return 0;
}
static void __exit exit_fun( void )
{
printk(“<1>Goodbye, World! leaving kernel space…\n”);
}
module_init(init_fun);
module_exit(exit_fun);
MODULE_LICENSE(“GPL”); //许可权限声明,如果不申明,模块加载时会收到内核的警告
模块编译
工具:make(GNU的工程化编译工具)
工作原理:
make 工具通过一个称为 Makefile 的文件来完成并自动维护编译工作。Makefile 需要按照某种语法进行编写,其中说明了如何编译各个源文件并连接生成可执行文件,并定义了源文件之间的依赖关系。
Makefile规则格式
:
[tab]
冒号前面部分叫target,后面的部分叫前置条件,第二行必须由一个tab键起首,后面跟命令。
这两篇文章可以做个入门
一个例子:
# Makefile2.6
obj-m += hellomod.o # 产生hellomod 模块的目标文件
CURRENT_PATH := $(shell pwd) #模块所在的当前路径
LINUX_KERNEL := $(shell uname -r) #Linux内核源代码的当前版本
LINUX_KERNEL_PATH := /usr/src/linux-headers-$(LINUX_KERNEL) #Linux内核源代码的绝对路径
all:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules #编译模块了
clean:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean #清理
常用的模块编程命令
- lsmod 获得系统中加载了的所有模块以及模块间的依赖关系
- cat /proc/modules 查看加载模块的信息
- tree -a 在/sys/module 对应模块的文件夹下使用,可以显示一些联系
- modinfo <模块名> 显示模块的信息
- insmod <模块名.ko> 将模块插入内核
- rmmod <模块名.ko> 将模块从内核中移除
后续如果有新东西的话会继续补充
reference
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!