Linux驱动开发笔记(三):基于ubuntu的helloworld驱动源码编写、makefile编写以及驱动编译加载流程测试

简介: 前面学习了驱动的基础框架,上一篇编译了gcc7.3.0,那么为了方便很好的熟悉流程,本篇,将使用ubuntu18.04,直接编译ubuntu18.04的驱动,然后做好本篇文章的相关实战测试。

前言

  前面学习了驱动的基础框架,上一篇编译了gcc7.3.0,那么为了方便很好的熟悉流程,本篇,将使用ubuntu18.04,直接编译ubuntu18.04的驱动,然后做好本篇文章的相关实战测试。


Ubuntu虚拟机准备

步骤一:安装虚拟机

  本次使用之前rk3568的ubuntu18.04,笔者没有重新弄了,安装虚拟机的过程请自行搜索查找完成。

  

步骤二:获取内核版本号

  获取内核版本号是为了确认内核版本号一致。

sudo cat /proc/version

  

步骤三:校准编译器版本

  前面获取了内核的编译器版本是gcc7.3.0,但是本机是gcc7.5,需要变更版本:

  

步骤四:下载内核源码

sudo cat /proc/version
sudo apt-cache search linux-source
sudo apt-get install linux-source-4.15.0

  查看到本ubuntu的内核版本,然后下载对应的版本:

  

  以上准备好的内核源码和编译器则可以开始编译内核。


内核编译

  注意1:ubuntu的/usr/src下有内核的头文件可编译直接使用。

  注意2:本标题章节所编译的内核然后使用该内核编译的驱动是不可兼容的。

  

