找回密码
 注册
关于网站域名变更的通知
查看: 254|回复: 1
打印 上一主题 下一主题

iTOP-iMX6开发板-设备树驱动-以module的方式编译驱动

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2020-10-15 11:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
内核驱动不仅可以将驱动编译到内核中,还可以动态的编译内核驱动。本文档介绍如何以( |! H, z0 W. ^% D, t9 `" s& L
模块的方式编译内核驱动。
% t! h) Q% i9 h  {以 module 的方式编译驱动,需要以下几个部分:6 t! ]! d1 u+ M$ w1 Z. |  Y
1 内核成功编译过;6 ^% H9 j% ~! i- m. j  X' A
2 找到内核的 ARM 编译器;
- I- M9 S" k& b0 C) u3 编译简单驱动;
/ |  z" g( o4 L6 h4 Z4 编译简单的 Makefile 文件,Makefile 文件中需要指向内核源码目录(成功编译过的内核源码目录);
" c  n: T$ T- b. L3 u1 b和文档在一起的有“Makefile”、c 文件和 ko 文件,大家可以用来测试。9 e9 E9 n* n: I" T! m
要动态的编译内核,首先需要将内核源码编译通过,内核的编译请参考使用手册第五章。& T' |0 R0 p: R8 f
1. 内核和编译器路径
  T% w5 [  V5 T: w本节介绍内核路径、编译器路径。无论是 Qt 和 Ubuntu 的内核源码,都是在 android 源码包中,所以必须先解压 android 源码到 Ubuntu14.04 中。8 p! E- t1 n- g' }0 b! i
如下图所示,作者的 android 源码在“/home/iMX6Q/iTOP-iMX6_android6.0.1”目录下,内核源码在其中的“kernel_imx”目录下。
/ p% C) \( J+ e. m进入“kernel_imx”目录,查看“build_android_kernel.sh”中的脚本文件,如下图所示。7 V3 T$ R2 b0 w0 E& I$ f* {

- K2 G' _1 M: W/ i! a: _3 g. C6 V如上图所示,我们可以得到一些信息,在后面编译内核模块的时候,需要设置编译目标平台为 arm,“export ARCH=arm”;% }0 e% d5 |1 ]* r" ?: ^8 [3 L
编译器的路径为“$(pwd)/../prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/arm-linux-androideabi-”。理论上,应该使用这个编译器,但是实际上以, b' @; v8 S! n: Z. m8 q8 \
modules 的方式编译内核驱动的时候,使用这个编译器,是无法编译的!!
  F+ k' J! Y, f* h" X应该使用“../prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin/arm-eabi-”这个编译器才行,如下图所示。
4 D0 F4 S. H5 }; b
- t+ d6 h7 l: K# @& m% l& M5 Q/ j编译器路径为内核源码目录对应的../prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin/arm-eabi-”,这是作者测试出来的,作者没有太多时间深入研究编译脚本,但是这个编译器是可以的。前面红色部分介绍的编译器,会提示报错,对于这个报错,飞思卡尔官方给出的是简单的回复“你使用了 android 的编译器”,没有提供更多的解释,也没有提示方法,不过作者测试了几个内核驱动,都是可以正常 insmod 和 rmmod 的。
9 x; I. @/ u1 [9 p; z
2 f8 i+ n2 o8 B  Z" s2 V2. Makefile 和测试驱动源码以及编译' u& q; ^! E% Z% d) a) V
作者在“/home/imx6”目录下新建一个“imx_driver_modules”目录,将要编译的驱动和 Makefile 文件放到这个目录下。
6 x6 C; a3 \6 z; p2 v5 X0 M
% `  p2 o- Z$ l2.1 Makefile" O6 f; X5 z9 T; P9 M1 s" `* l+ N
Makefile 脚本文件:
* d$ L- V& W  w: o; }$ y' Eobj-m += iTOP_IMX6_treedriver_hello.o6 X& H1 K9 [( p. l7 h; y% R$ {
KDIR =/home/iMX6Q/iTOP-iMX6_android6.0.1/kernel_imx
  N+ ?) t, f! Z+ u7 f2 o: pPWD ?= $(shell pwd)
% D) O* u+ V8 ~* u4 q0 x- M8 J9 m9 kall:" m) J3 g; S( Q8 L
make -C $(KDIR) M=$(PWD) modules modules ARCH=arm5 O! I  s4 r2 D. w4 P0 Y5 O! M# T- y
CROSS_COMPILE=$(KDIR)/../prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin/arm-eabi-6 ~2 X# U, a% r+ r8 ?
clean:
5 C6 ^% W4 V- w1 I. |8 prm -RF modules.order *.o workqueue.o Module.symvers *.mod.c *.ko8 s0 c; k- L! p( i0 D) A$ b
脚本中:
) G9 t  P% a1 ^; f6 L. V* V第一行bj-m += iTOP_IMX6_treedriver_hello.o 表示编译的源文件为iTOP_IMX6_treedriver_hello.c,如果源文件名有变化,则需要修改成对应的。( k3 e0 |9 _. l; e. O) r8 R
第二行:KDIR 参数指向对应的内核源码目录。作者的内核源码是在/home/iMX6Q/iTOP-iMX6_android6.0.1/kernel_imxx 目录下,用户要根据自己的具体情况来修改。
, H4 ?  r6 O) L第三行:PWD ?= $(shell pwd)表示将当前目录的路径赋值给 PWD 变量,也就是/home/imx6_tree_driver/iTOP_IMX6_treedriver_hello。作者将会把 Makefile 文件和驱动源码放到这个目录下编译。7 m: Z, v5 B: b' ^* U
第五行:其中 make -C $(KDIR) M=$(PWD) modules,表示将当前目录下的文件编译为模块,并且制定了内核源码的路径;
: M; M" T; b, Z0 X3 L其中 ARCH=arm 表示设置目标 CPU 类别为 arm,也就是编译的依赖内核和驱动模块目标 CPU 为 ARM7 }+ K' \. o7 D
其中 CROSS_COMPILE=$(KDIR)/../prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin/arm-eabi- ,这里的路径,指向内核编译器的路径。4 e1 n' r) V8 M; S+ u* e/ s
2.2 简单驱动源码: C, }5 W' |  P' d  e
驱动文件名称为:iTOP_IMX6_treedriver_hello.c,源码如下:5 k$ I$ k7 s: H: B

. C; l. u- Q" Z: r% D. _#include5 h1 @3 c6 I3 ~: G  h
#include/ C. Q# u3 V; k: T6 X2 i+ e
MODULE_LICENSE("Dual BSD/GPL");
0 E2 W. W! _$ {2 i: f" ^MODULE_AUTHOR("iTOPEET_dz");
4 b' ]8 A8 D- Q9 Hstatic int hello_init(void)
) s+ ?2 T0 m9 V5 Y{
% V0 Q; Y) c* Y2 B) cprintk(KERN_EMERG "Hello World enter!\n");' O- x0 [3 B. A0 o6 X9 q
return 0;
, _& s  U- k4 E: E, f0 B}
! B- e) R0 h' Y6 m" R! c  Tstatic void hello_exit(void)4 L: E  T  R) u, B0 X4 A: ?/ G
{9 E% o/ P- {$ c) O9 ~6 p) \4 J( a# p
printk(KERN_EMERG "Hello world exit!\n");" q* g9 m$ _7 `* o7 I
}
! Y: O& l! f1 T9 p/ C" s4 zmodule_init(hello_init);
; l- J; V* g6 ?0 `) vmodule_exit(hello_exit);
) g$ n! T3 O$ Q9 F驱动源码只有基本的入口和出口函数。加载和卸载的时候分别打印“Hello Worldenter!”和“Hello world exit!”。- Q* p/ k- a9 K$ L. x: w& E* j
! b" l7 I$ g) F+ [+ J2 o& J3 v
2.3 编译4 g8 G+ O. S( _5 ?+ N* V% ^
将源码和 Makefile 文件拷贝到 Ubuntu14 系统下。
6 Z: [0 h) T8 j6 D$ _0 k使用命令“make”,如下图所示,可以看到有“iTOP_IMX6_treedriver_hello.ko”文件生成。/ g" V0 x1 f' w& ~# e3 Y
$ M# c2 n2 O) t. W: _9 s% r

* P9 n2 ]& n' a  j使用命令“make clean”,可以删除中间文件。7 M, W! J) x& B3 ~( d! S! _
3.模块编译常见问题7 v  L0 @& R/ b) ?( H0 O% x
在以模块的方式编译驱动的过程中,新手可能会以下问题。# h  `: x5 J+ \
1.内核源码没有编译或者内核源码路径设置不正确。2 F5 u- O% N' f$ i8 J8 o7 E! C
如果内核源码没有编译,那么模块将会提示缺少库之类的错误;如果路径设置不正确,会提示找不到内核。* T8 ~2 a) a; |9 a
2.源码和 Makefile 文件在 Windows 下编写,然后拷贝到 Ubuntu 上,由于编辑器不同导致转码错误。
4 ~+ D5 N1 f( r, l) G这种错误比较容易解决,Make 编译之后,系统会提示 Makefile 或者驱动文件具体某一行出现问题。使用 vim 编辑器打开查看一下,就能找出一些乱码,使用 vim 编辑器修正一下再编译即可。# W; g9 `& y. V; h. _7 |) j

