linux内核启用64位除法,请问怎么让4.3.2版本交叉编译工具编译通过第一期加强版的除法?...

编译器编译老师讲的视频,我在看视频过程中一直用的4.3.2版本交叉编译工具编译项目,当我看到视频的第11课第005节的时候,演示自己实现printf裸机打印,里面用到了lib1funcs.S文件,我编译的时候发现会遇到这样一个错误

ARM-linux-gcc -c -o LED.o led.c

arm-linux-gcc -c -o uart.o uart.c

arm-linux-gcc -c -o lib1funcs.o lib1funcs.S

arm-linux-gcc -c -o my_printf.o my_printf.c

arm-linux-gcc -c -o main.o main.c

arm-linux-gcc -c -o start.o start.S

arm-linux-ld -Ttext 0  -Tdata 0xe80 start.o led.o uart.o lib1funcs.o my_printf.o main.o -o uart.elf

my_printf.o: In function `out_num':

my_printf.c:(.text+0x120): undefined reference to `__aeabi_uidivmod'

my_printf.c:(.text+0x158): undefined reference to `__aeabi_uidiv'

Makefile:2: recipe for target 'all' failed

make: *** [all] Error 1

这是因为编译器的库没有实现除法运算,可是老师演示的时候明明可以编译通过啊,而且代码也反复检查了一下,没有不同,后来了解到老师用的是3.4.5版本的交叉编译工具,换成3.4.5版本的编译工具,果然可以编译通过。但是我想试试4.3.2版本能不能编译通过。

首先这个错误提示说明是一个未定义引用的错误,说的是my_printf.c文件out_num方法有问题,根据__aeabi_uidivmod,和__aeabi_uidiv猜想应该是除法实现的问题,这里用到了lib1funcs.S这个除法库文件,于是我在里面搜索__aeabi_uidiv和__aeabi_uidivmod,可是发现找不到这两个关键字的定义,事实表明应该是4.3.2版本的编译工具需要找这两个关键字的定义,但是找不到。于是猜测应该是这个lib1funcs.S是比较老版本的库文件,可是这个较新版本的去哪找呢,除法运算在u-boot和Linux内核里肯定实现了,就到这两个里面去找这个文件。

4.3.2编译通过的两个项目版本分别是u-boot-2012.04.01以及linux-3.4.2,就到这两个项目中找,你会发现u-boot里面没有这个文件,u-boot肯定实现了,但是不是用这个来实现的,我们到linux内核里找,你会搜索到如下结果:

song@dev:/work/hardware/009_uart$ find /work/system/linux-3.4.2 -name "lib1funcs.S"

/work/system/linux-3.4.2/arch/arm/lib/lib1funcs.S

/work/system/linux-3.4.2/arch/arm/boot/compressed/lib1funcs.S

/work/system/linux-3.4.2/arch/arm/lib/lib1funcs.S,这个文件应该就是我们找的库文件把他copy到项目里,然后make

arm-linux-gcc -c -o led.o led.c

arm-linux-gcc -c -o uart.o uart.c

arm-linux-gcc -c -o lib1funcs.o lib1funcs.S

lib1funcs.S:36:27: error: linux/linkage.h: No such file or directory

lib1funcs.S:37:27: error: asm/assembler.h: No such file or directory

lib1funcs.S:38:24: error: asm/unwind.h: No such file or directory

Makefile:2: recipe for target 'all' failed

make: *** [all] Error 1

遇到如上错误,提示我们找不到这些头文件,我们没有引用怎么可能找到,对比以前的lib1funcs.S不需要这些头文件,我们直接去掉就行。保存make

song@dev:/work/hardware/009_uart$ make

arm-linux-gcc -c -o led.o led.c

arm-linux-gcc -c -o uart.o uart.c

arm-linux-gcc -c -o lib1funcs.o lib1funcs.S

lib1funcs.S: Assembler messages:

lib1funcs.S:175: Error: bad instruction `entry(__udivsi3)'

lib1funcs.S:176: Error: bad instruction `entry(__aeabi_uidiv)'

lib1funcs.S:177: Error: bad instruction `unwind(.fnstart)'

lib1funcs.S:201: Error: bad instruction `unwind(.fnend)'

lib1funcs.S:202: Error: bad instruction `endproc(__udivsi3)'

lib1funcs.S:203: Error: bad instruction `endproc(__aeabi_uidiv)'

lib1funcs.S:205: Error: bad instruction `entry(__umodsi3)'

lib1funcs.S:206: Error: bad instruction `unwind(.fnstart)'

lib1funcs.S:220: Error: bad instruction `unwind(.fnend)'

lib1funcs.S:221: Error: bad instruction `endproc(__umodsi3)'

lib1funcs.S:223: Error: bad instruction `entry(__divsi3)'

lib1funcs.S:224: Error: bad instruction `entry(__aeabi_idiv)'

lib1funcs.S:225: Error: bad instruction `unwind(.fnstart)'

lib1funcs.S:262: Error: bad instruction `unwind(.fnend)'

lib1funcs.S:263: Error: bad instruction `endproc(__divsi3)'

lib1funcs.S:264: Error: bad instruction `endproc(__aeabi_idiv)'

lib1funcs.S:266: Error: bad instruction `entry(__modsi3)'

