mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-08 10:50:28 +00:00
[metal] Reclaim base memory pages for later app use
This commit is contained in:
parent
e4b5fb76e4
commit
6da7709fb8
5 changed files with 60 additions and 21 deletions
|
@ -1504,7 +1504,6 @@ long: movabs $BANE+PHYSICAL(0f),%rax
|
|||
xor %r15d,%r15d
|
||||
xor %ebx,%ebx
|
||||
xor %ebp,%ebp
|
||||
push %rbp
|
||||
mov $mm,%rdi
|
||||
mov %cr3,%rsi
|
||||
mov $IMAGE_BASE_PHYSICAL,%edx
|
||||
|
@ -1594,6 +1593,10 @@ kernel: movabs $ape_stack_vaddr,%rsp
|
|||
.byte 0x0f,0x1f,0207 # nop rdi binbase
|
||||
.long (IMAGE_BASE_VIRTUAL-IMAGE_BASE_REAL)/512
|
||||
#endif
|
||||
movabs $BANE+mm,%rdi
|
||||
mov $0x79000,%esi
|
||||
mov $0x7f000,%edx
|
||||
call __reclaim_boot_pages
|
||||
push $_HOSTMETAL # sets __hostos in crt.S
|
||||
pop %rcx
|
||||
pushq .Lenv0(%rip) # envp[0][0]
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
│ αcτµαlly pδrταblε εxεcµταblε § no-frills virtual memory management │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "ape/relocations.h"
|
||||
#include "libc/assert.h"
|
||||
#include "libc/elf/def.h"
|
||||
#include "libc/elf/struct/phdr.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
@ -44,13 +45,25 @@
|
|||
|
||||
#define INVERT(x) (BANE + PHYSICAL(x))
|
||||
|
||||
struct ReclaimedPage {
|
||||
uint64_t next;
|
||||
};
|
||||
|
||||
/**
|
||||
* Allocates new page of physical memory.
|
||||
*/
|
||||
noasan texthead uint64_t __new_page(struct mman *mm) {
|
||||
uint64_t p;
|
||||
uint64_t p = mm->frp;
|
||||
if (p) {
|
||||
uint64_t q;
|
||||
struct ReclaimedPage *rp = (struct ReclaimedPage *)(BANE + p);
|
||||
_unassert(p == (p & PAGE_TA));
|
||||
q = rp->next;
|
||||
_unassert(q == (q & PAGE_TA));
|
||||
mm->frp = q;
|
||||
return p;
|
||||
}
|
||||
if (mm->pdpi == mm->e820n) {
|
||||
/* TODO: reclaim free pages */
|
||||
return 0;
|
||||
}
|
||||
while (mm->pdp >= mm->e820[mm->pdpi].addr + mm->e820[mm->pdpi].size) {
|
||||
|
@ -113,6 +126,7 @@ static noasan textreal void __normalize_e820(struct mman *mm, uint64_t top) {
|
|||
mm->pdp = MAX(top, mm->e820[0].addr);
|
||||
mm->pdpi = 0;
|
||||
mm->e820n = n;
|
||||
mm->frp = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -210,3 +224,21 @@ noasan textreal void __map_phdrs(struct mman *mm, uint64_t *pml4t, uint64_t b,
|
|||
}
|
||||
mm->pdp = MAX(mm->pdp, m);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reclaim memory pages which were used at boot time but which can now be
|
||||
* made available for the application.
|
||||
*/
|
||||
noasan textreal void __reclaim_boot_pages(struct mman *mm, uint64_t skip_start,
|
||||
uint64_t skip_end) {
|
||||
uint64_t p = mm->frp, q = IMAGE_BASE_REAL, e;
|
||||
e = mm->e820[0].addr + mm->e820[0].size;
|
||||
while (q != e) {
|
||||
struct ReclaimedPage *rp = (struct ReclaimedPage *)(BANE + q);
|
||||
rp->next = p;
|
||||
p = q;
|
||||
q += 4096;
|
||||
if (q == skip_start) q = skip_end;
|
||||
}
|
||||
mm->frp = p;
|
||||
}
|
||||
|
|
|
@ -136,6 +136,7 @@ __msabi noasan EFI_STATUS EfiMain(EFI_HANDLE ImageHandle,
|
|||
pml4t[0] = (intptr_t)pdpt1 + PAGE_V + PAGE_RW;
|
||||
pml4t[256] = (intptr_t)pdpt2 + PAGE_V + PAGE_RW;
|
||||
__map_phdrs(mm, pml4t, 1024 * 1024, 1024 * 1024 + (_end - _base));
|
||||
__reclaim_boot_pages(mm, 0x79000, 0x7f000);
|
||||
|
||||
/*
|
||||
* Asks UEFI to handover control?
|
||||
|
|
|
@ -8,31 +8,33 @@ 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[6]; /* 0x1d2b */
|
||||
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) */
|
||||
};
|
||||
|
|
|
@ -189,6 +189,7 @@ 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);
|
||||
void __reclaim_boot_pages(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