This commit is contained in:
xwashere 2024-03-19 08:44:57 -04:00
parent f0ec001801
commit 91d3d1b663
Signed by: XWasHere
GPG Key ID: 042F8BFA1B0EF93B
4 changed files with 131 additions and 43 deletions

View File

@ -6,7 +6,7 @@ lw_project(lcrash
) )
lw_add_executable(lcrash lw_add_executable(lcrash
SOURCES lcrash.c SOURCES lcrash.c efi/memmap.c
) )
add_executable(lcrashld IMPORTED) 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}/lcrash.ld)
@ -15,3 +15,4 @@ set_property(TARGET lcrash PROPERTY LINK_DEPENDS
$<TARGET_FILE:LindowsCompilerSpec> $<TARGET_FILE:LindowsCompilerSpec>
) )
set_property(TARGET lcrash PROPERTY LINK_OPTIONS -nostdlib -Wl,-T,${CMAKE_CURRENT_SOURCE_DIR}/lcrash.ld) set_property(TARGET lcrash PROPERTY LINK_OPTIONS -nostdlib -Wl,-T,${CMAKE_CURRENT_SOURCE_DIR}/lcrash.ld)
target_compile_options(lcrash PRIVATE -ggdb)

View File

@ -1,4 +1,6 @@
#include "lnxboot.h" #include "lnxboot.h"
#include "efi/types.h"
#include "efi/memmap.h"
extern void _start(); extern void _start();
@ -7,7 +9,7 @@ extern void _start();
[[gnu::aligned(1)]] [[gnu::aligned(1)]]
[[gnu::unavailable("not present at runtime. use setup_info instead")]] [[gnu::unavailable("not present at runtime. use setup_info instead")]]
struct setup_info bzhead = { struct setup_info bzhead = {
.setup_sects = 1, // 1 512-byte sector .setup_sects = 2, // 1 512-byte sector
.boot_flag = 0xAA55, .boot_flag = 0xAA55,
.syssize = 16, .syssize = 16,
.jump_instruction = 0xEB, .jump_instruction = 0xEB,
@ -16,7 +18,7 @@ struct setup_info bzhead = {
.version = 0x020F, .version = 0x020F,
.loadflags = 0x01, // LOADED_HIGH, .loadflags = 0x01, // LOADED_HIGH,
.kernel_alignment = 1, .kernel_alignment = 1,
.relocatable_kernel = 1, .relocatable_kernel = 0,
.xloadflags = 0x13, // XLF_KERNEL_64 | XLF_CAN_BE_LOADED_ABOVE_4G | XLF_5LEVEL .xloadflags = 0x13, // XLF_KERNEL_64 | XLF_CAN_BE_LOADED_ABOVE_4G | XLF_5LEVEL
.cmdline_size = 255, // max command line size .cmdline_size = 255, // max command line size
.init_size = 0x10000 // we dont need THAT much memory .init_size = 0x10000 // we dont need THAT much memory
@ -60,8 +62,31 @@ void serial_put_formatted_u64(u64 v) {
} }
} }
[[gnu::section(".text._start"), gnu::naked]] /**
* We can't do anything, just hang.
*/
[[noreturn, gnu::naked]]
void Hang() {
// This should make us hang
asm volatile (
" cli\n"
"1: hlt\n"
" jmp 1b"
);
}
/**
* Congratulations, you panicked twice!
*/
[[noreturn]]
void Panic(const char* message) {
// We don't even do anything with the message, but it's nice to have just in case.
Hang();
}
[[gnu::section(".text._start"), gnu::naked, gnu::no_reorder]]
extern void _start() { extern void _start() {
asm ("jmp _start");
asm ( // grab the setup_info and boot_params locations asm ( // grab the setup_info and boot_params locations
"mov %%rsi, %1\n" "mov %%rsi, %1\n"
"mov %%rsi, %0\n" "mov %%rsi, %0\n"
@ -72,27 +97,70 @@ extern void _start() {
asm ("jmp entry"); asm ("jmp entry");
} }
[[gnu::section(".text._start")]] c16* FirmwareVendor = 0;
/**
* 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() { void entry() {
// get the zero page // get command line from kernel. we likely won't use it, but its nice to have.
//boot_params = (struct boot_params*)( u8* cmdline_ptr = (u8*)((u64)setup_info->cmd_line_ptr | ((u64)boot_params->ext_cmd_line_ptr << 32));
// 0x202 - 0x1f1
// + setup_info->jump_offset // do we have efi?
// + (u64)setup_info); struct EfiSystemTable* systab_ptr = 0;
if (boot_params) {
systab_ptr = (struct EfiSystemTable*)(
(u64)boot_params->efi_info.EfiSystemTable |
((u64)boot_params->efi_info.EfiSystemTableHigh << 32)
);
// orignally we would try to import the serial port from the kernel (see kexec tools) EfiLoadStoredMemoryMap(
// as you can see, we gave up! (struct EfiMemoryDescription*)(
// serial_port = (unsigned short)*(long*)&serial_base; (u64)boot_params->efi_info.EfiMemoryMap |
serial_port = 0x3f8; ((u64)boot_params->efi_info.EfiMemoryMapHigh << 32)
), // this might be 0, we should probably check ---------------V
boot_params->efi_info.EfiMemoryMapSize / boot_params->efi_info.EfiMemoryDescriptionSize,
boot_params->efi_info.EfiMemoryDescriptionSize
);
// construct pointers FirmwareVendor = EfiTranslatePointer(systab_ptr->FirmwareVendor);
u8* cmdline_ptr = (u8*)((u64)setup_info->cmd_line_ptr | ((u64)boot_params->ext_cmd_line_ptr << 32)); while (1) {
volatile char* a = FirmwareVendor;
}
}
// check out command line // -- find acpi --
serial_puts(cmdline_ptr); struct AcpiRSDP* AcpiRSDP = 0;
serial_putc('\r');
serial_putc('\n');
// check bootparams
if (boot_params->acpi_rsdp_addr) AcpiRSDP = boot_params->acpi_rsdp_addr;
// check efi
if (!AcpiRSDP && systab_ptr && systab_ptr->NumberOfTableEntries) {
volatile void* ConfigurationTable = EfiTranslatePointer(systab_ptr->ConfigurationTable);
}
// we're playing where's waldo with this stupid fucking tableS
if (!AcpiRSDP) {
for (struct AcpiRSDP* addr = 0x00000000; addr < 0x000FFFFF; addr = (void*)addr + 16) {
if (addr->Signature[0] == 'R' && addr->Signature[1] == 'S'
&& addr->Signature[2] == 'D' && addr->Signature[3] == ' '
&& addr->Signature[4] == 'P' && addr->Signature[5] == 'T'
&& addr->Signature[6] == 'R' && addr->Signature[7] == ' ') {
AcpiRSDP = addr;
break;
}
}
}
if (!AcpiRSDP) Panic("Failed to find ACPI RSDP");
// do we have acpi?
asm volatile ("ljmp 0");
// we dont have the privilege of getting a rodata segment. any reads off our stack cause a triple fault // 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. // for some fucking reason. allocate our strings and shit on the stack.
//char s_you_fucked_up[] = "!!! YOU FUCKED UP !!!\n"; //char s_you_fucked_up[] = "!!! YOU FUCKED UP !!!\n";
@ -124,6 +192,5 @@ void entry() {
// serial_puts(bzhead.cmd_line_ptr); // serial_puts(bzhead.cmd_line_ptr);
// Die. // Die.
asm ("cli"); Panic("Nothing left to do.");
asm ("hlt");
} }

View File

@ -1,24 +1,36 @@
OUTPUT_FORMAT(elf64-x86-64) OUTPUT_FORMAT(elf64-x86-64)
ENTRY(_start)
MEMORY {
code (rx) : ORIGIN = 0x0dfe8000, LENGTH = 0x00001000
data (rw) : ORIGIN = 0x0dff0000, LENGTH = 0x00001000
}
SECTIONS { SECTIONS {
.lnxhead 0x01f1 : ALIGN(1) { .lnxhead 0x01f1 : ALIGN(1) {
*(.lnxhead); *(.lnxhead);
} }
.rodata 0x900000 : ALIGN(1) { .rodata : ALIGN(1) {
*(.rodata); *(.rodata);
} } > data
.text._start 0x80000000 : ALIGN(1) { /* this section helps us to coerce the linker into not breaking down because of big addresses */
.text._start 0xdfe8000 : ALIGN(1) {
*(.text._start); *(.text._start);
} } > code
.text : ALIGN(512) { *(.text); } .text : ALIGN(512) { *(.text); } > code
.bss : { *(.bss); } .bss : { *(.bss); }
.kernel_imports 0xFFFFFFFF : { .debug_info 0 : { *(.debug_info); }
*(.kernel_imports); .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); }
/DISCARD/ : { /DISCARD/ : {
*(*); *(*);

View File

@ -1,9 +1,7 @@
#pragma once #pragma once
typedef unsigned char u8; #include "types.h"
typedef unsigned short u16; #include "acpi/acpi.h"
typedef unsigned int u32;
typedef unsigned long long u64;
struct [[gnu::packed]] setup_info { struct [[gnu::packed]] setup_info {
u8 setup_sects; u8 setup_sects;
@ -61,13 +59,14 @@ struct [[gnu::packed]] screen_info {
u16 reserved2; u16 reserved2;
u8 orig_video_lines; u8 orig_video_lines;
u8 orig_video_isVGA; u8 orig_video_isVGA;
u8 orig_video_points; u16 orig_video_points;
// linear frame buffer // linear frame buffer
u16 lfb_width; u16 lfb_width;
u16 lfb_height; u16 lfb_height;
u16 lfb_depth; u16 lfb_depth;
u32 lfb_base; u32 lfb_base;
u32 lfb_size;
u16 cl_magic; u16 cl_magic;
u16 cl_offset; u16 cl_offset;
u16 lfb_linelength; u16 lfb_linelength;
@ -79,8 +78,8 @@ struct [[gnu::packed]] screen_info {
u8 blue_pos; u8 blue_pos;
u8 reserved_size; u8 reserved_size;
u8 reserved_pos; u8 reserved_pos;
u8 vesapm_seg; u16 vesapm_seg;
u8 vesapm_off; u16 vesapm_off;
u16 pages; u16 pages;
u16 vesa_attributes; u16 vesa_attributes;
u32 capabilities; u32 capabilities;
@ -106,11 +105,20 @@ struct [[gnu::packed]] edid_info {
}; };
struct [[gnu::packed]] efi_info { struct [[gnu::packed]] efi_info {
u8 pad[0x20]; u32 EfiLoaderSignature;
u32 EfiSystemTable;
u32 EfiMemoryDescriptionSize;
u32 EfiMemoryDescriptionVersion;
u32 EfiMemoryMap;
u32 EfiMemoryMapSize;
u32 EfiSystemTableHigh;
u32 EfiMemoryMapHigh;
}; };
struct [[gnu::packed]] e820_entry { struct [[gnu::packed]] e820_entry {
u8 pad; u64 base;
u64 length;
u32 type;
}; };
struct [[gnu::packed]] edd_info { struct [[gnu::packed]] edd_info {
@ -123,8 +131,8 @@ 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;
void* acpi_rsdp_addr; struct acpi_rsdp* acpi_rsdp_addr;
u8 reserved1[0x2]; u8 reserved1[0x8];
u8 hd0_info[0x10]; u8 hd0_info[0x10];
u8 hd1_info[0x10]; u8 hd1_info[0x10];
struct sys_desc_table sys_desc_table; struct sys_desc_table sys_desc_table;
@ -136,7 +144,7 @@ struct [[gnu::packed]] boot_params {
/// cmd_line_ptr high 32 bits /// cmd_line_ptr high 32 bits
u32 ext_cmd_line_ptr; u32 ext_cmd_line_ptr;
u8 reserved2[0x70]; u8 reserved2[0x70];
void* cc_blob_address; u32 cc_blob_address;
struct edid_info edid_info; struct edid_info edid_info;
struct efi_info efi_info; struct efi_info efi_info;
u32 alt_mem_k; u32 alt_mem_k;
@ -150,7 +158,7 @@ struct [[gnu::packed]] boot_params {
u8 sentinel; u8 sentinel;
u8 reserved4[0xa0]; // setup_info lives here! u8 reserved4[0xa0]; // setup_info lives here!
u8 edd_mbr_sig_buffer[0x40]; u8 edd_mbr_sig_buffer[0x40];
u8 e20_table[0xa00]; struct e820_entry e820_table[128];
u8 reserved5[0x30]; u8 reserved5[0x30];
u8 eddbuf[0x1ec]; u8 eddbuf[0x1ec];
}; };