x86: intel64: Split 'locore' and 'main' kernel images for QEMU
This commit splits the 'locore' and 'main' memory regions into separate executable images and specifies 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. The Zephyr x86-64 kernel image consists of two discontiguous load memory regions: 'locore' at 0x8000 and 'main' at 0x100000, but the QEMU treats these as single contiguous memory region starting at 0x8000 and ending at (0x100000 + MAIN_IMAGE_SIZE - 1). This results in the direct multiboot kernel loader overwriting the BIOS and option ROM areas as part of the kernel loading process, and causes any writable system regions to be corrupted (e.g. KVMVAPIC ROM). By splitting the two discontiguous memory regions into separate images and specifying only the boot image (i.e. 'locore') as the '-kernel', it is possible to work around the QEMU direct kernel loading design limitation. This workaround is required to support the QEMU v4.2.0 and above. For more details, refer to the issue zephyrproject-rtos/sdk-ng#168. Signed-off-by: Stephanos Ioannidis <root@stephanos.io>
This commit is contained in:
parent
5e54a8f1c4
commit
04e874485b
1 changed files with 37 additions and 2 deletions
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue