[lcrash/cckernel] FIX: don't depend on undefined behavior + fix typo in addend tables
This commit is contained in:
parent
8c6bfe0edf
commit
d4bb65f49b
@ -365,7 +365,7 @@ add_custom_command(OUTPUT lindows_c.img
|
||||
COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Users
|
||||
|
||||
# unmount filesystem
|
||||
COMMAND "umount" ARGS lindows_c
|
||||
COMMAND umount ARGS lindows_c
|
||||
|
||||
DEPENDS
|
||||
lexecutive lcrash
|
||||
|
@ -8,7 +8,7 @@ lw_project(lcrash
|
||||
enable_language(ASM)
|
||||
|
||||
lw_add_executable(lcrashkern
|
||||
SOURCES lcrash.c util.c efi/guid.c efi/memmap.c gdb/gdb.c
|
||||
SOURCES main.c util.c lnxboot.c acpi/acpi.c efi/efi.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)
|
||||
@ -17,7 +17,7 @@ set_property(TARGET lcrashkern PROPERTY LINK_DEPENDS
|
||||
$<TARGET_FILE:LindowsCompilerSpec>
|
||||
)
|
||||
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_compile_options(lcrashkern PRIVATE -ggdb -fpic -pie -Wall -fanalyzer)
|
||||
target_link_options(lcrashkern PRIVATE -fpic -pie)
|
||||
|
||||
add_custom_command(
|
||||
@ -45,7 +45,7 @@ lw_add_executable(cckernel
|
||||
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
|
||||
target_compile_options(cckernel PRIVATE -ggdb -mno-sse -mno-avx -Wall -fanalyzer) # 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
|
||||
)
|
||||
|
@ -5,13 +5,28 @@
|
||||
struct AcpiRSDP;
|
||||
struct AcpiXSDT;
|
||||
|
||||
/**
|
||||
* Common ACPI table header
|
||||
*/
|
||||
struct AcpiSDTHeader {
|
||||
c8 Signature[4];
|
||||
u32 Length;
|
||||
u8 Revision;
|
||||
u8 Checksum;
|
||||
c8 OEMID[6];
|
||||
c8 OEMTableID[6];
|
||||
u32 OEMRevision;
|
||||
u32 CreatorID;
|
||||
u32 CreatorRevision;
|
||||
};
|
||||
|
||||
/**
|
||||
* ACPI Root System Description Pointer
|
||||
*/
|
||||
struct [[gnu::packed]] AcpiRSDP {
|
||||
char Signature[8];
|
||||
c8 Signature[8];
|
||||
u8 Checksum;
|
||||
char OEM[6];
|
||||
c8 OEM[6];
|
||||
u8 Revision;
|
||||
[[gnu::deprecated]] // we dont care :>
|
||||
u32 RSDTAddress;
|
||||
@ -20,3 +35,24 @@ struct [[gnu::packed]] AcpiRSDP {
|
||||
u8 ExtendedChecksum;
|
||||
u8 Reserved[3];
|
||||
};
|
||||
|
||||
/**
|
||||
* The table of tables
|
||||
*/
|
||||
struct AcpiXSDT {
|
||||
struct AcpiSDTHeader Header;
|
||||
|
||||
/// Pointers to other tables
|
||||
[[gnu::aligned(4)]]
|
||||
u64 Tables[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize ACPI code
|
||||
*/
|
||||
void AcpiInitialize();
|
||||
|
||||
/**
|
||||
* Check if ACPI is present
|
||||
*/
|
||||
bool AcpiPresent();
|
||||
|
@ -15,19 +15,23 @@ void EfiLoadStoredMemoryMap(
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate a pointer using what we can recover from the UEFI memory map, may return something invalid.
|
||||
* Translate a pointer using what we can recover from the UEFI memory map, returns 0 if not found
|
||||
*/
|
||||
void* EfiTranslatePointer(void* FirmwarePointer) {
|
||||
void* CurrentEntry = (void*)StoredMemoryMap;
|
||||
|
||||
// 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);
|
||||
struct EfiMemoryDescription* Entry = (struct EfiMemoryDescription*)CurrentEntry;
|
||||
|
||||
if (FirmwarePointer >= Entry->VirtualStart &&
|
||||
FirmwarePointer < Entry->VirtualStart + 0x1000 * Entry->NumberOfPages) {
|
||||
return FirmwarePointer - Entry->VirtualStart + Entry->PhysicalStart;
|
||||
}
|
||||
|
||||
CurrentEntry += StoredMemoryMapEntrySize;
|
||||
}
|
||||
|
||||
// Well, we tried
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ typedef c16 EfiChar16;
|
||||
|
||||
typedef EfiVoid* EfiHandle;
|
||||
|
||||
#define EFI_SIZEOF_GUID 16
|
||||
typedef struct _EfiGuid {
|
||||
u32 data1;
|
||||
u16 data2;
|
||||
|
@ -27,4 +27,5 @@ def add_pretty_printer(name, printer, custom_lookup = None):
|
||||
|
||||
add_pretty_printer("_EfiGuid", EfiGuidPrinter, lambda val: EfiGuidPrinter(val) if val.type.strip_typedefs().tag == "_EfiGuid" else None);
|
||||
|
||||
# --- ---
|
||||
# --- code ---
|
||||
# def transition_cckernel():
|
||||
|
@ -61,7 +61,7 @@ void Panic(const char* message) {
|
||||
Hang();
|
||||
}
|
||||
|
||||
void entry64() {
|
||||
void entry64(struct boot_params* boot_params) {
|
||||
while (1) {};
|
||||
|
||||
Panic("HELLO WORLD.");
|
||||
|
@ -131,7 +131,7 @@ struct [[gnu::packed]] boot_params {
|
||||
u8 reserved0[0x4];
|
||||
void* tboot_addr;
|
||||
struct ist_info ist_info;
|
||||
struct acpi_rsdp* acpi_rsdp_addr;
|
||||
struct AcpiRSDP* acpi_rsdp_addr;
|
||||
u8 reserved1[0x8];
|
||||
u8 hd0_info[0x10];
|
||||
u8 hd1_info[0x10];
|
||||
@ -162,3 +162,13 @@ struct [[gnu::packed]] boot_params {
|
||||
u8 reserved5[0x30];
|
||||
u8 eddbuf[0x1ec];
|
||||
};
|
||||
|
||||
/**
|
||||
* Setup info provided by cckernel
|
||||
*/
|
||||
extern struct setup_info* BootSetupInfo;
|
||||
|
||||
/**
|
||||
* Boot params provided by cckernel
|
||||
*/
|
||||
extern struct boot_params* BootBootParams;
|
||||
|
@ -1,7 +1,49 @@
|
||||
#include "elf.h"
|
||||
|
||||
int ElfExecute(void* Binary, void* LoadAddr) {
|
||||
extern void* memset(void* dest, int ch, uptr count);
|
||||
extern void* memcpy(void* dest, const void* src, uptr count);
|
||||
|
||||
[[noreturn]]
|
||||
void ElfExecute(void* Binary, void* LoadAddr, struct boot_params* BootParams) {
|
||||
struct Elf64_Ehdr* ElfHeader = (struct Elf64_Ehdr*)Binary;
|
||||
|
||||
while (1) {}
|
||||
// Here we would check if we have a valid elf binary
|
||||
// unfortunately, we would have no way to notify the
|
||||
// user, so we'll just pray it is
|
||||
|
||||
// Hopefully we have progtam headers
|
||||
void* ProgramHeaders = Binary + ElfHeader->e_phoff;
|
||||
|
||||
// Load everything into memory
|
||||
for (int i = 0; i < ElfHeader->e_phnum; i++) {
|
||||
struct Elf64_Phdr* ProgramHeader = (struct Elf64_Phdr*)ProgramHeaders;
|
||||
|
||||
// Only load loadable segments
|
||||
if (ProgramHeader->p_type == PT_LOAD) {
|
||||
void* FileStart = Binary + ProgramHeader->p_offset;
|
||||
void* LoadStart = LoadAddr + ProgramHeader->p_vaddr;
|
||||
|
||||
uptr LoadSize = ProgramHeader->p_memsz;
|
||||
if (LoadSize > ProgramHeader->p_filesz) LoadSize = ProgramHeader->p_filesz;
|
||||
|
||||
memset(LoadStart, 0, ProgramHeader->p_memsz);
|
||||
memcpy(LoadStart, FileStart, LoadSize);
|
||||
}
|
||||
|
||||
ProgramHeaders += ElfHeader->e_phentsize;
|
||||
}
|
||||
|
||||
// Collect entry point
|
||||
[[noreturn]] void fake_dont_call(struct boot_params*); // stupid hack
|
||||
typeof(fake_dont_call)* KernelEntry = LoadAddr + ElfHeader->e_entry;
|
||||
|
||||
// Set boot parameters
|
||||
struct setup_info* SetupInfo = (void*)BootParams + 0x1f1;
|
||||
SetupInfo->code32_start = LoadAddr;
|
||||
|
||||
// Enter the kernel
|
||||
KernelEntry(BootParams);
|
||||
|
||||
// we shouldnt ever end up here
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
@ -1,9 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../types.h"
|
||||
#include "../../lnxboot.h"
|
||||
|
||||
[[packed]]
|
||||
struct Elf64_Ehdr {
|
||||
#define PT_NULL 0
|
||||
#define PT_LOAD 1
|
||||
#define PT_DYNAMIC 2
|
||||
#define PT_INTERP 3
|
||||
#define PT_NOTE 4
|
||||
#define PT_SHLIB 5
|
||||
#define PT_PHDR 6
|
||||
#define PT_TLS 7
|
||||
|
||||
struct [[gnu::packed]] Elf64_Ehdr {
|
||||
c8 e_ident[16];
|
||||
u16 e_type;
|
||||
u16 e_machine;
|
||||
@ -20,8 +29,7 @@ struct Elf64_Ehdr {
|
||||
u16 e_shstrndx;
|
||||
};
|
||||
|
||||
[[packed]]
|
||||
struct Elf64_Phdr {
|
||||
struct [[gnu::packed]] Elf64_Phdr {
|
||||
u32 p_type;
|
||||
u32 p_flags;
|
||||
u64 p_offset;
|
||||
@ -33,4 +41,4 @@ struct Elf64_Phdr {
|
||||
};
|
||||
|
||||
/// 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);
|
||||
void ElfExecute(void* Binary, void* LoadAddr, struct boot_params*);
|
||||
|
@ -33,7 +33,7 @@ void GzipPopulateTable(
|
||||
// Fill in the table in a horribly inefficient manner
|
||||
Code = 0;
|
||||
for (u32 Bits = 0; Bits < 15; Bits++) {
|
||||
const uptr OutputMask = ~(-1 << Bits);
|
||||
const uptr OutputMask = ~((uptr)-1 << Bits);
|
||||
for (int i = 0; i < CodeCounts[Bits]; i++) {
|
||||
// Take the next symbol
|
||||
Code = NextSym[Bits];
|
||||
@ -93,7 +93,7 @@ uptr GzipDecompress(c8* Input, uptr InputSize, c8* Output) {
|
||||
|
||||
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
|
||||
1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577
|
||||
};
|
||||
|
||||
void* Location = (void*)Input;
|
||||
|
@ -23,7 +23,7 @@ void ccmain(void* imgbase, struct boot_params* boot_params) {
|
||||
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);
|
||||
ElfExecute(kernel_load_addr, kernel_load_addr + BinaryLength + 0x1000 - BinaryLength % 0x1000, boot_params);
|
||||
|
||||
// we fucked up
|
||||
while (1) {}
|
||||
|
@ -1,9 +1,16 @@
|
||||
/// File with support code for gcc memory stuff
|
||||
.section ".text", "ax"
|
||||
.globl memset
|
||||
.globl memset
|
||||
memset:
|
||||
mov %rdx, %rcx
|
||||
mov %sil, %al
|
||||
rep stosb (%rdi)
|
||||
mov %rdi, %rax
|
||||
ret
|
||||
|
||||
.globl memcpy
|
||||
memcpy:
|
||||
mov %rdx, %rcx
|
||||
rep movsb (%rsi), (%rdi)
|
||||
mov %rdi, %rax
|
||||
ret
|
||||
|
@ -1,9 +1,9 @@
|
||||
#include "util.h"
|
||||
#include "types.h"
|
||||
|
||||
bool CompareMemory(void* Addr1, void* Addr2, uptr Length) {
|
||||
u8* Data1 = Addr1;
|
||||
u8* Data2 = Addr2;
|
||||
bool CompareMemory(const void* Addr1, const void* Addr2, u32 Length) {
|
||||
const u8* Data1 = Addr1;
|
||||
const u8* Data2 = Addr2;
|
||||
|
||||
for (uptr i = 0; i < Length; i++) {
|
||||
if (Data1[i] != Data2[i]) return false;
|
||||
|
@ -5,4 +5,4 @@
|
||||
/**
|
||||
* Compare the data at two memory addresses
|
||||
*/
|
||||
bool CompareMemory(void* Addr1, void* Addr2, uptr Length);
|
||||
bool CompareMemory(const void* Addr1, const void* Addr2, u32 Length);
|
||||
|
Loading…
x
Reference in New Issue
Block a user