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.
This commit is contained in:
Gunnar Beutner 2021-07-14 21:04:18 +02:00 committed by Andreas Kling
parent 5a44a0b9f4
commit 7236584132
5 changed files with 28 additions and 18 deletions

View file

@ -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)

View file

@ -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 });
}
}

5
Kernel/embedmap.sh Normal file
View file

@ -0,0 +1,5 @@
#!/bin/sh
tmp=$(mktemp)
(cat kernel.map; printf '%b' '\0') > "$tmp"
objcopy --update-section .ksyms="$tmp" Kernel
rm -f "$tmp"

View file

@ -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;

View file

@ -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
}