arm-none-eabi for os development, hardfp/softfp libgcc issue

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
vhaudiquet
Member
Member
Posts: 43
Joined: Sun Aug 20, 2017 10:59 am

arm-none-eabi for os development, hardfp/softfp libgcc issue

Post by vhaudiquet »

Hi,

My kernel supports ARM architectures ; to build i use the arm-none-eabi toolchain (https://developer.arm.com/tools-and-sof ... /downloads). I did not build a cross-compiler and directly used this toolchain because i believe it does targets bare metal, so no need to rebuild a compiler to do that. Am i wrong ?

However, i had problems recently :
i link with libgcc, which gives me support for divmod (division and reminder) (_udivmoddi4 and such)
I target multiple architectures, and i only compiled for i686 ; when i tried to compile for ARM again, i got this error :

Code: Select all

arm-none-eabi-ld: error: kernel.elf uses VFP register arguments, libgcc.a (_udivmoddi4.o) does not
I compile my kernel with

Code: Select all

-mfpu=neon-vfpv4 -mfloat-abi=hard
, as i target RPI2. I don't understand where i am using a VFP register, because i don't have any floating point operation in the kernel ; but i added a 64-bits integer division, which i suspect gcc will optimize using vfp registers (ARMv7 is 32-bits).
It appears that the libgcc provided with arm-none-eabi is 'softfp' : software-only floating point operations, and that is incompatible with 'hardfp' : hardware floating points operations.

The way i see it, i only have 2 solutions :
- Change the kernel compile flag to softfp (which means all operations are done in software, no hardware acceleration : poor performances...)
- Rebuild/have a libgcc on each kernel compilation for my target (vfpv4 here, but might be different for rpi0 or rpi4 or ...) with hardfp (which seems really boring and tedious to setup...)

I think i'll go for the second option ; but is there something i'm missing ? something i don't see ?

EDIT : something that seems strange to me is that uint64_t division generated code that uses VFP registers, but uint32_t division used libgcc udivmod...
vhaudiquet
Member
Member
Posts: 43
Joined: Sun Aug 20, 2017 10:59 am

Re: arm-none-eabi for os development, hardfp/softfp libgcc i

Post by vhaudiquet »

Okay, i found another solution :
the toolchain actually provides different libgcc, it seems to be one for every use case.
I now link with the one in : lib/gcc/arm-none-eabi/10.3.1/thumb/v7-a+fp/hard/ and there seems to be no problem.
I'm not forced to build libgcc myself and keep it arround in the project then, that is acceptable to me.

However, i don't understand why those libraries are in the 'thumb' subdirectory. I did not look there before, because my issue has nothing to do with thumb mode...
I'm not really familiar with thumb mode, but i don't see why those different libgcc versions would be there...
Also these are only available with the most recent versions of the toolchain i think...

Anyway, the main problem seems fixed...
I would still like to have an explanation as why these libraries are below the thumb directory (are they using thumb mode ? why ??)
or why gcc generated vfp code only for 64-bits divisions and not 32-bits ones...
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: arm-none-eabi for os development, hardfp/softfp libgcc i

Post by Octocontrabass »

That cross-compiler only has multilib configurations for the Cortex-A/R/M series CPUs, but the default CPU is ARM7TDMI. Add -mcpu=cortex-a7 (or whatever is appropriate) to your command line and GCC will automatically choose the correct libgcc.
vhaudiquet
Member
Member
Posts: 43
Joined: Sun Aug 20, 2017 10:59 am

Re: arm-none-eabi for os development, hardfp/softfp libgcc i

Post by vhaudiquet »

Octocontrabass wrote:That cross-compiler only has multilib configurations for the Cortex-A/R/M series CPUs, but the default CPU is ARM7TDMI. Add -mcpu=cortex-a7 (or whatever is appropriate) to your command line and GCC will automatically choose the correct libgcc.
I already passed to gcc `-march=armv7-a` and `-mtune=cortex-a7` ; i think these are equivalent to `-mcpu=coretex-a7` for GCC ?
But i'm linking with ld (should i just replace it with gcc ? i'm always confused as how those two are not equivalent because i don't think there is a way to know which flags or options gcc will pass to ld when it invokes it...).
i had to add manually `-L ${cc_path}/../lib/gcc/${cc_toolchain}/${cc_version}/thumb/v7-a+fp/hard` and before `-L ${cc_path}/../lib/gcc/${cc_toolchain}/${cc_version}` for ld to be able to find `-lgcc`.

I can't pass `-mcpu` to ld i think ; are you saying that passing to gcc should be enough so that ld finds the correct libgcc, or that i should link with gcc ?
nullplan
Member
Member
Posts: 1790
Joined: Wed Aug 30, 2017 8:24 am

Re: arm-none-eabi for os development, hardfp/softfp libgcc i

Post by nullplan »

vhaudiquet wrote:But i'm linking with ld (should i just replace it with gcc ? i'm always confused as how those two are not equivalent because i don't think there is a way to know which flags or options gcc will pass to ld when it invokes it...).
If you use gcc to link object files, gcc will select the correct options and start files, and construct the linker command line accordingly. Which admittedly hardly matters for a kernel written in C, and these days doesn't even matter for C++ kernels because the .init_array mechanism works without start files. Also, adding gcc will add libgcc to the command line, which ought to help with exactly the kind of problem you were having here.
Carpe diem!
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: arm-none-eabi for os development, hardfp/softfp libgcc i

Post by Octocontrabass »

vhaudiquet wrote:I already passed to gcc `-march=armv7-a` and `-mtune=cortex-a7` ; i think these are equivalent to `-mcpu=coretex-a7` for GCC ?
Yeah, they should be.
vhaudiquet wrote:But i'm linking with ld (should i just replace it with gcc ? i'm always confused as how those two are not equivalent because i don't think there is a way to know which flags or options gcc will pass to ld when it invokes it...).
You should link with gcc. If you want to see the flags gcc will pass to ld, add "-v" to the command line. (Actually gcc will invoke collect2 and collect2 will invoke ld, but collect2 passes the flags to ld unchanged.)
Post Reply