bad
This commit is contained in:
parent
f0ec001801
commit
91d3d1b663
@ -6,7 +6,7 @@ lw_project(lcrash
|
||||
)
|
||||
|
||||
lw_add_executable(lcrash
|
||||
SOURCES lcrash.c
|
||||
SOURCES lcrash.c efi/memmap.c
|
||||
)
|
||||
add_executable(lcrashld IMPORTED)
|
||||
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>
|
||||
)
|
||||
set_property(TARGET lcrash PROPERTY LINK_OPTIONS -nostdlib -Wl,-T,${CMAKE_CURRENT_SOURCE_DIR}/lcrash.ld)
|
||||
target_compile_options(lcrash PRIVATE -ggdb)
|
||||
|
109
lcrash/lcrash.c
109
lcrash/lcrash.c
@ -1,4 +1,6 @@
|
||||
#include "lnxboot.h"
|
||||
#include "efi/types.h"
|
||||
#include "efi/memmap.h"
|
||||
|
||||
extern void _start();
|
||||
|
||||
@ -7,7 +9,7 @@ extern void _start();
|
||||
[[gnu::aligned(1)]]
|
||||
[[gnu::unavailable("not present at runtime. use setup_info instead")]]
|
||||
struct setup_info bzhead = {
|
||||
.setup_sects = 1, // 1 512-byte sector
|
||||
.setup_sects = 2, // 1 512-byte sector
|
||||
.boot_flag = 0xAA55,
|
||||
.syssize = 16,
|
||||
.jump_instruction = 0xEB,
|
||||
@ -16,7 +18,7 @@ struct setup_info bzhead = {
|
||||
.version = 0x020F,
|
||||
.loadflags = 0x01, // LOADED_HIGH,
|
||||
.kernel_alignment = 1,
|
||||
.relocatable_kernel = 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
|
||||
@ -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() {
|
||||
asm ("jmp _start");
|
||||
asm ( // grab the setup_info and boot_params locations
|
||||
"mov %%rsi, %1\n"
|
||||
"mov %%rsi, %0\n"
|
||||
@ -72,27 +97,70 @@ extern void _start() {
|
||||
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() {
|
||||
// get the zero page
|
||||
//boot_params = (struct boot_params*)(
|
||||
// 0x202 - 0x1f1
|
||||
// + setup_info->jump_offset
|
||||
// + (u64)setup_info);
|
||||
// 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));
|
||||
|
||||
// do we have efi?
|
||||
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)
|
||||
// as you can see, we gave up!
|
||||
// serial_port = (unsigned short)*(long*)&serial_base;
|
||||
serial_port = 0x3f8;
|
||||
EfiLoadStoredMemoryMap(
|
||||
(struct EfiMemoryDescription*)(
|
||||
(u64)boot_params->efi_info.EfiMemoryMap |
|
||||
((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
|
||||
u8* cmdline_ptr = (u8*)((u64)setup_info->cmd_line_ptr | ((u64)boot_params->ext_cmd_line_ptr << 32));
|
||||
FirmwareVendor = EfiTranslatePointer(systab_ptr->FirmwareVendor);
|
||||
while (1) {
|
||||
volatile char* a = FirmwareVendor;
|
||||
}
|
||||
}
|
||||
|
||||
// check out command line
|
||||
serial_puts(cmdline_ptr);
|
||||
serial_putc('\r');
|
||||
serial_putc('\n');
|
||||
// -- find acpi --
|
||||
struct AcpiRSDP* AcpiRSDP = 0;
|
||||
|
||||
// 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
|
||||
// for some fucking reason. allocate our strings and shit on the stack.
|
||||
//char s_you_fucked_up[] = "!!! YOU FUCKED UP !!!\n";
|
||||
@ -124,6 +192,5 @@ void entry() {
|
||||
// serial_puts(bzhead.cmd_line_ptr);
|
||||
|
||||
// Die.
|
||||
asm ("cli");
|
||||
asm ("hlt");
|
||||
Panic("Nothing left to do.");
|
||||
}
|
||||
|
@ -1,24 +1,36 @@
|
||||
OUTPUT_FORMAT(elf64-x86-64)
|
||||
|
||||
ENTRY(_start)
|
||||
|
||||
MEMORY {
|
||||
code (rx) : ORIGIN = 0x0dfe8000, LENGTH = 0x00001000
|
||||
data (rw) : ORIGIN = 0x0dff0000, LENGTH = 0x00001000
|
||||
}
|
||||
|
||||
SECTIONS {
|
||||
.lnxhead 0x01f1 : ALIGN(1) {
|
||||
*(.lnxhead);
|
||||
}
|
||||
|
||||
.rodata 0x900000 : ALIGN(1) {
|
||||
.rodata : ALIGN(1) {
|
||||
*(.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);
|
||||
}
|
||||
} > code
|
||||
|
||||
.text : ALIGN(512) { *(.text); }
|
||||
.text : ALIGN(512) { *(.text); } > code
|
||||
.bss : { *(.bss); }
|
||||
|
||||
.kernel_imports 0xFFFFFFFF : {
|
||||
*(.kernel_imports);
|
||||
}
|
||||
.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); }
|
||||
|
||||
/DISCARD/ : {
|
||||
*(*);
|
||||
|
@ -1,9 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned long long u64;
|
||||
#include "types.h"
|
||||
#include "acpi/acpi.h"
|
||||
|
||||
struct [[gnu::packed]] setup_info {
|
||||
u8 setup_sects;
|
||||
@ -61,13 +59,14 @@ struct [[gnu::packed]] screen_info {
|
||||
u16 reserved2;
|
||||
u8 orig_video_lines;
|
||||
u8 orig_video_isVGA;
|
||||
u8 orig_video_points;
|
||||
u16 orig_video_points;
|
||||
|
||||
// linear frame buffer
|
||||
u16 lfb_width;
|
||||
u16 lfb_height;
|
||||
u16 lfb_depth;
|
||||
u32 lfb_base;
|
||||
u32 lfb_size;
|
||||
u16 cl_magic;
|
||||
u16 cl_offset;
|
||||
u16 lfb_linelength;
|
||||
@ -79,8 +78,8 @@ struct [[gnu::packed]] screen_info {
|
||||
u8 blue_pos;
|
||||
u8 reserved_size;
|
||||
u8 reserved_pos;
|
||||
u8 vesapm_seg;
|
||||
u8 vesapm_off;
|
||||
u16 vesapm_seg;
|
||||
u16 vesapm_off;
|
||||
u16 pages;
|
||||
u16 vesa_attributes;
|
||||
u32 capabilities;
|
||||
@ -106,11 +105,20 @@ struct [[gnu::packed]] edid_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 {
|
||||
u8 pad;
|
||||
u64 base;
|
||||
u64 length;
|
||||
u32 type;
|
||||
};
|
||||
|
||||
struct [[gnu::packed]] edd_info {
|
||||
@ -123,8 +131,8 @@ struct [[gnu::packed]] boot_params {
|
||||
u8 reserved0[0x4];
|
||||
void* tboot_addr;
|
||||
struct ist_info ist_info;
|
||||
void* acpi_rsdp_addr;
|
||||
u8 reserved1[0x2];
|
||||
struct acpi_rsdp* acpi_rsdp_addr;
|
||||
u8 reserved1[0x8];
|
||||
u8 hd0_info[0x10];
|
||||
u8 hd1_info[0x10];
|
||||
struct sys_desc_table sys_desc_table;
|
||||
@ -136,7 +144,7 @@ struct [[gnu::packed]] boot_params {
|
||||
/// cmd_line_ptr high 32 bits
|
||||
u32 ext_cmd_line_ptr;
|
||||
u8 reserved2[0x70];
|
||||
void* cc_blob_address;
|
||||
u32 cc_blob_address;
|
||||
struct edid_info edid_info;
|
||||
struct efi_info efi_info;
|
||||
u32 alt_mem_k;
|
||||
@ -150,7 +158,7 @@ struct [[gnu::packed]] boot_params {
|
||||
u8 sentinel;
|
||||
u8 reserved4[0xa0]; // setup_info lives here!
|
||||
u8 edd_mbr_sig_buffer[0x40];
|
||||
u8 e20_table[0xa00];
|
||||
struct e820_entry e820_table[128];
|
||||
u8 reserved5[0x30];
|
||||
u8 eddbuf[0x1ec];
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user