Ubuntu搭建驱动开发环境

1 环境

1.0 系统

  • Ubuntu 18.04
    Linux xhwl 4.15.0-39-generic #42-Ubuntu SMP Tue Oct 23 15:48:01 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

1.1 依赖列

  • build-essential
  • kernel-package
  • gcc
  • make
  • kernel-source
  • kernel-headers
  • libncurses5-dev
  • libssl-dev
  • libelf-dev

1.2 安装依赖

sudo apt-get build-essential kernel-package kernek-source libncurses5-dev libssl-dev libelf-dev

2 源文件获取与安装

2.1 获取

# 查看系统内核版本
uname -r
4.15.0-39-generic
# 获取源文件包
sudo apt-get install linux-source-4.15.0
# 文件包默认在/usr/src中
cd /usr/src
linux-source-4.15.0.bz2
# 解压至指定目录
sudo tar -jxvf linux-source-4.15.0.bz2 -C /path
# 进入源码包目录
cd path/linux-source-4.15.0

2.2 安装

# 编译
sudo make oldconfig
# 最耗时
sudo make
# 生成设备树
sudo make modules
sudo make modules_install
# 在lib/modules目录中生成设备树
cd /lib/modules
# 目录结构
|-- modules
   |-- 4.15.0-29-generic
   |-- 4.15.0-30-generic
   |-- 4.15.0-32-generic
   |-- 4.15.0-33-generic
   |-- 4.15.0-34-generic
   |-- 4.15.0-36-generic
   |-- 4.15.0-39-generic
   |-- 4.15.0-42-generic
   `-- 4.15.18

3 测试

3.1 目录结构

DriverConfig
|   `-- linux-source-4.15.0
`-- driverTest
    |-- Makefile
    `-- hello.c

3.2 hello.c

#include<linux/init.h>
#include<linux/module.h>
#include<linux/kernel.h>
MODULE_LICENSE("Dual BSD/GPL")
# 初始化
# KERN_ALERT设定printk日志级别,但X86无效
static int __init hello_init(void){
	printk(KERN_ALERT "Hello, Xin Daqi!");
	return 0;
}
# 退出
static void __exit hello_exit(void){
	printk(KERN_ALERT "Goodbye!");
	// KERN_ALERT
}
# 调用函数
module_init(hello_init);
module_exit(hello_exit);

3.3 Makefile V0

# 生成的模块名hello.o
obj-m:=hello.o
# 生成这个模块名需要的目标文件
# modules-objs:=hello.o
# 生成的设备树路径/lib/modules
# 其中$(shell uname -r)即获取内核版本,同uname -r
KERNELDIR:=/lib/modules/$(shell uname -r)/build
# 获取当前文件路径
# pwd即是获取路劲命令
PWD:=$(shell pwd)
# 编译
modules:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

3.4 Makefile V1

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
  • 注意
    ifneq后有一个空格。

3.5 编译

# 在driverTest目录下
make
# 提示信息
make -C /lib/modules/4.15.0-39-generic/build M=/home/xdq/xinPrj/Linux/driverTest modules
make[1]: 进入目录“/usr/src/linux-headers-4.15.0-39-generic”
  CC [M]  /home/xdq/xinPrj/Linux/driverTest/hello.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/xdq/xinPrj/Linux/driverTest/hello.mod.o
  LD [M]  /home/xdq/xinPrj/Linux/driverTest/hello.ko
make[1]: 离开目录“/usr/src/linux-headers-4.15.0-39-generic”
# 生成文件目录结构
|-- DriverConfig
|   `-- linux-source-4.15.0
`-- driverTest
    |-- Makefile
    |-- Module.symvers
    |-- hello.c
    |-- hello.ko
    |-- hello.mod.c
    |-- hello.mod.o
    |-- hello.o
    `-- modules.order

3.6 测试

# 加载驱动
sudo insmod hello.ko
# 终端输出
无输出
# 日志查看
/var/log/kern.log或dmesg
GoodBye!
# 查看加载的驱动
lsmod
# 卸载驱动
rmmod hello
Hello, Xin Daqi!

4 内核日志

4.1 日志级别

序号描述等级说明
1KERN_EMERG0突发性事件消息,通常在系统崩溃之前报告此类信息
2KERN_ALERT1需要立即操作的情况下使用此消息
3KERN_CRIT2临界条件,遇到严重软硬件错误时使用
4KERN_ERR3报告错误条件,设备驱动经常使用该级别报告硬件问题
5KERN_WARNING4问题警告,一般不会引起系统严重问题
6KERN_NOTICE5普通通知,许多安全性相关的情况会使用这个级别报告
7KERN_INFO6信息,驱动程序启动时获取硬件信息
8KERN_DEBUG7调试信息

4.2 打印日志配置

# 日志级别目录
/proc/sys/kernel/printk
# 查看级别
cat /proc/sys/kernel/printk
4	4	1	7
序号级别说明
14内核打印函数printk的打印级别,只有级别比他高的信息才能在控制台打印,即0-3级别
24默认消息日志级别,该优先级打印没有优先级的消息
31最低的控制台日志级别,控制台日志级别可别设置的最小值(最高优先级)
47默认的控制台日志级别,控制台日志级别的缺省值
# 修改日志级别
dmesg -n 8
# 权限不够
echo 8 >/proc/sys/kernel/printk
# 使用sudo依旧权限不够
sudo echo 8 > printk
# 终极大招
sudo sh -c 'echo 8 > printk'
# X86_64机器依旧不能显示printk信息
# 只能通过日志文件了dmesg最方便
dmesg
GoogBye!
Hello, Xin Daqi!

5 问题

  • 1
scripts/sign-file.c:25:10: fatal error: openssl/opensslv.h: 没有那个文件或目录
 #include <openssl/opensslv.h>
  • 解决
    安装依赖
 sudo apt-get install libssl-dev 
  • 2
scripts/Makefile.build:504: recipe for target 'scripts/basic/modules.order' failed
make[1]: *** [scripts/basic/modules.order] Error 2
Makefile:488: recipe for target 'scripts_basic' failed
make: *** [scripts_basic] Error 2
  • 解决
    安装依赖
sudo apt-get install libelf-dev
  • 3
cannot create scripts/basic/modules.order: Permission denied
  • 解决
sudo make modules
  • 4
arch/x86/Makefile:156: CONFIG_X86_X32 enabled but no binutils support
  • 解决
sudo make modules
  • 5
make-C /lib/models/4.15.0-39-generic/build M=/home/xdq/xinPrj/Linux/driverTest modules
make: make-C: Command not found
Makefile:5: recipe for target 'modules' failed
make: *** [modules] Error 127
  • 6
Makefile:2: *** 遗漏分隔符 (null)。 停止。
  • 解决
    查找Makefile中ifneq后是否有空格,及其他语句空格

6 总结

  • 明确部署系统的配置,安装相应依赖及核心文件;
  • 日志信息在X86平台不能终端输出,需查看日志文件;
  • 调试过程注意语法格式,规范编码;
  • 记录异常信息,做好笔记,方便后续查阅;
  • 积累,就是练本事。

[参考文献]
[1]https://blog.csdn.net/liufei191010/article/details/80826906
[2]https://blog.csdn.net/wr132/article/details/73825888
[3]https://www.cnblogs.com/wmx-learn/p/5344821.html


  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天然玩家

坚持才能做到极致

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值