panic: Prevent recursive panics during early boot

This commit is contained in:
lukflug 2021-12-14 06:47:28 +01:00 committed by mintsuki
parent 1e69aff0d7
commit 4cb616bcad
7 changed files with 153 additions and 4 deletions

View File

@ -216,6 +216,12 @@ test.hdd:
parted -s test.hdd mklabel gpt parted -s test.hdd mklabel gpt
parted -s test.hdd mkpart primary 2048s 100% parted -s test.hdd mkpart primary 2048s 100%
.PHONY: mbrtest.hdd
mbrtest.hdd:
rm -f mbrtest.hdd
dd if=/dev/zero bs=1M count=0 seek=64 of=mbrtest.hdd
echo -e "o\nn\np\n1\n2048\n\nt\n6\na\nw\n" | fdisk mbrtest.hdd -H 16 -S 63
.PHONY: echfs-test .PHONY: echfs-test
echfs-test: echfs-test:
$(MAKE) test-clean $(MAKE) test-clean
@ -326,6 +332,30 @@ fat16-test:
$(BINDIR)/limine-install test.hdd $(BINDIR)/limine-install test.hdd
qemu-system-x86_64 -net none -smp 4 -hda test.hdd -debugcon stdio qemu-system-x86_64 -net none -smp 4 -hda test.hdd -debugcon stdio
.PHONY: legacy-fat16-test
legacy-fat16-test:
$(MAKE) test-clean
$(MAKE) mbrtest.hdd
fdisk -l mbrtest.hdd
$(MAKE) limine-bios
$(MAKE) limine-install
$(MAKE) -C test
rm -rf test_image/
mkdir test_image
sudo losetup -Pf --show mbrtest.hdd > loopback_dev
sudo partprobe `cat loopback_dev`
sudo mkfs.fat -F 16 `cat loopback_dev`p1
sudo mount `cat loopback_dev`p1 test_image
sudo mkdir test_image/boot
sudo cp -rv $(BINDIR)/* test_image/boot/
sudo cp -rv test/* test_image/boot/
sync
sudo umount test_image/
sudo losetup -d `cat loopback_dev`
rm -rf test_image loopback_dev
$(BINDIR)/limine-install mbrtest.hdd
qemu-system-i386 -cpu pentium2 -m 16M -M isapc -net none -hda mbrtest.hdd -debugcon stdio
.PHONY: fat32-test .PHONY: fat32-test
fat32-test: fat32-test:
$(MAKE) test-clean $(MAKE) test-clean

View File

@ -13,6 +13,100 @@
#include <mm/pmm.h> #include <mm/pmm.h>
#include <menu.h> #include <menu.h>
#if bios == 1
void fallback_raw_putchar(uint8_t c) {
struct rm_regs r = {0};
r.eax = 0x0e00 | c;
rm_int(0x10, &r, &r);
}
void fallback_clear(bool move) {
(void)move;
struct rm_regs r = {0};
rm_int(0x11, &r, &r);
switch ((r.eax >> 4) & 3) {
case 0:
r.eax = 3;
break;
case 1:
r.eax = 1;
break;
case 2:
r.eax = 3;
break;
case 3:
r.eax = 7;
break;
}
rm_int(0x10, &r, &r);
}
void fallback_set_cursor_pos(size_t x, size_t y) {
struct rm_regs r = {0};
r.eax = 0x0200;
r.ebx = 0;
r.edx = (y << 8) + x;
rm_int(0x10, &r, &r);
}
void fallback_get_cursor_pos(size_t *x, size_t *y) {
struct rm_regs r = {0};
r.eax = 0x0300;
r.ebx = 0;
rm_int(0x10, &r, &r);
*x = r.edx & 0xff;
*y = r.edx >> 8;
}
#elif uefi == 1
static int cursor_x = 0, cursor_y = 0;
void fallback_raw_putchar(uint8_t c) {
CHAR16 string[2];
string[0] = c;
string[1] = 0;
gST->ConOut->OutputString(gST->ConOut, string);
switch (c) {
case 0x08:
if (cursor_x > 0)
cursor_x--;
break;
case 0x0A:
cursor_x = 0;
break;
case 0x0D:
if (cursor_y < 24)
cursor_y++;
break;
default:
if (++cursor_x > 80) {
cursor_x = 0;
if (cursor_y < 24)
cursor_y++;
}
}
}
void fallback_clear(bool move) {
(void)move;
gST->ConOut->ClearScreen(gST->ConOut);
cursor_x = cursor_y = 0;
}
void fallback_set_cursor_pos(size_t x, size_t y) {
if (x >= 80 || y >= 25)
return;
gST->ConOut->SetCursorPosition(gST->ConOut, x, y);
cursor_x = x;
cursor_y = y;
}
void fallback_get_cursor_pos(size_t *x, size_t *y) {
*x = cursor_x;
*y = cursor_y;
}
#endif
__attribute__((noreturn)) void panic(bool allow_menu, const char *fmt, ...) { __attribute__((noreturn)) void panic(bool allow_menu, const char *fmt, ...) {
va_list args; va_list args;
@ -28,6 +122,26 @@ __attribute__((noreturn)) void panic(bool allow_menu, const char *fmt, ...) {
#endif #endif
} }
if (term_backend == NOT_READY) {
#if uefi == 1
if (!efi_boot_services_exited) {
gST->ConOut->Reset(gST->ConOut, false);
gST->ConOut->SetMode(gST->ConOut, 0);
cursor_x = cursor_y = 0;
#elif bios == 1
fallback_clear(true);
#endif
term_notready();
raw_putchar = fallback_raw_putchar;
clear = fallback_clear;
set_cursor_pos = fallback_set_cursor_pos;
get_cursor_pos = fallback_get_cursor_pos;
term_backend = FALLBACK;
#if uefi == 1
}
#endif
}
print("\033[31mPANIC\033[37;1m\033[0m: "); print("\033[31mPANIC\033[37;1m\033[0m: ");
vprint(fmt, args); vprint(fmt, args);

View File

@ -5,6 +5,7 @@
#include <lib/image.h> #include <lib/image.h>
#include <lib/blib.h> #include <lib/blib.h>
#include <lib/gterm.h> #include <lib/gterm.h>
#include <mm/pmm.h>
bool early_term = false; bool early_term = false;
@ -20,7 +21,7 @@ void term_deinit(void) {
void term_vbe(size_t width, size_t height) { void term_vbe(size_t width, size_t height) {
term_notready(); term_notready();
if (quiet) { if (quiet || allocations_disallowed) {
return; return;
} }

View File

@ -35,7 +35,8 @@ extern struct term_context {
enum { enum {
NOT_READY, NOT_READY,
VBE, VBE,
TEXTMODE TEXTMODE,
FALLBACK
}; };
extern int current_video_mode; extern int current_video_mode;

View File

@ -7,6 +7,7 @@
#include <lib/blib.h> #include <lib/blib.h>
#include <drivers/vga_textmode.h> #include <drivers/vga_textmode.h>
#include <lib/print.h> #include <lib/print.h>
#include <mm/pmm.h>
// Tries to implement this standard for terminfo // Tries to implement this standard for terminfo
// https://man7.org/linux/man-pages/man4/console_codes.4.html // https://man7.org/linux/man-pages/man4/console_codes.4.html
@ -157,7 +158,7 @@ void term_reinit(void) {
void term_textmode(void) { void term_textmode(void) {
term_notready(); term_notready();
if (quiet) { if (quiet || allocations_disallowed) {
return; return;
} }

View File

@ -37,6 +37,8 @@ extern struct e820_entry_t *untouched_memmap;
extern size_t untouched_memmap_entries; extern size_t untouched_memmap_entries;
#endif #endif
extern bool allocations_disallowed;
void init_memmap(void); void init_memmap(void);
struct e820_entry_t *get_memmap(size_t *entries); struct e820_entry_t *get_memmap(size_t *entries);
struct e820_entry_t *get_raw_memmap(size_t *entry_count); struct e820_entry_t *get_raw_memmap(size_t *entry_count);

View File

@ -17,7 +17,7 @@
extern symbol bss_end; extern symbol bss_end;
#endif #endif
static bool allocations_disallowed = true; bool allocations_disallowed = true;
static void sanitise_entries(struct e820_entry_t *, size_t *, bool); static void sanitise_entries(struct e820_entry_t *, size_t *, bool);
void *conv_mem_alloc(size_t count) { void *conv_mem_alloc(size_t count) {