From 72365841320b9677017ba1667d7cf243f0e01b1f Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Wed, 14 Jul 2021 21:04:18 +0200 Subject: [PATCH] Kernel: Make kernel symbols available much earlier in the boot process This adds a new section .ksyms at the end of the linker map, reserves 5MiB for it (which are after end_of_kernel_image so they get re-used once MemoryManager is initialized) and then embeds the symbol map into the kernel binary with objcopy. This also shrinks the .ksyms section to the real size of the symbol file (around 900KiB at the moment). By doing this we can make the symbol map available much earlier in the boot process, i.e. even before VFS is available. --- Kernel/CMakeLists.txt | 11 ++++------- Kernel/KSyms.cpp | 20 +++++++++++--------- Kernel/embedmap.sh | 5 +++++ Kernel/init.cpp | 4 ++-- Kernel/linker.ld | 6 ++++++ 5 files changed, 28 insertions(+), 18 deletions(-) create mode 100644 Kernel/embedmap.sh diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index e7f8b5eb955..d432da99806 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -414,16 +414,13 @@ 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 + COMMAND sh ${CMAKE_CURRENT_SOURCE_DIR}/mkmap.sh + COMMAND sh ${CMAKE_CURRENT_SOURCE_DIR}/embedmap.sh + BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/Kernel ${CMAKE_CURRENT_BINARY_DIR}/kernel.map ) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/Kernel" DESTINATION boot) - -add_custom_command( - TARGET ${KERNEL_TARGET} POST_BUILD - 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) serenity_install_headers(Kernel) serenity_install_sources(Kernel) diff --git a/Kernel/KSyms.cpp b/Kernel/KSyms.cpp index 5ee477829d3..f4444354cb9 100644 --- a/Kernel/KSyms.cpp +++ b/Kernel/KSyms.cpp @@ -18,6 +18,10 @@ FlatPtr g_lowest_kernel_symbol_address = 0xffffffff; FlatPtr g_highest_kernel_symbol_address = 0; bool g_kernel_symbols_available = false; +extern "C" { +__attribute__((section(".kernel_symbols"))) char kernel_symbols[5 * MiB] {}; +} + static KernelSymbol* s_symbols; static size_t s_symbol_count = 0; @@ -50,7 +54,7 @@ const KernelSymbol* symbolicate_kernel_address(FlatPtr address) return nullptr; } -UNMAP_AFTER_INIT static void load_kernel_symbols_from_data(const KBuffer& buffer) +UNMAP_AFTER_INIT static void load_kernel_symbols_from_data(ReadonlyBytes const& buffer) { g_lowest_kernel_symbol_address = 0xffffffff; g_highest_kernel_symbol_address = 0; @@ -68,7 +72,7 @@ UNMAP_AFTER_INIT static void load_kernel_symbols_from_data(const KBuffer& buffer size_t current_symbol_index = 0; - while (bufptr < buffer.end_pointer()) { + while ((u8 const*)bufptr < buffer.data() + buffer.size()) { for (size_t i = 0; i < 8; ++i) address = (address << 4) | parse_hex_digit(*(bufptr++)); bufptr += 3; @@ -166,13 +170,11 @@ void dump_backtrace() UNMAP_AFTER_INIT void load_kernel_symbol_table() { - auto result = VirtualFileSystem::the().open("/res/kernel.map", O_RDONLY, 0, VirtualFileSystem::the().root_custody()); - if (!result.is_error()) { - auto description = result.value(); - auto buffer = description->read_entire_file(); - if (!buffer.is_error()) - load_kernel_symbols_from_data(*buffer.value()); - } + auto kernel_symbols_size = strnlen(kernel_symbols, sizeof(kernel_symbols)); + // If we're hitting this VERIFY the kernel symbol file has grown beyond + // the array size of kernel_symbols. Try making the array larger. + VERIFY(kernel_symbols_size != sizeof(kernel_symbols)); + load_kernel_symbols_from_data({ kernel_symbols, kernel_symbols_size }); } } diff --git a/Kernel/embedmap.sh b/Kernel/embedmap.sh new file mode 100644 index 00000000000..2f341fd97d6 --- /dev/null +++ b/Kernel/embedmap.sh @@ -0,0 +1,5 @@ +#!/bin/sh +tmp=$(mktemp) +(cat kernel.map; printf '%b' '\0') > "$tmp" +objcopy --update-section .ksyms="$tmp" Kernel +rm -f "$tmp" diff --git a/Kernel/init.cpp b/Kernel/init.cpp index d6af14a8a95..29772473349 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -123,6 +123,8 @@ extern "C" [[noreturn]] UNMAP_AFTER_INIT void init() kmalloc_init(); slab_alloc_init(); + load_kernel_symbol_table(); + ConsoleDevice::initialize(); s_bsp_processor.initialize(0); @@ -264,8 +266,6 @@ void init_stage2(void*) Process::current()->set_root_directory(VirtualFileSystem::the().root_custody()); - load_kernel_symbol_table(); - // Switch out of early boot mode. g_in_early_boot = false; diff --git a/Kernel/linker.ld b/Kernel/linker.ld index 0194ad16e4a..698082f8379 100644 --- a/Kernel/linker.ld +++ b/Kernel/linker.ld @@ -9,6 +9,7 @@ PHDRS text PT_LOAD ; data PT_LOAD ; bss PT_LOAD ; + ksyms PT_LOAD ; } SECTIONS @@ -93,4 +94,9 @@ SECTIONS } :bss end_of_kernel_image = .; + + .ksyms ALIGN(4K) : AT (ADDR(.ksyms) - KERNEL_VIRTUAL_BASE) + { + *(.kernel_symbols) + } :ksyms }