mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-06 03:08:31 +00:00
[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:
parent
120079b0a6
commit
0da47c51de
16 changed files with 725 additions and 191 deletions
|
@ -16,9 +16,12 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "ape/relocations.h"
|
||||
#include "ape/sections.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/intrin/newbie.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/efi.h"
|
||||
#include "libc/nt/thunk/msabi.h"
|
||||
|
@ -37,6 +40,80 @@ struct EfiArgs {
|
|||
};
|
||||
|
||||
static const EFI_GUID kEfiLoadedImageProtocol = LOADED_IMAGE_PROTOCOL;
|
||||
static const EFI_GUID kEfiGraphicsOutputProtocol = GRAPHICS_OUTPUT_PROTOCOL;
|
||||
|
||||
extern const char vga_console[];
|
||||
extern void _EfiPostboot(struct mman *, uint64_t *, uintptr_t, char **);
|
||||
|
||||
static void EfiInitVga(struct mman *mm, EFI_SYSTEM_TABLE *SystemTable) {
|
||||
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphInfo;
|
||||
EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *GraphMode;
|
||||
EFI_PIXEL_BITMASK *PixelInfo;
|
||||
unsigned vid_typ = PC_VIDEO_TEXT;
|
||||
size_t bytes_per_pix = 0;
|
||||
|
||||
SystemTable->BootServices->LocateProtocol(&kEfiGraphicsOutputProtocol, NULL,
|
||||
&GraphInfo);
|
||||
GraphMode = GraphInfo->Mode;
|
||||
switch (GraphMode->Info->PixelFormat) {
|
||||
case PixelRedGreenBlueReserved8BitPerColor:
|
||||
vid_typ = PC_VIDEO_RGBX8888;
|
||||
bytes_per_pix = 4;
|
||||
break;
|
||||
case PixelBlueGreenRedReserved8BitPerColor:
|
||||
vid_typ = PC_VIDEO_BGRX8888;
|
||||
bytes_per_pix = 4;
|
||||
break;
|
||||
case PixelBitMask:
|
||||
PixelInfo = &GraphMode->Info->PixelInformation;
|
||||
switch (le32toh(PixelInfo->RedMask)) {
|
||||
case 0x00FF0000U:
|
||||
if (le32toh(PixelInfo->ReservedMask) >= 0x01000000U &&
|
||||
le32toh(PixelInfo->GreenMask) == 0x0000FF00U &&
|
||||
le32toh(PixelInfo->BlueMask) == 0x000000FFU) {
|
||||
vid_typ = PC_VIDEO_BGRX8888;
|
||||
bytes_per_pix = 4;
|
||||
}
|
||||
break;
|
||||
case 0x000000FFU:
|
||||
if (le32toh(PixelInfo->ReservedMask) >= 0x01000000U &&
|
||||
le32toh(PixelInfo->GreenMask) == 0x0000FF00U &&
|
||||
le32toh(PixelInfo->BlueMask) == 0x00FF0000U) {
|
||||
vid_typ = PC_VIDEO_RGBX8888;
|
||||
bytes_per_pix = 4;
|
||||
}
|
||||
break;
|
||||
case 0x0000F800U:
|
||||
if (le32toh(PixelInfo->ReservedMask) <= 0x0000FFFFU &&
|
||||
le32toh(PixelInfo->GreenMask) == 0x000007E0U &&
|
||||
le32toh(PixelInfo->BlueMask) == 0x0000001FU) {
|
||||
vid_typ = PC_VIDEO_BGR565;
|
||||
bytes_per_pix = 2;
|
||||
}
|
||||
break;
|
||||
case 0x00007C00U:
|
||||
if (le32toh(PixelInfo->ReservedMask) <= 0x0000FFFFU &&
|
||||
le32toh(PixelInfo->GreenMask) == 0x000003E0U &&
|
||||
le32toh(PixelInfo->BlueMask) == 0x0000001FU) {
|
||||
vid_typ = PC_VIDEO_BGR555;
|
||||
bytes_per_pix = 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
notpossible;
|
||||
}
|
||||
if (!bytes_per_pix) notpossible;
|
||||
mm->pc_video_type = vid_typ;
|
||||
mm->pc_video_stride = GraphMode->Info->PixelsPerScanLine * bytes_per_pix;
|
||||
mm->pc_video_width = GraphMode->Info->HorizontalResolution;
|
||||
mm->pc_video_height = GraphMode->Info->VerticalResolution;
|
||||
mm->pc_video_framebuffer = GraphMode->FrameBufferBase;
|
||||
mm->pc_video_framebuffer_size = GraphMode->FrameBufferSize;
|
||||
mm->pc_video_curs_info.y = mm->pc_video_curs_info.x = 0;
|
||||
SystemTable->BootServices->SetMem((void *)GraphMode->FrameBufferBase,
|
||||
GraphMode->FrameBufferSize, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* EFI Application Entrypoint.
|
||||
|
@ -64,27 +141,44 @@ static const EFI_GUID kEfiLoadedImageProtocol = LOADED_IMAGE_PROTOCOL;
|
|||
*/
|
||||
__msabi noasan EFI_STATUS EfiMain(EFI_HANDLE ImageHandle,
|
||||
EFI_SYSTEM_TABLE *SystemTable) {
|
||||
int type, x87cw;
|
||||
int type, x87cw = 0x037f;
|
||||
struct mman *mm;
|
||||
uint32_t DescVersion;
|
||||
uintptr_t i, j, MapSize;
|
||||
struct EfiArgs *ArgBlock;
|
||||
EFI_LOADED_IMAGE *ImgInfo;
|
||||
EFI_MEMORY_DESCRIPTOR *Map;
|
||||
EFI_MEMORY_DESCRIPTOR *Map, *Desc;
|
||||
uint64_t Address;
|
||||
uintptr_t Args, MapKey, DescSize;
|
||||
uint64_t p, pe, cr4, *m, *pd, *sp, *pml4t, *pdt1, *pdt2, *pdpt1, *pdpt2;
|
||||
extern char __os asm("__hostos");
|
||||
|
||||
__os = _HOSTMETAL;
|
||||
|
||||
/*
|
||||
* Allocates and clears PC-compatible memory and copies image.
|
||||
* Allocates and clears PC-compatible memory and copies image. Marks the
|
||||
* pages as EfiRuntimeServicesData, so that we can simply free up all
|
||||
* EfiLoader... and EfiBootServices... pages later. The first page at
|
||||
* address 0 is normally already allocated as EfiBootServicesData, so
|
||||
* handle it separately.
|
||||
*/
|
||||
Address = 0;
|
||||
SystemTable->BootServices->AllocatePages(
|
||||
AllocateAddress, EfiConventionalMemory,
|
||||
MAX(2 * 1024 * 1024, 1024 * 1024 + (_end - _base)) / 4096, 0);
|
||||
SystemTable->BootServices->SetMem(0, 0x80000, 0);
|
||||
SystemTable->BootServices->CopyMem((void *)(1024 * 1024), _base,
|
||||
AllocateAddress, EfiRuntimeServicesData, 4096 / 4096, &Address);
|
||||
Address = 4096;
|
||||
SystemTable->BootServices->AllocatePages(
|
||||
AllocateAddress, EfiRuntimeServicesData, (IMAGE_BASE_REAL - 4096) / 4096,
|
||||
&Address);
|
||||
Address = 0x79000;
|
||||
SystemTable->BootServices->AllocatePages(
|
||||
AllocateAddress, EfiRuntimeServicesData,
|
||||
(0x7e000 - 0x79000 + sizeof(struct EfiArgs) + 4095) / 4096, &Address);
|
||||
Address = IMAGE_BASE_PHYSICAL;
|
||||
SystemTable->BootServices->AllocatePages(
|
||||
AllocateAddress, EfiRuntimeServicesData,
|
||||
((_end - _base) + 4095) / 4096, &Address);
|
||||
mm = (struct mman *)0x0500;
|
||||
SystemTable->BootServices->SetMem(mm, sizeof(*mm), 0);
|
||||
SystemTable->BootServices->SetMem((void *)0x79000,
|
||||
0x7e000 - 0x79000 + sizeof(struct EfiArgs), 0);
|
||||
SystemTable->BootServices->CopyMem((void *)IMAGE_BASE_PHYSICAL, _base,
|
||||
_end - _base);
|
||||
|
||||
/*
|
||||
|
@ -97,6 +191,13 @@ __msabi noasan EFI_STATUS EfiMain(EFI_HANDLE ImageHandle,
|
|||
sizeof(ArgBlock->ArgBlock), ArgBlock->Args,
|
||||
ARRAYLEN(ArgBlock->Args));
|
||||
|
||||
/*
|
||||
* Gets information about our current video mode. Clears the screen.
|
||||
* TODO: if needed, switch to a video mode that has a linear frame buffer
|
||||
* type we support.
|
||||
*/
|
||||
if (_weaken(vga_console)) EfiInitVga(mm, SystemTable);
|
||||
|
||||
/*
|
||||
* Asks UEFI which parts of our RAM we're allowed to use.
|
||||
*/
|
||||
|
@ -104,16 +205,26 @@ __msabi noasan EFI_STATUS EfiMain(EFI_HANDLE ImageHandle,
|
|||
MapSize = 0;
|
||||
SystemTable->BootServices->GetMemoryMap(&MapSize, Map, &MapKey, &DescSize,
|
||||
&DescVersion);
|
||||
SystemTable->BootServices->AllocatePool(EfiLoaderData, MapSize, Map);
|
||||
SystemTable->BootServices->AllocatePool(EfiLoaderData, MapSize, &Map);
|
||||
MapSize *= 2;
|
||||
SystemTable->BootServices->GetMemoryMap(&MapSize, Map, &MapKey, &DescSize,
|
||||
&DescVersion);
|
||||
asm("xor\t%0,%0" : "=r"(mm)); /* gcc assumes null isn't mapped */
|
||||
for (j = i = 0; i < MapSize / sizeof(EFI_MEMORY_DESCRIPTOR); ++i) {
|
||||
if (Map[i].Type != EfiConventionalMemory) continue;
|
||||
mm->e820[j].addr = Map[i].PhysicalStart;
|
||||
mm->e820[j].size = Map[i].NumberOfPages * 4096;
|
||||
mm->e820[j].type = kMemoryUsable;
|
||||
++j;
|
||||
for (j = i = 0, Desc = Map; i < MapSize / DescSize; ++i) {
|
||||
switch (Desc->Type) {
|
||||
case EfiLoaderCode:
|
||||
case EfiLoaderData:
|
||||
case EfiBootServicesCode:
|
||||
case EfiBootServicesData:
|
||||
if (Desc->PhysicalStart != 0)
|
||||
break;
|
||||
/* fallthrough */
|
||||
case EfiConventionalMemory:
|
||||
mm->e820[j].addr = Desc->PhysicalStart;
|
||||
mm->e820[j].size = Desc->NumberOfPages * 4096;
|
||||
mm->e820[j].type = kMemoryUsable;
|
||||
++j;
|
||||
}
|
||||
Desc = (EFI_MEMORY_DESCRIPTOR *)((char *)Desc + DescSize);
|
||||
}
|
||||
SystemTable->BootServices->FreePool(Map);
|
||||
|
||||
|
@ -135,7 +246,6 @@ __msabi noasan EFI_STATUS EfiMain(EFI_HANDLE ImageHandle,
|
|||
pdpt2[0] = (intptr_t)pdt2 + PAGE_V + PAGE_RW;
|
||||
pml4t[0] = (intptr_t)pdpt1 + PAGE_V + PAGE_RW;
|
||||
pml4t[256] = (intptr_t)pdpt2 + PAGE_V + PAGE_RW;
|
||||
__map_phdrs(mm, pml4t, 1024 * 1024);
|
||||
|
||||
/*
|
||||
* Asks UEFI to handover control?
|
||||
|
@ -143,45 +253,8 @@ __msabi noasan EFI_STATUS EfiMain(EFI_HANDLE ImageHandle,
|
|||
SystemTable->BootServices->ExitBootServices(ImageHandle, MapKey);
|
||||
|
||||
/*
|
||||
* Launches program.
|
||||
* Switches to copied image and launches program.
|
||||
*/
|
||||
asm volatile("fldcw\t%3\n\t"
|
||||
"mov\t%4,%%cr3\n\t"
|
||||
".weak\tape_stack_vaddr\n\t"
|
||||
".weak\tape_stack_memsz\n\t"
|
||||
"movabs\t$ape_stack_vaddr,%%rsp\n\t"
|
||||
"add\t$ape_stack_memsz,%%rsp\n\t"
|
||||
"push\t$0\n\t" /* auxv[1][1] */
|
||||
"push\t$0\n\t" /* auxv[1][0] */
|
||||
"push\t(%1)\n\t" /* auxv[0][1] */
|
||||
"push\t$31\n\t" /* auxv[0][0] AT_EXECFN */
|
||||
"push\t$0\n\t" /* envp[0] */
|
||||
"sub\t%2,%%rsp\n\t"
|
||||
"mov\t%%rsp,%%rdi\n\t"
|
||||
"rep movsb\n\t" /* argv */
|
||||
"push\t%0\n\t" /* argc */
|
||||
"xor\t%%edi,%%edi\n\t"
|
||||
"xor\t%%eax,%%eax\n\t"
|
||||
"xor\t%%ebx,%%ebx\n\t"
|
||||
"xor\t%%ecx,%%ecx\n\t"
|
||||
"xor\t%%edx,%%edx\n\t"
|
||||
"xor\t%%edi,%%edi\n\t"
|
||||
"xor\t%%esi,%%esi\n\t"
|
||||
"xor\t%%ebp,%%ebp\n\t"
|
||||
"xor\t%%r8d,%%r8d\n\t"
|
||||
"xor\t%%r9d,%%r9d\n\t"
|
||||
"xor\t%%r10d,%%r10d\n\t"
|
||||
"xor\t%%r11d,%%r11d\n\t"
|
||||
"xor\t%%r12d,%%r12d\n\t"
|
||||
"xor\t%%r13d,%%r13d\n\t"
|
||||
"xor\t%%r14d,%%r14d\n\t"
|
||||
"xor\t%%r15d,%%r15d\n\t"
|
||||
".weak\t_start\n\t"
|
||||
"jmp\t_start"
|
||||
: /* no outputs */
|
||||
: "a"(Args), "S"(ArgBlock->Args), "c"((Args + 1) * 8),
|
||||
"m"(x87cw), "r"(pml4t)
|
||||
: "memory");
|
||||
|
||||
_EfiPostboot(mm, pml4t, Args, ArgBlock->Args);
|
||||
unreachable;
|
||||
}
|
||||
|
|
126
libc/runtime/efipostboot.S
Normal file
126
libc/runtime/efipostboot.S
Normal file
|
@ -0,0 +1,126 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "ape/relocations.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/runtime/pc.internal.h"
|
||||
.real
|
||||
|
||||
// Start the Cosmopolitan runtime after exiting UEFI Boot Services.
|
||||
//
|
||||
// @param rdi is mm
|
||||
// @param rsi is new pml4t
|
||||
// @param rdx is argc
|
||||
// @param rcx is argv
|
||||
// @see libc/runtime/efimain.greg.c
|
||||
_EfiPostboot:
|
||||
cli
|
||||
// Define handy mnemonics for parameters & constants stored in
|
||||
// call-saved registers.
|
||||
#define rMm %r12
|
||||
#define rArgc %r13
|
||||
#define rArgv %r14
|
||||
#define rBane %r15
|
||||
movabs $BANE,rBane
|
||||
mov %rdi,rMm
|
||||
mov %rdx,rArgc
|
||||
lea (rBane,%rcx),rArgv
|
||||
mov $PHYSICAL(.Ltmpstk),%rax # switch to temporary stack
|
||||
and $-16,%al # in physical space
|
||||
xchg %rax,%rsp
|
||||
mov $PHYSICAL(0f),%eax # resume execution in copied
|
||||
jmp *%rax # image
|
||||
0: mov $EFER,%ecx # enable syscall/sysret & nx
|
||||
rdmsr
|
||||
or $EFER_SCE|EFER_NXE,%eax
|
||||
wrmsr
|
||||
mov %rsi,%cr3 # load new page table
|
||||
add rBane,%rsp # we can now switch stack to
|
||||
add rBane,rMm # negative address space
|
||||
mov $1024*1024,%edx # set up virtual memory
|
||||
mov $1024*1024+_end,%ecx # mapping
|
||||
sub $_base,%ecx
|
||||
call __map_phdrs
|
||||
mov $1f,%eax # switch rip to virtual
|
||||
jmp *%rax # address space
|
||||
1: push $0x037f
|
||||
fldcw (%rsp)
|
||||
.weak _gdtr
|
||||
lgdt _gdtr # switch to our own GDT
|
||||
mov $GDT_LONG_DATA,%ax
|
||||
mov %ax,%ds
|
||||
mov %ax,%ss
|
||||
mov %ax,%es
|
||||
mov %ax,%fs
|
||||
mov %ax,%gs
|
||||
.weak ape_stack_vaddr
|
||||
.weak ape_stack_memsz
|
||||
movabs $ape_stack_vaddr,%rsp # switch to final stack in
|
||||
add $ape_stack_memsz,%rsp # virtual address space
|
||||
movl $0,0x7b000 # unmap null 2mb
|
||||
mov rMm,%rdi
|
||||
xor %esi,%esi # free up now-unused pages
|
||||
xor %edx,%edx
|
||||
call __reclaim_boot_pages
|
||||
push .Lenv0(%rip) # envp[0][0]
|
||||
mov %rsp,%rbp
|
||||
push $0 # auxv[1][1]
|
||||
push $0 # auxv[1][0]
|
||||
mov (rArgv),%rax
|
||||
add rBane,%rax
|
||||
push %rax # auxv[0][1]
|
||||
push $31 # auxv[0][0] AT_EXECFN
|
||||
push $0 # envp[1]
|
||||
push %rbp # envp[0]
|
||||
push $0 # argv[argc] NULL
|
||||
lea -8(rArgv,rArgc,8),%rsi # push rest of argv, &
|
||||
mov rArgc,%rcx # adjust pointers to point to
|
||||
std # negative space
|
||||
2: lodsq
|
||||
add rBane,%rax
|
||||
push %rax
|
||||
loop 2b
|
||||
cld
|
||||
push rArgc # argc
|
||||
pushpop _HOSTMETAL,%rcx # sets __hostos in crt.S
|
||||
xor %ebp,%ebp
|
||||
xor %eax,%eax
|
||||
xor %ebx,%ebx
|
||||
xor %edx,%edx
|
||||
xor %edi,%edi
|
||||
xor %esi,%esi
|
||||
xor %r8d,%r8d
|
||||
xor %r9d,%r9d
|
||||
xor %r10d,%r10d
|
||||
xor %r11d,%r11d
|
||||
xor %r12d,%r12d
|
||||
xor %r13d,%r13d
|
||||
xor %r14d,%r14d
|
||||
xor %r15d,%r15d
|
||||
push $GDT_LONG_CODE
|
||||
.weak _start
|
||||
push $_start
|
||||
lretq
|
||||
.endfn _EfiPostboot,globl,hidden
|
||||
.rodata
|
||||
.Lenv0: .asciz "METAL=1"
|
||||
.bss
|
||||
.space 0x1000
|
||||
.Ltmpstk:
|
||||
.previous
|
|
@ -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) */
|
||||
};
|
||||
|
|
|
@ -167,6 +167,9 @@
|
|||
#define PAGE_GROD /* blinkenlights MAP_GROWSDOWN */ 0b010000000000
|
||||
#define PAGE_TA 0x00007ffffffff000
|
||||
#define PAGE_PA2 0x00007fffffe00000
|
||||
#define PAGE_IGN2 0x07f0000000000000
|
||||
#define PAGE_REFC PAGE_IGN2 /* libc reference counting */
|
||||
#define PAGE_1REF 0x0010000000000000 /* libc reference counting */
|
||||
#define PAGE_XD 0x8000000000000000
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
@ -186,9 +189,13 @@ struct IdtDescriptor {
|
|||
uint64_t *__get_virtual(struct mman *, uint64_t *, int64_t, bool);
|
||||
uint64_t __clear_page(uint64_t);
|
||||
uint64_t __new_page(struct mman *);
|
||||
void __invert_memory_area(struct mman *, uint64_t *, uint64_t, uint64_t,
|
||||
uint64_t);
|
||||
void __map_phdrs(struct mman *, uint64_t *, uint64_t);
|
||||
uint64_t * __invert_memory_area(struct mman *, uint64_t *, uint64_t, uint64_t,
|
||||
uint64_t);
|
||||
void __map_phdrs(struct mman *, uint64_t *, uint64_t, uint64_t);
|
||||
void __reclaim_boot_pages(struct mman *, uint64_t, uint64_t);
|
||||
void __ref_page(struct mman *, uint64_t *, uint64_t);
|
||||
void __ref_pages(struct mman *, uint64_t *, uint64_t, uint64_t);
|
||||
void __unref_page(struct mman *, uint64_t *, uint64_t);
|
||||
|
||||
forceinline unsigned char inb(unsigned short port) {
|
||||
unsigned char al;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue