问题描述
我们将要学习 Linux Kernel Module 的开发方法,以为学习 Linux Kernel 做准备。
该笔记将记录:Linux Kernel Module 的开发方法,旨在快速入门,以及常见问题处理方案。
解决方案
Kernel Module 是已编译的二进制程序,直接插入到 Linux Kernle 中运行。
Kernel Module 运行在 RING0 中,在 x86 CPU 中最低且受保护最少的运行级别。这里的代码完全不受检查地运行,但运行速度令人难以置信,并且可以访问系统的所有内容。
准备工作
1)操作系统:虚拟机或独立运行的 Linux 发行版,用于内核代码测试;应避免在当前系统中直接测试内容,否则可能会导致系统崩溃、数据丢失等等问题;
2)编程语言:需要懂得些 C 语言编程;懂得 Linux Shell 命令行等等工具的使用方法;如果懂得硬件知识或汇编语言会更加的有帮助;
安装开发环境
我们使用 Eclipse 作为开发工具,
我们在 Ubuntu 20.04 TLS 中进行开发工作,需要安装如下包:
apt-get install build-essential # 安装编译器、调试器、库、其他工具
# Depends: libc6-dev | libc-dev, gcc (>= 4:9.2), g++ (>= 4:9.2), make, dpkg-dev (>= 1.17.11)
apt-get install linux-headers-`uname -r` # 安装内核头文件
模块开发
第一步、编写代码
lkm_example.c
// 用于模块开发的头文件
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
// 模块描述信息
MODULE_LICENSE("GPL");
MODULE_AUTHOR("k4nz@d3rm.org");
MODULE_DESCRIPTION("A simple example Linux module.");
MODULE_VERSION("0.01");
// 模块初始函数
static int __init lkm_example_init(void) {
printk(KERN_INFO "Hello, World!\n");
return 0;
}
// 模块退出函数
static void __exit lkm_example_exit(void) {
printk(KERN_INFO "Goodbye, World!\n");
}
// 模块加载与卸载
module_init(lkm_example_init);
module_exit(lkm_example_exit);
第二步、编写 Makefile 文件
obj-m += lkm_example.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean test: dmesg -C insmod lkm_example.ko rmmod lkm_example.ko dmesg
第三步、编译调试
# make test dmesg -C insmod lkm_example.ko rmmod lkm_example.ko dmesg [ 1692.496320] Hello, World! [ 1692.502960] Goodbye, World!
参考文献
How to Install GCC (build-essential) on Ubuntu 20.04 | Linuxize
Writing a Simple Linux Kernel Module | by Robert W. Oliver II | Sourcerer Blog