From 8c6bfe0edf9d8bb261d0fee09453270cb5b2ede5 Mon Sep 17 00:00:00 2001 From: xwashere Date: Thu, 28 Mar 2024 09:49:31 -0400 Subject: [PATCH] oh yeah we can decompress the kernel now --- CMakeLists.txt | 4 +- lcrash/CMakeLists.txt | 68 +++++- lcrash/acpi/acpi.h | 22 ++ lcrash/efi/guid.c | 3 + lcrash/efi/guid.h | 5 + lcrash/efi/memmap.c | 33 +++ lcrash/efi/memmap.h | 24 ++ lcrash/efi/types.h | 54 +++++ lcrash/empty.S | 0 lcrash/gdb/autorun.py | 30 +++ lcrash/gdb/gdb.c | 3 + lcrash/gdb/gdb.h | 9 + lcrash/lcrash.c | 77 ++----- lcrash/lcrash.ld | 40 ++-- lcrash/setup/compressed/cckernel.S.in | 6 + lcrash/setup/compressed/compressed.ld | 35 +++ lcrash/setup/compressed/elf.c | 7 + lcrash/setup/compressed/elf.h | 36 +++ lcrash/setup/compressed/entry64.S | 32 +++ lcrash/setup/compressed/gzip.c | 304 ++++++++++++++++++++++++++ lcrash/setup/compressed/gzip.h | 5 + lcrash/setup/compressed/main.c | 30 +++ lcrash/setup/compressed/mem.S | 9 + lcrash/setup/header.S | 64 ++++++ lcrash/setup/setup.ld | 37 ++++ lcrash/types.h | 29 +++ lcrash/util.c | 13 ++ lcrash/util.h | 8 + scripts/gdb/lcrash.gdb | 16 ++ src/grub/grub.cfg | 2 +- src/linux/config | 15 +- 31 files changed, 940 insertions(+), 80 deletions(-) create mode 100644 lcrash/acpi/acpi.h create mode 100644 lcrash/efi/guid.c create mode 100644 lcrash/efi/guid.h create mode 100644 lcrash/efi/memmap.c create mode 100644 lcrash/efi/memmap.h create mode 100644 lcrash/efi/types.h create mode 100644 lcrash/empty.S create mode 100644 lcrash/gdb/autorun.py create mode 100644 lcrash/gdb/gdb.c create mode 100644 lcrash/gdb/gdb.h create mode 100644 lcrash/setup/compressed/cckernel.S.in create mode 100644 lcrash/setup/compressed/compressed.ld create mode 100644 lcrash/setup/compressed/elf.c create mode 100644 lcrash/setup/compressed/elf.h create mode 100644 lcrash/setup/compressed/entry64.S create mode 100644 lcrash/setup/compressed/gzip.c create mode 100644 lcrash/setup/compressed/gzip.h create mode 100644 lcrash/setup/compressed/main.c create mode 100644 lcrash/setup/compressed/mem.S create mode 100644 lcrash/setup/header.S create mode 100644 lcrash/setup/setup.ld create mode 100644 lcrash/types.h create mode 100644 lcrash/util.c create mode 100644 lcrash/util.h create mode 100644 scripts/gdb/lcrash.gdb diff --git a/CMakeLists.txt b/CMakeLists.txt index 227bd4b..8ddc8c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,7 @@ set_property(TARGET LindowsLinkerScript PROPERTY IMPORTED_LOCATION "${CMAKE_CURR # compiler stuff set(LW_CROSS_CC "${CMAKE_CURRENT_BINARY_DIR}/gcc/prefix/bin/gcc") set(LW_CROSS_CXX "${CMAKE_CURRENT_BINARY_DIR}/gcc/prefix/bin/g++") +set(LW_CROSS_ASM "${LW_CROSS_CC}") set(LW_CROSS_LD "${LW_CROSS_CC}") set(LW_CROSS_INCFLAGS -isystem${CMAKE_CURRENT_BINARY_DIR}/gcc/prefix/include/c++/13.2.0 -isystem${CMAKE_CURRENT_BINARY_DIR}/gcc/prefix/lib/gcc/x86_64-pc-linux-gnu/13.2.0/include -isystem${CMAKE_CURRENT_BINARY_DIR}/gcc/prefix/lib/gcc/x86_64-pc-linux-gnu/13.2.0/include-fixed -isystem${CMAKE_CURRENT_BINARY_DIR}/gcc/prefix/include/c++/13.2.0/x86_64-pc-linux-gnu -isystem${CMAKE_CURRENT_BINARY_DIR}/glibc/prefix/include -isystem${CMAKE_CURRENT_BINARY_DIR}/linux/headers/include) set(LW_CROSS_CFLAGS -nostdinc ${LW_CROSS_INCFLAGS}) @@ -41,7 +42,7 @@ function(lw_project PROJECTNAME) set(cpa_single DESCRIPTION TARGET) set(cpa_multi) cmake_parse_arguments(PARSE_ARGV 1 ARG "${cpa_flag}" "${cpa_single}" "${cpa_multi}") - + if(NOT ARG_DESCRIPTION) set(ARG_DESCRIPTION "No description provided.") endif() @@ -61,6 +62,7 @@ function(lw_project PROJECTNAME) elseif(${ARG_TARGET} STREQUAL "LINDOWS") set(CMAKE_C_COMPILER "${LW_CROSS_CC}" PARENT_SCOPE) set(CMAKE_CXX_COMPILER "${LW_CROSS_CXX}" PARENT_SCOPE) + set(CMAKE_ASM_COMPILER "${LW_CROSS_ASM}" PARENT_SCOPE) set_property(DIRECTORY . PROPERTY INCLUDE_DIRECTORIES "") else() message(FATAL_ERROR "Unrecognized target type \"${ARG_TARGET}\"") diff --git a/lcrash/CMakeLists.txt b/lcrash/CMakeLists.txt index d57c1d4..f8ddf26 100644 --- a/lcrash/CMakeLists.txt +++ b/lcrash/CMakeLists.txt @@ -5,14 +5,72 @@ lw_project(lcrash TARGET LINDOWS ) -lw_add_executable(lcrash - SOURCES lcrash.c efi/memmap.c +enable_language(ASM) + +lw_add_executable(lcrashkern + SOURCES lcrash.c util.c efi/guid.c efi/memmap.c gdb/gdb.c ) +add_executable(lcrashkernld IMPORTED) +set_property(TARGET lcrashkernld PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lcrash.ld) +set_property(TARGET lcrashkern PROPERTY LINK_DEPENDS + $ + $ +) +set_property(TARGET lcrashkern PROPERTY LINK_OPTIONS -nostdlib -Wl,-T,${CMAKE_CURRENT_SOURCE_DIR}/lcrash.ld ) +target_compile_options(lcrashkern PRIVATE -ggdb -fpic -pie) +target_link_options(lcrashkern PRIVATE -fpic -pie) + +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lcrashkern.gz + DEPENDS lcrashkern + COMMAND gzip -fk $ > ${CMAKE_CURRENT_BINARY_DIR}/lcrashkern.gz +) +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lcrashkern_locs.h + DEPENDS lcrashkern ${CMAKE_CURRENT_BINARY_DIR}/lcrashkern.gz + COMMAND nm ${CMAKE_CURRENT_BINARY_DIR}/lcrashkern | sed -E '"s/([0-9a-f]*) . (.*)/#define KK_\\2 0x\\1/g"' > lcrashkern_locs.h + COMMAND echo -n "'#'define _KKCLEN " >> lcrashkern_locs.h + COMMAND du -b lcrashkern.gz | cut -f 1 >> lcrashkern_locs.h +) + +# UnityOS cckernel stuffed into the bzImage +lw_add_executable(cckernel + SOURCES setup/compressed/cckernel.S + setup/compressed/entry64.S + setup/compressed/mem.S + setup/compressed/main.c + setup/compressed/gzip.c + setup/compressed/elf.c +) +add_executable(cckernelld IMPORTED) +set_property(TARGET cckernelld PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/setup/compressed/compressed.ld) +set_property(TARGET cckernel PROPERTY LINK_OPTIONS -nostdlib -Wl,-T,${CMAKE_CURRENT_SOURCE_DIR}/setup/compressed/compressed.ld) +target_compile_options(cckernel PRIVATE -ggdb -mno-sse -mno-avx) # disable generating SIMD code since we haven't configured it at this stage of the boot thing +set_property(SOURCE setup/compressed/cckernel.S PROPERTY OBJECT_DEPENDS + ${CMAKE_CURRENT_BINARY_DIR}/lcrashkern.gz +) +set_property(TARGET cckernel PROPERTY LINK_DEPENDS + $ +) +set(COMPRESSED_KERNEL_PATH ${CMAKE_CURRENT_BINARY_DIR}/lcrashkern.gz) +configure_file(setup/compressed/cckernel.S.in setup/compressed/cckernel.S) + +# This is the actual bzImage used by linux/grub +lw_add_executable(lcrash + SOURCES setup/header.S lcrashkern_locs.h +) +target_include_directories(lcrash PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) add_executable(lcrashld IMPORTED) -set_property(TARGET lcrashld PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lcrash.ld) +set_property(TARGET lcrashld PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/setup/setup.ld) set_property(TARGET lcrash PROPERTY LINK_DEPENDS $ $ + $ +) +set_property(TARGET lcrash PROPERTY LINK_OPTIONS -nostdlib -Wl,-T,${CMAKE_CURRENT_SOURCE_DIR}/setup/setup.ld) +add_custom_command(TARGET lcrash POST_BUILD + DEPENDS cckernel + COMMAND bash -c "truncate \"$\" -s \"$((0x$(nm \"$\" | grep \" _end$\" | cut -d\" \" -f 1)))\"" + COMMAND dd "if=$" "of=$" conv=notrunc oflag=append + VERBATIM ) -set_property(TARGET lcrash PROPERTY LINK_OPTIONS -nostdlib -Wl,-T,${CMAKE_CURRENT_SOURCE_DIR}/lcrash.ld) -target_compile_options(lcrash PRIVATE -ggdb) diff --git a/lcrash/acpi/acpi.h b/lcrash/acpi/acpi.h new file mode 100644 index 0000000..4ee288d --- /dev/null +++ b/lcrash/acpi/acpi.h @@ -0,0 +1,22 @@ +#pragma once + +#include "../types.h" + +struct AcpiRSDP; +struct AcpiXSDT; + +/** + * ACPI Root System Description Pointer + */ +struct [[gnu::packed]] AcpiRSDP { + char Signature[8]; + u8 Checksum; + char OEM[6]; + u8 Revision; + [[gnu::deprecated]] // we dont care :> + u32 RSDTAddress; + u32 Length; + struct AcpiXSDT* XSDTAddress; + u8 ExtendedChecksum; + u8 Reserved[3]; +}; diff --git a/lcrash/efi/guid.c b/lcrash/efi/guid.c new file mode 100644 index 0000000..37313a1 --- /dev/null +++ b/lcrash/efi/guid.c @@ -0,0 +1,3 @@ +#include "guid.h" + +EfiGuid EFI_ACPI_20_TABLE_GUID = {0x8868e871, 0xe4f1, 0x11d3, {0xbc,0x22,0x00,0x80,0xc7,0x3c,0x88,0x81}}; diff --git a/lcrash/efi/guid.h b/lcrash/efi/guid.h new file mode 100644 index 0000000..de0a3c5 --- /dev/null +++ b/lcrash/efi/guid.h @@ -0,0 +1,5 @@ +#pragma once + +#include "./types.h" + +extern EfiGuid EFI_ACPI_20_TABLE_GUID; diff --git a/lcrash/efi/memmap.c b/lcrash/efi/memmap.c new file mode 100644 index 0000000..c486cdd --- /dev/null +++ b/lcrash/efi/memmap.c @@ -0,0 +1,33 @@ +#include "memmap.h" + +struct EfiMemoryDescription *StoredMemoryMap; +u32 StoredMemoryMapEntryCount = 0; +u32 StoredMemoryMapEntrySize = 0; + +void EfiLoadStoredMemoryMap( + struct EfiMemoryDescription* MemoryMap, + u32 MemoryMapEntryCount, + u32 MemoryMapEntrySize +) { + StoredMemoryMap = MemoryMap; + StoredMemoryMapEntryCount = MemoryMapEntryCount; + StoredMemoryMapEntrySize = MemoryMapEntrySize; +} + +/** + * Translate a pointer using what we can recover from the UEFI memory map, may return something invalid. + */ +void* EfiTranslatePointer(void* FirmwarePointer) { + // Scan the memory map for where our thing is + for (int i = 0; i < StoredMemoryMapEntryCount; i++) { + struct EfiMemoryDescription* Entry = (struct EfiMemoryDescription*)((void*)StoredMemoryMap + i * StoredMemoryMapEntrySize); + + if (FirmwarePointer >= Entry->VirtualStart && + FirmwarePointer < Entry->VirtualStart + 0x1000 * Entry->NumberOfPages) { + return FirmwarePointer - Entry->VirtualStart + Entry->PhysicalStart; + } + } + + // Well, we tried + return -1; +} diff --git a/lcrash/efi/memmap.h b/lcrash/efi/memmap.h new file mode 100644 index 0000000..4540de0 --- /dev/null +++ b/lcrash/efi/memmap.h @@ -0,0 +1,24 @@ +#pragma once + +#include "types.h" + +/// EFI Memory Descriptor +struct EfiMemoryDescription { + EfiUint32 Type; + EfiVoid *PhysicalStart; + EfiVoid *VirtualStart; + EfiUint64 NumberOfPages; + EfiUint64 Attribute; +}; + +/** + * Load a memory map to use for translating pointers recovered from EFI tables. + */ +void EfiLoadStoredMemoryMap( + struct EfiMemoryDescription* StoredMemoryMap, + u32 StoredMemoryMapEntryCount, + u32 StoredMemoryMapEntrySize +); + +/// Translate a pointer to something we can use using the stored memory map. +void* EfiTranslatePointer(void* FirmwarePointer); diff --git a/lcrash/efi/types.h b/lcrash/efi/types.h new file mode 100644 index 0000000..9a37787 --- /dev/null +++ b/lcrash/efi/types.h @@ -0,0 +1,54 @@ +#pragma once + +#include "../types.h" + +typedef void EfiVoid; + +typedef u8 EfiUint8; +typedef u16 EfiUint16; +typedef u32 EfiUint32; +typedef u64 EfiUint64; +typedef uptr EfiUintN; + +typedef c16 EfiChar16; + +typedef EfiVoid* EfiHandle; + +typedef struct _EfiGuid { + u32 data1; + u16 data2; + u16 data3; + u8 data4[8]; +} EfiGuid; + +/// Generic EFI table header +struct EfiTableHeader { + EfiUint64 Signature; + EfiUint32 Revision; + EfiUint32 HeaderSize; + EfiUint32 CRC32; + EfiUint32 Reserved; +}; + +/// EFI System Table +struct EfiSystemTable { + struct EfiTableHeader Hdr; + EfiChar16 *FirmwareVendor; + EfiUint32 FirmwareRevision; + EfiHandle ConsoleInHandle; + EfiVoid *ConIn; + EfiHandle ConsoleOutHandle; + EfiVoid *ConOut; + EfiHandle StandardErrorHandle; + EfiVoid *StdErr; + struct EfiRuntimeServices *RuntimeServices; + struct EfiBootServices *BootServices; + EfiUintN NumberOfTableEntries; + struct EfiConfigurationTable *ConfigurationTable; +}; + +/// EFI Configuration Table +struct EfiConfigurationTable { + EfiGuid VendorGuid; + EfiVoid *VendorTable; +}; diff --git a/lcrash/empty.S b/lcrash/empty.S new file mode 100644 index 0000000..e69de29 diff --git a/lcrash/gdb/autorun.py b/lcrash/gdb/autorun.py new file mode 100644 index 0000000..2a235b2 --- /dev/null +++ b/lcrash/gdb/autorun.py @@ -0,0 +1,30 @@ +import functools; + +# --- printers for stuff and yeah --- +class EfiGuidPrinter(gdb.ValuePrinter): + "Print an EfiGuid" + + def __init__(self, val): + self.__val = val; + + def to_string(self): + # it's really disappointing that you cant iterate these silly arrays + d4 = self.__val["data4"]; + last = functools.reduce(lambda s, bit: f'{s}{int(bit):0>2X}', [d4[0], d4[1], d4[2], d4[3], d4[4], d4[5], d4[6], d4[7]], ""); + + return f'{int(self.__val["data1"]):0>8X}-{int(self.__val["data2"]):0>4X}-{int(self.__val["data3"]):0>4X}-{last}'; + +def add_pretty_printer(name, printer, custom_lookup = None): + def lookup(val): + if val.type.tag == name: + return printer(val); + + return None; + + gdb.current_objfile().pretty_printers.append(lookup if custom_lookup is None else custom_lookup); + + return; + +add_pretty_printer("_EfiGuid", EfiGuidPrinter, lambda val: EfiGuidPrinter(val) if val.type.strip_typedefs().tag == "_EfiGuid" else None); + +# --- --- diff --git a/lcrash/gdb/gdb.c b/lcrash/gdb/gdb.c new file mode 100644 index 0000000..eb1efd5 --- /dev/null +++ b/lcrash/gdb/gdb.c @@ -0,0 +1,3 @@ +#include "gdb.h" + +DEFINE_GDB_PY_SCRIPT("lcrash/gdb/autorun.py") diff --git a/lcrash/gdb/gdb.h b/lcrash/gdb/gdb.h new file mode 100644 index 0000000..2db8a4f --- /dev/null +++ b/lcrash/gdb/gdb.h @@ -0,0 +1,9 @@ +#pragma once + +#define DEFINE_GDB_PY_SCRIPT(name) \ + asm("\ + .pushsection \".debug_gdb_scripts\", \"MS\", @progbits, 1\n\ + .byte 1\n\ + .asciz \""name"\"\n\ + .popsection \n\ + "); diff --git a/lcrash/lcrash.c b/lcrash/lcrash.c index 81e87a7..66b8fe4 100644 --- a/lcrash/lcrash.c +++ b/lcrash/lcrash.c @@ -1,31 +1,8 @@ #include "lnxboot.h" +#include "util.h" #include "efi/types.h" #include "efi/memmap.h" - -extern void _start(); - -[[gnu::section(".lnxhead")]] -[[gnu::used]] -[[gnu::aligned(1)]] -[[gnu::unavailable("not present at runtime. use setup_info instead")]] -struct setup_info bzhead = { - .setup_sects = 2, // 1 512-byte sector - .boot_flag = 0xAA55, - .syssize = 16, - .jump_instruction = 0xEB, - .jump_offset = sizeof(struct setup_info) - __builtin_offsetof(struct setup_info, signature), - .signature = 0x53726448, - .version = 0x020F, - .loadflags = 0x01, // LOADED_HIGH, - .kernel_alignment = 1, - .relocatable_kernel = 0, - .xloadflags = 0x13, // XLF_KERNEL_64 | XLF_CAN_BE_LOADED_ABOVE_4G | XLF_5LEVEL - .cmdline_size = 255, // max command line size - .init_size = 0x10000 // we dont need THAT much memory -}; - -struct setup_info* setup_info; -struct boot_params* boot_params; +#include "efi/guid.h" unsigned short serial_port; @@ -84,28 +61,12 @@ void Panic(const char* message) { Hang(); } -[[gnu::section(".text._start"), gnu::naked, gnu::no_reorder]] -extern void _start() { - asm ("jmp _start"); - asm ( // grab the setup_info and boot_params locations - "mov %%rsi, %1\n" - "mov %%rsi, %0\n" - "addq $0x1f1, %0" - : "=m" (setup_info), - "=m" (boot_params) - ); - asm ("jmp entry"); -} +void entry64() { + while (1) {}; -c16* FirmwareVendor = 0; + Panic("HELLO WORLD."); -/** - * we're in some kind of purgatory between booted and not booted, a lot of devices are currently initialized from the previous - * kernel, but we have no idea where they are, what they are, or how to use them. all we have is the stuff in setup_info and - * boot_params, and whatever we can salvage from the crashed kernel. - */ -[[gnu::section(".text._start"), gnu::no_reorder]] -void entry() { + /* // get command line from kernel. we likely won't use it, but its nice to have. u8* cmdline_ptr = (u8*)((u64)setup_info->cmd_line_ptr | ((u64)boot_params->ext_cmd_line_ptr << 32)); @@ -125,11 +86,6 @@ void entry() { boot_params->efi_info.EfiMemoryMapSize / boot_params->efi_info.EfiMemoryDescriptionSize, boot_params->efi_info.EfiMemoryDescriptionSize ); - - FirmwareVendor = EfiTranslatePointer(systab_ptr->FirmwareVendor); - while (1) { - volatile char* a = FirmwareVendor; - } } // -- find acpi -- @@ -138,9 +94,22 @@ void entry() { // check bootparams if (boot_params->acpi_rsdp_addr) AcpiRSDP = boot_params->acpi_rsdp_addr; + while (true) { + volatile void* a = &EFI_ACPI_20_TABLE_GUID; + } + // check efi if (!AcpiRSDP && systab_ptr && systab_ptr->NumberOfTableEntries) { - volatile void* ConfigurationTable = EfiTranslatePointer(systab_ptr->ConfigurationTable); + struct EfiConfigurationTable* ConfigurationTable = EfiTranslatePointer(systab_ptr->ConfigurationTable); + for (int i = 0; i < systab_ptr->NumberOfTableEntries; i++) { + if (CompareMemory(&ConfigurationTable[i].VendorGuid, &EFI_ACPI_20_TABLE_GUID, sizeof(EfiGuid))) { + AcpiRSDP = ConfigurationTable[i].VendorTable; + while (true) { + volatile void* a = AcpiRSDP; + } + break; + } + } } // we're playing where's waldo with this stupid fucking tableS @@ -159,7 +128,9 @@ void entry() { if (!AcpiRSDP) Panic("Failed to find ACPI RSDP"); // do we have acpi? - asm volatile ("ljmp 0"); + while (1) { + volatile void* p = AcpiRSDP; + } // we dont have the privilege of getting a rodata segment. any reads off our stack cause a triple fault // for some fucking reason. allocate our strings and shit on the stack. @@ -191,6 +162,6 @@ void entry() { // serial_puts("test\n"); // serial_puts(bzhead.cmd_line_ptr); - // Die. + // Die.*/ Panic("Nothing left to do."); } diff --git a/lcrash/lcrash.ld b/lcrash/lcrash.ld index fecff53..ca8efe6 100644 --- a/lcrash/lcrash.ld +++ b/lcrash/lcrash.ld @@ -1,28 +1,33 @@ OUTPUT_FORMAT(elf64-x86-64) -ENTRY(_start) - -MEMORY { - code (rx) : ORIGIN = 0x0dfe8000, LENGTH = 0x00001000 - data (rw) : ORIGIN = 0x0dff0000, LENGTH = 0x00001000 -} +ENTRY(entry64) SECTIONS { - .lnxhead 0x01f1 : ALIGN(1) { - *(.lnxhead); + . = 0; + + .text : { + _text = .; + *(.text); + _etext = .; } - .rodata : ALIGN(1) { + .rodata : { + _rodata = .; *(.rodata); - } > data + _erodata = .; + } - /* this section helps us to coerce the linker into not breaking down because of big addresses */ - .text._start 0xdfe8000 : ALIGN(1) { - *(.text._start); - } > code + .data : { + _data = .; + *(.data); + _edata = .; + } - .text : ALIGN(512) { *(.text); } > code - .bss : { *(.bss); } + .bss : { + _bss = .; + *(.bss); + _ebss = .; + } .debug_info 0 : { *(.debug_info); } .debug_abbrev 0 : { *(.debug_abbrev); } @@ -31,7 +36,8 @@ SECTIONS { .debug_line 0 : { *(.debug_line); } .debug_str 0 : { *(.debug_str); } .debug_line_str 0 : { *(.debug_line_str); } - + .debug_gdb_scripts 0 : { *(.debug_gdb_scripts); } + /DISCARD/ : { *(*); } diff --git a/lcrash/setup/compressed/cckernel.S.in b/lcrash/setup/compressed/cckernel.S.in new file mode 100644 index 0000000..2791e87 --- /dev/null +++ b/lcrash/setup/compressed/cckernel.S.in @@ -0,0 +1,6 @@ + .section ".cckernel", "a" + .globl _CC_cckernel +_CC_cckernel: + .incbin "@COMPRESSED_KERNEL_PATH@" + .globl _CC_ecckernel +_CC_ecckernel: diff --git a/lcrash/setup/compressed/compressed.ld b/lcrash/setup/compressed/compressed.ld new file mode 100644 index 0000000..ceaf344 --- /dev/null +++ b/lcrash/setup/compressed/compressed.ld @@ -0,0 +1,35 @@ +OUTPUT_FORMAT(elf64-x86-64) + +SECTIONS { + _CC_start = .; + + .text : { + *(.text) + } + + .cckernel : { + *(.cckernel) + } + + _CC_end = .; + + .bss : { + *(.bss) + *(COMMON) + } + + .debug_info 0 : { *(.debug_info); } + .debug_abbrev 0 : { *(.debug_abbrev); } + .debug_aranges 0 : { *(.debug_aranges); } + .debug_rnglists 0 : { *(.debug_rnglists); } + .debug_line 0 : { *(.debug_line); } + .debug_str 0 : { *(.debug_str); } + .debug_line_str 0 : { *(.debug_line_str); } + .debug_gdb_scripts 0 : { *(.debug_gdb_scripts); } + + /DISCARD/ : { + *(*); + } + + /* ASSERT(entry64 != 0x200, "entry64 is not the entry point, this should never happen.") */ +} diff --git a/lcrash/setup/compressed/elf.c b/lcrash/setup/compressed/elf.c new file mode 100644 index 0000000..92d8954 --- /dev/null +++ b/lcrash/setup/compressed/elf.c @@ -0,0 +1,7 @@ +#include "elf.h" + +int ElfExecute(void* Binary, void* LoadAddr) { + + + while (1) {} +} diff --git a/lcrash/setup/compressed/elf.h b/lcrash/setup/compressed/elf.h new file mode 100644 index 0000000..ec35c1f --- /dev/null +++ b/lcrash/setup/compressed/elf.h @@ -0,0 +1,36 @@ +#pragma once + +#include "../../types.h" + +[[packed]] +struct Elf64_Ehdr { + c8 e_ident[16]; + u16 e_type; + u16 e_machine; + u32 e_version; + u64 e_entry; + u64 e_phoff; + u64 e_shoff; + u32 e_flags; + u16 e_ehsize; + u16 e_phentsize; + u16 e_phnum; + u16 e_shentsize; + u16 e_shentnum; + u16 e_shstrndx; +}; + +[[packed]] +struct Elf64_Phdr { + u32 p_type; + u32 p_flags; + u64 p_offset; + u64 p_vaddr; + u64 p_paddr; + u64 p_filesz; + u64 p_memsz; + u64 p_align; +}; + +/// We don't have space to allocate memory, so we have no idea where we can pass back ELF state, we'll have to do this all at once +int ElfExecute(void* Binary, void* LoadAddr); diff --git a/lcrash/setup/compressed/entry64.S b/lcrash/setup/compressed/entry64.S new file mode 100644 index 0000000..1dcf2f4 --- /dev/null +++ b/lcrash/setup/compressed/entry64.S @@ -0,0 +1,32 @@ + .section ".text", "ax" + .org 0x200 + .global entry64 +entry64: // 64-bit entry point for kernel decompression + // get the cckernel image base. if the opcode generated by the assembler changes, this will break + lea -0x207(%rip), %rdi + + // we might get some stack space from the previous kernel, but we have no idea how much + // it could just be a few bytes for all we know. it's far safer to just use our own + mov $einit_stack, %rsp + mov %rsp, %rbp + + // lets get out of here -- ccmain(rdi: IMGBASE, rsi: BOOTPARAMS) + call ccmain + + // what the fuck is going on, why have you returned here, was my work not enough for you + // ungrateful fucking machine. away with you, you do not deserve the privilege of my + // loving grace. + int3 + int3 + int3 + int3 + + // begone + cli +1: hlt + jmp 1b + + .section ".bss" +init_stack: // this should be sufficient for kernel decompression + .skip 0x8000, 0 +einit_stack: diff --git a/lcrash/setup/compressed/gzip.c b/lcrash/setup/compressed/gzip.c new file mode 100644 index 0000000..d8c9176 --- /dev/null +++ b/lcrash/setup/compressed/gzip.c @@ -0,0 +1,304 @@ +#include "gzip.h" + +// we build a table of uh everything. this uses a lot of stack space, +void GzipPopulateTable( + u8* InputLengths, // Lengths of symbol bits + uptr InputCount, // Number of symbols + u8* OutputLengths, // Output bit lengths + u32* OutputSymbols, // Output symbols + uptr OutputCount, // Number of outputs + uptr OutputBits // Highest bit length +) { + u32 NextSym[15]; /// Next symbol for a specific bit length + for (int i = 0; i < 15; i++) NextSym[i] = -1; + + // Count the symbols in each bit length + u32 CodeCounts[15] = {}; + for (int i = 0; i < InputCount; i++) { + CodeCounts[InputLengths[i]]++; + if (NextSym[InputLengths[i]] == -1) NextSym[InputLengths[i]] = i; + } + + // Ignore null symbols + CodeCounts[0] = 0; + + // Find lowest code for each bit length + u32 Code = 0; + u32 NextCode[15] = {}; // Next code to add to the table + for (u32 Bits = 1; Bits < 15; Bits++) { + Code = (Code + CodeCounts[Bits - 1]) << 1; + NextCode[Bits] = Code; + } + + // Fill in the table in a horribly inefficient manner + Code = 0; + for (u32 Bits = 0; Bits < 15; Bits++) { + const uptr OutputMask = ~(-1 << Bits); + for (int i = 0; i < CodeCounts[Bits]; i++) { + // Take the next symbol + Code = NextSym[Bits]; + + // Set the next next symbol + for (int j = Code + 1; j < InputCount; j++) { + if (InputLengths[j] == Bits) { + NextSym[Bits] = j; + break; + } + } + + // reverse the bits i dont fucking know it doesn't work if i dont + u32 Reversed = 0; + for (int j = 0; j < Bits; j++) { + Reversed |= ((NextCode[Bits] >> j) & 1) << (Bits - j - 1); + } + + // this is horrible + for (int j = 0; j < OutputCount; j++) { + if ((j & OutputMask) == Reversed) { + OutputLengths[j] = Bits; + OutputSymbols[j] = Code; + } + } + + // Next + NextCode[Bits]++; + Code++; + } + } + + // "Good Practice" insists that i inform you that this is in fact, a return statement. + return; +} + +u64 GzipFetchBits(u8* Stream, u64* Location, uptr Length) { + u64 Output = 0; + for (uptr i = 0; i < Length; i++) { + Output |= ((Stream[*Location / 8] >> (*Location % 8)) & 1) << i; + *Location += 1; + } + return Output; +} + +uptr GzipDecompress(c8* Input, uptr InputSize, c8* Output) { + #define TAKE_(_TYPE) (\ + (Location += sizeof(_TYPE)), \ + *(_TYPE*)(Location - sizeof(_TYPE)) \ + ) + + const u32 LengthAddends[29] = { + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, + 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, + 67, 83, 99, 115, 131, 163, 195, 227, 258 + }; + + const u32 DistanceAddends[30] = { + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, + 1537, 2049, 3073, 40097, 6145, 8193, 12289, 15385, 24577 + }; + + void* Location = (void*)Input; + void* End = Location + InputSize; + void* BinaryStart = (void*)Output; + + // each member hopefully. any bug will result in complete failure c: + // we dont even bother making sure it's valid, we have no way to tell + // the user there's something wrong + while (Location < End) { + c8 Id1 = TAKE_(c8); + c8 Id2 = TAKE_(c8); + + u8 Method = TAKE_(u8); + u8 Flags = TAKE_(u8); + u32 LastModified = TAKE_(u32); + u8 ExtraFlags = TAKE_(u8); + u8 OperatingSystem = TAKE_(u8); + + // for the magic extra field + u16 XLen = 0; + void* XBuf = 0; + if (Flags & 0x04) { // FLG.FEXTRA + XLen = TAKE_(u16); + XBuf = Location; + Location += XLen; + } + + // filename + c8* FileName = 0; + if (Flags & 0x08) { // FLG.FNAME + FileName = Location; + while (TAKE_(c8) != 0) {} + } + + // comment + c8* FileComment = 0; + if (Flags & 0x10) { // FLG.FCOMMENT + FileComment = Location; + while (TAKE_(c8) != 0) {} + } + + // hash + u16 CRC16 = 0; + if (Flags & 0x02) { // FLG.FHCRC + CRC16 = TAKE_(u16); + } + + u8* Stream = Location; + u64 BitLocation = 0; + while (true) { + u8 head = GzipFetchBits(Stream, &BitLocation, 3); + switch ((head & 0x06) >> 1) { + case 0: { // NO COMPRESSION + break; + } + case 1: { + // FIXED HUFFMAN + break; + } + case 2: { // DYNAMIC HUFFMAN + // Get huffman code counts + u64 OperationCount = GzipFetchBits(Stream, &BitLocation, 5) + 257; + u64 DistanceCount = GzipFetchBits(Stream, &BitLocation, 5) + 1; + u64 CodeCount = GzipFetchBits(Stream, &BitLocation, 4) + 4; + + const u8 CodeLengthLengthOffset[19] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; + u8 CodeLengthLengthProto[19] = {}; + for (int i = 0; i < CodeCount; i++) { + CodeLengthLengthProto[CodeLengthLengthOffset[i]] = GzipFetchBits(Stream, &BitLocation, 3); + } + + // Build our decoding tables + u8 CodeLengthLengths[0x80] = {}; + u32 CodeLengthSymbols[0x80] = {}; + GzipPopulateTable(CodeLengthLengthProto, 19, CodeLengthLengths, CodeLengthSymbols, 0x80, 7); + + // Collect lengths + u8 Lengths[OperationCount + DistanceCount] = {}; + uptr CurrentLen = 0; + while (CurrentLen < OperationCount + DistanceCount) { + // Fetch the next op + u64 Code = GzipFetchBits(Stream, &BitLocation, 7); + u64 Error = 7 - CodeLengthLengths[Code]; + BitLocation -= Error; + Code = CodeLengthSymbols[Code]; + + if (Code < 16) { // Literal + Lengths[CurrentLen++] = Code; + } else { // Repeat + u64 RepeatCount = 0; + u64 RepeatedLen = 0; + + if (Code == 16) { + RepeatCount = 3 + GzipFetchBits(Stream, &BitLocation, 2); + RepeatedLen = Lengths[CurrentLen - 1]; + } else if (Code == 17) { + RepeatCount = 3 + GzipFetchBits(Stream, &BitLocation, 3); + } else if (Code == 18) { + RepeatCount =11 + GzipFetchBits(Stream, &BitLocation, 7); + } else {} // Should be unreachable + + for (int i = 0; i < RepeatCount; i++) { + Lengths[CurrentLen++] = RepeatedLen; + } + } + } + + // Build operation table + u32 OperationMaxBits = 0; + for (int i = 0; i < OperationCount; i++) { + if (Lengths[i] > OperationMaxBits) OperationMaxBits = Lengths[i]; + } + + // We have no standard library + u32 OperationTableLength = 1; + for (int i = 0; i < OperationMaxBits; i++) OperationTableLength *= 2; + + // Tables + u32 OperationSymbols[OperationTableLength + 0x10]; + u8 OperationLengths[OperationTableLength + 0x10]; + GzipPopulateTable(Lengths, OperationCount, + OperationLengths, OperationSymbols, OperationTableLength, + OperationMaxBits); + + // Build distance tables + u32 DistanceMaxBits = 0; + for (int i = 0; i < DistanceCount; i++) { + if (Lengths[OperationCount + i] > DistanceMaxBits) { + DistanceMaxBits = Lengths[OperationCount + i]; + } + } + + // Power + u32 DistanceTableLength = 1; + for (int i = 0; i < DistanceMaxBits; i++) DistanceTableLength *= 2; + + // More tables + u32 DistanceSymbols[DistanceTableLength + 0x10]; // ad dsome padding theres some bugs i cant see + u8 DistanceLengths[DistanceTableLength + 0x10]; + GzipPopulateTable(Lengths + OperationCount, DistanceCount, + DistanceLengths, DistanceSymbols, DistanceTableLength, + DistanceMaxBits); + + // Inflate + while (Location + BitLocation / 8 < End) { + // Fetch + u32 Code = GzipFetchBits(Stream, &BitLocation, OperationMaxBits); + u64 Error = OperationMaxBits - OperationLengths[Code]; + BitLocation -= Error; + Code = OperationSymbols[Code]; + + if (Code < 256) { // Literal + *Output++ = Code; + } else if (Code == 256) { // End block + break; + } else if (Code < OperationCount) { // Copy + // You'd need to look at the spec yourself to understand this + u32 CopyLength = GzipFetchBits(Stream, &BitLocation, + Code <= 284 && Code > 264 + ? (Code - 1) / 4 - 65 + : 0) + + LengthAddends[Code - 257]; + + // More bitstream shit! I'm done formatting this stuff nicely. + Code = GzipFetchBits(Stream, &BitLocation, DistanceMaxBits); + Error = DistanceMaxBits - DistanceLengths[Code]; + BitLocation -= Error; + Code = DistanceSymbols[Code]; + + // make this a s32 because address and offset awaaa + s32 Distance = GzipFetchBits(Stream, &BitLocation, + Code > 3 && Code <= 29 + ? (Code - 2) / 2 + : 0) + + DistanceAddends[Code]; + + // Finally copy the thing + for (int i = 0; i < CopyLength; i++) { + Output[i] = Output[i - Distance]; + } + + Output += CopyLength; + } else { while (1) {} } // Unreachable unless invalid + } + + break; + } + case 3: { + // THIS SHOULD NEVER HAPPEN + break; + } + } + if (head & 0x01) break; // BFINAL + } + + // I think this is necessary but im not completely sure + Location += BitLocation / 8 + 1; + + // trailer..? hey siri, what's the opposite of a header? + u32 CRC32 = TAKE_(u32); + u32 InputSize = TAKE_(u32); + } + + return (void*)Output - BinaryStart; + + #undef TAKE_ +} diff --git a/lcrash/setup/compressed/gzip.h b/lcrash/setup/compressed/gzip.h new file mode 100644 index 0000000..a2d9132 --- /dev/null +++ b/lcrash/setup/compressed/gzip.h @@ -0,0 +1,5 @@ +#pragma once + +#include "../../types.h" + +uptr GzipDecompress(c8* Input, uptr InputSize, c8* Output); diff --git a/lcrash/setup/compressed/main.c b/lcrash/setup/compressed/main.c new file mode 100644 index 0000000..9a0197f --- /dev/null +++ b/lcrash/setup/compressed/main.c @@ -0,0 +1,30 @@ +#include "../../lnxboot.h" + +#include "gzip.h" +#include "elf.h" + +extern void* _CC_cckernel; +extern void* _CC_ecckernel; + +/// C entry point for cckernel +[[noreturn]] +void ccmain(void* imgbase, struct boot_params* boot_params) { + struct setup_info* setup_info = (struct setup_info*)((void*)boot_params + 0x1f1); + + char* kernel_load_addr = (char*)setup_info->code32_start; + if (kernel_load_addr == 0) kernel_load_addr = (char*)0x100000; + + char* cckernel = imgbase + (uptr)&_CC_cckernel; + //for (long i = 0; i < setup_info->payload_length; i++) { + // kernel_load_addr[i] = cckernel[i]; + //} + + // decompress the kernel + uptr BinaryLength = GzipDecompress(cckernel, (u8*)&_CC_ecckernel - (u8*)&_CC_cckernel, kernel_load_addr); + + // start the kernel + ElfExecute(kernel_load_addr, kernel_load_addr + BinaryLength + 0x1000 - BinaryLength % 0x1000); + + // we fucked up + while (1) {} +} diff --git a/lcrash/setup/compressed/mem.S b/lcrash/setup/compressed/mem.S new file mode 100644 index 0000000..ca4049d --- /dev/null +++ b/lcrash/setup/compressed/mem.S @@ -0,0 +1,9 @@ + /// File with support code for gcc memory stuff + .section ".text", "ax" + .globl memset +memset: + mov %rdx, %rcx + mov %sil, %al + rep stosb (%rdi) + mov %rdi, %rax + ret diff --git a/lcrash/setup/header.S b/lcrash/setup/header.S new file mode 100644 index 0000000..038e111 --- /dev/null +++ b/lcrash/setup/header.S @@ -0,0 +1,64 @@ +#include + + .extern _end + .extern cckernel_size + .extern cckernel_start + + .section ".header", "ax" + .globl setup_info +setup_sects: .byte setup_sectors - 1 +root_flags: .word 0 +syssize: .long KK__ebss / 16 +ram_size: .word 0 +vid_mode: .word 0 +root_dev: .word 0 +boot_flag: .word 0xAA55 + .globl _start +_start: +jump: .byte 0xeb + .byte -2 // entrylow - 1f + 1: +signature: .ascii "HdrS" +version: .word 0x020f +realmode_switch: .word 0, 0 +start_sys_seg: .word 0 + .word 0 //kernel_version - 512 +type_of_loader: .byte 0 +loadflags: .byte 0x81 +setup_move_size: .word 0x8000 +code32_start: .long 0 # .long 0x100000 +ramdisk_image: .long 0 +ramdisk_size: .long 0 +bootsect_kludge: .long 0 +heap_end_ptr: .word 0 # _end + 512 +ext_loader_ver: .byte 0 +ext_loader_type: .byte 0 +cmd_line_ptr: .long 0 +initrd_addr_max: .long 0x7fffffff +kernel_alignment: .long 1 +relocatable_kernel: .byte 1 +min_alignment: .byte 1 +xloadflags: .word 0x13 +cmdline_size: .long 512 +hardware_subarch: .long 0 +hardware_subarch_data: .quad 0 +payload_offset: .long _end // cckernel_start +payload_length: .long _KKCLEN // cckernel_size +setup_data: .quad 0 +pref_address: .quad 0 +init_size: .long 0x20000 // a bit of space +handover_offset: .long 0 // TODO +kernel_info_offset: .long 0 // TODO +/* .globl entrylow + .section ".entrytext", "ax" +entrylow: + 1: jmp 1b + 2: jmp 2b + 3: jmp 3b + 4: jmp 4b + 5: jmp 5b + 6: jmp 6b + 7: jmp 7b + + .section ".initdata", "a" +kernel_version: .asciz "lcrash 0.1.0"*/ diff --git a/lcrash/setup/setup.ld b/lcrash/setup/setup.ld new file mode 100644 index 0000000..df6d074 --- /dev/null +++ b/lcrash/setup/setup.ld @@ -0,0 +1,37 @@ +/* linker script shamelessly ripped from the linux kernel */ + +OUTPUT_FORMAT(elf64-x86-64) +ENTRY(_start) + +SECTIONS { + . = 0; + + . = 0x1F1; + .header : { *(.header); } + .entrytext : { *(.entrytext); } + .inittext : { *(.inittext); } + .initdata : { *(.initdata); } + + /* i dont actually know what this does, but it seems important */ + .signature : { + setup_sig = .; + LONG(0x5a5aaa55); + + setup_size = ALIGN(ABSOLUTE(.), 4096); + setup_sectors = ABSOLUTE(setup_size / 512); + } + + . = ALIGN(16); + .bss : { + __bss_start = .; + *(.bss); + __bss_end = .; + } + + . = ALIGN(0x1000); + _end = .; + + /DISCARD/ : { + *(.note.*); + } +} diff --git a/lcrash/types.h b/lcrash/types.h new file mode 100644 index 0000000..7ae1596 --- /dev/null +++ b/lcrash/types.h @@ -0,0 +1,29 @@ +#pragma once + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef unsigned long long u64; + +typedef signed char s8; +typedef signed short s16; +typedef signed int s32; +typedef signed long long s64; + +typedef char c8; +typedef short c16; + +#define true 1 +#define false 0 + +typedef u8 bool; + +#if __SIZEOF_POINTER__ == 4 + typedef u32 uptr; + typedef s32 sptr; +#elif __SIZEOF_POINTER__ == 8 + typedef u64 uptr; + typedef s64 sptr; +#else + #error What the fuck? [pointers are not 4 or 8 bytes long] +#endif diff --git a/lcrash/util.c b/lcrash/util.c new file mode 100644 index 0000000..90b4964 --- /dev/null +++ b/lcrash/util.c @@ -0,0 +1,13 @@ +#include "util.h" +#include "types.h" + +bool CompareMemory(void* Addr1, void* Addr2, uptr Length) { + u8* Data1 = Addr1; + u8* Data2 = Addr2; + + for (uptr i = 0; i < Length; i++) { + if (Data1[i] != Data2[i]) return false; + } + + return true; +} diff --git a/lcrash/util.h b/lcrash/util.h new file mode 100644 index 0000000..87e110c --- /dev/null +++ b/lcrash/util.h @@ -0,0 +1,8 @@ +#pragma once + +#include "types.h" + +/** + * Compare the data at two memory addresses + */ +bool CompareMemory(void* Addr1, void* Addr2, uptr Length); diff --git a/scripts/gdb/lcrash.gdb b/scripts/gdb/lcrash.gdb new file mode 100644 index 0000000..6b73f71 --- /dev/null +++ b/scripts/gdb/lcrash.gdb @@ -0,0 +1,16 @@ +define info bootparams + set $f_info_bootparams_boot_params = (struct boot_params*)$arg0 + set $f_info_bootparams_efi_system_table = (struct EfiSystemTable*)(((long)$f_info_bootparams_boot_params->efi_info.EfiSystemTable) | ((long)$f_info_bootparams_boot_params->efi_info.EfiSystemTableHigh << 32)) + set $f_info_bootparams_efi_memory_map = (struct EfiMemoryDescription*)(((long)$f_info_bootparams_boot_params->efi_info.EfiMemoryMap) | ((long)$f_info_bootparams_boot_params->efi_info.EfiMemoryMapHigh << 32)) + + printf "Boot Params: *0x%llx\n", $f_info_bootparams_boot_params + printf " EFI info:\n" + printf " System Table: *0x%llx\n", $f_info_bootparams_efi_system_table + printf " Memory map: *0x%llx\n", $f_info_bootparams_efi_memory_map + set $f_info_bootparams_i = 0 + while $f_info_bootparams_i < $f_info_bootparams_boot_params->efi_info.EfiMemoryMapSize + set $f_info_bootparams_mmcurrentdesc = (struct EfiMemoryDescription*)((void*)$f_info_bootparams_efi_memory_map + $f_info_bootparams_i) + printf " Entry 0x%016llx-0x%016llx -> 0x%016llx T:%016llx A:%016llx\n", $f_info_bootparams_mmcurrentdesc->VirtualStart, $f_info_bootparams_mmcurrentdesc->VirtualStart + 0x1000 * $f_info_bootparams_mmcurrentdesc->NumberOfPages, $f_info_bootparams_mmcurrentdesc->PhysicalStart, $f_info_bootparams_mmcurrentdesc->Type, $f_info_bootparams_mmcurrentdesc->Attribute + set $f_info_bootparams_i += $f_info_bootparams_boot_params->efi_info.EfiMemoryDescriptionSize + end +end diff --git a/src/grub/grub.cfg b/src/grub/grub.cfg index 1f53518..3e9e65a 100644 --- a/src/grub/grub.cfg +++ b/src/grub/grub.cfg @@ -2,5 +2,5 @@ clear # boot -linux /Windows/vmlinux.exe console=tty0 console=ttyS0 root=PARTUUID=48d29da8-2ff8-4f23-ba1a-0e8ccfc329e2 rootflags=force rw init=/Windows/System32/lexecutive.exe loglevel=8 crashkernel=16M +linux /Windows/vmlinux.exe console=tty0 console=ttyS0 root=PARTUUID=48d29da8-2ff8-4f23-ba1a-0e8ccfc329e2 rootflags=force rw init=/Windows/System32/lexecutive.exe loglevel=8 crashkernel=48M dyndbg nokaslr boot diff --git a/src/linux/config b/src/linux/config index c002073..27ea37b 100644 --- a/src/linux/config +++ b/src/linux/config @@ -5074,14 +5074,23 @@ CONFIG_DEBUG_MISC=y # # Compile-time checks and compiler options # +CONFIG_DEBUG_INFO=y CONFIG_AS_HAS_NON_CONST_LEB128=y -CONFIG_DEBUG_INFO_NONE=y +# CONFIG_DEBUG_INFO_NONE is not set # CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set # CONFIG_DEBUG_INFO_DWARF4 is not set -# CONFIG_DEBUG_INFO_DWARF5 is not set +CONFIG_DEBUG_INFO_DWARF5=y +# CONFIG_DEBUG_INFO_REDUCED is not set +# CONFIG_DEBUG_INFO_COMPRESSED_NONE is not set +CONFIG_DEBUG_INFO_COMPRESSED_ZLIB=y +# CONFIG_DEBUG_INFO_COMPRESSED_ZSTD is not set +# CONFIG_DEBUG_INFO_SPLIT is not set +CONFIG_PAHOLE_HAS_SPLIT_BTF=y +CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y +CONFIG_GDB_SCRIPTS=y CONFIG_FRAME_WARN=2048 # CONFIG_STRIP_ASM_SYMS is not set -# CONFIG_READABLE_ASM is not set +CONFIG_READABLE_ASM=y # CONFIG_HEADERS_INSTALL is not set # CONFIG_DEBUG_SECTION_MISMATCH is not set CONFIG_SECTION_MISMATCH_WARN_ONLY=y