设备驱动开发实验教程(3)_在Ubuntu 18.04环境下编写一个简单的内核模块

内核模块定义      

      模块是具有独立功能的程序,可以单独编译,但是不能单独运行。模块在运行时,会被链接到内核,作为内核的一部分在内核空间运行。模块通常由一组函数和数据结构组成,用来实现一种文件系统、驱动程序或其他内核上层的功能。

 

内核模块基本原理

      Linux 内核模块(LKM)是一些在启动的操作系统内核需要时可以载入内核执行的代码块,不需要时由操作系统卸载。它们扩展了操作系统内核功能却不需要重新编译内核、启动系统。如果没有内核模块,就不得不反复编译生成操作系统的内核镜像来加入新功能,当附加的功能很多时,还会使内核变得臃肿。一个Linux 内核模块主要由以下几个部分组成: 
(1) 模块加载函数(必须):当通过insmod 或modprobe 命令加载内核模块时,模块的加载函数会自动被内核执行,完成本模块相关初始化工作。 
(2) 模块卸载函数(必须):当通过rmmod 命令卸载模块时,模块的卸载函数会自动被内核执行,完成与模块加载函数相反的功能。 
(3) 模块许可证声明(必须):模块许可证(LICENCE)声明描述内核模块的许可权限,如果不声明LICENCE,模块被加载时将收到内核被污染的警告。大多数情况下,内核模块应遵循GPL 兼容许可权。Linux2.6 内核模块最常见的是以MODULE_LICENSE(“Dual BSD/GPL”)语句声明模块采用BSD/GPL 双LICENSE。 
(4) 模块参数(可选):模块参数是模块被加载的时候可以被传递给他的值,它本身对应模块内部的全局变量。 
(5) 模块导出符号(可选):内核模块可以导出符号(symbol,对应于函数或变量),这样其他模块可以使用本模块中的变量或函数。 
(6) 模块作者等信息声明(可选)。

      一个内核模块至少包含两个函数,模块被加载时执行的初始化函数init_module()和模块被卸载时执行的结束函数cleanup_module()。在最新内核稳定版本2.6 中,两个函数可以起任意的名字,通过宏module_init()和module_exit()注册调用要编译内核模块,把代码嵌进内核空间,首先要获取内核源代码,且版本必需与当前正在运行的版本一致。

 

hello.c代码清单如下:

#include
#include
#include

static int __init lkp_init(void)
{
	printk("<0>" "Hello World from the kernel space...\n");
	return 0;
}

static void __exit lkp_cleanup(void)
{
	printk("<0>" "Good Bye World! leaving kernel space...\n");
}

module_init(lkp_init);	// 注册模块
module_exit(lkp_cleanup);	// 注销模块
MODULE_LICENSE("GPL"); 	//告诉内核该模块具有GNU公共许可证

 

Makefile代码清单如下:

# Makefile 4.0
obj-m := hello.o
CURRENT_PATH := $(shell pwd)
LINUX_KERNEL := $(shell uname -r)
LINUX_KERNEL_PATH := /usr/src/linux-headers-$(LINUX_KERNEL)

all:
	make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
clean:
	make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean

 

编译:执行make命令,如下图。

设备驱动开发实验教程(3)_在Ubuntu 18.04环境下编写一个简单的内核模块_第1张图片

 

加载模块: insmod hello.ko

卸载模块: rmmod hello

模块加载、卸载过程中并未输出printk信息,如下所示:

设备驱动开发实验教程(3)_在Ubuntu 18.04环境下编写一个简单的内核模块_第2张图片

 

要查看printk打印的信息,可执行命令: cat /var/log/syslog | grep Hello

                                                                cat /var/log/syslog | grep Good

grep的信息要与hello.c中printk输出的信息对应。

设备驱动开发实验教程(3)_在Ubuntu 18.04环境下编写一个简单的内核模块_第3张图片

设备驱动开发实验教程(3)_在Ubuntu 18.04环境下编写一个简单的内核模块_第4张图片

 

编程实例参考:

编写一个简单的内核模块程序Hello World!   https://blog.csdn.net/sh21_/article/details/60878812

在Ubuntu 18.04环境下编写一个简单的内核模块    https://blog.csdn.net/song_lee/article/details/82995312

你可能感兴趣的:(嵌入式Linux,驱动实验)