步骤一:下载解压

  

  发现其实系统自带了header头文件。(PS:-header- 就是头文件,驱动和某些和内核功能关联的东西都要调用当前内核版本的对应头文件才能正确的编译出来而且可以使用。所以有些发行版就制作了专用的 header 包来让需要的程序调用。这种包只有 header 文件,没有其他无关开发的内容。

cd linux-source-4.18.0/
sudo tar xvf linux-source-4.18.0.tar.bz2

  

步骤二:内核配置

cd linux-source-4.18.0
sudo make menuconfig

  

  进入了配置:

  

  不做任何配置变动,退出。

步骤三:直接编译

make -j8

  

  半小时左右编译完成:

  


驱动编译

  把驱动编译城模块,然后加载到内核里面。

步骤一:使用前面编写的驱动和makefile

  

驱动代码文件

  

#include <linux/init.h>
#include <linux/module.h>
static int hello_init(void)
{
    // 在内核里面无法使用基础c库printf,需要使用内核库printk
    printk(“Hello, I’m hongPangZi\n”);
    return 0;
}
static void hello_exit(void)
{
    printk(“bye-bye!!!\n”);
}
MODULE_LICENSE(“GPL”);
module_init(hello_init);
module_exit(hello_exit);

驱动makefile

  

  这里make过不去,发现这里不能是空格,如下图,才可以:

  

obj-m += helloworld.o
KDIR:=/usr/src/linux-source-4.18.0/linux-source-4.18.0
PWD?=$(shell pwd)
all:
    make -C $(KDIR) M=$(PWD) modules

步骤二:编译make

make

  直接在驱动工程目录编译:

  

  这里是makefile的m要大写,修改后可编译:

  

  应该是windows拷贝 过来字符编码啥的变了(双引号),这里更正一下:

  

  

  然后再编译:

  

  编译成功

  

步骤三:加载卸载驱动测试

  将驱动拷贝到开发板或者目标系统,然后使用加载指令:

insmod helloworld.ko

  会打印入口加载的printk输出。

  

  出现问题可能原因一是内核编译使用的编译器和模块使用的编译器版本不一致。

  这里我们核对过是一样的,所以此处暂时也不知道如何,如下图:

  

  那么怀疑问题二:编译模块时选择的Linux头文件目录与当前运行的系统版本不匹配(可能是配置吧,明显大版本和子版本是一致的)

  所以这里我们重新配置一下makefile,直接引用linux-header如下:

  

  编译通过:

  

  继续加载、查看和卸载测试:

  

  发现ubuntu中printk终端无打印的问题,是重定向问题,打入内核日志消息了,可以使用dmesg进行查看:

  

  至此,会发现作为ubuntu来说,自带的/usr/src下的就是内核的头文件编译直接使用就可以了,无需编译内核,但是编译器还是需要的。

  本文章内核编译保留,因为编译内核是一个准备条件。

相关文章
|
2月前
|
数据采集 人工智能 监控
人工智能驱动的软件工程:测试左移的崛起价值
本文探讨了人工智能驱动下测试左移理念在软件工程中的重要性,分析测试工程师在需求评估、AI代码生成及遗留系统优化中的关键作用,揭示AI带来的挑战与机遇,并指出测试工程师需提升技能、关注合规与可维护性,以在AI时代保障软件质量。
194 88
|
5月前
|
机器学习/深度学习 人工智能 并行计算
AI部署架构:A100、H100、A800、H800、H20的差异以及如何选型?开发、测试、生产环境如何进行AI大模型部署架构?
AI部署架构:A100、H100、A800、H800、H20的差异以及如何选型?开发、测试、生产环境如何进行AI大模型部署架构?
AI部署架构:A100、H100、A800、H800、H20的差异以及如何选型?开发、测试、生产环境如何进行AI大模型部署架构?
|
2月前
|
敏捷开发 运维 数据可视化
DevOps看板工具中的协作功能:如何打破开发、测试与运维之间的沟通壁垒
在DevOps实践中,看板工具通过可视化任务管理和自动化流程,提升开发与运维团队的协作效率。它支持敏捷开发、持续交付,助力团队高效应对需求变化,实现跨职能协作与流程优化。
|
3月前
|
传感器 人工智能 JavaScript
鸿蒙开发:DevEcoTesting中的稳定性测试
DevEcoTesting主要的目的也是用于软件的测试,可以让开发者无需复杂的配置,即可一键执行测试任务,同时提供了测试报告和分析,无论是对于开发者还是测试同学来说,都是一个非常方便的工具。
117 3
鸿蒙开发:DevEcoTesting中的稳定性测试
|
2月前
|
运维 jenkins 测试技术
"还在苦等开发部署环境?3步教你用Jenkins拿回测试主动权"
测试工程师最头疼的问题是什么?依赖开发部署环境! 开发延期→测试时间被压缩→紧急上线后BUG频出→测试背锅。传统流程中,测试被动等待部署,效率低下。而Jenkins自动化部署让测试人员自主搭建环境,实现: ✅ 随时触发测试,不再苦等开发 ✅ 部署效率提升10倍,抢回测试时间 ✅ 改善团队协作,减少互相甩锅 学习Jenkins部署能力,成为高效测试工程师,告别被动等待!
|
5月前
|
人工智能 自然语言处理 JavaScript
测试工程师要失业?Magnitude:开源AI Agent驱动的端到端测试框架,让Web测试更智能,自动完善测试用例!
Magnitude是一个基于视觉AI代理的开源端到端测试框架,通过自然语言构建测试用例,结合推理代理和视觉代理实现智能化的Web应用测试,支持本地运行和CI/CD集成。
698 15
测试工程师要失业?Magnitude:开源AI Agent驱动的端到端测试框架,让Web测试更智能,自动完善测试用例!
|
6月前
|
数据采集 算法 数据安全/隐私保护
【硬件测试】基于FPGA的4ASK调制解调通信系统开发与硬件片内测试,包含信道模块,误码统计模块,可设置SNR
本文介绍了基于FPGA的4ASK调制解调系统的硬件测试版本,该系统包括testbench、高斯信道模块和误码率统计模块,并新增了ILA在线数据采集和VIO在线SNR设置功能。通过VIO设置不同SNR(如15dB和25dB),实现了对系统性能的实时监测与调整。4ASK是一种通过改变载波幅度表示数据的数字调制方式,适用于多种通信场景。FPGA平台的高效性和灵活性使其成为构建高性能通信系统的理想选择。
147 17
|
6月前
|
Ubuntu PHP 数据库
|
2月前
|
监控 Linux 网络安全
Linux命令大全:从入门到精通
日常使用的linux命令整理
624 13