linux嵌入式驱动开发,makefile到问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux嵌入式驱动开发,makefile到问题相关的知识,希望对你有一定的参考价值。

obj-m := helloworld.o
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD = $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
$(RM) *.o *.ko *.mod.c Module.symvers Module.markers Module.symvers module.order

问题1.obj-m := helloworld.o 有什么用
问题2:$(MAKE) -C $(KERNELDIR) M=$(PWD) modules 这个没看懂特别是为什么有个=号,还有个modules?
问题3:$(RM) *.o *.ko *.mod.c Module.symvers Module.markers Module.symvers module.order 后面那么多东西干什么到啊!!

最重要到问题,我要完全看懂需要什么知识点。和我以前写到makefile不一样啊。

首先说一下,你要编译驱动程序,不再是跟原本编译应用程序那样可以在当前目录下直接make就好。
因为编译内核驱动的时候,是要用到内核文件里的头文件,还有内核提供的接口函数,要借助于内核文件夹里的makefile来编译你写好的驱动源代码,如果按一般的操作,你就得把源代码放到内核文件夹指定的目录下,然后再在那个目录下得makefile里添加一些语句,比如obj -m什么的(把相应的驱动代码编译成模块),然后到内核文件夹的顶层目录make,生成相应的模块文件,就有你问题3的那一大堆东西,其中.ko就是要用到的。
把一些驱动编译成模块,和编译进内核的区别,你可以去了解下。。编译成模块用的是-m。
而为了方便你可以在任何目录下直接用make来编译驱动代码;就有以下这指令:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
-C 指定的就是内核文件夹所在的地方
M=当前路径
modules的,是和make 联合起来的..make modules命令,这个命令你可以去查查。
.ko文件就是用insmod命令插入到内核中,在去添加相应的设备文件,就可以在内核里跑起来了。追问

高手回答到点上了,请问我这水平 推荐本书给我啊?

追答

说真的,我之前稍微学了下驱动开发,写过一arm11板的按键驱动。但在我学习过程里,
根本没觉得有一本比较适合的书,大多都是零散的资料,或是别人的指导。。
而且这才是刚开始,学驱动郁闷就郁闷在这。基本都是靠零散的资料来摸索。。
真没有一本比较系统全面的学习linux内核驱动的书,外面吼的那些多经典的书根本就是
给神人看的。。--"...
要不你去看看韦东山写的一本arm9的,还凑合。。但个人建议是最好想尽一切办法找着
个这方面的资深人士给些指导什么的,不至于入门得太迷糊了。

参考技术A 这个你得看一下makefile是如何写的, makefile与shell很像,
obj-m是固定格式的,-m表示的是内核模块,helloworld.o是生成目标文件
2.4内核为.o 2.6为.ko
$(MAKE) $(RM) 是环境变量 分别代码 make 和 rm -rf
-C 切换目录到 $(KERNELDIR) ,其中$(KERNELDIR) 是一个变量,,也就是:KERNELDIR ?= /lib/modules/$(shell uname -r)/build
M=$(PWD) 其中 M是一个宏
$(PWD)是一变量,该变量的值为 $(shell pwd)
$(shell pwd) 是makefile中的函数
调用makefile中函数与使用$()
shell为函数名
pwd 为函数的参数
这个shell函数的作用就是执行shell命令 所以它的参数也必然是一个命令 pwd就是一个命令
modules是目标 具体modules是什么 ,要体该目录下的 makefile 是如何来定义这个目标的
clean :是一个伪目标 ,没有依赖,但它有执行的命令 :$(RM) *.o *.ko *.mod.c Module.symvers Module.markers Module.symvers module.order
就是删除编译时产生的文件
clean这个伪不会自动执行,自动执行的必须第一个目录,也就是默认目标 default
所以当进行编译时,只需要输入make 就可以编译了,它默认执行是第一个目标
也就是default伪目标
但clean 伪目标是不会执行的,,
make命令的格式
make [选项参数] [宏] [目标]

需要手动执行 输入make clean 其中clean 为伪目标
参考技术B obj-m := helloworld.o //生成目标文件 helloworld.o 当然中间还有其他产物,但是2.4内核是安装.o 文件的,后来2.6就 变成.ko文件,但是还保留着 .o 的格式

$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
MAKE 可以理解为调用MAKE 函数 你用make函数肯定要有编译好的内核镜像撒,就用 (KERNELDIR) 就是内核镜像的目录, pwd就是当前目录 学过shell命令吧,就是编译你当前的 ,一般这些都是格式 ,照着格式来 知道 它的目的就好了。modules 你编译的是个模块,所以要进去。

$(RM) 删除 知道 rm就是删除的shell命令 *.o就是代表只要是后缀为.o的文件 都会被删除掉,因为编译一个模块会产生很多 过程 文件 ,如果不及时清除就会造成很大的空间浪费 ,至于后面几个真不知道了

在命令行下输入make
就是编译 因为那个是default 学过switch case 吧
查找所有 ,当不存在时就会到default

当输入make clean 时 就会找到clean 这个下面的命令行 删除过程程序。
参考技术C (RM) *.o *.ko *.mod.c Module.symvers Module.markers Module.symvers module.
这句话的意思是删除编译过程中产生的临时文件。
*.o *.ko *.mod.c Module.symvers Module.markers Module.symvers module.这些就是临时文件的名字,但然使用了一些通配符。这个你懂的。
参考技术D 现代跟以前不一样

如何用arm-linux-gcc编译驱动程序,Makefile文件怎么写?

本人是新手,前天编写一个最简单驱动到嵌入式ARM板上时出现了错误,然后试了很多方法都不成功,不知道怎么写和配置。请各位先辈指点一下。参考本版精华贴,肯定会找到满意的回答

参考技术A 回复
http://bbs.chinaunix.net/viewthread.php?tid=1921952
上面说的方法我还是不是很明白啊,我现在简直没办法了,昨天晚我看到一个资料上面写的helloworld驱动的例子有两份Makefile,一份是x86机子上的,一份是arm平台上的,arm上的这样写:ifneq
($(KERNELRELEASE),)obj-m:=hello.oelseKDIR/usr/src/kernels/opt/EmbedSky/linux-2.6.30.4/all:
make
-C
$(KDIR)
M=$(PWD)
modules
ARCH=arm
CROSS_COMPLIE=arm-linux-clean:
rm
-f
*.ko
*.o
*.mod.o
*.mod.c
*.symversendif看到后我想应该是要用用于移植的内核来编译吧,于是我干脆把资料提供的内核拷贝到PC的Linux系统中然后解压、编译直至安装,然后就再模仿例子写了Makefile如上所示,然后make后终于通过编译成功了,然后我再下载到arm板上安装,却又出现下面的错误:insmod:
can't
insert
'hello.ko':
unknown
symbol
in
module,
or
unknown
parameter。我就又彻底晕了。到底是怎么回事,应该怎么办的呢?

以上是关于linux嵌入式驱动开发,makefile到问题的主要内容,如果未能解决你的问题,请参考以下文章

Linux驱动开发笔记:helloworld驱动源码编写makefile编写以及驱动编译基本流程

嵌入式Linux第二部分 - 裸机开发/系统移植/驱动开发/内核开发

嵌入式Linux第二部分 - 裸机开发/系统移植/驱动开发/内核开发

嵌入式开发(七):linux字符型设备驱动初步

改变嵌软开发思维方式之:状态机+事件驱动框架

如何用arm-linux-gcc编译驱动程序,Makefile文件怎么写?