作为一名嵌入式Linux的初学者,在拿到功能强大的RK3568开发板时,我的心情既兴奋又忐忑。兴奋在于终于可以动手实践,忐忑则源于对复杂开发环境的恐惧。网络上零散的资料、版本不匹配的工具链、以及深不见底的“坑”,都巨大挑战。
然而,迅为提供的一站式资料包,可以让嵌入式Linux学习之旅却出乎意料地顺畅和高效。本文将分享《【北京迅为】itop-3568开发板驱动开发指南》第3章 内核模块实验的完整过程。
迅为一站式学习教程资料包的价值所在
,迅为的一站式资料包在以下几个方面让我效率翻倍:
1. 完整性: 从工具链、源码、到文档和工具,所有要素版本匹配,开箱即用,形成了闭环生态。
2. 指引性: 步步为营的文档如同一位无声的导师,消除了过程中的不确定性,让学习路径清晰可见。
3. 排障效率: 技术支持是强大的“安全网”,能将绝大多数常见问题的解决,
对于一名新手而言,时间是最宝贵的成本。迅为的资料包所做的,正是通过体系化的知识工程,最大限度地节约的时间,保护了学习热情,能够快速进入嵌入式Linux开发的核心殿堂——驱动开发。这无疑是一次价值远超硬件本身的投资。

北京迅为RK3568开发板:迅为RK3568开发板ARM3568J核心板瑞芯微人工智能AI鸿蒙Linux安卓
联系我们获得《迅为itop-3568开发板驱动开发指南》完整版本。
【北京迅为itop-3568开发板驱动开发指南第 3 章 内核模块实验】
在上一章节编写了最简单的驱动程序 helloworld。helloworld 驱动程序要如何编译并运行
呢?编译驱动有两种方法,分别是将驱动编译进内核和将驱动编译成内核模块。我们先来学习
如何将驱动编译成内核模块。
把驱动编译成内核模块并运行需要设置交叉编译器、编写 Makefile 和编译模块三个步骤。
编译好的内核模块可以使用 insmod 命令加载到内核运行,从内核中卸载内核模块使用 rmmod
命令。
3.1 设置交叉编译器
1.下载交叉编译器
在网盘“iTOP-3568 开发板\03_【iTOP-RK3568 开发板】指南教程\02_Linux 驱动配套资料\03_
交叉编译器”路径下下载交叉编译器,将下载好的交叉编译器拷贝到虚拟机 Ubuntu 环境中的
/usr/local 目录下,如图 3.1 所示。

输入 tar -vxf gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu.tar.gz 命令解压交叉编译压缩
包,解压完毕后会生成交叉编译器所在的文件夹。如图 3.2 所示。

2.设置环境变量
在终端输入 sudo vi /etc/profile 命令打开 profile 文件,接着在 profile 文件末尾添加以下
代码。
export PATH=$PATH:/usr/local/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin
添加完后如图 3.3 所示。

保存退出后在终端输入 reboot 命令重新启动 Ubuntu 系统,使交叉编译环境生效。
3.检查是否设置成功
Ubuntu 系统重新启动登录到系统后,打开命令行终端,输入命令 aarch64-linux-gnu-gcc -v,
如果终端有如图 3.4 所示的打印信息,说明交叉编译环境搭建成功。如果没有出现如图 3.4 的
打印信息,需要检查上一步骤是否设置正确。

3.2 编写 Makefile

编译驱动程序需要使用 Makefile 文件。接下来为 helloworld.c 编写一个简单的 Makefile,其
代码如代码清单 3.1 所示。

源文件 helloworld.c 与 Makefile 文件需要位于同一级目录下。如下图 3.5 所示:

3.3 编译成内核模块
在把驱动编译成内核模块之前需先编译通过在 Makefile 文件中通过 KDIR 变量指定路径下
的内核源码。内核源码编译通过后,在 Makefile 与 helloworld 驱动路径下输入 make 命令即可
把 helloworld 驱动编译成内核模块,如图 3.6 所示。

内核模块是以 ko 为后缀名,因此编译成功得到的 helloworld.ko 文件即内核模块,也就是
编译好的驱动程序。如图 3.7 所示:

输入 make clean 命令可清除编译文件,如图 3.8 所示:

3.4 模块加载与卸载
内核模块可以通过 insmod 命令加载、通过 rmmod 命令卸载。
将 helloworld.ko 内核模块拷贝到 iTOP-RK3568 开发板上,通过 insmod helloworld.ko 命令加
载 helloworld 内核模块,加载内核模块时会调用驱动入口函数 helloworld_init,从而输出打印
字符串信息“helloworld_init”,如图 3.9 所示:

如果要卸载 helloworld 内核模块,执行 rmmod helloworld 命令。同理,在卸载内核模块的
时候会执行驱动出口函数,所以可以看到驱动出口函数打印出来的字符串信息 helloworld_exit,
如下 3.10 所示:

加载内核模块也可以使用 modprobe 命令,它比 insmod 命令更强大,modprobe 命令在加
载驱动模块的时候,会同时加载该模块依赖的其他模块。比如 helloworld.ko 依赖 before.ko,
使用 insmod 加载的时候,就必须先加载 before.ko,然后再加载 helloworld.ko 才可以加载成功。
使用 modprobe 加载的时候,他会自动分析模块的依赖关系,然后将所有依赖的模块都加载到
内核当中,所以 modprobe 命令比较“聪明”。
同样,在卸载驱动模块的时候,如果模块存在依赖关系,如果使用 insmod 命令,需要手
动卸载依赖的内核模块,但是使用 modprobe 命令可以自动卸载驱动模块所依赖的其他模块。
如果驱动模块是以 modprobe helloworld.ko 命令加载的,卸载的时候使用 modprobe -r
helloworld.ko 命令卸载。
但是,使用 modprobe 卸载存在一个问题,如果所依赖的模块被其他模块所使用,比如刚
才例子中的 before.ko 还被其他的模块使用,这时候就不能使用 modprobe 卸载。所以要根据
需求选择合适的命令进行操作。
3.5 查看模块信息
lsmod 命令可以列出已经载入 Linux 内核模块,在 helloworld 驱动加载之后,使用 lsmod
命令查看内核中加载的模块,如图 3.11 所示:

除了使用 lsmod 命令,也可以使用 modinfo helloworld.ko 命令可以获得模块的其他信息,
如模块作者,模块说明,模块支持的参数等等。
全部0条评论
快来发表一下你的评论吧 !