[metal] Allow programs larger than 440 KiB to run in bare metal mode (#685)

* [metal] Copy program pages to extended memory at startup
* [metal] Reclaim base memory pages for later app use
* [metal] Load program pages beyond 1st 440 KiB to extended memory

o//examples/hellolua.com now runs correctly under QEMU (in
legacy BIOS mode).

* [metal] Place GDT in read/write segment

The CPU absolutely needs to alter the GDT when loading the
task register (via ltr).  To account for this, I move the
GDT into a read/write data section.  There is still a "rump"
read-only GDT in the text section that is used by the real
mode bootloader.

We also delay the loading of the task register (ltr) until
after the IDT and TSS are finally set up.

* [metal] Get examples/vga2.c serial output working for UEFI boot
* [metal] Get examples/vga2.c VGA output working for UEFI boot
* [metal] Allow munmap() to reclaim dynamically allocated pages
* Place TLS sections right after .text, not after embedded zip file

Co-authored-by: tkchia <tkchia-cosmo@gmx.com>
This commit is contained in:
tkchia 2022-12-18 09:51:20 +08:00 committed by GitHub
parent 120079b0a6
commit 0da47c51de
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 725 additions and 191 deletions

View file

@ -8,31 +8,38 @@ struct mman {
int64_t pdp; /* 0x0500 */
int32_t pdpi; /* 0x0508 */
int32_t e820n; /* 0x050c */
struct SmapEntry e820[256]; /* 0x0510 */
struct SmapEntry e820_end[0]; /* 0x1d10 */
char pc_drive_base_table[11]; /* 0x1d10 */
unsigned char pc_drive_type; /* 0x1d1b */
unsigned char pc_drive_last_sector; /* 0x1d1c */
unsigned short pc_drive_last_cylinder; /* 0x1d1e */
unsigned char pc_drives_attached; /* 0x1d20 */
unsigned char pc_drive_last_head; /* 0x1d21 */
unsigned char pc_drive; /* 0x1d22 */
char bad_idt[6]; /* 0x1d23 */
unsigned char pc_video_type; /* 0x1d29 */
unsigned short pc_video_stride; /* 0x1d2a — line width, including any
uint64_t frp; /* 0x0510 — free list of reclaimed,
previously used pages */
struct SmapEntry e820[256]; /* 0x0518 */
struct SmapEntry e820_end[0]; /* 0x1d18 */
char pc_drive_base_table[11]; /* 0x1d18 */
unsigned char pc_drive_type; /* 0x1d23 */
unsigned char pc_drive_last_sector; /* 0x1d24 */
unsigned short pc_drive_last_cylinder; /* 0x1d26 */
unsigned char pc_drives_attached; /* 0x1d28 */
unsigned char pc_drive_last_head; /* 0x1d29 */
unsigned char pc_drive; /* 0x1d2a */
char bad_idt[2]; /* 0x1d2b — IDTR value for an invalid
IDT; really 6 bytes which
overlap w/ fields below */
unsigned char pc_drive_next_sector; /* 0x1d2d */
unsigned short pc_drive_next_cylinder; /* 0x1d2e */
unsigned char pc_drive_next_head; /* 0x1d30 */
unsigned char pc_video_type; /* 0x1d31 */
unsigned short pc_video_stride; /* 0x1d32 — line width, including any
invisible "pixels" in
bytes (NOTE) */
unsigned short pc_video_width; /* 0x1d2c — width in chars. (text)
unsigned short pc_video_width; /* 0x1d34 — width in chars. (text)
or pixels (graphics) */
unsigned short pc_video_height; /* 0x1d2e — height in chars. (text)
unsigned short pc_video_height; /* 0x1d36 — height in chars. (text)
or pixels (graphics) */
uint64_t pc_video_framebuffer; /* 0x1d30 — physical address of
uint64_t pc_video_framebuffer; /* 0x1d38 — physical address of
video frame buffer */
uint64_t pc_video_framebuffer_size; /* 0x1d38 */
struct { /* 0x1d40 — starting cursor pos. */
uint64_t pc_video_framebuffer_size; /* 0x1d40 */
struct { /* 0x1d48 — starting cursor pos. */
unsigned short y, x;
} pc_video_curs_info;
unsigned short pc_video_char_height; /* 0x1d44 — character height (useful
unsigned short pc_video_char_height; /* 0x1d4c — character height (useful
for setting cursor shape
in text mode) */
};