Chinaunix

标题: 如何用arm-linux-gcc编译驱动程序,Makefile文件怎么写? [打印本页]

作者: psp3000pes    时间: 2011-04-09 09:28
标题: 如何用arm-linux-gcc编译驱动程序,Makefile文件怎么写?
本人是新手,前天编写一个最简单驱动到嵌入式ARM板上时出现了错误,然后试了很多方法都不成功,不知道怎么写和配置。请各位先辈指点一下。
作者: T-Bagwell    时间: 2011-04-09 11:52
参考本版精华贴,肯定会找到满意的回答
作者: psp3000pes    时间: 2011-04-09 16:28
回复 2# T-Bagwell


    没有啊,哪一个有?我就是不明白怎么移植。我是这样写的:刚开始我直接参考桌面平台的写Makefile:
KVERS = $(shell uname -r)

# Kernel modules
obj-m += hello.o

# Specify flags for the module compilation.
#EXTRA_CFLAGS=-g -O0

build: kernel_modules

kernel_modules:
make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules

clean:
make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean


在PC上编译生成了.ko文件,然后我下载到ARM板上运行insmod hello.ko时出现错误:can't insert 'hello.ko':invalid module format .

我就想不通,我想可能要修改什么配置吧,然后网上搜索看到要这样修改:在内核源代码目录下修改Makefile:

找到下列行:   
              ARCH                         ?=$(SUBARCH)
              CROSS_COMPILE         ?=
              改成:
              ARCH         :=   arm
              CROSS_COMPILE   =/usr/local/arm-linux/bin/arm-linux-gcc

这样把系统添加对ARM的支持。
但是这样编译时却没有通过了。。。
最后我在一些资料上看到一个现成的用arm-linux-gcc编译的驱动的Makefile文件,这样的:

ifneq ($(KERNELRELEASE),)
obj-m:=hello.o
else
KDIR:=/lib/modules/$(shell uname -r)/build
all:
        make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
clean:
        rm -f *.ko *.o *.mod.o *.mod.c *.symvers
endif

我看到以为找到了,便仿照之用来编译,但是make却又出现如下错误:

[root@FedoraFor2440 cs]# make
make -C /lib/modules/2.6.27.5-117.fc10.i686/build M=/home/admin/cs modules ARCH=arm CROSS_COMPILE=arm-linux-
make[1]: Entering directory `/usr/src/kernels/2.6.27.5-117.fc10.i686'
  CC [M]  /home/admin/cs/hello.o
In file included from include/asm/system.h:10,
                 from include/asm/processor.h:17,
                 from include/linux/prefetch.h:14,
                 from include/linux/list.h:6,
                 from include/linux/module.h:9,
                 from /home/admin/cs/hello.c:9:
include/linux/kernel.h:195: warning: 'regparm' attribute directive ignored
include/linux/kernel.h:197: warning: 'regparm' attribute directive ignored
include/linux/kernel.h:217: warning: 'regparm' attribute directive ignored
In file included from include/linux/thread_info.h:47,
                 from include/linux/preempt.h:9,
                 from include/linux/spinlock.h:50,
                 from include/linux/seqlock.h:29,
                 from include/linux/time.h:8,
                 from include/linux/stat.h:60,
                 from include/linux/module.h:10,
                 from /home/admin/cs/hello.c:9:
include/asm/thread_info.h:174: error: invalid register name for 'current_stack_pointer'
In file included from include/linux/rwsem.h:22,
                 from include/linux/notifier.h:14,
                 from include/linux/memory_hotplug.h:6,
                 from include/linux/mmzone.h:560,
                 from include/linux/gfp.h:4,
                 from include/linux/kmod.h:22,
                 from include/linux/module.h:13,
                 from /home/admin/cs/hello.c:9:
include/asm/rwsem.h:48: warning: 'regparm' attribute directive ignored
include/asm/rwsem.h:50: warning: 'regparm' attribute directive ignored
include/asm/rwsem.h:52: warning: 'regparm' attribute directive ignored
include/asm/rwsem.h:54: warning: 'regparm' attribute directive ignored
In file included from include/asm/smp.h:12,
                 from include/linux/smp.h:28,
                 from include/linux/topology.h:33,
                 from include/linux/mmzone.h:683,
                 from include/linux/gfp.h:4,
                 from include/linux/kmod.h:22,
                 from include/linux/module.h:13,
                 from /home/admin/cs/hello.c:9:
include/asm/mpspec.h:9:25: error: mach_mpspec.h: No such file or directory
In file included from include/asm/smp.h:12,
                 from include/linux/smp.h:28,
                 from include/linux/topology.h:33,
                 from include/linux/mmzone.h:683,
                 from include/linux/gfp.h:4,
                 from include/linux/kmod.h:22,
                 from include/linux/module.h:13,
                 from /home/admin/cs/hello.c:9:
include/asm/mpspec.h:39: error: 'MAX_MP_BUSSES' undeclared here (not in a function)
In file included from include/asm/smp.h:15,
                 from include/linux/smp.h:28,
                 from include/linux/topology.h:33,
                 from include/linux/mmzone.h:683,
                 from include/linux/gfp.h:4,
                 from include/linux/kmod.h:22,
                 from include/linux/module.h:13,
                 from /home/admin/cs/hello.c:9:
include/asm/io_apic.h:149: error: 'MAX_IRQ_SOURCES' undeclared here (not in a function)
In file included from include/linux/smp.h:28,
                 from include/linux/topology.h:33,
                 from include/linux/mmzone.h:683,
                 from include/linux/gfp.h:4,
                 from include/linux/kmod.h:22,
                 from include/linux/module.h:13,
                 from /home/admin/cs/hello.c:9:
include/asm/smp.h:187:28: error: mach_apicdef.h: No such file or directory
In file included from include/linux/smp.h:28,
                 from include/linux/topology.h:33,
                 from include/linux/mmzone.h:683,
                 from include/linux/gfp.h:4,
                 from include/linux/kmod.h:22,
                 from include/linux/module.h:13,
                 from /home/admin/cs/hello.c:9:
include/asm/smp.h: In function 'hard_smp_processor_id':
include/asm/smp.h:191: error: implicit declaration of function 'GET_APIC_ID'
make[2]: *** [/home/admin/cs/hello.o] 错误 1
make[1]: *** [_module_/home/admin/cs] 错误 2
make[1]: Leaving directory `/usr/src/kernels/2.6.27.5-117.fc10.i686'
make: *** [all] 错误 2
[root@FedoraFor2440 cs]# make

