Show "screen of death" on VGA console upon program crash (#650)

* [metal] Refactoring: separate out sys_writev_vga() and _vga_init() modules

* [metal] Read VGA info from BDA before long mode entry, not after

If using a pre-existing VGA text console, the VGA initialization
code now retrieves the cursor position & character height from
the BIOS data area while still in real mode — rather than
reading from the BIOS data area only after entering long mode.

(This should help make the code more correct, if Cosmopolitan
were to support UEFI graphics output in the future.  If the
program were booted via UEFI, then the long mode IsMetal()
code would still be activated, but the BIOS data area might
not have been initialized in that case.)

This change also means that there are now a few more fields
in the `struct mman`.

* [metal] VGA console can now show "screen of death" upon a crash

There is now a new function _klog_vga(), which can be called
by kprintf() to output system messages — e.g. information about
CPU exceptions — on the VGA screen.

* [metal] CPU exception handler now dumps cr2 value
* [metal] Add demo of program crash reporting w/ bare metal VGA TTY
* [metal] Reduce size of "screen of death" code
This commit is contained in:
tkchia 2022-10-06 20:36:15 +08:00 committed by GitHub
parent 7822917fc2
commit d3efa47f81
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 695 additions and 338 deletions

View file

@ -70,9 +70,11 @@ __excep0_isr:
push %rcx # preserve registers which we will
push %rdx # use to call kprintf
push %r8
mov 40(%rsp),%rcx # edx:rcx = "caller" cs:rip
mov 48(%rsp),%edx
mov 32(%rsp),%r8 # r8 = error code
push %r9
mov 48(%rsp),%rcx # edx:rcx = "caller" cs:rip
mov 56(%rsp),%edx
mov 40(%rsp),%r8 # r8 = error code
mov %cr2,%r9 # r9 = cr2, in case it is useful
push %rax # preserve other call-used registers
push %rdi
push %r9
@ -141,7 +143,8 @@ isr_init:
// String constants.
.rodata.str1.1
.excep_msg:
.asciz "CPU exception %d @ %#llx:%#llx err code %#llx\n"
.ascii "\033[1;31mCPU exception %d @ %#llx:%#llx err code %#llx "
.asciz "cr2 %#llx\33[0m\n"
.previous
// IDTR value.