QEMU 半主机不产生输出
QEMU semihosting doesn't produce output
我正在尝试使用 QEMU 中的半主机为我的项目设置测试环境。
到目前为止,我在 之后对 hello.c
没有任何问题,但是我无法让它与 CMake 一起工作。
下面是我如何构建完全相同的 hello.c
(toolchain file on pastebin):
C:\hello_cmake>cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake . -Btmp
-- The C compiler identification is GNU 10.3.1
-- The CXX compiler identification is GNU 10.3.1
-- Configuring done
-- Generating done
-- Build files have been written to: C:/hello_cmake/tmp
C:\hello_cmake>cmake --build tmp --verbose
"C:/Program Files/CMake/bin/cmake.exe" -SC:/hello_cmake -BC:/hello_cmake/tmp --check-build-system CMakeFiles/Makefile.cmake 0
"C:/Program Files/CMake/bin/cmake.exe" -E cmake_progress_start C:/hello_cmake/tmp/CMakeFiles C:/hello_cmake/tmp//CMakeFiles/progress.marks
C:/buildtools/bin/make.exe -f CMakeFiles/Makefile2 all
make.exe[1]: Entering directory 'C:/hello_cmake/tmp'
C:/buildtools/bin/make.exe -f CMakeFiles/hello.dir/build.make CMakeFiles/hello.dir/depend
make.exe[2]: Entering directory 'C:/hello_cmake/tmp'
"C:/Program Files/CMake/bin/cmake.exe" -E cmake_depends "Unix Makefiles" C:/hello_cmake C:/hello_cmake C:/hello_cmake/tmp C:/hello_cmake/tmp C:/hello_cmake/tmp/CMakeFiles/hello.dir/DependInfo.cmake --color=
make.exe[2]: Leaving directory 'C:/hello_cmake/tmp'
C:/buildtools/bin/make.exe -f CMakeFiles/hello.dir/build.make CMakeFiles/hello.dir/build
make.exe[2]: Entering directory 'C:/hello_cmake/tmp'
[ 50%] Building C object CMakeFiles/hello.dir/hello.c.obj
"C:/Program Files (x86)/GNU Arm Embedded Toolchain/10 2021.10/bin/arm-none-eabi-gcc.exe" -specs=rdimon.specs -mcpu=cortex-a9 -O0 -g -MD -MT CMakeFiles/hello.dir/hello.c.obj -MF CMakeFiles/hello.dir/hello.c.obj.d -o CMakeFiles/hello.dir/hello.c.obj -c C:/hello_cmake/hello.c
[100%] Linking C executable hello
"C:/Program Files (x86)/GNU Arm Embedded Toolchain/10 2021.10/bin/arm-none-eabi-gcc.exe" -lc -lrdimon -lc -lrdimon "CMakeFiles/hello.dir/hello.c.obj" -o hello
make.exe[2]: Leaving directory 'C:/hello_cmake/tmp'
[100%] Built target hello
make.exe[1]: Leaving directory 'C:/hello_cmake/tmp'
"C:/Program Files/CMake/bin/cmake.exe" -E cmake_progress_start C:/hello_cmake/tmp/CMakeFiles 0
下面是我调用 QEMU 的方式:
qemu-system-arm.exe -nographic -machine xilinx-zynq-a9 -cpu cortex-a9 -monitor none -serial stdio -kernel app -m 512 -semihosting
QEMU 几乎立即退出而不产生任何输出,但是 -d exec
和 -d init
日志看起来代码是 运行 并且半主机实际上有效:
...
Trace 0: 0000000004705540 [00000400/0000828c/000005a0/ff000000] __libc_init_array
Trace 0: 0000000004705780 [00000400/000081ec/000005a0/ff000000] frame_dummy
Trace 0: 00000000047058c0 [00000400/00010460/000005a0/ff000000] main
Trace 0: 0000000004705c00 [00000400/00029158/000005a0/ff000000] printf
Trace 0: 0000000004706040 [00000400/000301f0/000005a0/ff000000] _vfprintf_r
Trace 0: 0000000004706440 [00000400/000375b8/000005a0/ff000000] _localeconv_r
Trace 0: 00000000047065c0 [00000400/0003020c/000005a0/ff000000] _vfprintf_r
Trace 0: 00000000047067c0 [00000400/0000a704/000005a0/ff000000] strlen
...
Taking exception 16 [Semihosting call] on CPU 0
...from EL1 to EL0
...handling as semihosting call 0xc
Taking exception 16 [Semihosting call] on CPU 0
...from EL1 to EL0
...handling as semihosting call 0x13
Taking exception 16 [Semihosting call] on CPU 0
...from EL1 to EL0
...handling as semihosting call 0x5
Taking exception 16 [Semihosting call] on CPU 0
...from EL1 to EL0
...
问题是:CMake 做什么(或不做什么)会破坏 printf
输出?
备案:
arm-none-eabi-gcc (GNU Arm Embedded Toolchain 10.3-2021.10)
QEMU emulator version 7.0.0 (v7.0.0-11902-g1d935f4a02-dirty)
Microsoft Windows [Version 10.0.19044.1645]
cmake version 3.22.2
我无法找到您正在使用的 CMakeLists.lst
,但我能够 produce/run hello.elf
使用以下文件:
hello.c
:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char** argv)
{
printf("Hello, World!\n");
return EXIT_SUCCESS;
}
CMakeLists.lst
:
project(hello_world)
add_executable(hello.elf hello.c)
toolchain.cmake
(删除了 -specs=rdimon.specs
,因为这是一个链接选项,对链接器使用 --specs=rdimon.specs
选项 - 不需要 -lc
,因为与使用 rdimon.specs):
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR Cortex-A9)
# Common options
add_compile_options(
-mcpu=cortex-a9
-O0
-g
)
set(CMAKE_EXE_LINKER_FLAGS "--specs=rdimon.specs")
set(CMAKE_C_COMPILER_FORCED TRUE)
set(CMAKE_CXX_COMPILER_FORCED TRUE)
find_program(CMAKE_C_COMPILER $ENV{ARMGCC_DIR}/bin/arm-none-eabi-gcc.exe)
find_program(CMAKE_CXX_COMPILER $ENV{ARMGCC_DIR}/bin/arm-none-eabi-g++.exe)
find_program(CMAKE_ASM_COMPILER $ENV{ARMGCC_DIR}/bin/arm-none-eabi-gcc.exe)
find_program(CMAKE_OBJCOPY $ENV{ARMGCC_DIR}/bin/arm-none-eabi-objcopy)
find_program(CMAKE_OBJDUMP $ENV{ARMGCC_DIR}/bin/arm-none-eabi-objdump)
find_program(CMAKE_NM $ENV{ARMGCC_DIR}/bin/arm-none-eabi-nm)
find_program(CMAKE_LINKER $ENV{ARMGCC_DIR}/bin/arm-none-eabi-ld)
build-cmake.cmd
:
@set ARMGCC_DIR=D:\opt\arm\gcc-arm-10.3-2021.07-mingw-w64-i686-arm-none-eabi
@set CMAKE=D:\opt\cmake-3.23.1-windows-x86_64\bin\cmake
@set MAKE=D:\opt\Whosebug199730\make.exe
@set QEMU_SYSTEM_ARM=D:\opt\qemu-7.0.0\qemu-system-arm
%CMAKE% -E rm -rf tmp
%CMAKE% -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake . -Btmp
%MAKE% -C tmp
%QEMU_SYSTEM_ARM% -semihosting --semihosting-config enable=on,target=native -nographic -serial mon:stdio -machine xilinx-zynq-a9 -m 768M -cpu cortex-a9 -kernel tmp\hello.elf
执行:
D:\opt\Whosebug199730>build-cmake.cmd
D:\opt\Whosebug199730>D:\opt\cmake-3.23.1-windows-x86_64\bin\cmake -E rm -rf tmp
D:\opt\Whosebug199730>D:\opt\cmake-3.23.1-windows-x86_64\bin\cmake -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake . -Btmp
-- The C compiler identification is GNU 10.3.1
-- The CXX compiler identification is GNU 10.3.1
-- Configuring done
-- Generating done
-- Build files have been written to: D:/opt/Whosebug/72199730/tmp
D:\opt\Whosebug199730>D:\opt\Whosebug199730\make.exe -C tmp
make: Entering directory 'D:/opt/Whosebug/72199730/tmp'
make[1]: Entering directory 'D:/opt/Whosebug/72199730/tmp'
make[2]: Entering directory 'D:/opt/Whosebug/72199730/tmp'
make[2]: Leaving directory 'D:/opt/Whosebug/72199730/tmp'
make[2]: Entering directory 'D:/opt/Whosebug/72199730/tmp'
[ 50%] Building C object CMakeFiles/hello.elf.dir/hello.c.obj
[100%] Linking C executable hello.elf
make[2]: Leaving directory 'D:/opt/Whosebug/72199730/tmp'
[100%] Built target hello.elf
make[1]: Leaving directory 'D:/opt/Whosebug/72199730/tmp'
make: Leaving directory 'D:/opt/Whosebug/72199730/tmp'
D:\opt\Whosebug199730>D:\opt\qemu-7.0.0\qemu-system-arm -semihosting --semihosting-config enable=on,target=native -nographic -serial mon:stdio -machine xilinx-zynq-a9 -m 768M -cpu cortex-a9 -kernel tmp\hello.elf
Hello, World!
使用的版本:
\opt\arm\gcc-arm-10.3-2021.07-mingw-w64-i686-arm-none-eabi\bin\arm-none-eabi-gcc --version
arm-none-eabi-gcc (GNU Toolchain for the A-profile Architecture 10.3-2021.07 (arm-10.29)) 10.3.1 20210621
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
\opt\cmake-3.23.1-windows-x86_64\bin\cmake.exe --version
cmake version 3.23.1
CMake suite maintained and supported by Kitware (kitware.com/cmake).
D:\opt\Whosebug199730>\opt\qemu-7.0.0\qemu-system-arm.exe --version
QEMU emulator version 7.0.0 (v7.0.0-11902-g1d935f4a02-dirty)
Copyright (c) 2003-2022 Fabrice Bellard and the QEMU Project developers
make --version
GNU Make 4.2.1
Built for x86_64-w64-mingw32
Copyright (C) 1988-2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
wmic os get version
Version
10.0.19044
我正在尝试使用 QEMU 中的半主机为我的项目设置测试环境。
到目前为止,我在 hello.c
没有任何问题,但是我无法让它与 CMake 一起工作。
下面是我如何构建完全相同的 hello.c
(toolchain file on pastebin):
C:\hello_cmake>cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake . -Btmp
-- The C compiler identification is GNU 10.3.1
-- The CXX compiler identification is GNU 10.3.1
-- Configuring done
-- Generating done
-- Build files have been written to: C:/hello_cmake/tmp
C:\hello_cmake>cmake --build tmp --verbose
"C:/Program Files/CMake/bin/cmake.exe" -SC:/hello_cmake -BC:/hello_cmake/tmp --check-build-system CMakeFiles/Makefile.cmake 0
"C:/Program Files/CMake/bin/cmake.exe" -E cmake_progress_start C:/hello_cmake/tmp/CMakeFiles C:/hello_cmake/tmp//CMakeFiles/progress.marks
C:/buildtools/bin/make.exe -f CMakeFiles/Makefile2 all
make.exe[1]: Entering directory 'C:/hello_cmake/tmp'
C:/buildtools/bin/make.exe -f CMakeFiles/hello.dir/build.make CMakeFiles/hello.dir/depend
make.exe[2]: Entering directory 'C:/hello_cmake/tmp'
"C:/Program Files/CMake/bin/cmake.exe" -E cmake_depends "Unix Makefiles" C:/hello_cmake C:/hello_cmake C:/hello_cmake/tmp C:/hello_cmake/tmp C:/hello_cmake/tmp/CMakeFiles/hello.dir/DependInfo.cmake --color=
make.exe[2]: Leaving directory 'C:/hello_cmake/tmp'
C:/buildtools/bin/make.exe -f CMakeFiles/hello.dir/build.make CMakeFiles/hello.dir/build
make.exe[2]: Entering directory 'C:/hello_cmake/tmp'
[ 50%] Building C object CMakeFiles/hello.dir/hello.c.obj
"C:/Program Files (x86)/GNU Arm Embedded Toolchain/10 2021.10/bin/arm-none-eabi-gcc.exe" -specs=rdimon.specs -mcpu=cortex-a9 -O0 -g -MD -MT CMakeFiles/hello.dir/hello.c.obj -MF CMakeFiles/hello.dir/hello.c.obj.d -o CMakeFiles/hello.dir/hello.c.obj -c C:/hello_cmake/hello.c
[100%] Linking C executable hello
"C:/Program Files (x86)/GNU Arm Embedded Toolchain/10 2021.10/bin/arm-none-eabi-gcc.exe" -lc -lrdimon -lc -lrdimon "CMakeFiles/hello.dir/hello.c.obj" -o hello
make.exe[2]: Leaving directory 'C:/hello_cmake/tmp'
[100%] Built target hello
make.exe[1]: Leaving directory 'C:/hello_cmake/tmp'
"C:/Program Files/CMake/bin/cmake.exe" -E cmake_progress_start C:/hello_cmake/tmp/CMakeFiles 0
下面是我调用 QEMU 的方式:
qemu-system-arm.exe -nographic -machine xilinx-zynq-a9 -cpu cortex-a9 -monitor none -serial stdio -kernel app -m 512 -semihosting
QEMU 几乎立即退出而不产生任何输出,但是 -d exec
和 -d init
日志看起来代码是 运行 并且半主机实际上有效:
...
Trace 0: 0000000004705540 [00000400/0000828c/000005a0/ff000000] __libc_init_array
Trace 0: 0000000004705780 [00000400/000081ec/000005a0/ff000000] frame_dummy
Trace 0: 00000000047058c0 [00000400/00010460/000005a0/ff000000] main
Trace 0: 0000000004705c00 [00000400/00029158/000005a0/ff000000] printf
Trace 0: 0000000004706040 [00000400/000301f0/000005a0/ff000000] _vfprintf_r
Trace 0: 0000000004706440 [00000400/000375b8/000005a0/ff000000] _localeconv_r
Trace 0: 00000000047065c0 [00000400/0003020c/000005a0/ff000000] _vfprintf_r
Trace 0: 00000000047067c0 [00000400/0000a704/000005a0/ff000000] strlen
...
Taking exception 16 [Semihosting call] on CPU 0
...from EL1 to EL0
...handling as semihosting call 0xc
Taking exception 16 [Semihosting call] on CPU 0
...from EL1 to EL0
...handling as semihosting call 0x13
Taking exception 16 [Semihosting call] on CPU 0
...from EL1 to EL0
...handling as semihosting call 0x5
Taking exception 16 [Semihosting call] on CPU 0
...from EL1 to EL0
...
问题是:CMake 做什么(或不做什么)会破坏 printf
输出?
备案:
arm-none-eabi-gcc (GNU Arm Embedded Toolchain 10.3-2021.10)
QEMU emulator version 7.0.0 (v7.0.0-11902-g1d935f4a02-dirty)
Microsoft Windows [Version 10.0.19044.1645]
cmake version 3.22.2
我无法找到您正在使用的 CMakeLists.lst
,但我能够 produce/run hello.elf
使用以下文件:
hello.c
:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char** argv)
{
printf("Hello, World!\n");
return EXIT_SUCCESS;
}
CMakeLists.lst
:
project(hello_world)
add_executable(hello.elf hello.c)
toolchain.cmake
(删除了 -specs=rdimon.specs
,因为这是一个链接选项,对链接器使用 --specs=rdimon.specs
选项 - 不需要 -lc
,因为与使用 rdimon.specs):
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR Cortex-A9)
# Common options
add_compile_options(
-mcpu=cortex-a9
-O0
-g
)
set(CMAKE_EXE_LINKER_FLAGS "--specs=rdimon.specs")
set(CMAKE_C_COMPILER_FORCED TRUE)
set(CMAKE_CXX_COMPILER_FORCED TRUE)
find_program(CMAKE_C_COMPILER $ENV{ARMGCC_DIR}/bin/arm-none-eabi-gcc.exe)
find_program(CMAKE_CXX_COMPILER $ENV{ARMGCC_DIR}/bin/arm-none-eabi-g++.exe)
find_program(CMAKE_ASM_COMPILER $ENV{ARMGCC_DIR}/bin/arm-none-eabi-gcc.exe)
find_program(CMAKE_OBJCOPY $ENV{ARMGCC_DIR}/bin/arm-none-eabi-objcopy)
find_program(CMAKE_OBJDUMP $ENV{ARMGCC_DIR}/bin/arm-none-eabi-objdump)
find_program(CMAKE_NM $ENV{ARMGCC_DIR}/bin/arm-none-eabi-nm)
find_program(CMAKE_LINKER $ENV{ARMGCC_DIR}/bin/arm-none-eabi-ld)
build-cmake.cmd
:
@set ARMGCC_DIR=D:\opt\arm\gcc-arm-10.3-2021.07-mingw-w64-i686-arm-none-eabi
@set CMAKE=D:\opt\cmake-3.23.1-windows-x86_64\bin\cmake
@set MAKE=D:\opt\Whosebug199730\make.exe
@set QEMU_SYSTEM_ARM=D:\opt\qemu-7.0.0\qemu-system-arm
%CMAKE% -E rm -rf tmp
%CMAKE% -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake . -Btmp
%MAKE% -C tmp
%QEMU_SYSTEM_ARM% -semihosting --semihosting-config enable=on,target=native -nographic -serial mon:stdio -machine xilinx-zynq-a9 -m 768M -cpu cortex-a9 -kernel tmp\hello.elf
执行:
D:\opt\Whosebug199730>build-cmake.cmd
D:\opt\Whosebug199730>D:\opt\cmake-3.23.1-windows-x86_64\bin\cmake -E rm -rf tmp
D:\opt\Whosebug199730>D:\opt\cmake-3.23.1-windows-x86_64\bin\cmake -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake . -Btmp
-- The C compiler identification is GNU 10.3.1
-- The CXX compiler identification is GNU 10.3.1
-- Configuring done
-- Generating done
-- Build files have been written to: D:/opt/Whosebug/72199730/tmp
D:\opt\Whosebug199730>D:\opt\Whosebug199730\make.exe -C tmp
make: Entering directory 'D:/opt/Whosebug/72199730/tmp'
make[1]: Entering directory 'D:/opt/Whosebug/72199730/tmp'
make[2]: Entering directory 'D:/opt/Whosebug/72199730/tmp'
make[2]: Leaving directory 'D:/opt/Whosebug/72199730/tmp'
make[2]: Entering directory 'D:/opt/Whosebug/72199730/tmp'
[ 50%] Building C object CMakeFiles/hello.elf.dir/hello.c.obj
[100%] Linking C executable hello.elf
make[2]: Leaving directory 'D:/opt/Whosebug/72199730/tmp'
[100%] Built target hello.elf
make[1]: Leaving directory 'D:/opt/Whosebug/72199730/tmp'
make: Leaving directory 'D:/opt/Whosebug/72199730/tmp'
D:\opt\Whosebug199730>D:\opt\qemu-7.0.0\qemu-system-arm -semihosting --semihosting-config enable=on,target=native -nographic -serial mon:stdio -machine xilinx-zynq-a9 -m 768M -cpu cortex-a9 -kernel tmp\hello.elf
Hello, World!
使用的版本:
\opt\arm\gcc-arm-10.3-2021.07-mingw-w64-i686-arm-none-eabi\bin\arm-none-eabi-gcc --version
arm-none-eabi-gcc (GNU Toolchain for the A-profile Architecture 10.3-2021.07 (arm-10.29)) 10.3.1 20210621
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
\opt\cmake-3.23.1-windows-x86_64\bin\cmake.exe --version
cmake version 3.23.1
CMake suite maintained and supported by Kitware (kitware.com/cmake).
D:\opt\Whosebug199730>\opt\qemu-7.0.0\qemu-system-arm.exe --version
QEMU emulator version 7.0.0 (v7.0.0-11902-g1d935f4a02-dirty)
Copyright (c) 2003-2022 Fabrice Bellard and the QEMU Project developers
make --version
GNU Make 4.2.1
Built for x86_64-w64-mingw32
Copyright (C) 1988-2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
wmic os get version
Version
10.0.19044