我就郁闷了,现在也没办法。。。
作者: T-Bagwell    时间: 2011-04-09 17:03
http://bbs.chinaunix.net/viewthread.php?tid=1921952
作者: psp3000pes    时间: 2011-04-10 18:53
回复 4# T-Bagwell
http://bbs.chinaunix.net/viewthread.php?tid=1921952 上面说的方法我还是不是很明白啊,我现在简直没办法了,昨天晚我看到一个资料上面写的helloworld驱动的例子有两份Makefile,一份是x86机子上的,一份是arm平台上的,arm上的这样写:

ifneq ($(KERNELRELEASE),)
obj-m:=hello.o
else
KDIR:=/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  *.symvers
endif

看到后我想应该是要用用于移植的内核来编译吧,于是我干脆把资料提供的内核拷贝到PC的Linux系统中然后解压、编译直至安装,然后就再模仿例子写了Makefile如上所示,然后make后终于通过编译成功了,然后我再下载到arm板上安装,却又出现下面的错误:insmod: can't insert 'hello.ko': unknown symbol in module, or unknown parameter。我就又彻底晕了。到底是怎么回事,应该怎么办的呢?
作者: T-Bagwell    时间: 2011-04-10 19:37
编译器版本?
编译kernel配置的config做成附件发上来看看吧
作者: psp3000pes    时间: 2011-04-10 20:25
回复 6# T-Bagwell


    哦,好,编译器好像是Arm-linux-gcc 4.3.2 ,我编译内核的配置是按照开发板提供的《天嵌科技出品Linux移植之step by step》设置的

config.zip

13.91 KB, 下载次数: 475


作者: T-Bagwell    时间: 2011-04-10 20:54
看上去没啥问题
确认以下几项
1.编译kernel 的编译器和你编译driver的编译器是同一个版本
2.make你的driver的时候有警告信息没有,有的话贴出来,或者make -n,然后把信息贴出来
3.用file命令看看你编译出来的.ko的信息,贴出来
4.把你的操作步骤发一下,大伙看一下

应该不是大问题
作者: goldenfort    时间: 2011-04-10 21:33
回复 1# psp3000pes



编辑  Makefile  如下。



    obj-m += hello-1.o

all:
        make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
        make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean


然后 make.


如果 是给embedded  系统编译 module,  先把 embedded 系统的kernel 搞好,编译一道。然后  编辑  Makefile  如下。



   obj-m += hello-1.o

all:
        make -C /dirto/kernel/src   M=$(PWD) modules

clean:
        make  -C /dirto/kernel/src   M=$(PWD) clean


