diff --git a/cmake/emu/qemu.cmake b/cmake/emu/qemu.cmake index 4b2cceb50fe..2378927a25b 100644 --- a/cmake/emu/qemu.cmake +++ b/cmake/emu/qemu.cmake @@ -226,8 +226,7 @@ endif(QEMU_PIPE_STACK) if(CONFIG_X86_64) # QEMU doesn't like 64-bit ELF files. Since we don't use any >4GB # addresses, converting it to 32-bit is safe enough for emulation. - set(QEMU_KERNEL_FILE "${CMAKE_BINARY_DIR}/zephyr-qemu.elf") - add_custom_target(qemu_kernel_target + add_custom_target(qemu_image_target COMMAND ${CMAKE_OBJCOPY} -O elf32-i386 @@ -235,6 +234,42 @@ if(CONFIG_X86_64) ${CMAKE_BINARY_DIR}/zephyr-qemu.elf DEPENDS ${logical_target_for_zephyr_elf} ) + + # Split the 'locore' and 'main' memory regions into separate executable + # images and specify the 'locore' as the boot kernel, in order to prevent + # the QEMU direct multiboot kernel loader from overwriting the BIOS and + # option ROM areas located in between the two memory regions. + # (for more details, refer to the issue zephyrproject-rtos/sdk-ng#168) + add_custom_target(qemu_locore_image_target + COMMAND + ${CMAKE_OBJCOPY} + -j .locore + ${CMAKE_BINARY_DIR}/zephyr-qemu.elf + ${CMAKE_BINARY_DIR}/zephyr-qemu-locore.elf + 2>&1 | grep -iv \"empty loadable segment detected\" || true + DEPENDS qemu_image_target + ) + + add_custom_target(qemu_main_image_target + COMMAND + ${CMAKE_OBJCOPY} + -R .locore + ${CMAKE_BINARY_DIR}/zephyr-qemu.elf + ${CMAKE_BINARY_DIR}/zephyr-qemu-main.elf + 2>&1 | grep -iv \"empty loadable segment detected\" || true + DEPENDS qemu_image_target + ) + + add_custom_target( + qemu_kernel_target + DEPENDS qemu_locore_image_target qemu_main_image_target + ) + + set(QEMU_KERNEL_FILE "${CMAKE_BINARY_DIR}/zephyr-qemu-locore.elf") + + list(APPEND QEMU_EXTRA_FLAGS + "-device;loader,file=${CMAKE_BINARY_DIR}/zephyr-qemu-main.elf" + ) endif() if(NOT QEMU_PIPE)