Commit f5c1533d authored by Florian Lukas's avatar Florian Lukas

arch/i386: split Bochs, QEMU, Grub CMakeFiles

- ADDITIONAL_TARGETS changed to a list for flexibility
- more checks/flexibility with find_program
- separate, correct gdbinit file for QEMU
- debugger, RAM, gdbstub port configurable
- build .iso files only when needed and with correct path
- nogui bochs config

Change-Id: I396ad782d7e47b3c6636123d930390b204d275a6
parent 2120be1d
......@@ -29,6 +29,15 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ISA_CXX_FLAGS} ${CMAKE_C_FLAGS} -fno-
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} ${ISA_ASM_FLAGS}")
message(STATUS "[${PROJECT_NAME}] Assembler flags: ${ISA_ASM_FLAGS}")
# Find python
find_program(PYTHON "python")
if(NOT PYTHON)
message(ERROR "[${PROJECT_NAME}] Python not found!")
endif()
# Variable for additional targets
set(ADDITIONAL_TARGETS "" CACHE INTERNAL STRING)
include(helpers)
# Include source directory
......@@ -54,12 +63,10 @@ add_subdirectory(os)
# Platform specific custom targets/commands.
# Must be included after add_executable, as they depend on the main target.
if(ADDITIONAL_TARGETS)
message(STATUS "[${PROJECT_NAME}] Preparing addtional targets: ${ADDITIONAL_TARGETS}")
add_subdirectory(${ADDITIONAL_TARGETS})
else()
message(STATUS "[${PROJECT_NAME}]No additional targets found.")
endif()
foreach(TARGETS ${ADDITIONAL_TARGETS})
message(STATUS "[${PROJECT_NAME}] Preparing addtional targets: ${TARGETS}")
add_subdirectory(${TARGETS})
endforeach()
# Static analysis (oclint/clang-static-analyzer
# Find all sources for code cccc metrics.
......
# (Emulated) RAM size
set(RAM_SIZE "16" CACHE STRING "(Emulated) RAM size in MB")
OPTION(X86_TARGET_FAIL "FailBochs" ON)
# Debugger to use
find_program(DEBUGGER "gdb" DOC "Debugger (gdb/ddd)")
if(X86_TARGET_FAIL)
message(STATUS "Target i386 fail")
set(ADDITIONAL_TARGETS "${CMAKE_CURRENT_SOURCE_DIR}/failbochs" CACHE INTERNAL STRING)
endif()
# (Random) port for debugging
string(RANDOM LENGTH 4 ALPHABET "123456789" DPORT)
set(DEBUG_PORT ${DPORT} CACHE STRING "Debug (stub) port")
message(STATUS "[${PROJECT_NAME}] Using port ${DEBUG_PORT} for debug stub")
# Enable emulators
OPTION(X86_TARGET_BOCHS "Bochs" ON)
OPTION(X86_TARGET_QEMU "QEMU" ON)
if(X86_TARGET_BOCHS OR X86_TARGET_QEMU)
set(ADDITIONAL_TARGETS ${ADDITIONAL_TARGETS}
${CMAKE_CURRENT_SOURCE_DIR}/grub CACHE INTERNAL STRING)
endif()
if(X86_TARGET_BOCHS)
message(STATUS "Target i386 Bochs")
set(ADDITIONAL_TARGETS ${ADDITIONAL_TARGETS}
${CMAKE_CURRENT_SOURCE_DIR}/bochs CACHE INTERNAL STRING)
endif()
if(X86_TARGET_QEMU)
message(STATUS "Target i386 QEMU")
set(ADDITIONAL_TARGETS ${ADDITIONAL_TARGETS}
${CMAKE_CURRENT_SOURCE_DIR}/qemu CACHE INTERNAL STRING)
endif()
# setup x86-32 specific sources
set(SRCS
startup.cc
startup.s
cga.cc
serial.cc
startup.cc
startup.s
cga.cc
serial.cc
)
add_library(arch ${SRCS})
......
# Get bochs binary
find_program(BOCHS "bochs")
if(NOT BOCHS)
message(WARNING "[${PROJECT_NAME}] No bochs found, not generating bochs targets!")
return()
endif()
# Create additional targets for all executables
foreach(ELF ${EXECUTABLES})
# Do not suffix targets for main executable
if(${ELF} STREQUAL ${ELFFILE})
set(SUFFIX "")
set(DSUFFIX "")
else()
GET_FILENAME_COMPONENT(SUFFIX ${ELF} NAME_WE)
set(DSUFFIX "-${SUFFIX}")
endif()
get_target_property(ELF_ABS ${ELF} LOCATION)
set(ISOFILE "${ELF_ABS}.iso")
# Bochs
set(BOCHS_BIOS "${CMAKE_CURRENT_SOURCE_DIR}/BIOS-bochs-latest")
set(BOCHS_GUEST_RAM ${RAM_SIZE})
set(BOCHS_HOST_RAM ${RAM_SIZE})
set(BOCHS_VGA_IMAGE "${CMAKE_CURRENT_SOURCE_DIR}/vgabios.bin")
set(BOCHS_ISO_IMAGE "${ISOFILE}")
set(STARTUP_SCRIPTS ${PROJECT_BINARY_DIR}/startup_scripts)
file(MAKE_DIRECTORY ${STARTUP_SCRIPTS})
set(BOCHSRC "${STARTUP_SCRIPTS}/bochsrc${DSUFFIX}")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bochsrc.in" ${BOCHSRC} )
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bochsrc-gdb.in" "${BOCHSRC}-gdb" )
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bochsrc-term.in" "${BOCHSRC}-term" )
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bochsrc-nogui.in" "${BOCHSRC}-nogui" )
# GDB init file
set(GDBINITFILE ${STARTUP_SCRIPTS}/${SUFFIX}.gdbinit)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/gdbinit.in" ${GDBINITFILE})
# Start bochs
add_custom_target(run${DSUFFIX}
DEPENDS iso${DSUFFIX} ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ISOFILE} in Bochs."
COMMAND ${BOCHS} -f ${BOCHSRC}
)
# Start bochs in terminal (for ssh)
add_custom_target(runterm${DSUFFIX}
DEPENDS iso${DSUFFIX} ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ISOFILE} in Bochs term mode"
COMMAND ${BOCHS} -f ${BOCHSRC}-term
)
# Start bochs with GDB stub for debugging
add_custom_target(debug${DSUFFIX}
DEPENDS iso${DSUFFIX} ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ISOFILE} in Bochs with gdb"
COMMAND ${BOCHS} -f ${BOCHSRC}-gdb
)
# Start debugger attach to bochs
add_custom_target(debugger${DSUFFIX}
DEPENDS iso${DSUFFIX} ${ELF}
COMMENT "Starting debugger for ${ISOFILE}..."
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
COMMAND ${DEBUGGER} -n -x ${GDBINITFILE} $<TARGET_FILE:${ELF}>
)
endforeach()
......@@ -880,7 +880,7 @@ i440fxsupport: enabled=1
# Enable GDB stub. See user documentation for details.
# Default value is enabled=0.
#=======================================================================
gdbstub: enabled=1, port=1234, text_base=0, data_base=0, bss_base=0
gdbstub: enabled=1, port=@DEBUG_PORT@, text_base=0, data_base=0, bss_base=0
#=======================================================================
# PLUGIN_CTRL:
......
This diff is collapsed.
file @ELF@
set archi i386:x64-32:intel
target remote localhost:1234
target remote localhost:@DEBUG_PORT@
define pe
printf "[vc] %u - [B] %u - [D] %u %% [A] %u = %u (rem %u)\n", $arg0.vc, $arg0.B, $arg0.D, $arg0.A, (($arg0.vc - $arg0.B - $arg0.D) / $arg0.A), (($arg0.vc - $arg0.B - $arg0.D) % $arg0.A)
# Create additional targets for all executables
foreach(ELF ${EXECUTABLES})
set(FAIL_BINARY "Fail binary not set yet :(" CACHE STRING "Fail binary")
# Do not suffix targets for main executable
if(${ELF} STREQUAL ${ELFFILE})
set(SUFFIX "")
set(DSUFFIX "")
else()
GET_FILENAME_COMPONENT(SUFFIX ${ELF} NAME_WE)
set(DSUFFIX "-${SUFFIX}")
endif()
set(ISOFILE "${PROJECT_BINARY_DIR}/${ELF}.iso")
# Bochs
set(BOCHS_BIOS "${CMAKE_CURRENT_SOURCE_DIR}/BIOS-bochs-latest")
set(BOCHS_GUEST_RAM 32)
set(BOCHS_HOST_RAM 32)
set(BOCHS_VGA_IMAGE "${CMAKE_CURRENT_SOURCE_DIR}/vgabios.bin")
set(BOCHS_ISO_IMAGE "${ISOFILE}")
set(STARTUP_SCRIPTS ${PROJECT_BINARY_DIR}/startup_scripts)
file(MAKE_DIRECTORY ${STARTUP_SCRIPTS})
set(BOCHSRC "${STARTUP_SCRIPTS}/bochsrc${DSUFFIX}")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bochsrc.in" ${BOCHSRC} )
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bochsrc-gdb.in" "${BOCHSRC}-gdb" )
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bochsrc-term.in" "${BOCHSRC}-term" )
set(GDBINITFILE ${STARTUP_SCRIPTS}/${SUFFIX}.gdbinit)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/gdbinit.in" ${GDBINITFILE})
# Grub
find_program(GRUB_MKRESCUE "grub-mkrescue")
if(NOT GRUB_MKRESCUE)
message(FATAL_ERROR "grub-mkrescue not found, cannot create bootable iso :(")
endif()
set(ISODIR "${PROJECT_BINARY_DIR}/grub_iso")
message(STATUS "[${PROJECT_NAME}] Building bootable ISO for ${ELF}")
# Generate build directory for grub-mkrescue
set(BOOTDIR "${ISODIR}/boot/")
set(GRUBDIR "${BOOTDIR}/grub")
file(MAKE_DIRECTORY ${GRUBDIR})
# Copy and configure grub configuration file
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/grub.cfg.in" "${GRUBDIR}/grub.cfg")
# Create bootable ISO from ELF
add_custom_command(
DEPENDS ${ELF}
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${ELF}> ${BOOTDIR}/${ELFFILE}
COMMAND ${GRUB_MKRESCUE}
ARGS -o ${ISOFILE} ${ISODIR}
OUTPUT ${ISOFILE} ${BOOTDIR}/${ELF}
)
# Create bootable ISO
add_custom_target( grubiso${DSUFFIX}
DEPENDS ${ISOFILE}
COMMENT "[${PROJECT_NAME}] Generating bootable grub iso."
)
# Start FAIL
add_custom_target( fail${DSUFFIX}
COMMAND FAIL_ELF_PATH=$<TARGET_FILE:${ELF}> ${FAIL_BINARY} -f ${BOCHSRC}${DSUFFIX} -q
DEPENDS ${ISOFILE}
COMMENT "[${PROJECT_NAME}] Starting Fail*"
)
# Start qemu
add_custom_target(qrun${DSUFFIX}
DEPENDS ${ISOFILE} ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ISOFILE} in qemu-system-i386"
COMMAND qemu-system-i386 -cdrom ${ISOFILE} -no-reboot
)
# Start qemu in terminal (for ssh)
add_custom_target(qrunterm${DSUFFIX}
DEPENDS ${ISOFILE} ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ISOFILE} in qemu-system-i386 curses mode"
COMMAND qemu-system-i386 -cdrom ${ISOFILE} -display curses -no-reboot
)
# Start qemu for tests (only serial console)
add_custom_target(qtest${DSUFFIX}
DEPENDS ${ISOFILE} ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ISOFILE} in qemu-system-i386 no graphic mode."
COMMAND qemu-system-i386 -cdrom ${ISOFILE} -nographic -no-reboot
)
# Start qemu and attach debugger
add_custom_target(qdebug${DSUFFIX}
DEPENDS ${ISOFILE} ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ISOFILE} in qemu-system-i386 debug mode. "
COMMAND qemu-system-i386 -cdrom ${ISOFILE} -s -S -no-reboot &
ddd $<TARGET_FILE:${ELF}>
)
# Start bochs
add_custom_target(run${DSUFFIX}
DEPENDS ${ISOFILE} ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ISOFILE} in Bochs."
COMMAND bochs -f ${BOCHSRC}
)
# Start bochs in terminal (for ssh)
add_custom_target(runterm${DSUFFIX}
DEPENDS ${ISOFILE} ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ISOFILE} in Bochs term mode"
COMMAND bochs -f ${BOCHSRC}-term
)
# Start bochs with GDB stub for debugging
add_custom_target(debug${DSUFFIX}
DEPENDS ${ISOFILE} ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ISOFILE} in Bochs with gdb"
COMMAND bochs -f ${BOCHSRC}-gdb
)
# Start GDB and attach to bochs
add_custom_target(gdb${DSUFFIX}
DEPENDS ${ISOFILE} ${ELF}
COMMENT "Starting gdb for ${ISOFILE}..."
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
COMMAND gdb -n -x ${GDBINITFILE}
)
endforeach()
# Create additional targets for all executables
foreach(ELF ${EXECUTABLES})
# Do not suffix targets for main executable
if(${ELF} STREQUAL ${ELFFILE})
set(SUFFIX "")
set(DSUFFIX "")
else()
GET_FILENAME_COMPONENT(SUFFIX ${ELF} NAME_WE)
set(DSUFFIX "-${SUFFIX}")
endif()
get_target_property(ELF_ABS ${ELF} LOCATION)
set(ISOFILE "${ELF_ABS}.iso")
set(STARTUP_SCRIPTS ${PROJECT_BINARY_DIR}/startup_scripts)
file(MAKE_DIRECTORY ${STARTUP_SCRIPTS})
# Grub
find_program(GRUB_MKRESCUE "grub-mkrescue")
if(NOT GRUB_MKRESCUE)
message(FATAL_ERROR "grub-mkrescue not found, cannot create bootable iso :(")
endif()
set(ISODIR "${PROJECT_BINARY_DIR}/grub_iso")
message(STATUS "[${PROJECT_NAME}] Building bootable ISO for ${ELF}")
# Generate build directory for grub-mkrescue
set(BOOTDIR "${ISODIR}/boot/")
set(GRUBDIR "${BOOTDIR}/grub")
file(MAKE_DIRECTORY ${GRUBDIR})
# Copy and configure grub configuration file
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/grub.cfg.in" "${GRUBDIR}/grub.cfg")
# Create bootable ISO from ELF
add_custom_command(
DEPENDS ${ELF}
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${ELF}> ${BOOTDIR}/${ELFFILE}
COMMAND ${GRUB_MKRESCUE} -o ${ISOFILE} ${ISODIR}
COMMENT "[${PROJECT_NAME}] Generating bootable grub iso."
OUTPUT ${ISOFILE}
)
# Create bootable ISO
add_custom_target(iso${DSUFFIX}
DEPENDS ${ISOFILE}
)
endforeach()
# Get QEMU binary
find_program(QEMU "qemu-system-i386")
if(NOT QEMU)
message(WARNING "[${PROJECT_NAME} No QEMU found, not generating QEMU targets!")
return()
endif()
# Create additional targets for all executables
foreach(ELF ${EXECUTABLES})
# Do not suffix targets for main executable
if(${ELF} STREQUAL ${ELFFILE})
set(SUFFIX "")
set(DSUFFIX "")
else()
GET_FILENAME_COMPONENT(SUFFIX ${ELF} NAME_WE)
set(DSUFFIX "-${SUFFIX}")
endif()
get_target_property(ELF_ABS ${ELF} LOCATION)
set(ISOFILE "${ELF_ABS}.iso")
set(STARTUP_SCRIPTS ${PROJECT_BINARY_DIR}/startup_scripts)
file(MAKE_DIRECTORY ${STARTUP_SCRIPTS})
# GDB init file
set(GDBINITFILE ${STARTUP_SCRIPTS}/${SUFFIX}.qemu.gdbinit)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/gdbinit.in" ${GDBINITFILE})
# Common arguments
set(QEMU_ARGS -cdrom ${ISOFILE} -no-reboot -m ${RAM_SIZE})
# Start QEMU
add_custom_target(qrun${DSUFFIX}
DEPENDS iso${DSUFFIX} ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ISOFILE} in qemu-system-i386"
COMMAND ${QEMU} ${QEMU_ARGS}
)
# Start qemu in terminal (for ssh)
add_custom_target(qrunterm${DSUFFIX}
DEPENDS iso${DSUFFIX} ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ISOFILE} in qemu-system-i386 curses mode"
COMMAND ${QEMU} ${QEMU_ARGS} -display curses
)
# Start qemu for tests (only serial console)
add_custom_target(qtest${DSUFFIX}
DEPENDS iso${DSUFFIX} ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ISOFILE} in qemu-system-i386 no graphic mode."
COMMAND ${QEMU} ${QEMU_ARGS} -nographic
)
# Start qemu and attach debugger
add_custom_target(qdebug${DSUFFIX}
DEPENDS iso${DSUFFIX} ${ELF}
COMMENT "[${PROJECT_NAME}] Running ${ISOFILE} in qemu-system-i386 debug mode. "
COMMAND ${QEMU} ${QEMU_ARGS} -gdb tcp::${DEBUG_PORT} -S &
${DEBUGGER} -n -x ${GDBINITFILE} $<TARGET_FILE:${ELF}>
)
endforeach()
file @ELF@
target remote localhost:@DEBUG_PORT@
define pe
printf "[vc] %u - [B] %u - [D] %u %% [A] %u = %u (rem %u)\n", $arg0.vc, $arg0.B, $arg0.D, $arg0.A, (($arg0.vc - $arg0.B - $arg0.D) / $arg0.A), (($arg0.vc - $arg0.B - $arg0.D) % $arg0.A)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment