bad
This commit is contained in:
parent
f0ec001801
commit
91d3d1b663
@ -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)
|
||||||
|
109
lcrash/lcrash.c
109
lcrash/lcrash.c
@ -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");
|
|
||||||
}
|
}
|
||||||
|
@ -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/ : {
|
||||||
*(*);
|
*(*);
|
||||||
|
@ -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];
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user