【IMX6ULL】学习笔记(二)编译Linux内核并运行第一个驱动程序 hello_drv


在 Linux 驱动开发过程中,驱动程序并不是一个独立文件,它依赖当前运行的 Linux 内核版本。因此,在编译第一个驱动之前,需要先完成内核配置、内核编译以及模块环境准备。本篇记录基于 IMX6ULL 开发板完成 hello_drv 驱动编译运行全过程。

驱动程序依赖于内核源码,而且内核必须编译过(配置编译),

  • 配置编译内核、设备树、驱动
  • 放到开发板上
  • 编译测试 第一个驱动
开发环境:
开发板:100ask IMX6ULL
Linux Kernel:4.9.88
开发主机:Ubuntu
工具:ADB文件传输【见学习笔记(一)】

一、配置编译内核、设备树、驱动程序

命令_内核编译常用清理效果
make clean删除编译出来的.o、模块,保留内核配置.config
make mrpropermake clean + 删除 .config、备份配置,回到源码原始状态
make distclean和 mrproper 几乎等价,现代内核两者基本一样

1.1 配置编译内核

book@100ask:~$ cd /home/book/100ask_imx6ull-sdk/Linux-4.9.88
book@100ask:~/100ask_imx6ull-sdk/Linux-4.9.88$ make mrproper
book@100ask:~/100ask_imx6ull-sdk/Linux-4.9.88$ make 100ask_imx6ull_defconfig		## 配置
book@100ask:~/100ask_imx6ull-sdk/Linux-4.9.88$ make zImage -j4                   	## 编译内核
book@100ask:~/100ask_imx6ull-sdk/Linux-4.9.88$ make dtbs							## 编译设备树
book@100ask:~/100ask_imx6ull-sdk/Linux-4.9.88$ cp arch/arm/boot/zImage ~/nfs_rootfs
book@100ask:~/100ask_imx6ull-sdk/Linux-4.9.88$ cp arch/arm/boot/dts/100ask_imx6ull-14x14.dtb ~/nfs_rootfs/

1.2 编译安装内核模块

编译内核模块

book@100ask:~/100ask_imx6ull-sdk/Linux-4.9.88$ make modules

安装内核模块到 Ubuntu 某个目录下备用

book@100ask:~/100ask_imx6ull-sdk/Linux-4.9.88$ make ARCH=arm INSTALL_MOD_PATH=/home/book/nfs_rootfs modules_install
验证 是否 编译安装内核模块 成功
在这里插入图片描述

二、上传 内核、设备树文件、lib 到开发板上

一定要将Ubuntu上编译的内核 zImage 放在 开发板 /boot 目录,再重启,最后安装驱动程序;

以免发生安装驱动出现版本不匹配的问题;disagrees about version of symbol module layout

zImage 是一个为了节省存储空间而“瘦身”的内核文件,并且能够自己将自己解压并启动

设备树是描述硬件的配置文件,告诉内核“硬件长什么样”

内核源码的lib/是给内核开发者使用的代码库,为内核自身提供“基础工具”

根文件系统的/lib是系统运行时的共享库仓库,为应用程序提供“运行环境”

book@100ask:~$ cd /home/book/nfs_rootfs
book@100ask:~/nfs_rootfs$ adb push zImage /boot
book@100ask:~/nfs_rootfs$ adb push 100ask_imx6ull-14x14.dtb /boot
book@100ask:~/nfs_rootfs$ adb push lib/modules /lib
验证 开发板内核 是否更新成功
在这里插入图片描述

sync 是 Linux 中一个用于强制将内存缓冲区中的数据写入磁盘的命令。简单来说,它就像一个“保存”按钮,但作用于操作系统层面


三、编译测试 第一个驱动程序

3.1 驱动地址

git clone https://e.coding.net/weidongshan/01_all_series_quickstart.git

.\01_all_series_quickstart\05_嵌入式Linux驱动开发基础知识\source\01_hello_drv

3.2 上传驱动程序到虚拟机_hello_drv

FileZilla 传递文件
在这里插入图片描述

3.3 修改驱动程序中的 Makefile

修改驱动程序的Makefile
在这里插入图片描述

修改 Makefile 中的内核路径 KERN_DIR

KERN_DIR = /home/book/100ask_imx6ull-sdk/Linux-4.9.88

3.4 编译驱动程序

编译驱动程序
在这里插入图片描述

3.5 上传到开发板上

book@100ask:~/nfs_rootfs/01_hello_drv$ adb push hello_drv.ko /root
book@100ask:~/nfs_rootfs/01_hello_drv$ adb push hello_drv_test /root

3.6 在开发板上 安装驱动程序 并且 运行测试程序

book@100ask:~/nfs_rootfs/01_hello_drv$ adb shell     			## 进入开发板命令行
sh-5.0# cd /root
sh-5.0# ls
1.txt  2.txt  S05lvgl  hello_drv.ko  hello_drv_test  test_dir2
sh-5.0# insmod hello_drv.ko										## 安装驱动程序


sh-5.0# ls /dev/hello											## 安装的驱动程序,有没有生成设备节点
/dev/hello														## 有生成
sh-5.0# 
sh-5.0# ./hello_drv_test				## 执行测试程序
Usage: ./hello_drv_test -w <string>		## 用法
       ./hello_drv_test -r
sh-5.0# ./hello_drv_test -w hello_tp	## 写入
sh-5.0# ./hello_drv_test -r         	## 读出
APP read : hello_tp
sh-5.0# 


四、总结

本文完成了Linux驱动开发的第一个完整流程:

  1. 编译Linux内核
  2. 编译设备树
  3. 安装内核模块
  4. 编译hello_drv驱动
  5. 加载驱动并完成应用测试

通过这个过程,可以理解Linux驱动、内核以及用户程序之间的关系,为后续字符设备、GPIO、I2C、SPI等驱动开发打下基础。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