MIPS 架构 Linux driver编译时遇到的问题

文章详细介绍了Linux内核模块的编译流程调整,特别是在V2.6版本之后的变化,以及如何在特定平台上编译蓝牙驱动模块。同时,探讨了解决交叉编译工具指定问题的方法,并提供了关于MIPS架构中EndianessSelection的知识点。最后,分享了检查Linux内核模块版本和解决mipsel-linux-gcc找不到库位置的问题的技巧。
摘要由CSDN通过智能技术生成

 

Linux kernel在V2.6之后,modules的编译有些修改。不再是单独编译,而是将本module添加入:obj-m,并最终调用Linux KernelMakefile 来编译modules.

 

任务一:

这次Sam需要在某一平台上编译Bluetooth driver.其实也就是BlueZ的Kernel部分。但这个平台KernelSource Code做过精简,Bluetooth子系统已经被去掉了。所以Sam将Bluetoothdriver从其它平台Kernel Source Code中抽出来,以Modules的形式加入。

 

1. 确定copy文件:

Sam需要声成bluetooth.ko, hci_usb.ko, l2cap.ko, hidp.ko。

 

2. 写Modules Makefile:

ifneq ($(KERNELRELEASE),)
       obj-m += hci_usb.o
       obj-m += hidp.o
       obj-m += l2cap.o
       obj-m += bluetooth.o
       bluetooth-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.ohci_sock.o hci_sysfs.o lib.o
       hidp-objs := core.o sock.o


else
       KERNELDIR ?=/home/sam/work/current/BCM/Kernel2.6
       PWD := $(shell pwd)

default:
       $(MAKE) -C $(KERNELDIR) M=$(PWD) modules

endif

 

这个结构很简单:手动调用Makefile时,会进入else.设置了Kernel目录和当前目录,然后利用 -C进入Kernel Source顶层目录,调用的是Kernel 顶层Makefile。  M=则让Kernel Makefile去编译这个目录内的Module。 则KernelMakefile再次调用我们写的Makefile。这次因为KERNELRELEASE已被设置。所以在obj-m(所需要编译的Modules)中添加了我们需要的这些项目。

又因为bluetooth.ko 和hidp.ko是多个文件编译而成的,所以又作了以下动作:

bluetooth-objs := af_bluetooth.ohci_core.o hci_conn.o hci_event.o hci_sock.o hci_sysfs.olib.o
hidp-objs := core.o sock.o #这两句也是从Bluetooth KernelMakefile中抄来的。

 

3. 将所需要的.c, .h文件从Kernel 树中 copy到本目录内。

 

4. #make . 4个 ko文件就顺利生产了。

 

注意:如果当前Kernel树中有Bluetooth目录,则这个办法有缺陷。因为很可能两部分blueZVersion不同,造成很多struct 有变化,无法编译通过。

blueZ版本号: net/bluetooth/af_bluetooth.c中:version就是。

 

 

 

 

任务二:

工作Linux Server机器上,不同平台的交叉编译工具有不少,所以Sam很不喜欢有人用exportPATH=...的方式指定交叉编译器。这样很容易造成错误和误会。

 

Sam的办法是:每个人在写Makefile中,都用绝对路径指定所需要的cross comple.但在编译Kernel时,就有问题了。需要去改动Kernel Makefile。这样很不方便。也觉得很硬,一直没有好的办法。

 

先说之前的办法:

一般是在arch/*/Makefile中去强硬的修改CROSS_COMPILE。这样的问题是,如果ToolChain换了地点或者这份SourceCode 换到另一台机器。就需要再去修改。让人很烦。

 

今天无意中看了一眼CROSS_COMPILE说明,才发现有非常好的办法:

#make CROSS_COMPLE="绝对路径"/mipsel-linux-

这样就很容易解决了上述问题。 当然,定义环境变量也能达到以上效果。

 

 

知识点1:

MIPS架构中的EndianessSelection.

MIPS架构中,有Little endian和Big endian.所以,在针对MIPS架构的Kernel中,有配置大头或小头的选项。 Endianessselection-->

因为MIPS架构中分大小头,所以理所当然,交叉编译器也需要分大小头。

通常,MIPS交叉编译器中会有 mipsel-linux, mips-linux这2个目录。

其中,mips-linux是指 大头(Big endian)所使用的交叉编译器。

mipsel-linux是小头(little endian)所使用的交叉编译器。

 

 

知识点2:

LinuxModules版本察看:

Sam在提供bluetooth modules (ko文件)给另家公司时,反映kernel版本与modules版本不同。

kernel版本可以使用#uname -r 来查看。但Modules版本怎么看,一下子来不及查,就直接使用emacs打开ko文件,去看了版本信息。呵呵,觉得太粗暴了。查了一下:

#modinfo xxx.ko 就可以查看。嘿嘿。

 

知识点3:

mipsel-linux-gcc找不到库位置的处理:

#mipsel-linux-gcc -Wl,-rpath-link-Wl,/home/sam/work/current/BCM/BCM7403/ToolChain/crosstools_sf-linux-2.6.12.0_gcc-3.4.6-21_uclibc-0.9.28-20050817-20070607/mipsel-linux/lib test.c -o test

 

知识点4:

-rpath, -rpath-link 与 -L的区别。

当Link阶段,找不到库时,编译器会自动找几个地点(具体地点在libtool学习中有)

但 -L也是这个作用。

 

Sam猜想是这样的,如果显式的使用 -lxxx. 则 -rpath-link与-L都可指定位置。

如果是c基本库,则只能使用-rpath, -rpath-link。

另外,-rpath, -rpath-link都是给link的,所以需要用 -W1,的形式传递给ld.

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值