我是这种编码的新手,我正在尝试做一些测试,为Cortex-A处理器执行裸金属软件。我有使用Cortex-M MCU的经验,我用类似于ARM Keil的IDE和北欧的SDK编译了代码,用于一些BLE工作。现在,我想尝试更好地理解Cortex-A的世界,我将以一种赤裸裸的方式学习编码,从我在网上找到的一些例子开始。我有一些使用Cortex-M的freeRTOS的经验,所以我在网上找到了一些git存储库,它是从一个好家伙那里找到的,他正在为RaspberryPI和BeableBoneBlack移植freeRTOS。从现在开始,我将只为BeableBoneBlack解释我的问题,为RaspberryPI解释我的问题--这是类似的。
我在linux上,我安装了gcc-arm-无eabi编译器,所以我从这个BeagleBone上克隆了freeRTOS存储库的freeRTOS黑。
我通常使用VS代码来编写代码,所以在集成终端中,当我运行命令使正常工作时,我的BBB就会正确地闪烁。所以现在我想改进我的代码,为了进行一些测试,我想使用stdlib.h中的rand()函数。不幸的是,我发现有一些错误:undefined reference to rand。在过去的几个月里,在对BBB进行测试之前,我为RPi2找到了其他的repos,并且我了解到了arm的链接器--无eabi编译器,它需要在过程中添加一些参数来排列链接库文件。现在我有两个文件:makedefs_ti和makefile。打开我在第26-27行中找到的make文件--文件应用程序生成的部分,因此调用链接器。在这一行中,有对makedefs_ti.中定义的LIB_GCC和LIB_C的引用。在第49-50行中,有对安装编译器的目录的引用(我修改了4.7.3,正确地安装在我的linux pc上,即9.2.1)。在makefile中,在-L$(LIB_C)之后,如果添加链接器参数(如-lc或-lg )并尝试重新编译,则会出现类似于arm-none-eabi-ld: cannot find -lc的错误。根据在线资源的一些理解,我对makedefs_ti进行了如下修改:
# Toolchain/library path. LIB_PATH is an exported environmental variable which
# shall point to the installation of toolchain
#
#LIB_GCC=${LIB_PATH}/lib/gcc/arm-none-eabi/4.7.3/
#LIB_C=${LIB_PATH}/arm-none-eabi/lib/
LIB_GCC= /usr/lib/gcc/arm-none-eabi/9.2.1
LIB_C= /usr/lib/arm-none-eabi/lib以及makefile:
$(LD) -o $@.out $< -T bbb.ld -Map bbb.map $(APP_LIB) $(LDFLAGS) $(RUNTIMELIB) -L $(LPATH) \
-L $(LIB_GCC) -lgcc -L $(LIB_C) -lc -lg这样,调用rand()函数的main.c文件就能正确编译。在另一个测试中,我试图编译另一个代码。现在,我编写了一对.c和.h文件(我将它们放在rtos目录中,以便利用当前存在的同一个makefile ),它们在调用sqrt()的函数中。因此,调用main()中的函数并编译,即使我包含了everywhere <math.h>,我也有错误:
undefined reference to `sqrt'显然编译工作停止了。从此开始,我尝试向链接器添加另一个参数,因此我修改了makefile,如下所示:
$(LD) -o $@.out $< -T bbb.ld -Map bbb.map $(APP_LIB) $(LDFLAGS) $(RUNTIMELIB) -L $(LPATH) \
-L $(LIB_GCC) -lgcc -L $(LIB_C) -lc -lg -lm我还发现了其他我无法解决的错误:
arm-none-eabi-ld: /usr/lib/arm-none-eabi/lib/libm.a(lib_a-w_sqrt.o): in function `sqrt':
/build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libm/math/../../../../../newlib/libm/math/w_sqrt.c:62: undefined reference to `__aeabi_dcmpun'
arm-none-eabi-ld: /build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libm/math/../../../../../newlib/libm/math/w_sqrt.c:63: undefined reference to `__aeabi_dcmplt'
arm-none-eabi-ld: /build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libm/math/../../../../../newlib/libm/math/w_sqrt.c:64: undefined reference to `__errno'
arm-none-eabi-ld: /build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libm/math/../../../../../newlib/libm/math/w_sqrt.c:65: undefined reference to `__aeabi_ddiv'
arm-none-eabi-ld: /usr/lib/arm-none-eabi/lib/libm.a(lib_a-e_sqrt.o): in function `__ieee754_sqrt':
/build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libm/machine/arm/../../../../../../newlib/libm/machine/arm/../../math/e_sqrt.c:110: undefined reference to `__aeabi_dmul'
arm-none-eabi-ld: /build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libm/machine/arm/../../../../../../newlib/libm/machine/arm/../../math/e_sqrt.c:110: undefined reference to `__aeabi_dadd'
arm-none-eabi-ld: /build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libm/machine/arm/../../../../../../newlib/libm/machine/arm/../../math/e_sqrt.c:117: undefined reference to `__aeabi_dsub'
arm-none-eabi-ld: /build/newlib-CVVEyx/newlib-3.3.0/build/arm-none-eabi/newlib/libm/machine/arm/../../../../../../newlib/libm/machine/arm/../../math/e_sqrt.c:117: undefined reference to `__aeabi_ddiv'
make: *** [makefile:26: app] Errore 1我要指出的是,在主工作中正确调用sqrt()时,当我在其他.c文件中调用sqrt()时,问题就会发生。相反,rand()函数在.c附加文件中正确工作。
我不知道如何解决这些错误,有人能帮我吗?
另一天,我尝试的是在项目中编写相同的代码,它可以工作(使用在附加的.c文件中调用sqrt和rand的相同函数)。有什么关系?
如果这是一个很长的解释,我很抱歉,但我没有找到其他方法来解释我的情况。
提前谢谢。
扫射
发布于 2020-12-06 05:05:11
start.s
.globl _start
_start:
;@ enable fpu
mrc p15, 0, r0, c1, c0, 2
orr r0,r0,#0x300000 ;@ single precision
orr r0,r0,#0xC00000 ;@ double precision
mcr p15, 0, r0, c1, c0, 2
mov r0,#0x40000000
fmxr fpexc,r0
mov sp,#0x8000
bl notmain
hang: b hangnotmain.c
double notmain ( double a, double b )
{
return(a+b);
}(不是一个真正的裸金属应用程序,源自其中之一)
为硬浮子而建
arm-none-eabi-as --warn --fatal-warnings -mcpu=arm1176jzf-s -march=armv6 -mfpu=vfp start.s -o start.o
arm-none-eabi-gcc -Wall -O2 -ffreestanding -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mhard-float -mfpu=vfp -c notmain.c -o notmain.o
arm-none-eabi-ld -nostdlib -nostartfiles start.o notmain.o -T memmap -o notmain.elf
arm-none-eabi-objdump -D notmain.elf > notmain.list
arm-none-eabi-objcopy --srec-forceS3 notmain.elf -O srec notmain.srec
arm-none-eabi-objcopy notmain.elf -O binary kernel.img硬件浮点
00008024 <notmain>:
8024: ee300b01 vadd.f64 d0, d0, d1
8028: e12fff1e bx lr软浮子建造
arm-none-eabi-as --warn --fatal-warnings -mcpu=arm1176jzf-s -march=armv6 -mfpu=vfp start.s -o start.o
arm-none-eabi-gcc -Wall -O2 -ffreestanding -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -c notmain.c -o notmain.o
arm-none-eabi-ld -nostdlib -nostartfiles start.o notmain.o -T memmap -o notmain.elf
arm-none-eabi-ld: notmain.o: in function `notmain':
notmain.c:(.text+0x4): undefined reference to `__aeabi_dadd'
Makefile:33: recipe for target 'notmain.elf' failed
make: *** [notmain.elf] Error 1它需要gcclib。
用gcc作为链接者(我知道这是多么可怕的想法)。
arm-none-eabi-as --warn --fatal-warnings -mcpu=arm1176jzf-s -march=armv6 -mfpu=vfp start.s -o start.o
arm-none-eabi-gcc -Wall -O2 -ffreestanding -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -c notmain.c -o notmain.o
arm-none-eabi-gcc -Wall -O2 -ffreestanding -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -nostdlib -nostartfiles start.o notmain.o -T memmap -o notmain.elf -lgcc
arm-none-eabi-objdump -D notmain.elf > notmain.list
arm-none-eabi-objcopy --srec-forceS3 notmain.elf -O srec notmain.srec
arm-none-eabi-objcopy notmain.elf -O binary kernel.img..。
00008024 <notmain>:
8024: e92d4010 push {r4, lr}
8028: eb000003 bl 803c <__adddf3>
802c: e8bd8010 pop {r4, pc}
00008030 <__aeabi_drsub>:
8030: e2211102 eor r1, r1, #-2147483648 ; 0x80000000
8034: ea000000 b 803c <__adddf3>
00008038 <__aeabi_dsub>:
8038: e2233102 eor r3, r3, #-2147483648 ; 0x80000000
0000803c <__adddf3>:
803c: e92d4030 push {r4, r5, lr}gcc正在把这些东西转交给ld。
[0][/opt/gnuarm/lib/gcc/arm-none-eabi/10.2.0/../../../../arm-none-eabi/bin/ld]
[1][-plugin]
[2][/opt/gnuarm/libexec/gcc/arm-none-eabi/10.2.0/liblto_plugin.so]
[3][-plugin-opt=/opt/gnuarm/libexec/gcc/arm-none-eabi/10.2.0/lto-wrapper]
[4][-plugin-opt=-fresolution=/tmp/ccRiWZtk.res]
[5][-X]
[6][-o]
[7][notmain.elf]
[8][-L/opt/gnuarm/lib/gcc/arm-none-eabi/10.2.0]
[9][-L/opt/gnuarm/lib/gcc/arm-none-eabi/10.2.0/../../../../arm-none-eabi/lib]
[10][start.o]
[11][notmain.o]
[12][-lgcc]
[13][-T]
[14][memmap]
find | grep libgcc
./lib/gcc/arm-none-eabi/10.2.0/libgcc.a
./lib/gcc/arm-none-eabi/10.2.0/thumb/libgcc.a
./lib/gcc/arm-none-eabi/10.2.0/thumb/autofp/v7/fpu/libgcc.a
./lib/gcc/arm-none-eabi/10.2.0/arm/autofp/v5te/fpu/libgcc.a那就用ld
arm-none-eabi-as --warn --fatal-warnings -mcpu=arm1176jzf-s -march=armv6 -mfpu=vfp start.s -o start.o
arm-none-eabi-gcc -Wall -O2 -ffreestanding -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -c notmain.c -o notmain.o
arm-none-eabi-ld -nostdlib -nostartfiles start.o notmain.o -T memmap -o notmain.elf -L/opt/gnuarm/lib/gcc/arm-none-eabi/10.2.0/ -lgcc
arm-none-eabi-objdump -D notmain.elf > notmain.list
arm-none-eabi-objcopy --srec-forceS3 notmain.elf -O srec notmain.srec
arm-none-eabi-objcopy notmain.elf -O binary kernel.img为什么现在使用addf3?不知道。
00008024 <notmain>:
8024: e92d4010 push {r4, lr}
8028: eb000003 bl 803c <__adddf3>
802c: e8bd8010 pop {r4, pc}
00008030 <__aeabi_drsub>:
8030: e2211102 eor r1, r1, #-2147483648 ; 0x80000000
8034: ea000000 b 803c <__adddf3>
00008038 <__aeabi_dsub>:
8038: e2233102 eor r3, r3, #-2147483648 ; 0x80000000
0000803c <__adddf3>:
803c: e92d4030 push {r4, r5, lr}
8040: e1a04081 lsl r4, r1, #1
8044: e1a05083 lsl r5, r3, #1这就是您处理aeabi的方法,您需要使用硬浮点数,或者包含到gcclib的路径,或者只是将其添加到行中。
arm-none-eabi-as --warn --fatal-warnings -mcpu=arm1176jzf-s -march=armv6 -mfpu=vfp start.s -o start.o
arm-none-eabi-gcc -Wall -O2 -ffreestanding -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -c notmain.c -o notmain.o
arm-none-eabi-ld -nostdlib -nostartfiles start.o notmain.o -T memmap -o notmain.elf /opt/gnuarm/lib/gcc/arm-none-eabi/10.2.0/libgcc.a
#arm-none-eabi-gcc -Wall -O2 -ffreestanding -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -nostdlib -nostartfiles start.o notmain.o -T memmap -o notmain.elf -lgcc
arm-none-eabi-objdump -D notmain.elf > notmain.list
arm-none-eabi-objcopy --srec-forceS3 notmain.elf -O srec notmain.srec
arm-none-eabi-objcopy notmain.elf -O binary kernel.img现在sqrt()是一个C库,而不是gcc库,所以您需要一个C库(看起来您正在尝试使用newlib),并且您需要构建C库来匹配gcc,所以您需要为硬或软浮动构建它,并且需要包含正确的库。但我不have...well..。
arm-none-eabi-as --warn --fatal-warnings -mcpu=arm1176jzf-s -march=armv6 -mfpu=vfp start.s -o start.o
arm-none-eabi-gcc -Wall -O2 -ffreestanding -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -c notmain.c -o notmain.o
arm-none-eabi-ld -nostdlib -nostartfiles start.o notmain.o -T memmap -o notmain.elf /home/so/gcc-arm-none-eabi-9-2019-q4-major/lib/gcc/arm-none-eabi/9.2.1/libgcc.a
arm-none-eabi-objdump -D notmain.elf > notmain.list
arm-none-eabi-objcopy --srec-forceS3 notmain.elf -O srec notmain.srec
arm-none-eabi-objcopy notmain.elf -O binary kernel.img所以
double sqrt(double x);
double notmain ( double a )
{
return(sqrt(a));
}看起来很眼熟
arm-none-eabi-gcc -Wall -O2 -ffreestanding -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -c notmain.c -o notmain.o
arm-none-eabi-ld -nostdlib -nostartfiles start.o notmain.o -T memmap -o notmain.elf /home/so/gcc-arm-none-eabi-9-2019-q4-major/lib/gcc/arm-none-eabi/9.2.1/libgcc.a /home/so/gcc-arm-none-eabi-9-2019-q4-major/arm-none-eabi/lib/libm.a
arm-none-eabi-ld: /home/so/gcc-arm-none-eabi-9-2019-q4-major/arm-none-eabi/lib/libm.a(lib_a-w_sqrt.o): in function `sqrt':
w_sqrt.c:(.text.sqrt+0x34): undefined reference to `__aeabi_dcmpun'
arm-none-eabi-ld: w_sqrt.c:(.text.sqrt+0x6c): undefined reference to `__aeabi_dcmplt'
arm-none-eabi-ld: w_sqrt.c:(.text.sqrt+0xc4): undefined reference to `__aeabi_ddiv'
arm-none-eabi-ld: w_sqrt.c:(.text.sqrt+0xd8): undefined reference to `__errno'
arm-none-eabi-ld: w_sqrt.c:(.text.sqrt+0x120): undefined reference to `__errno'
arm-none-eabi-ld: /home/so/gcc-arm-none-eabi-9-2019-q4-major/arm-none-eabi/lib/libm.a(lib_a-e_sqrt.o): in function `__ieee754_sqrt':
e_sqrt.c:(.text.__ieee754_sqrt+0x200): undefined reference to `__aeabi_dmul'
arm-none-eabi-ld: e_sqrt.c:(.text.__ieee754_sqrt+0x20c): undefined reference to `__aeabi_dadd'
arm-none-eabi-ld: e_sqrt.c:(.text.__ieee754_sqrt+0x22c): undefined reference to `__aeabi_dsub'
arm-none-eabi-ld: e_sqrt.c:(.text.__ieee754_sqrt+0x238): undefined reference to `__aeabi_ddiv'
Makefile:33: recipe for target 'notmain.elf' failed
make: *** [notmain.elf] Error 1发现
./arm-none-eabi/lib/libm.a
./arm-none-eabi/lib/thumb/v7e-m/nofp/libm.a
./arm-none-eabi/lib/thumb/v6-m/nofp/libm.a
./arm-none-eabi/lib/thumb/v8-m.base/nofp/libm.a
./arm-none-eabi/lib/thumb/v7/nofp/libm.a
./arm-none-eabi/lib/thumb/v8-m.main+dp/hard/libm.a
./arm-none-eabi/lib/thumb/v8-m.main+dp/softfp/libm.a
./arm-none-eabi/lib/thumb/v7e-m+dp/hard/libm.a
./arm-none-eabi/lib/thumb/v7e-m+dp/softfp/libm.a
./arm-none-eabi/lib/thumb/v7-r+fp.sp/hard/libm.a
./arm-none-eabi/lib/thumb/v7-r+fp.sp/softfp/libm.a
./arm-none-eabi/lib/thumb/v7e-m+fp/hard/libm.a
./arm-none-eabi/lib/thumb/v7e-m+fp/softfp/libm.a
./arm-none-eabi/lib/thumb/v8-m.main+fp/hard/libm.a
./arm-none-eabi/lib/thumb/v8-m.main+fp/softfp/libm.a
./arm-none-eabi/lib/thumb/v7-m/nofp/libm.a
./arm-none-eabi/lib/thumb/nofp/libm.a
./arm-none-eabi/lib/thumb/v7+fp/hard/libm.a
./arm-none-eabi/lib/thumb/v7+fp/softfp/libm.a
./arm-none-eabi/lib/thumb/v8-m.main/nofp/libm.a
./arm-none-eabi/lib/arm/v5te/hard/libm.a
./arm-none-eabi/lib/arm/v5te/softfp/libm.aarmv5te应该适用于armv6
arm-none-eabi-ld -nostdlib -nostartfiles start.o notmain.o -T memmap -o notmain.elf /home/so/gcc-arm-none-eabi-9-2019-q4-major/lib/gcc/arm-none-eabi/9.2.1/libgcc.a /home/so/gcc-arm-none-eabi-9-2019-q4-major/arm-none-eabi/lib/arm/v5te/softfp/libm.a
arm-none-eabi-ld: /home/so/gcc-arm-none-eabi-9-2019-q4-major/arm-none-eabi/lib/arm/v5te/softfp/libm.a(lib_a-w_sqrt.o): in function `sqrt':
w_sqrt.c:(.text.sqrt+0x94): undefined reference to `__errno'
arm-none-eabi-ld: w_sqrt.c:(.text.sqrt+0xdc): undefined reference to `__errno'
Makefile:33: recipe for target 'notmain.elf' failed
make: *** [notmain.elf] Error 1errno是一个全局变量。C库可能希望用于软浮动。
int __errno;
double sqrt(double x);
double notmain ( double a )
{
return(sqrt(a));
}现在这个工具是快乐的
arm-none-eabi-as --warn --fatal-warnings -mcpu=arm1176jzf-s -march=armv6 -mfpu=vfp start.s -o start.o
arm-none-eabi-gcc -Wall -O2 -ffreestanding -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -c notmain.c -o notmain.o
arm-none-eabi-ld -nostdlib -nostartfiles start.o notmain.o -T memmap -o notmain.elf /home/so/gcc-arm-none-eabi-9-2019-q4-major/lib/gcc/arm-none-eabi/9.2.1/libgcc.a /home/so/gcc-arm-none-eabi-9-2019-q4-major/arm-none-eabi/lib/arm/v5te/softfp/libm.a
arm-none-eabi-objdump -D notmain.elf > notmain.list
arm-none-eabi-objcopy --srec-forceS3 notmain.elf -O srec notmain.srec
arm-none-eabi-objcopy notmain.elf -O binary kernel.img但这是硬浮,而不是软。
00008024 <notmain>:
8024: eaffffff b 8028 <sqrt>
00008028 <sqrt>:
8028: e52de004 push {lr} ; (str lr, [sp, #-4]!)
802c: ed2d8b02 vpush {d8}
8030: e1a02000 mov r2, r0
8034: e1a03001 mov r3, r1
8038: e24dd02c sub sp, sp, #44 ; 0x2c
803c: ec432b18 vmov d8, r2, r3
8040: eb000038 bl 8128 <__ieee754_sqrt>
8044: e59f30d4 ldr r3, [pc, #212] ; 8120 <sqrt+0xf8>
8048: eeb48b48 vcmp.f64 d8, d8
804c: e1d3c0d0 ldrsb ip, [r3]
8050: eef1fa10 vmrs APSR_nzcv, fpscr但是,对于解决这一问题的途径是什么,你会有自己的想法。您需要一个匹配的/构建的库,然后您需要链接它。Keil和其他人只是在工具链中为您做这件事,根据项目进行匹配。和/或与工具链集成的C库。
硬浮子建筑
arm-none-eabi-as --warn --fatal-warnings -mcpu=arm1176jzf-s -march=armv6 -mfpu=vfp start.s -o start.o
arm-none-eabi-gcc -Wall -O2 -ffreestanding -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mhard-float -mfpu=vfp -c notmain.c -o notmain.o
arm-none-eabi-ld -nostdlib -nostartfiles start.o notmain.o -T memmap -o notmain.elf /home/so/gcc-arm-none-eabi-9-2019-q4-major/lib/gcc/arm-none-eabi/9.2.1/libgcc.a /home/so/gcc-arm-none-eabi-9-2019-q4-major/arm-none-eabi/lib/arm/v5te/hard/libm.a
arm-none-eabi-objdump -D notmain.elf > notmain.list
arm-none-eabi-objcopy --srec-forceS3 notmain.elf -O srec notmain.srec
arm-none-eabi-objcopy notmain.elf -O binary kernel.img工具是快乐的。
00008024 <notmain>:
8024: eaffffff b 8028 <sqrt>
00008028 <sqrt>:
8028: e52de004 push {lr} ; (str lr, [sp, #-4]!)
802c: ed2d8b02 vpush {d8}
8030: eeb08b40 vmov.f64 d8, d0
8034: e24dd02c sub sp, sp, #44 ; 0x2c
8038: eb000038 bl 8120 <__ieee754_sqrt>
803c: eeb48b48 vcmp.f64 d8, d8
8040: e59f30d0 ldr r3, [pc, #208] ; 8118 <sqrt+0xf0>
8044: e1d310d0 ldrsb 必须使这成为一个真正的应用程序--主调用另一个函数,在其中调用sqrt。然后在硬件和/或检查这些指令上运行它。或者更好地获取sqrt的C库实现,并在项目中构建它,使其与目标和指令集相匹配。(与libgcc调用的情况相同,可以根据需要测试或构建它们)。
https://stackoverflow.com/questions/65161159
复制相似问题