[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
|
COMMAND ${CoreUtils_Mkdir_EXECUTABLE} ARGS lindows_c/Users
|
||||||
|
|
||||||
# unmount filesystem
|
# unmount filesystem
|
||||||
COMMAND "umount" ARGS lindows_c
|
COMMAND umount ARGS lindows_c
|
||||||
|
|
||||||
DEPENDS
|
DEPENDS
|
||||||
lexecutive lcrash
|
lexecutive lcrash
|
||||||
|
@ -8,7 +8,7 @@ lw_project(lcrash
|
|||||||
enable_language(ASM)
|
enable_language(ASM)
|
||||||
|
|
||||||
lw_add_executable(lcrashkern
|
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)
|
add_executable(lcrashkernld IMPORTED)
|
||||||
set_property(TARGET lcrashkernld PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lcrash.ld)
|
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>
|
$<TARGET_FILE:LindowsCompilerSpec>
|
||||||
)
|
)
|
||||||
set_property(TARGET lcrashkern PROPERTY LINK_OPTIONS -nostdlib -Wl,-T,${CMAKE_CURRENT_SOURCE_DIR}/lcrash.ld )
|
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)
|
target_link_options(lcrashkern PRIVATE -fpic -pie)
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
@ -45,7 +45,7 @@ lw_add_executable(cckernel
|
|||||||
add_executable(cckernelld IMPORTED)
|
add_executable(cckernelld IMPORTED)
|
||||||
set_property(TARGET cckernelld PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/setup/compressed/compressed.ld)
|
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)
|
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
|
set_property(SOURCE setup/compressed/cckernel.S PROPERTY OBJECT_DEPENDS
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/lcrashkern.gz
|
${CMAKE_CURRENT_BINARY_DIR}/lcrashkern.gz
|
||||||
)
|
)
|
||||||
|
@ -5,13 +5,28 @@
|
|||||||
struct AcpiRSDP;
|
struct AcpiRSDP;
|
||||||
struct AcpiXSDT;
|
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
|
* ACPI Root System Description Pointer
|
||||||
*/
|
*/
|
||||||
struct [[gnu::packed]] AcpiRSDP {
|
struct [[gnu::packed]] AcpiRSDP {
|
||||||
char Signature[8];
|
c8 Signature[8];
|
||||||
u8 Checksum;
|
u8 Checksum;
|
||||||
char OEM[6];
|
c8 OEM[6];
|
||||||
u8 Revision;
|
u8 Revision;
|
||||||
[[gnu::deprecated]] // we dont care :>
|
[[gnu::deprecated]] // we dont care :>
|
||||||
u32 RSDTAddress;
|
u32 RSDTAddress;
|
||||||
@ -20,3 +35,24 @@ struct [[gnu::packed]] AcpiRSDP {
|
|||||||
u8 ExtendedChecksum;
|
u8 ExtendedChecksum;
|
||||||
u8 Reserved[3];
|
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* EfiTranslatePointer(void* FirmwarePointer) {
|
||||||
|
void* CurrentEntry = (void*)StoredMemoryMap;
|
||||||
|
|
||||||
// Scan the memory map for where our thing is
|
// Scan the memory map for where our thing is
|
||||||
for (int i = 0; i < StoredMemoryMapEntryCount; i++) {
|
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 &&
|
if (FirmwarePointer >= Entry->VirtualStart &&
|
||||||
FirmwarePointer < Entry->VirtualStart + 0x1000 * Entry->NumberOfPages) {
|
FirmwarePointer < Entry->VirtualStart + 0x1000 * Entry->NumberOfPages) {
|
||||||
return FirmwarePointer - Entry->VirtualStart + Entry->PhysicalStart;
|
return FirmwarePointer - Entry->VirtualStart + Entry->PhysicalStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CurrentEntry += StoredMemoryMapEntrySize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Well, we tried
|
// Well, we tried
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ typedef c16 EfiChar16;
|
|||||||
|
|
||||||
typedef EfiVoid* EfiHandle;
|
typedef EfiVoid* EfiHandle;
|
||||||
|
|
||||||
|
#define EFI_SIZEOF_GUID 16
|
||||||
typedef struct _EfiGuid {
|
typedef struct _EfiGuid {
|
||||||
u32 data1;
|
u32 data1;
|
||||||
u16 data2;
|
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);
|
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();
|
Hang();
|
||||||
}
|
}
|
||||||
|
|
||||||
void entry64() {
|
void entry64(struct boot_params* boot_params) {
|
||||||
while (1) {};
|
while (1) {};
|
||||||
|
|
||||||
Panic("HELLO WORLD.");
|
Panic("HELLO WORLD.");
|
||||||
|
@ -131,7 +131,7 @@ struct [[gnu::packed]] boot_params {
|
|||||||
u8 reserved0[0x4];
|
u8 reserved0[0x4];
|
||||||
void* tboot_addr;
|
void* tboot_addr;
|
||||||
struct ist_info ist_info;
|
struct ist_info ist_info;
|
||||||
struct acpi_rsdp* acpi_rsdp_addr;
|
struct AcpiRSDP* acpi_rsdp_addr;
|
||||||
u8 reserved1[0x8];
|
u8 reserved1[0x8];
|
||||||
u8 hd0_info[0x10];
|
u8 hd0_info[0x10];
|
||||||
u8 hd1_info[0x10];
|
u8 hd1_info[0x10];
|
||||||
@ -162,3 +162,13 @@ struct [[gnu::packed]] boot_params {
|
|||||||
u8 reserved5[0x30];
|
u8 reserved5[0x30];
|
||||||
u8 eddbuf[0x1ec];
|
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"
|
#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;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
while (1) {}
|
// 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
|
#pragma once
|
||||||
|
|
||||||
#include "../../types.h"
|
#include "../../types.h"
|
||||||
|
#include "../../lnxboot.h"
|
||||||
|
|
||||||
[[packed]]
|
#define PT_NULL 0
|
||||||
struct Elf64_Ehdr {
|
#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];
|
c8 e_ident[16];
|
||||||
u16 e_type;
|
u16 e_type;
|
||||||
u16 e_machine;
|
u16 e_machine;
|
||||||
@ -20,8 +29,7 @@ struct Elf64_Ehdr {
|
|||||||
u16 e_shstrndx;
|
u16 e_shstrndx;
|
||||||
};
|
};
|
||||||
|
|
||||||
[[packed]]
|
struct [[gnu::packed]] Elf64_Phdr {
|
||||||
struct Elf64_Phdr {
|
|
||||||
u32 p_type;
|
u32 p_type;
|
||||||
u32 p_flags;
|
u32 p_flags;
|
||||||
u64 p_offset;
|
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
|
/// 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
|
// Fill in the table in a horribly inefficient manner
|
||||||
Code = 0;
|
Code = 0;
|
||||||
for (u32 Bits = 0; Bits < 15; Bits++) {
|
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++) {
|
for (int i = 0; i < CodeCounts[Bits]; i++) {
|
||||||
// Take the next symbol
|
// Take the next symbol
|
||||||
Code = NextSym[Bits];
|
Code = NextSym[Bits];
|
||||||
@ -93,7 +93,7 @@ uptr GzipDecompress(c8* Input, uptr InputSize, c8* Output) {
|
|||||||
|
|
||||||
const u32 DistanceAddends[30] = {
|
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,
|
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;
|
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);
|
uptr BinaryLength = GzipDecompress(cckernel, (u8*)&_CC_ecckernel - (u8*)&_CC_cckernel, kernel_load_addr);
|
||||||
|
|
||||||
// start the kernel
|
// 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
|
// we fucked up
|
||||||
while (1) {}
|
while (1) {}
|
||||||
|
@ -1,9 +1,16 @@
|
|||||||
/// File with support code for gcc memory stuff
|
/// File with support code for gcc memory stuff
|
||||||
.section ".text", "ax"
|
.section ".text", "ax"
|
||||||
.globl memset
|
.globl memset
|
||||||
memset:
|
memset:
|
||||||
mov %rdx, %rcx
|
mov %rdx, %rcx
|
||||||
mov %sil, %al
|
mov %sil, %al
|
||||||
rep stosb (%rdi)
|
rep stosb (%rdi)
|
||||||
mov %rdi, %rax
|
mov %rdi, %rax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
.globl memcpy
|
||||||
|
memcpy:
|
||||||
|
mov %rdx, %rcx
|
||||||
|
rep movsb (%rsi), (%rdi)
|
||||||
|
mov %rdi, %rax
|
||||||
|
ret
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
bool CompareMemory(void* Addr1, void* Addr2, uptr Length) {
|
bool CompareMemory(const void* Addr1, const void* Addr2, u32 Length) {
|
||||||
u8* Data1 = Addr1;
|
const u8* Data1 = Addr1;
|
||||||
u8* Data2 = Addr2;
|
const u8* Data2 = Addr2;
|
||||||
|
|
||||||
for (uptr i = 0; i < Length; i++) {
|
for (uptr i = 0; i < Length; i++) {
|
||||||
if (Data1[i] != Data2[i]) return false;
|
if (Data1[i] != Data2[i]) return false;
|
||||||
|
@ -5,4 +5,4 @@
|
|||||||
/**
|
/**
|
||||||
* Compare the data at two memory addresses
|
* 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