问题描述
我们将要学习 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