环境说明
- Dell T30 机器一台
- 操作系统 Ubuntu 18.04
- 参考书《Linux Device Driver Third Edition》
构建源码树步骤
- 查看当前系统版本
$ uname -a
Linux dell-PowerEdge-T30 5.0.0-31-generic #33~18.04.1-Ubuntu SMP Tue Oct 1 10:20:39 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
- 查看系统中是否已经安装了Kernel源码
$ cd /usr/src
$ ls -l
total 24
drwxr-xr-x 25 root root 4096 Sep 25 2019 linux-headers-5.0.0-29
drwxr-xr-x 8 root root 4096 Sep 25 2019 linux-headers-5.0.0-29-generic
drwxr-xr-x 25 root root 4096 Oct 6 2019 linux-headers-5.0.0-31
drwxr-xr-x 8 root root 4096 Oct 6 2019 linux-headers-5.0.0-31-generic
drwxrwxr-x 30 root root 4096 Apr 26 22:26 linux-source-5.0.0
lrwxrwxrwx 1 root root 45 Feb 10 19:33 linux-source-5.0.0.tar.bz2 -> linux-source-5.0.0/linux-source-5.0.0.tar.bz2
在我的系统中已经存在了源代码,因此无需重新安装。如果系统中没有源码,那么按下面步骤3进行安装配置。
- 如果系统中没有源码,可用以下面的命令进行安装
$ apt-cache search linux-source
linux-source - Linux kernel source with Ubuntu patches
linux-source-4.15.0 - Linux kernel source for version 4.15.0 with Ubuntu patches
linux-source-4.18.0 - Linux kernel source for version 4.18.0 with Ubuntu patches
linux-source-5.0.0 - Linux kernel source for version 5.0.0 with Ubuntu patches
linux-source-5.3.0 - Linux kernel source for version 5.3.0 with Ubuntu patches
linux-source-3.13.0 - Linux kernel source for version 3.13.0 with Ubuntu patches
$ sudo apt-get install linux-source-5.0.0
如果安装成功,在/usr/src目录下会看到一个linux-source-5.0.0.tar.bz2压缩包,解压:
$ sudo tar jxvf linux-source-5.0.0.tar.bz2
在/usr/src目录下会看到linux-source-5.0.0文件夹,这就是我们需要的源码树。
- 进入源码目录 linux-source-5.0.0
$ sudo make menuconfig
$ sudo make oldconfig
$ sudo make modules
$ sudo make modules_install
源码树构建完成,重启系统。
开始第一个Hello word驱动程序
- 编码hello.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h>
// 许可证(必要)
MODULE_LICENSE("Dual BSD/GPL");
// 模块作者
MODULE_AUTHOR("Kama Li");
// 简短描述
MODULE_DESCRIPTION("First driver module.");
// 模块版本
MODULE_VERSION("1.0.1");
// 模块别名
MODULE_ALIAS("Hello world");
void currentInfo(void)
{
printk(KERN_INFO "The process is \"%s\" (pid %i) (CPU %d)\n", current->comm, current->pid, smp_processor_id());
printk(KERN_INFO "in_irq() = %ld, in_interrupt() = %ld\n", in_irq(), in_interrupt());
}
static int hello_init(void)
{
printk(KERN_ALERT "Hello, world\n");
currentInfo();
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
- 编码makefile
ifneq ($(KERNELRELEASE),)
mymodule-bojs := hello.o
obj-m := hello.o
else
PWD := $(shell pwd)
KERNELDIR = /lib/modules/$(shell uname -r)/build
all:
$(MAKE) -C $(KERNELDIR) M=$(PWD)
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c
endif
- 编译及测试
$ make
$ sudo insmod hello.ko
- 查看kernel打印出来的log
$ sudo cat /var/log/syslog
Apr 26 22:22:19 dell-PowerEdge-T30 kernel: [20733.002512] Goodbye, cruel world
Apr 26 22:22:27 dell-PowerEdge-T30 kernel: [20740.842238] Hello, world
Apr 26 22:22:27 dell-PowerEdge-T30 kernel: [20740.842240] The process is "insmod" (pid 25112) (CPU 1)
Apr 26 22:22:27 dell-PowerEdge-T30 kernel: [20740.842241] in_irq() = 0, in_interrupt() = 0
$ sudo rmmod hello
$ sudo cat /var/log/syslog
Apr 26 22:23:43 dell-PowerEdge-T30 gnome-shell[1663]: [AppIndicatorSupport-WARN] Attempting to re-register :1.6/StatusNotifierItem; resetting instead
Apr 26 22:23:43 dell-PowerEdge-T30 gnome-shell[1663]: [AppIndicatorSupport-WARN] Item :1.6/StatusNotifierItem is already registered
Apr 26 22:24:10 dell-PowerEdge-T30 kernel: [20844.122386] Goodbye, cruel world
补充:查看系统日志,还可以用
$sudo dmesg
[20528.821058] Hello, world
[20528.821060] The process is "insmod" (pid 18391) (CPU 1)
[20528.821061] in_irq() = 0, in_interrupt() = 0
[20733.002512] Goodbye, cruel world
[20740.842238] Hello, world
[20740.842240] The process is "insmod" (pid 25112) (CPU 1)
[20740.842241] in_irq() = 0, in_interrupt() = 0
[20844.122386] Goodbye, cruel world
到此,驱动开发环境算是完成了。