-
Notifications
You must be signed in to change notification settings - Fork 8k
Description
Describe the bug
Trying to run samples/cpp/hello_world on qemu_cortex_m3 (with expanded flash size)
Using the Zephyr SDK works fine, with and without CONFIG_NEWLIB_LIBC=y.
Trying to use gnuarmemb results in no output and apparent hang (with some really weird stuff going on based on gdb output).
To Reproduce
- Fresh zephyr install using: https://docs.zephyrproject.org/latest/develop/getting_started/index.html
- Install GNU Arm Embedded toolchain , referring to: https://docs.zephyrproject.org/latest/develop/toolchains/gnu_arm_embedded.html
a. I chose 11.3 Release: x86_64 Linux hosted cross toolchains, AArch32 bare-metal target (arm-none-eabi) - export ZEPHYR_TOOLCHAIN_VARIANT to gnuarmemb and export GNUARMEMB_TOOLCHAIN_PATH to path to toolchain (e.g. ~/arm-gnu-toolchain-11.3/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/ )
- IMPORTANT: open dts/arm/ti/lm3s6965.dtsi and change flash0 reg to 256*1024*1024 (just so the image will "fit" in FLASH)
- west build -p always -b qemu_cortex_m3 samples/cpp/hello_world
- west build -t run
Output:
-- west build: running target run
[0/1] To exit from QEMU enter: 'CTRL+a, x'[QEMU] CPU: cortex-m3
qemu-system-arm: warning: nic stellaris_enet.0 has no peer
Timer with period zero, disabling
Expected behavior
Should see "Hello, C++ world!" just like with Zephyr SDK.
Impact
Annoyance...potentially a showstopper.
Logs and console output
My GDB session shows something really weird going on.
- The program gets into z_bss_zero() in kernel/init.c,
- I step into z_early_memset(__bss_start, 0, __bss_end - __bss_start);
Here's the disassembly
0x00003fbc <+0>: push {r3, lr}
0x00003fbe <+2>: ldr r0, [pc, #12] @ (0x3fcc <z_bss_zero+16>)
0x00003fc0 <+4>: ldr r2, [pc, #12] @ (0x3fd0 <z_bss_zero+20>)
0x00003fc2 <+6>: movs r1, #0
0x00003fc4 <+8>: subs r2, r2, r0
0x00003fc6 <+10>: bl 0x47b4e <z_early_memset>
0x00003fca <+14>: pop {r3, pc}
0x00003fcc <+16>: lsrs r0, r6, #31
0x00003fce <+18>: movs r0, #0
0x00003fd0 <+20>: cmp r5, #76 @ 0x4c
0x00003fd2 <+22>: movs r0, #0
- Program Counter will branch to 0x47b4e <z_early_memset>
Here's some more disassembly
00047b4e <z_early_memset>:
(void) memset(dst, c, n);
47b4e: f7f4 b9ff b.w 3bf5000047b52 <z_early_memcpy>:
(void) memcpy(dst, src, n);
47b52: f7b8 bbab b.w 2ac
This is very similar to assembly to when the Zephyr SDK is used.
5. With the Program Counter at 0x47b4e, on the next stepi instruction, instead of branching to 0x3bf50, it strangely just changes to 0x47b50...huh?!?
6. From that point on, the program counter just continues to increment by 2, as if to give no care to what the actual instructions are. Super weird.
7. I have verified 0x3bf50 is valid in memory and is the memset code (from newlib/libc.a)
Environment (please complete the following information):
- OS: Ubuntu 24.04
- Toolchain: GNU Arm Embedded Toolchain, 11.3 Release: x86_64 Linux hosted cross toolchains, AArch32 bare-metal target (arm-none-eabi)
- Commit SHA or Version used: At zephyr 62f5386
Additional context
For what it's worth, removing
std::cout << "Hello, C++ world!" << std::endl
does not fix it, but removing it and #include <iostream> does fix the problem.
I am able to do other C++ stuff, but something about iostream and/or cout with GNU Arm Toolchain and possibly memset is wrong.
I wish I knew the issue, but at this point, I'm stuck.