然后 make.
作者: T-Bagwell    时间: 2011-04-10 21:51
回复  psp3000pes



编辑  Makefile  如下。



    obj-m += hello-1.o

all:
        make -C /li ...
goldenfort 发表于 2011-04-10 21:33



    补充:最好先make以下kernel
作者: psp3000pes    时间: 2011-04-10 23:01
回复 10# T-Bagwell


    还是不行啊. . . 我就重新来过吧,我又新键了一个虚拟机的linux系统Fedaro10(和我现在用的这个是同一个镜像),那应该怎样建立交叉编译系统呢??
作者: psp3000pes    时间: 2011-04-11 13:10
回复 10# T-Bagwell


    这样太复杂了,我也不知我之前怎么配置的。算了,我打算重新建立交叉编译环境吧,怎么开始设置呢?我昨天新装了一个Linux虚拟机系统,和我现在这个是同一个镜像
作者: T-Bagwell    时间: 2011-04-11 13:11

和host无关,主要是交叉编译环境的事吧
作者: psp3000pes    时间: 2011-04-11 13:12
回复 9# goldenfort


    这样太复杂了,我也不知我之前怎么配置的。算了,我打算重新建立交叉编译环境吧,怎么开始设置呢?我昨天新装了一个Linux虚拟机系统,和我现在这个是同一个镜像
作者: psp3000pes    时间: 2011-04-11 13:15
回复 13# T-Bagwell


    那具体步骤有没有呢??
作者: T-Bagwell    时间: 2011-04-11 13:31

步骤说多不多,说少不少,还是自己查查吧
学好了写一下心得,分享一下
作者: amarant    时间: 2011-04-11 15:08
你这是交叉编译 不能这样写
作者: psp3000pes    时间: 2011-04-11 17:13
回复 16# T-Bagwell


    哦,好的
作者: psp3000pes    时间: 2011-04-11 17:15
回复 17# amarant


    哦?那怎样写啊~~?  还有关键怎样配置交叉编译环境啊?。。。
作者: amarant    时间: 2011-04-11 17:23
KDIR:=/lib/modules/$(shell uname -r)/build
这句改成
KDIR := /你的源码树

你五楼的写法是正确的  还要保证你kernel跑的就是你Kdir指向的源码
作者: psp3000pes    时间: 2011-04-11 18:33
回复 20# amarant


    哦,这样啊。不过我kernel跑的不是我五楼写的KDIR呀,因为那个KDIR所在的内核的配置是用于移植到ARM上的配置啊。。。我用过我kernel所跑的内核目录编译过 就是我在三楼写的那个:ifneq ($(KERNELRELEASE),)
obj-m:=hello.o
else
KDIR:=/lib/modules/$(shell uname -r)/build
all:
        make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
clean:
        rm -f *.ko *.o *.mod.o *.mod.c *.symvers
endif
但是还是不通过啊??
那我现在在另一个一样的系统重新做该怎么做呢?
作者: amarant    时间: 2011-04-11 18:48
/lib/modules/$(shell uname -r)/build
这个的是你宿主机的头文件
你必须要用你arm板子上跑的kernel的头文件
作者: psp3000pes    时间: 2011-04-11 21:07
回复 22# amarant


    哦,我明白了,可为什么我五楼那个却没有安装成功呢?那个错误好像是因为内核里缺少什么函数造成的?是不是这个用于编译arm驱动的内核也要怎样编译过呢?
作者: amarant    时间: 2011-04-11 21:22
可能你代码有问题
作者: psp3000pes    时间: 2011-04-11 22:18
回复 24# amarant


    但是我换一个别人写好的编译还是有这个问题啊
作者: goldenfort    时间: 2011-04-11 22:50
回复 23# psp3000pes


    先要把kernel  编译过才能行。
作者: psp3000pes    时间: 2011-04-12 00:34
回复 26# goldenfort


    kernel编译过了。我执行过make zImage、make modules、make modules_install和make install步骤了,只是是不是要用arm-linux-gcc编译的?
作者: amarant    时间: 2011-04-12 07:59
回复 25# psp3000pes


    因为你写的模块里面有内核里面没有导出的函数,你试试写个最简单的,就是init和exit的函数都是空的试试
作者: goldenfort    时间: 2011-04-12 11:24
回复 27# psp3000pes


    如果要  用arm-linux-gcc 编译 module, 应该用 arm-linux-gcc 编译kernel.

