最近想学习Linux内核驱动开发,了解了一些关于Linux的基础知识(看的B站汪晨的视频,CSDN有个博主也总结了这个视频的内容)配置了开发环境,即在windows10上安装了VMware,在VMware里安装了Ubuntu22,前面的搞定之后,就开始第一个helloworld内核编译。我有一个树莓派(Raspberry Pi),就算没有,也可以完成下面的helloworl驱动编译,因为模块编译只要有内核头文件就可以了。后面如果确定用树莓派还是imx6ull再下载他们相应的内核源码进行编译就好了。
先不讲要安装什么编译工具,我们最直白知道要编写一个helloword.c和一个Makefile。
内容如下:
helloworld.c
// 头文件
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>static int __init helloworld(void)
{prink("hello world\n");return 0;
}static void __exit goodbye(void)
{printk("goodbye\n");
}
module_init(helloworld); // 加载模块
module_exit(goodbye); // 卸载模块MODULE_LICENSE("GPL"); /* 必不可少的声明 */
Makefile
obj-m +=helloworld.o
KDIR := /lib/modules/$(shell uname -r)/buildPWD?= $(shell pwd)
all:make -C $(KDIR) M=$(PWD) modules
Makefile里面的内容表示:
- 要编译一个 可加载模块(module) ,模块目标文件是
helloworld.ko。最终生成的模块是.helloworld.ko. - 定义变量
KDIR为当前系统内核头文件目录,(指向当前运行内核版本源码或头文件的路径)。 - 定义变量
PWD为当前工作目录(即你放这个 Makefile 的目录)。 - 调用内核的顶层 Makefile 来编译你的模块。
驱动编译有两种方法(具体区别可以自己查一下)
- 把驱动编译成模块再编译到内核(现在采用这种)
- 直接把驱动编译到内核
下面是要make编译helloworld.c,需要安装编译环境:
`sudo apt update``sudo apt install build-essential linux-headers-$(uname -r)`
接着就是新建文件夹,存放helloworld.c和Makefile(要大写M),内容就是上面的内容。
- 编译模块
make如果第二次编译,记得make clean再make - 加载模块
sudo insmod helloworld.c如果你是在root下,就可以不用加sudo

- 查看日志输出(因为我们不是直接在硬件中编写的,所以只能通过日志查看)
dmseg | tail -n 10查看后面10条日志信息
能看到输出内容是hello world

- 卸载模块
sudo rmmod helloworld - 查看日志输出(因为我们不是直接在硬件中编写的,所以只能通过日志查看)
dmseg | tail -n 10查看后面10条日志信息
能看到输出内容是goodbye
🌈到此,恭喜你,第一个内核驱动成功运行了!