【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第三十七章 Linux内核模块

i.MX8MM处理器采用了先进的14LPCFinFET工艺,提供更快的速度和更高的电源效率;四核Cortex-A53,单核Cortex-M4,多达五个内核 ,主频高达1.8GHz,2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT、4G模块、CAN、RS485等接口一应俱全。H264、VP8视频硬编码,H.264、H.265、VP8、VP9视频硬解码,并提供相关历程,支持8路PDM接口、5路SAI接口、2路Speaker。系统支持Android9.0(支持获取root限)Linux4.14.78+Qt5.10.1、Yocto、Ubuntu20、Debian9系统。适用于智能充电桩,物联网,工业控制,医疗,智能交通等,可用于任何通用工业和物联网应用、

【公众号】迅为电子

【粉丝群】258811263(加群获取驱动文档+例程)


第二部分 Linux内核裁剪与定制

第三十七Linux内核模块

本章导读

Linux设备驱动会以内核模块的形式出现,因此,学会编写Linux内核模块编程是学习Linux设备驱动的先决条件。

37.1章节讲解了linux内核模块的概念,并以helloworld为例,将其编译为驱动模块。

37.1 Linux内核模块简介

Linux内核的整体架构本就非常庞大,其包含的组件也非常多。而我们怎样把需要驱动都包含在内

核中呢?

编译驱动有俩种方法

第一种方法:Linux提供了这样的机制,这种机制被称为模块(Module)。把驱动编译成模块,然后使用命令把驱动加载到内核里面。模块本身不被编译入内核映像,从而控制了内核的大小。模块一旦被加载,它就和内核中的其他部分完全一样。

第二种方法:直接把驱动编译到内核中

为了使读者初步建立对模块的感性认识,在第36.3章节我们已经写了一个最简单的驱动helloworld,那么这个章节将来学习怎么将我们写的驱动编译成驱动文件。

我们i.MX8MM开发板为例,我们编译驱动为内核模块。我们将36.3章节编写的helloworld.c拷贝到Ubuntu的任意路径目录下。

步骤一:

首先使用命令“vim Makefile”创建一个Makefile文件,作者是在/home/topeet/imx8mm/01目录下创建的。Makefile文件内容如下: 

obj-m += helloworld.o
KDIR:=/home/topeet/linux/linux-imx
PWD?=$(shell pwd)
all:
	make -C $(KDIR) M=$(PWD) modules
clean:
	make -C $(KDIR) M=$(PWD) clean
  • 我们来解释一下makefile的第一行,-m意思是把我们的驱动编译成模块,那么生成的中间文件的名字一般是和驱动C文件同名,这里是helloworld.o
  • Makefile的第二行KDIR意思是内核源码的实际路径,注意,大家要根据自己的实际的路径进行修改。作者的源码是放在/home/topeet/linux/linux-imx目录下的
  • Makefile第三行PWD?=$(shell pwd)意思是获取当前目录的变量
  • Makefile第五行意思是make会进入内核源码的路径,然后把当前路径下的代码编译成模块
  • Makefile第意思是make clean会清除编译文件

注意:

1 KDIR:=/home/topeet/linux/linux-imx是设备树内核的源码路径这里使用的是Linux源码包中的内核,请大家根据自己的实际情况进行修改。

2设备树内核源码一定要先编译通过,才能编译驱动否则会报错。

3 make -C前面的空格是一个tab键

步骤二

设置交叉编译器,请参考本手册“交叉编译器的安装和使用”章节,注意!!! 一定要安装好交叉编译器才可以进行下步操作!!!

为了简化编译步骤,笔者编写了编译脚本build.sh,作者是在/home/topeet/imx8mm/01目录下创建的。此编译脚本在以后的每个实验中要用到,拷贝到驱动文件同级目录即可,以后不在一一赘述,脚本的内容如下所示:

#!/bin/bash
#使用bash来执行此脚本
#clear screen
clear
echo ""
echo -e "\033[32m **** 让我们开始编译驱动程序! **** \033[0m"
echo ""
#set env
. /opt/fsl-imx-xwayland/4.14-sumo/environment-setup-aarch64-poky-linux
export ARCH=arm64
unset LDFLAGS

#clean cache files
make clean

#make 
make

#result
#\033[32m set color 
#\033[0m  clear color
result=$(ls |grep *.ko)
if [ "$result" = "" ];then 
    echo ""
    echo -e "\033[5m\033[31m **** 驱动程序编译失败!报错原因请参考上述提示 ****\033[0m"
    echo ""
else 
    echo ""
    echo -e "\033[32m **** 驱动程序编译成功! **** \033[0m"
    echo ""
fi

步骤三

我们将36.3章节编写的驱动代码helloworld.c拷贝到和Makefile,build.sh同级目录,如下图所示:

我们使用vscode打开,如下图所示,我们之后的编写代码的工作一律使用vscode。 

然后我们输入以下命令,设置文件权限,如下图所示:

chmod 777 -R *

然后运行编译脚本“./build.sh”,编译成功如下图所示:

 

编译会生生helloworld.ko目标文件,如下图所示: 

我们通过nfs将编译好的驱动程序在开发板上加载驱动模块,注意!nfs的配置和使用,请参考本手册“NFS服务器的搭建和使用”章节,此后的章节,我们也是通过nfs的方式往开发板传输文件,以后便不再赘述,大家也可以使用U盘的方式拷贝到开发板,但是为了方便调试,最好使用nfs。

我们进入到共享目录01 ,我们输入命令“insmod helloworld.ko”,可以看到我们编写的helloworld驱动加载成功,如图所示:

 我们输入命令“rmmod helloworld”,可以看到我们编写的helloworld驱动拆卸成功,如下图所示

在Linux中,使用lsmod命令可以获得系统中已加载的所有模块以及模块间的依赖关系。 

  • 12
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值