要不 arm-linux-gcc 编译出来的module, 往哪个 kernel 上加载
作者: psp3000pes    时间: 2011-04-12 22:06
回复 28# amarant


    不回吧。我想可能是那个ARM上跑的kernel没有包含这些头文件所致,但是现在我又用宿主机上的kernel目录来编译还是错误很多。唉. . .
作者: psp3000pes    时间: 2011-04-12 22:13
回复 29# goldenfort


    哦?这样的吗,那这样怎么编译,还有你们都用哪个kernel编译,是用宿主机跑的kernel还是用用于arm上跑的?
作者: goldenfort    时间: 2011-04-12 22:17
回复 31# psp3000pes


    把在 arm 上跑的kernel 先在pc 上编译一道。 然后编译 module  时, 将 -C 参数后边 写上 arm kernel 所在的目录
作者: psp3000pes    时间: 2011-04-13 14:26
回复 32# goldenfort


    哦,是这样那编译kernel是用gcc还是用arm-linux-gcc?是直接gcc编译就行了吗?
作者: goldenfort    时间: 2011-04-13 15:12
回复 33# psp3000pes


    用 arm-linux-gcc,  需要根据板子的不同, 搞好bsp 后,下到板子上才能运行
作者: psp3000pes    时间: 2011-04-13 15:12
回复 32# goldenfort


    问题还是不行啊,这个方法我试过,结果是编译是能编译,就是下到ARM板上时安装又出现这个错误:insmod: can't insert 'hello.ko': unknown symbol in module, or unknown paramete。搞不清这个问题了,现在也没办法。。。
作者: goldenfort    时间: 2011-04-13 15:15
回复 35# psp3000pes


    把kernel  用arm-linux-gcc 编译好, 然后 把 -C  后边的参数 搞成arm kernel 的目录,编译 module.

你现在 运行的板子上的 kernel 是如何编译出来的。

把 这个kernel  搞到你pc上, 编译一回, 再编译 module
作者: psp3000pes    时间: 2011-04-13 19:12
回复 36# goldenfort


    我板子上跑的kernel是商家提供的现现成的,不过也有对应的内核压缩文件,我现在就用这个kernel来编译了,不过没有用arm-linux-gcc编译,而是直接make的,我再重新编译一次(用arm-linux-gcc),再看看行不行吧
作者: psp3000pes    时间: 2011-04-13 19:40
回复 36# goldenfort


    可是还是不成啊,结果跟原来一样:insmod: can't insert 'hello.ko': unknown symbol in module, or unknown paramete,到底怎么搞呢?
作者: goldenfort    时间: 2011-04-13 21:30
本帖最后由 goldenfort 于 2011-04-13 21:33 编辑

回复 37# psp3000pes


    如果是商家提供的, 不用修改, 直接 make ,应该缺省的,就是用arm-linux-gcc 编译的吧。

    商家应该有详细的 如何安装 compiler,  如何编译 kernel 的步骤。

   按商家提供的步骤, 在pc 上把kernel 编译一遍。

    make -C /kernel目录  M=$(PWD) modules

   应该就可以了。

   不用自己 调用 arm-linux-gcc  , 商家的 kernel 里的 Makefile 文件已经调用了 合适的编译器了。

    然后编译 module,   有 -C  参数, 就会进入到kernel的目录,找到商家指定的编译器。
作者: santai543    时间: 2011-04-14 07:04
把一些相关东西补全就行了
作者: psp3000pes    时间: 2011-04-15 19:44
回复  psp3000pes


    如果是商家提供的, 不用修改, 直接 make ,应该缺省的,就是用arm-linux-gcc  ...
goldenfort 发表于 2011-04-13 21:30



    我就是 按照了商家提供的资料和手册安装了交叉编译器和编译了kernel啊,结果就是不成啊。。
作者: psp3000pes    时间: 2011-04-15 19:45
把一些相关东西补全就行了
santai543 发表于 2011-04-14 07:04



    你们是怎么弄的呢,到底是缺了什么呢。。
作者: goldenfort    时间: 2011-04-16 10:57
回复 41# psp3000pes


    不成 ,下载到板子上 insmod 的时候打印出什么信息来?
作者: psp3000pes    时间: 2011-04-16 23:11
回复 43# goldenfort

    能编译成.ko文件的现象就有两个:第一种:can't insert 'hello.ko':invalid module format .我估计第一种可能是没有用arm-linux-gcc编译和其他原因。
   第二种:can't insert 'hello.ko': unknown symbol in module, or unknown parameter。我估计是编译用的kernel没有全或者配置原因。
  而现在又不知道怎么改。
作者: shenzhou654321    时间: 2012-07-21 08:23
楼主后来问题解决了吗




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2