diff --git a/Kernel/Arch/init.cpp b/Kernel/Arch/init.cpp index 6b2d785af1..8f7cf5381b 100644 --- a/Kernel/Arch/init.cpp +++ b/Kernel/Arch/init.cpp @@ -84,6 +84,9 @@ extern "C" u8 end_of_safemem_atomic_text[]; extern "C" u8 end_of_kernel_image[]; +multiboot_module_entry_t multiboot_copy_boot_modules_array[16]; +size_t multiboot_copy_boot_modules_count; + READONLY_AFTER_INIT bool g_in_early_boot; namespace Kernel { @@ -134,10 +137,8 @@ READONLY_AFTER_INIT char const* kernel_cmdline; READONLY_AFTER_INIT u32 multiboot_flags; READONLY_AFTER_INIT multiboot_memory_map_t* multiboot_memory_map; READONLY_AFTER_INIT size_t multiboot_memory_map_count; +READONLY_AFTER_INIT multiboot_module_entry_t* multiboot_modules; READONLY_AFTER_INIT size_t multiboot_modules_count; -READONLY_AFTER_INIT PhysicalAddress multiboot_module_ramdisk_physical_start; -READONLY_AFTER_INIT PhysicalAddress multiboot_module_ramdisk_physical_end; -READONLY_AFTER_INIT PhysicalAddress multiboot_module_ramdisk_physical_string_addr; READONLY_AFTER_INIT PhysicalAddress multiboot_framebuffer_addr; READONLY_AFTER_INIT u32 multiboot_framebuffer_pitch; READONLY_AFTER_INIT u32 multiboot_framebuffer_width; @@ -169,10 +170,8 @@ extern "C" [[noreturn]] UNMAP_AFTER_INIT void init([[maybe_unused]] BootInfo con multiboot_flags = boot_info.multiboot_flags; multiboot_memory_map = (multiboot_memory_map_t*)boot_info.multiboot_memory_map; multiboot_memory_map_count = boot_info.multiboot_memory_map_count; + multiboot_modules = (multiboot_module_entry_t*)boot_info.multiboot_modules; multiboot_modules_count = boot_info.multiboot_modules_count; - multiboot_module_ramdisk_physical_start = PhysicalAddress { boot_info.multiboot_module_ramdisk_physical_start }; - multiboot_module_ramdisk_physical_end = PhysicalAddress { boot_info.multiboot_module_ramdisk_physical_end }; - multiboot_module_ramdisk_physical_string_addr = PhysicalAddress { boot_info.multiboot_module_ramdisk_physical_string_addr }; multiboot_framebuffer_addr = PhysicalAddress { boot_info.multiboot_framebuffer_addr }; multiboot_framebuffer_pitch = boot_info.multiboot_framebuffer_pitch; multiboot_framebuffer_width = boot_info.multiboot_framebuffer_width; @@ -201,6 +200,8 @@ extern "C" [[noreturn]] UNMAP_AFTER_INIT void init([[maybe_unused]] BootInfo con // We need to copy the command line before kmalloc is initialized, // as it may overwrite parts of multiboot! CommandLine::early_initialize(kernel_cmdline); + memcpy(multiboot_copy_boot_modules_array, multiboot_modules, multiboot_modules_count * sizeof(multiboot_module_entry_t)); + multiboot_copy_boot_modules_count = multiboot_modules_count; new (&bsp_processor()) Processor(); bsp_processor().early_initialize(0); diff --git a/Kernel/Arch/x86_64/linker.ld b/Kernel/Arch/x86_64/linker.ld index e9b7a870f1..e11648fe13 100644 --- a/Kernel/Arch/x86_64/linker.ld +++ b/Kernel/Arch/x86_64/linker.ld @@ -69,8 +69,6 @@ SECTIONS start_of_kernel_data = .; *(.data*) end_of_kernel_data = .; - . = ALIGN(4K); - *(.heap) } :data .ro_after_init ALIGN(4K) : AT(ADDR(.ro_after_init)) @@ -87,6 +85,9 @@ SECTIONS *(COMMON) *(.bss*) end_of_kernel_bss = .; + + . = ALIGN(4K); + *(.heap) } :bss .dynamic ALIGN(4K) : AT (ADDR(.dynamic)) diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index 635de831f9..54d7ae41ef 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -720,25 +720,7 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang$") target_link_libraries(Kernel PRIVATE kernel_heap clang_rt.builtins) endif() -if ("${SERENITY_ARCH}" STREQUAL "x86_64") - set(KERNEL_ELF_OBJCOPY_TARGET "elf64-x86-64") -endif() - -# In x86_64 the Kernel is linked to the Pre-kernel binary. -if ("${SERENITY_ARCH}" STREQUAL "x86_64") - add_custom_command( - TARGET Kernel POST_BUILD - COMMAND ${CMAKE_COMMAND} -E env NM=${CMAKE_NM} sh ${CMAKE_CURRENT_SOURCE_DIR}/mkmap.sh - COMMAND ${CMAKE_COMMAND} -E env OBJCOPY=${CMAKE_OBJCOPY} sh ${CMAKE_CURRENT_SOURCE_DIR}/embedmap.sh - COMMAND ${CMAKE_OBJCOPY} --only-keep-debug Kernel Kernel.debug - COMMAND ${CMAKE_OBJCOPY} --strip-debug Kernel - COMMAND ${CMAKE_OBJCOPY} --add-gnu-debuglink=Kernel.debug Kernel - COMMAND ${CMAKE_OBJCOPY} --set-section-flags .heap=load Kernel Kernel_shared_object - COMMAND ${CMAKE_OBJCOPY} -I binary -O ${KERNEL_ELF_OBJCOPY_TARGET} --rename-section .data=.Kernel_image --set-section-alignment .Kernel_image=4096 Kernel_shared_object Kernel.o - BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/Kernel.o ${CMAKE_CURRENT_BINARY_DIR}/kernel.map - ) -elseif ("${SERENITY_ARCH}" STREQUAL "aarch64") - add_custom_command( +add_custom_command( TARGET Kernel POST_BUILD COMMAND "${CMAKE_COMMAND}" -E env NM=${CMAKE_NM} sh ${CMAKE_CURRENT_SOURCE_DIR}/mkmap.sh COMMAND "${CMAKE_COMMAND}" -E env OBJCOPY=${CMAKE_OBJCOPY} sh ${CMAKE_CURRENT_SOURCE_DIR}/embedmap.sh @@ -746,14 +728,9 @@ elseif ("${SERENITY_ARCH}" STREQUAL "aarch64") COMMAND ${CMAKE_OBJCOPY} --strip-debug Kernel COMMAND ${CMAKE_OBJCOPY} --add-gnu-debuglink=Kernel.debug Kernel BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/kernel.map - ) -endif() +) -# Both architectures (x86_64, aarch64) share the same location in their respective architecture build folder. -# In x86_64 the Kernel is linked to the Pre-kernel binary and then generates the result Kernel binary. -# In aarch64 there's no Pre-kernel stage yet, so we immediately get a Kernel binary. install(FILES "${CMAKE_CURRENT_BINARY_DIR}/Kernel" DESTINATION boot) - install(FILES "${CMAKE_CURRENT_BINARY_DIR}/Kernel.debug" DESTINATION boot) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/kernel.map" DESTINATION res) diff --git a/Kernel/Memory/MemoryManager.cpp b/Kernel/Memory/MemoryManager.cpp index 4388d263ee..74bebae9ea 100644 --- a/Kernel/Memory/MemoryManager.cpp +++ b/Kernel/Memory/MemoryManager.cpp @@ -38,6 +38,9 @@ extern u8 end_of_unmap_after_init[]; extern u8 start_of_kernel_ksyms[]; extern u8 end_of_kernel_ksyms[]; +extern multiboot_module_entry_t multiboot_copy_boot_modules_array[16]; +extern size_t multiboot_copy_boot_modules_count; + namespace Kernel::Memory { ErrorOr page_round_up(FlatPtr x) @@ -268,6 +271,15 @@ UNMAP_AFTER_INIT void MemoryManager::parse_memory_map() #endif global_data.used_memory_ranges.append(UsedMemoryRange { UsedMemoryRangeType::Kernel, PhysicalAddress(virtual_to_low_physical((FlatPtr)start_of_kernel_image)), PhysicalAddress(page_round_up(virtual_to_low_physical((FlatPtr)end_of_kernel_image)).release_value_but_fixme_should_propagate_errors()) }); + if (multiboot_flags & 0x4) { + auto* bootmods_start = multiboot_copy_boot_modules_array; + auto* bootmods_end = bootmods_start + multiboot_copy_boot_modules_count; + + for (auto* bootmod = bootmods_start; bootmod < bootmods_end; bootmod++) { + global_data.used_memory_ranges.append(UsedMemoryRange { UsedMemoryRangeType::BootModule, PhysicalAddress(bootmod->start), PhysicalAddress(bootmod->end) }); + } + } + auto* mmap_begin = multiboot_memory_map; auto* mmap_end = multiboot_memory_map + multiboot_memory_map_count; diff --git a/Kernel/Prekernel/CMakeLists.txt b/Kernel/Prekernel/CMakeLists.txt index a007bb9376..f554ce4820 100644 --- a/Kernel/Prekernel/CMakeLists.txt +++ b/Kernel/Prekernel/CMakeLists.txt @@ -8,21 +8,14 @@ set(SOURCES ) if ("${SERENITY_ARCH}" STREQUAL "x86_64") - set(PREKERNEL_TARGET kernel_x86-64) + set(PREKERNEL_TARGET Prekernel64) elseif("${SERENITY_ARCH}" STREQUAL "aarch64") message(SEND_ERROR "Prekernel is not needed on aarch64 and should not be compiled!") endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static") -add_library(KernelObject OBJECT IMPORTED) - -set_property(TARGET KernelObject PROPERTY - IMPORTED_OBJECTS ${CMAKE_CURRENT_BINARY_DIR}/../Kernel.o -) - -add_executable(${PREKERNEL_TARGET} ${SOURCES} $) -add_dependencies(${PREKERNEL_TARGET} Kernel) +add_executable(${PREKERNEL_TARGET} ${SOURCES}) target_compile_options(${PREKERNEL_TARGET} PRIVATE -no-pie -fno-pic -fno-threadsafe-statics) target_link_options(${PREKERNEL_TARGET} PRIVATE LINKER:-T ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld -nostdlib LINKER:--no-pie) @@ -34,20 +27,13 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang$") target_link_libraries(${PREKERNEL_TARGET} PRIVATE clang_rt.builtins) endif() -if ("${SERENITY_ARCH}" STREQUAL "x86_64") - set(ELF_OBJCOPY_TARGET "elf32-i386") -elseif("${SERENITY_ARCH}" STREQUAL "aarch64") - message(SEND_ERROR "Prekernel is not needed on aarch64 and should not be compiled!") -endif() - - add_custom_command( TARGET ${PREKERNEL_TARGET} POST_BUILD - COMMAND ${CMAKE_OBJCOPY} -O ${ELF_OBJCOPY_TARGET} ${CMAKE_CURRENT_BINARY_DIR}/${PREKERNEL_TARGET} ${CMAKE_CURRENT_BINARY_DIR}/../Kernel + COMMAND ${CMAKE_OBJCOPY} -O elf32-i386 ${CMAKE_CURRENT_BINARY_DIR}/${PREKERNEL_TARGET} ${CMAKE_CURRENT_BINARY_DIR}/Prekernel BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/Prekernel ) -install(FILES "${CMAKE_CURRENT_BINARY_DIR}/../Kernel" DESTINATION boot) +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/Prekernel" DESTINATION boot) # Remove options which the Prekernel environment doesn't support. get_target_property(PREKERNEL_TARGET_OPTIONS ${PREKERNEL_TARGET} COMPILE_OPTIONS) diff --git a/Kernel/Prekernel/Prekernel.h b/Kernel/Prekernel/Prekernel.h index 65e876ad83..7c0176fc12 100644 --- a/Kernel/Prekernel/Prekernel.h +++ b/Kernel/Prekernel/Prekernel.h @@ -41,11 +41,8 @@ struct [[gnu::packed]] BootInfo { u32 multiboot_flags; u64 multiboot_memory_map; u32 multiboot_memory_map_count; - u64 multiboot_modules_physical_ptr; + u64 multiboot_modules; u32 multiboot_modules_count; - u32 multiboot_module_ramdisk_physical_start; - u32 multiboot_module_ramdisk_physical_end; - u32 multiboot_module_ramdisk_physical_string_addr; u64 multiboot_framebuffer_addr; u32 multiboot_framebuffer_pitch; u32 multiboot_framebuffer_width; diff --git a/Kernel/Prekernel/init.cpp b/Kernel/Prekernel/init.cpp index 53ff0c94fb..b892b75647 100644 --- a/Kernel/Prekernel/init.cpp +++ b/Kernel/Prekernel/init.cpp @@ -27,9 +27,6 @@ extern "C" [[noreturn]] void __stack_chk_fail(); extern "C" u8 start_of_prekernel_image[]; extern "C" u8 end_of_prekernel_image[]; -extern "C" u8 _binary_Kernel_standalone_start[]; -extern "C" u8 end_of_prekernel_image_after_kernel_image[]; - extern "C" u8 gdt64ptr[]; extern "C" u16 code64_sel; extern "C" u64 boot_pml4t[512]; @@ -79,7 +76,12 @@ u64 generate_secure_seed(); extern "C" [[noreturn]] void init() { - u8* kernel_image = _binary_Kernel_standalone_start; + if (multiboot_info_ptr->mods_count < 1) + halt(); + + multiboot_module_entry_t* kernel_module = (multiboot_module_entry_t*)(FlatPtr)multiboot_info_ptr->mods_addr; + + u8* kernel_image = (u8*)(FlatPtr)kernel_module->start; // copy the ELF header and program headers because we might end up overwriting them ElfW(Ehdr) kernel_elf_header = *(ElfW(Ehdr)*)kernel_image; ElfW(Phdr) kernel_program_headers[16]; @@ -87,8 +89,8 @@ extern "C" [[noreturn]] void init() halt(); __builtin_memcpy(kernel_program_headers, kernel_image + kernel_elf_header.e_phoff, sizeof(ElfW(Phdr)) * kernel_elf_header.e_phnum); - FlatPtr kernel_physical_base = (FlatPtr)kernel_image; - FlatPtr default_kernel_load_base = KERNEL_MAPPING_BASE + kernel_physical_base; + FlatPtr kernel_physical_base = 0x200000; + FlatPtr default_kernel_load_base = KERNEL_MAPPING_BASE + 0x200000; FlatPtr kernel_load_base = default_kernel_load_base; @@ -166,6 +168,9 @@ extern "C" [[noreturn]] void init() __builtin_memset((u8*)kernel_load_base + kernel_program_header.p_vaddr + kernel_program_header.p_filesz, 0, kernel_program_header.p_memsz - kernel_program_header.p_filesz); } + multiboot_info_ptr->mods_count--; + multiboot_info_ptr->mods_addr += sizeof(multiboot_module_entry_t); + auto adjust_by_mapping_base = [kernel_mapping_base](auto ptr) { return (decltype(ptr))((FlatPtr)ptr + kernel_mapping_base); }; @@ -189,16 +194,8 @@ extern "C" [[noreturn]] void init() info.multiboot_flags = multiboot_info_ptr->flags; info.multiboot_memory_map = adjust_by_mapping_base((FlatPtr)multiboot_info_ptr->mmap_addr); info.multiboot_memory_map_count = multiboot_info_ptr->mmap_length / sizeof(multiboot_memory_map_t); - info.multiboot_modules_physical_ptr = (FlatPtr)multiboot_info_ptr->mods_addr; + info.multiboot_modules = adjust_by_mapping_base((FlatPtr)multiboot_info_ptr->mods_addr); info.multiboot_modules_count = multiboot_info_ptr->mods_count; - - if (info.multiboot_modules_count > 0) { - auto* entry = reinterpret_cast(multiboot_info_ptr->mods_addr); - info.multiboot_module_ramdisk_physical_start = entry->start; - info.multiboot_module_ramdisk_physical_end = entry->end; - info.multiboot_module_ramdisk_physical_string_addr = entry->string_addr; - } - if ((multiboot_info_ptr->flags & MULTIBOOT_INFO_FRAMEBUFFER_INFO) != 0) { info.multiboot_framebuffer_addr = multiboot_info_ptr->framebuffer_addr; info.multiboot_framebuffer_pitch = multiboot_info_ptr->framebuffer_pitch; diff --git a/Kernel/Prekernel/linker.ld b/Kernel/Prekernel/linker.ld index 32cf31436e..1204520540 100644 --- a/Kernel/Prekernel/linker.ld +++ b/Kernel/Prekernel/linker.ld @@ -44,13 +44,4 @@ SECTIONS } :bss end_of_prekernel_image = .; - - .Kernel_image ALIGN(4K) : AT (ADDR(.Kernel_image)) - { - _binary_Kernel_standalone_start = .; - KEEP(*(.Kernel_image)) - } - - end_of_prekernel_image_after_kernel_image = .; - } diff --git a/Meta/debug-kernel.sh b/Meta/debug-kernel.sh index 7231366a04..4e902155b6 100755 --- a/Meta/debug-kernel.sh +++ b/Meta/debug-kernel.sh @@ -60,7 +60,7 @@ exec $SERENITY_KERNEL_DEBUGGER \ -ex "file $SCRIPT_DIR/../Build/${SERENITY_ARCH:-x86_64}$toolchain_suffix/Kernel/Prekernel/$prekernel_image" \ -ex "set confirm off" \ -ex "directory $SCRIPT_DIR/../Build/${SERENITY_ARCH:-x86_64}$toolchain_suffix/" \ - -ex "add-symbol-file $SCRIPT_DIR/../Build/${SERENITY_ARCH:-x86_64}$toolchain_suffix/Kernel/Kernel_shared_object -o $kernel_base" \ + -ex "add-symbol-file $SCRIPT_DIR/../Build/${SERENITY_ARCH:-x86_64}$toolchain_suffix/Kernel/Kernel -o $kernel_base" \ -ex "set confirm on" \ -ex "set arch $gdb_arch" \ -ex "set print frame-arguments none" \ diff --git a/Meta/run.sh b/Meta/run.sh index 2a9b0b6fc1..a2b366dc78 100755 --- a/Meta/run.sh +++ b/Meta/run.sh @@ -328,9 +328,16 @@ if [ "$NATIVE_WINDOWS_QEMU" -ne "1" ]; then -qmp unix:qmp-sock,server,nowait" fi -SERENITY_KERNEL_AND_INITRD=" +if [ "$SERENITY_ARCH" = "aarch64" ]; then + SERENITY_KERNEL_AND_INITRD=" -kernel Kernel/Kernel " +else + SERENITY_KERNEL_AND_INITRD=" + -kernel Kernel/Prekernel/Prekernel + -initrd Kernel/Kernel + " +fi [ -z "$SERENITY_COMMON_QEMU_ARGS" ] && SERENITY_COMMON_QEMU_ARGS="