( c5 D$ s( W" g5 a& B4 P# g; ?8 F1 G: U4. 模块加载和卸载# D: I3 Z- T) C; v' b( e2 q  B
作者这里使用最小 linux 系统来测试模块的加载和卸载,最小系统在使用手册第十三章有介绍。在编译模块前,内核源码必须要编译通过,作者这里是在最小系统是加载模块,那么内核源码也必须编译为 qt 的内核(最小系统使用的是 qt 的内核),否则是无法加载的。* z! g( ]0 w! n% S, `! G( X# l- |
如下图所示,将驱动模块拷贝到开发板(作者采用的是 nfs 共享目录的方式,关于 nfs 大家可以参考群共享中 nfs 相关的文档,设备树和非设备的 Ubuntu 都通用。也可以用 tf 卡或者 U 盘)。2 l8 f; Z. ~+ J
6 T1 ?4 ^! R. l, ?- f3 B

1 ^# t, G+ x. t5 }* T% k' h" ]' z8 z& a然后使用命令“insmod iTOP_IMX6_treedriver_hello.ko”加载驱动模块,如下图示,打印出“Hello World enter!”,表明模块驱动加载成功。  a, U- H6 f7 m3 g

) h3 f1 L0 u- J2 k+ I, [3 U/ `0 H1 A
8 H8 n& K, [! ~, V3 ]) F6 B$ p$ B& i接着使用命令“rmmod iTOP_IMX6_treedriver_hello”卸载模块,如下图所示,发现提示没有目录 4.1.15,这里我们新建“/lib/modules/4.1.15”。
( S+ M8 `7 p! [* u
% Z2 `( b1 l: o" g* e  i6 x
: N. y4 K5 J- V: w- Z  V4 C如下图所示,使用命令“mkdir /lib/modules/4.1.15”新建目录,再次使用命令“rmmod iTOP_IMX6_treedriver_helloello”卸载驱动模块。
: y' M; `( v% P6 d3 ^5 L9 s
6 u9 ^& w# a4 F5 p2 [, D: u: M8 @' ]: _
发现打印信息“Hello world exit!”,模块卸载成功。
# v: k* ^. g0 d4 s; o7 L: N只要重新烧写系统,这些新建目录只需要建立一次即可。
( a+ u, j" K! w7 C5 U) i# M0 |+ C1 ^  m
+ z1 e  r+ ^2 R9 z9 F

该用户从未签到

2#
发表于 2020-10-15 13:12 | 只看该作者
来学习一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-6-26 09:21 , Processed in 0.093750 second(s), 23 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表