本文最后更新于:星期五, 二月 1日 2019, 5:45 下午

最近想研究下linux内核,就开始学习内核模块编程,写篇博客,做下学习笔记。

内核模块编程

模块的定义

内核模块就是具有独立功能的程序,它能被单独编译,但是不能单独运行,它的运行必须被链接到内核作为内核的一部分在内核空间运行。

用户编程和内核模块编程的区别

1547897572940

基本组成

模块通常由一组函数和数据结构组成,用来实现一种文件系统、一个驱动程序或其他内核上层的功能。

内核编程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

linux 内核之旅


CODE      kernel

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!