使用crosstool-ng编译的toolchain,开启了vfp:
CT_ARCH_FPU="neon-vfpv4"
CT_ARCH_FLOAT="hard"
编译进入rootfs后,概率性出现illegal instruction,也不知道是啥指令。今天在使用bare metal的时候,也出现了illegal instruction。这很好,因为uboot打印除了PC的地址。
IPQ5018# go 44000000
## Starting application at 0x44000000 ...
undefined instruction
pc : [<44000148>] lr : [<440002e0>]
reloc pc : [<44000148>] lr : [<440002e0>]
sp : 4a822934 ip : 00000000 fp : 4a822934
r10: 00000000 r9 : 4a822ea0 r8 : 4a97b1a0
r7 : 4a928b61 r6 : 00000002 r5 : 44000000 r4 : 4a82a84c
r3 : 44000318 r2 : 44000318 r1 : 4a82a84c r0 : 00000001
Flags: nzCv IRQs off FIQs off Mode SVC_32
Resetting CPU ...
反汇编:
ipq_timer.timer_load_val = 0x00FFFFFFFFFFFFFF;
4400013c: e3003318 movw r3, #792 ; 0x318
44000140: e3443400 movt r3, #17408 ; 0x4400
44000144: f2c70e3f vmov.i64 d16, #0x00ffffffffffffff
44000148: edc30b04 vstr d16, [r3, #16]
定位vstr原来是浮点数指令。尝试使用soft。第一次修改为softfp,产生的指令不变,修改为soft即可。
hard/softfp/soft 3种,soft才完全是软件soft。
然后在openwrt的toolchain中还发现了一个选项:
Configured with: /work/ax3000/build_dir/toolchain-arm_cortex-a7_gcc-5.5.0_musl_eabi/gcc-5.5.0/configure
--with-bugurl=http://www.lede-project.org/bugs/
--with-pkgversion='OpenWrt GCC 5.5.0 unknown'
--prefix=/work/ax3000/staging_dir/toolchain-arm_cortex-a7_gcc-5.5.0_musl_eabi
--build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu
--target=arm-openwrt-linux-muslgnueabi
--with-gnu-ld
--enable-target-optspace
--disable-libgomp
--disable-libmudflap --disable-multilib --disable-libmpx --disable-nls --without-isl --without-cloog --with-host-libstdcxx=-lstdc++
--with-float=soft
--with-gmp=/work/ax3000/staging_dir/host --with-mpfr=/work/ax3000/staging_dir/host --with-mpc=/work/ax3000/staging_dir/host --disable-decimal-float --with-diagnostics-color=auto-if-env --disable-libssp --enable-__cxa_atexit
--with-arch=armv7-a
--with-headers=/work/ax3000/staging_dir/toolchain-arm_cortex-a7_gcc-5.5.0_musl_eabi/include --disable-libsanitizer --enable-languages=c,c++ --enable-shared --enable-threads --with-slibdir=/work/ax3000/staging_dir/toolchain-arm_cortex-a7_gcc-5.5.0_musl_eabi/lib --enable-lto --with-libelf=/work/ax3000/staging_dir/host
代码里面根本没有浮点数运算,应该是整数也使用了浮点数了。disable-decimal-float可能也可以解决这个问题。
使用soft后,反汇编正常了:
ipq_timer.timer_load_val = 0x00FFFFFFFFFFFFFF;
4400013c: e3003318 movw r3, #792 ; 0x318
44000140: e3443400 movt r3, #17408 ; 0x4400
44000144: e3e00000 mvn r0, #0
44000148: e3e014ff mvn r1, #-16777216 ; 0xff000000
4400014c: e1c301f0 strd r0, [r3, #16]
IPQ5018是支持硬件浮点运算的。但是可能uboot并没有初始化fpu,导致uboot不支持fpu。有一个编译选项可以不适用fpu寄存器:
-mgeneral-regs-only
Generate code which uses only the general-purpose registers. This will prevent
the compiler from using floating-point and Advanced SIMD registers but will
not impose any restrictions on the assembler.
使用这个编译选项后,产生的汇编代码如下:
125 ipq_timer.timer_load_val = 0x00FFFFFFFFFFFFFF;
126 4400013c: e3003398 movw r3, #920 ; 0x398
127 44000140: e3443400 movt r3, #17408 ; 0x4400
128 44000144: e3e00000 mvn r0, #0
129 44000148: e3e014ff mvn r1, #-16777216 ; 0xff000000
130 4400014c: e1c301f0 strd r0, [r3, #16]