在 Ubuntu 上开发驱动程序,需要安装内核头文件、编译工具和相关依赖项:
sudo apt update
sudo apt install build-essential linux-headers-$(uname -r) dkms
build-essential:包含 gcc、make、binutils 等基本开发工具。
linux-headers-$(uname -r):安装当前运行内核的头文件,驱动程序需要它来编译。
dkms(可选):用于管理动态内核模块。
//#include <linux/init.h> //下面的头文件包含了,所以这里不调用也可以
#include <linux/module.h>
#include<linux/kernel.h>
static int __init hello_init(void) //__init表示该函数只在初始化期间使用,模块装载后就直接丢弃,并释放内存
{
printk(KERN_INFO "hello word\r\n");
return 0;
}
static void __exit hello_exit(void)
{
printk(KERN_INFO "hello exit!!!!\r\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL"); //许可GPL GPL v2 Dual MPL/GPL等
obj-m := hello.o
KDIR :=/lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
四、加载和卸载驱动
1. 加载模块sudo insmod hello.ko
2.lsmod
命令用于查看当前模块加载情况
3.dmesg | tail -n 10
.然后检查 dmesg 输出
cat /proc/modules
查看模块
ls /sys/modules
也可以查看到模块(每加载一个就会在sys/modules目录下生成一个文件夹,文件夹中就是模块的相关的一些信息)
五、 卸载模块
sudo rmmod hello
dmesg | tail -n 10
六、调试驱动
查看模块信息:
lsmod | grep hello
查看日志:
dmesg | tail -n 20
使用 modinfo 查看驱动信息:
modinfo hello.ko
安装开发环境:build-essential、linux-headers、dkms 等。
编写驱动:创建 .c 文件,实现 module_init 和 module_exit。
编写 Makefile:用于编译驱动。
编译驱动:使用 make 生成 .ko 模块文件。
加载和卸载驱动:使用 insmod 和 rmmod。
调试:使用 dmesg、lsmod、modinfo 等工具。
七、如果编译arm的驱动
首先需要先下载内核源码
- 进入内核源码目录
cd /LinuxSource/linux-4.19.198
2. 配置内核
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- vexpress_defconfig
这一步会生成 .config 文件。
3. 准备编译环境
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- oldconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- prepare
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules_prepare
4. 编译内核
(如果是完整内核编译,执行下面命令)
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j$(nproc)
如果你的设备是多核的,可以用 -j$(nproc) 来加速编译,nproc 会自动使用所有 CPU 核心。
5. 编译模块
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules -j$(nproc)
6. 安装模块
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules_install INSTALL_MOD_PATH=output
这会把内核模块安装到 output/lib/modules/ 目录。
如果只是编译驱动
如果你只是想编译 外部驱动,不需要完整编译内核,只需要:
make -C /LinuxSource/linux-4.19.198 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- M=/root/Dtest modules
obj-m := hello.o
ARCH := arm
CROSS_COMPILE := arm-linux-gnueabihf-
KDIR :=/LinuxSource/linux-4.19.198
PWD := $(shell pwd)
all:
$(MAKE) -C $(KDIR) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) M=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) M=$(PWD) clean
#include <linux/init.h>
#include <linux/module.h>
#include<linux/kernel.h>
static int __init hello_init(void)
{
printk(KERN_INFO "hello word\r\n");
return 0;
}
static void __exit hello_exit(void)
{
printk(KERN_INFO "hello exit!!!!\r\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");