mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-30 16:28:30 +00:00
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:
parent
7822917fc2
commit
d3efa47f81
13 changed files with 695 additions and 338 deletions
|
@ -29,10 +29,6 @@
|
|||
#include "libc/calls/struct/iovec.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/vga/vga.internal.h"
|
||||
#include "libc/runtime/pc.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
struct Tty _vga_tty;
|
||||
|
||||
ssize_t sys_writev_vga(struct Fd *fd, const struct iovec *iov, int iovlen) {
|
||||
size_t i, wrote = 0;
|
||||
|
@ -51,41 +47,3 @@ ssize_t sys_writev_vga(struct Fd *fd, const struct iovec *iov, int iovlen) {
|
|||
return res;
|
||||
return wrote;
|
||||
}
|
||||
|
||||
__attribute__((__constructor__)) static textstartup void _vga_init(void) {
|
||||
if (IsMetal()) {
|
||||
struct mman *mm = (struct mman *)(BANE + 0x0500);
|
||||
unsigned char vid_type = mm->pc_video_type;
|
||||
unsigned short height = mm->pc_video_height, width = mm->pc_video_width,
|
||||
stride = mm->pc_video_stride;
|
||||
uint64_t vid_buf_phy = mm->pc_video_framebuffer;
|
||||
void *vid_buf = (void *)(BANE + vid_buf_phy);
|
||||
size_t vid_buf_sz = mm->pc_video_framebuffer_size;
|
||||
/*
|
||||
* Get the initial cursor position from the BIOS data area. Also get
|
||||
* the height (in scan lines) of each character; this is used to set the
|
||||
* cursor shape.
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned char col, row;
|
||||
} bios_curs_pos_t;
|
||||
bios_curs_pos_t pos = *(bios_curs_pos_t *)(BANE + 0x0450ull);
|
||||
uint8_t chr_ht, chr_ht_hi, chr_wid;
|
||||
if (vid_type == PC_VIDEO_TEXT) {
|
||||
chr_ht = *(uint8_t *)(BANE + 0x0485ull),
|
||||
chr_ht_hi = *(uint8_t *)(BANE + 0x0486ull);
|
||||
if (chr_ht_hi != 0 || chr_ht > 32 || chr_ht < 2)
|
||||
chr_ht = VGA_ASSUME_CHAR_HEIGHT_PX;
|
||||
} else
|
||||
chr_ht = VGA_ASSUME_CHAR_HEIGHT_PX;
|
||||
chr_wid = VGA_ASSUME_CHAR_WIDTH_PX;
|
||||
/* Make sure the video buffer is mapped into virtual memory. */
|
||||
__invert_memory_area(mm, __get_pml4t(), vid_buf_phy, vid_buf_sz, PAGE_RW);
|
||||
/*
|
||||
* Initialize our tty structure from the current screen geometry,
|
||||
* screen contents, cursor position, & character dimensions.
|
||||
*/
|
||||
_StartTty(&_vga_tty, vid_type, height, width, stride, pos.row, pos.col,
|
||||
chr_ht, chr_wid, vid_buf, false);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue