瀏覽代碼

Kernel: Build the x86_64 kernel as an ELF32 executable

Multiboot only supports ELF32 executables. This changes the build
process to build an ELF32 executable which has a 32-bit entry point,
but consists of mostly 64-bit code.
Gunnar Beutner 4 年之前
父節點
當前提交
c9747a3236
共有 3 個文件被更改,包括 37 次插入11 次删除
  1. 21 8
      Kernel/CMakeLists.txt
  2. 6 1
      Kernel/mkmap.sh
  3. 10 2
      Meta/debug-kernel.sh

+ 21 - 8
Kernel/CMakeLists.txt

@@ -387,22 +387,35 @@ else()
     link_directories(${TOOLCHAIN_ROOT}/Kernel/lib/gcc/${SERENITY_ARCH}-pc-serenity/${GCC_VERSION}/)
     link_directories(${TOOLCHAIN_ROOT}/Kernel/lib/gcc/${SERENITY_ARCH}-pc-serenity/${GCC_VERSION}/)
 endif()
 endif()
 
 
-add_executable(Kernel ${SOURCES})
-add_dependencies(Kernel generate_EscapeSequenceStateMachine.h)
+if ("${SERENITY_ARCH}" STREQUAL "i686")
+    set(KERNEL_TARGET Kernel32)
+else()
+    set(KERNEL_TARGET Kernel64)
+endif()
+
+add_executable(${KERNEL_TARGET} ${SOURCES})
+add_dependencies(${KERNEL_TARGET} generate_EscapeSequenceStateMachine.h)
 
 
-set_target_properties(Kernel PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld)
+set_target_properties(${KERNEL_TARGET} PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld)
 
 
 if (ENABLE_KERNEL_LTO)
 if (ENABLE_KERNEL_LTO)
     include(CheckIPOSupported)
     include(CheckIPOSupported)
     check_ipo_supported()
     check_ipo_supported()
-    set_property(TARGET Kernel PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
+    set_property(TARGET ${KERNEL_TARGET} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
 endif()
 endif()
-target_link_libraries(Kernel kernel_heap gcc supc++)
-add_dependencies(Kernel kernel_heap)
-install(TARGETS Kernel RUNTIME DESTINATION boot)
+target_link_libraries(${KERNEL_TARGET} kernel_heap gcc supc++)
+add_dependencies(${KERNEL_TARGET} kernel_heap)
+
+add_custom_command(
+    TARGET ${KERNEL_TARGET} POST_BUILD
+    COMMAND ${TOOLCHAIN_PREFIX}objcopy -O elf32-i386 ${CMAKE_CURRENT_BINARY_DIR}/${KERNEL_TARGET} ${CMAKE_CURRENT_BINARY_DIR}/Kernel
+    BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/Kernel
+)
+
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/Kernel" DESTINATION boot)
 
 
 add_custom_command(
 add_custom_command(
-    TARGET Kernel
+    TARGET ${KERNEL_TARGET} POST_BUILD
     COMMAND sh ${CMAKE_CURRENT_SOURCE_DIR}/mkmap.sh
     COMMAND sh ${CMAKE_CURRENT_SOURCE_DIR}/mkmap.sh
 )
 )
 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/kernel.map DESTINATION res)
 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/kernel.map DESTINATION res)

+ 6 - 1
Kernel/mkmap.sh

@@ -1,6 +1,11 @@
 #!/bin/sh
 #!/bin/sh
 tmp=$(mktemp)
 tmp=$(mktemp)
-nm -n Kernel | awk '{ if ($2 != "a") print; }' | uniq > "$tmp"
+if [ -f Kernel32 ]; then
+    kernel_binary=Kernel32
+else
+    kernel_binary=Kernel64
+fi
+nm -n $kernel_binary | awk '{ if ($2 != "a") print; }' | uniq > "$tmp"
 printf "%08x\n" "$(wc -l "$tmp" | cut -f1 -d' ')" > kernel.map
 printf "%08x\n" "$(wc -l "$tmp" | cut -f1 -d' ')" > kernel.map
 cat "$tmp" >> kernel.map
 cat "$tmp" >> kernel.map
 rm -f "$tmp"
 rm -f "$tmp"

+ 10 - 2
Meta/debug-kernel.sh

@@ -8,9 +8,17 @@
 # remote on localhost:1234. So point our debugger there, and inform
 # remote on localhost:1234. So point our debugger there, and inform
 # the debugger which binary to load symbols, etc from.
 # the debugger which binary to load symbols, etc from.
 #
 #
+if [ "$SERENITY_ARCH" = "x86_64" ]; then
+    gdb_arch=i386:x86-64
+    kernel_binary=Kernel64
+else
+    gdb_arch=i386:intel
+    kernel_binary=Kernel
+fi
+
 exec $SERENITY_KERNEL_DEBUGGER \
 exec $SERENITY_KERNEL_DEBUGGER \
-    -ex "file $(dirname "$0")/../Build/${SERENITY_ARCH:-i686}/Kernel/Kernel" \
-    -ex 'set arch i386:intel' \
+    -ex "file $(dirname "$0")/../Build/${SERENITY_ARCH:-i686}/Kernel/$kernel_binary" \
+    -ex "set arch $gdb_arch" \
     -ex 'target remote localhost:1234' \
     -ex 'target remote localhost:1234' \
     -ex "source $(dirname "$0")/serenity_gdb.py" \
     -ex "source $(dirname "$0")/serenity_gdb.py" \
     "$@"
     "$@"