lib1funcs.S:267: Error: bad instruction `unwind(.fnstart)'

lib1funcs.S:287: Error: bad instruction `unwind(.fnend)'

lib1funcs.S:288: Error: bad instruction `endproc(__modsi3)'

lib1funcs.S:350: Error: bad instruction `unwind(.fnstart)'

lib1funcs.S:351: Error: bad instruction `unwind(.pad #4)'

lib1funcs.S:352: Error: bad instruction `unwind(.save {lr})'

lib1funcs.S:357: Error: bad instruction `unwind(.fnend)'

lib1funcs.S:358: Error: bad instruction `endproc(Ldiv0)'

Makefile:2: recipe for target 'all' failed

make: *** [all] Error 1

这些错误,从意思应该是也是对这些定义不理解,应该是去掉头文件引起来的,也就是说头文件中有这些的定义,我们对比老的lib1funcs开头有一些宏定义我们先加上,其中有entry的宏定义,我们可以猜想这些都是在头文件里的宏定义,其实你去linux内核里找这个头文件#include 在这里就可以找到entry的宏定义。然后保存make

还会报这种错误,也是没有写宏定义

lib1funcs.S:357: Error: bad instruction `unwind(.fnend)'

lib1funcs.S:358: Error: bad instruction `endproc(Ldiv0)'

但是我们对别老的lib1funcs.S发现这些都没有,所以这些关键字标识符我们先去掉只要是UNWIND和ENDPROC开头的都去掉,然后make

arm-linux-gcc -c -o led.o led.c

arm-linux-gcc -c -o uart.o uart.c

arm-linux-gcc -c -o lib1funcs.o lib1funcs.S

arm-linux-gcc -c -o my_printf.o my_printf.c

arm-linux-gcc -c -o main.o main.c

arm-linux-gcc -c -o start.o start.S

arm-linux-ld -Ttext 0  -Tdata 0xe80 start.o led.o uart.o lib1funcs.o my_printf.o main.o -o uart.elf

my_printf.o: In function `out_num':

my_printf.c:(.text+0x120): undefined reference to `__aeabi_uidivmod'

Makefile:2: recipe for target 'all' failed

make: *** [all] Error 1

你会发现还是报未定义的错误,在lib1funcs.S搜索这个定义,它的上面有个#IFdef CONFIG_AEABI,需要先定义这个宏定义,我们在开头加一句 #define CONFIG_AEABI 1,然后保存make

arm-linux-gcc -c -o led.o led.c

arm-linux-gcc -c -o uart.o uart.c

arm-linux-gcc -c -o lib1funcs.o lib1funcs.S

arm-linux-gcc -c -o my_printf.o my_printf.c

arm-linux-gcc -c -o main.o main.c

arm-linux-gcc -c -o start.o start.S

arm-linux-ld -Ttext 0  -Tdata 0xe80 start.o led.o uart.o lib1funcs.o my_printf.o main.o -o uart.elf

arm-linux-ld: section .data [00000e80 -> 00000e8f] overlaps section .rodata [00000d74 -> 00000e9b]

arm-linux-ld: uart.elf: section .data lma 0xe80 overlaps previous sections

lib1funcs.o: In function `Ldiv0':

(.text+0x3ec): undefined reference to `__div0'

Makefile:2: recipe for target 'all' failed

make: *** [all] Error 1

还有一个未定义搜索lib1funcs.S,是在最后相对跳转到一个c函数里面执行,我们对比老的lib1funcs.S发现这里注释掉了,我们也注释掉,然后保存make

arm-linux-gcc -c -o led.o led.c

arm-linux-gcc -c -o uart.o uart.c

arm-linux-gcc -c -o lib1funcs.o lib1funcs.S

arm-linux-gcc -c -o my_printf.o my_printf.c

arm-linux-gcc -c -o main.o main.c

arm-linux-gcc -c -o start.o start.S

arm-linux-ld -Ttext 0  -Tdata 0xe80 start.o led.o uart.o lib1funcs.o my_printf.o main.o -o uart.elf

arm-linux-ld: section .data [00000e80 -> 00000e8f] overlaps section .rodata [00000d74 -> 00000e9b]

arm-linux-ld: uart.elf: section .data lma 0xe80 overlaps previous sections

Makefile:2: recipe for target 'all' failed

make: *** [all] Error 1,

你可能会遇到这个问题这个应该是代码段太长了,超过了定义的数据段的位置,可以自己适当延长代码段,我试了一下用0xea0就可以,到此第一期arm加强版demo程序009-uart移植4.3.2编译器完毕。

在后面的lcd那里的除法解决方案里需要用到libgcc.a库,我当时用的是/usr/local/arm/4.3.2/lib/gcc/arm-none-linux-gnueabi/4.3.2/libgcc.a这个文件,在后面的adc实验的时候发现这个库无法解决浮点数除法的问题,解决了一段时间,最后还是微信请教了韦老师,老师最后发现是我用的libgcc.a文件错误,应该用4.3.2/lib/gcc/arm-none-linux-gnueabi/4.3.2/armv4t/libgcc.a这个位置的libgcc.a文件

备注:这里我用的是009_uart项目重新走了一遍。

699ba7046c51816a17b33a7caa85f179.png

0

97b4b3417991aabde46fdac613e34292.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值