mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-08 19:00:27 +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 %r15d,%r15d
|
||||||
xor %ebx,%ebx
|
xor %ebx,%ebx
|
||||||
xor %ebp,%ebp
|
xor %ebp,%ebp
|
||||||
push %rbp
|
|
||||||
mov $mm,%rdi
|
mov $mm,%rdi
|
||||||
mov %cr3,%rsi
|
mov %cr3,%rsi
|
||||||
mov $IMAGE_BASE_PHYSICAL,%edx
|
mov $IMAGE_BASE_PHYSICAL,%edx
|
||||||
|
@ -1594,6 +1593,10 @@ kernel: movabs $ape_stack_vaddr,%rsp
|
||||||
.byte 0x0f,0x1f,0207 # nop rdi binbase
|
.byte 0x0f,0x1f,0207 # nop rdi binbase
|
||||||
.long (IMAGE_BASE_VIRTUAL-IMAGE_BASE_REAL)/512
|
.long (IMAGE_BASE_VIRTUAL-IMAGE_BASE_REAL)/512
|
||||||
#endif
|
#endif
|
||||||
|
movabs $BANE+mm,%rdi
|
||||||
|
mov $0x79000,%esi
|
||||||
|
mov $0x7f000,%edx
|
||||||
|
call __reclaim_boot_pages
|
||||||
push $_HOSTMETAL # sets __hostos in crt.S
|
push $_HOSTMETAL # sets __hostos in crt.S
|
||||||
pop %rcx
|
pop %rcx
|
||||||
pushq .Lenv0(%rip) # envp[0][0]
|
pushq .Lenv0(%rip) # envp[0][0]
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
│ αcτµαlly pδrταblε εxεcµταblε § no-frills virtual memory management │
|
│ αcτµαlly pδrταblε εxεcµταblε § no-frills virtual memory management │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "ape/relocations.h"
|
#include "ape/relocations.h"
|
||||||
|
#include "libc/assert.h"
|
||||||
#include "libc/elf/def.h"
|
#include "libc/elf/def.h"
|
||||||
#include "libc/elf/struct/phdr.h"
|
#include "libc/elf/struct/phdr.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
|
@ -44,13 +45,25 @@
|
||||||
|
|
||||||
#define INVERT(x) (BANE + PHYSICAL(x))
|
#define INVERT(x) (BANE + PHYSICAL(x))
|
||||||
|
|
||||||
|
struct ReclaimedPage {
|
||||||
|
uint64_t next;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates new page of physical memory.
|
* Allocates new page of physical memory.
|
||||||
*/
|
*/
|
||||||
noasan texthead uint64_t __new_page(struct mman *mm) {
|
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) {
|
if (mm->pdpi == mm->e820n) {
|
||||||
/* TODO: reclaim free pages */
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
while (mm->pdp >= mm->e820[mm->pdpi].addr + mm->e820[mm->pdpi].size) {
|
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->pdp = MAX(top, mm->e820[0].addr);
|
||||||
mm->pdpi = 0;
|
mm->pdpi = 0;
|
||||||
mm->e820n = n;
|
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);
|
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[0] = (intptr_t)pdpt1 + PAGE_V + PAGE_RW;
|
||||||
pml4t[256] = (intptr_t)pdpt2 + PAGE_V + PAGE_RW;
|
pml4t[256] = (intptr_t)pdpt2 + PAGE_V + PAGE_RW;
|
||||||
__map_phdrs(mm, pml4t, 1024 * 1024, 1024 * 1024 + (_end - _base));
|
__map_phdrs(mm, pml4t, 1024 * 1024, 1024 * 1024 + (_end - _base));
|
||||||
|
__reclaim_boot_pages(mm, 0x79000, 0x7f000);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Asks UEFI to handover control?
|
* Asks UEFI to handover control?
|
||||||
|
|
|
@ -8,31 +8,33 @@ struct mman {
|
||||||
int64_t pdp; /* 0x0500 */
|
int64_t pdp; /* 0x0500 */
|
||||||
int32_t pdpi; /* 0x0508 */
|
int32_t pdpi; /* 0x0508 */
|
||||||
int32_t e820n; /* 0x050c */
|
int32_t e820n; /* 0x050c */
|
||||||
struct SmapEntry e820[256]; /* 0x0510 */
|
uint64_t frp; /* 0x0510 — free list of reclaimed,
|
||||||
struct SmapEntry e820_end[0]; /* 0x1d10 */
|
previously used pages */
|
||||||
char pc_drive_base_table[11]; /* 0x1d10 */
|
struct SmapEntry e820[256]; /* 0x0518 */
|
||||||
unsigned char pc_drive_type; /* 0x1d1b */
|
struct SmapEntry e820_end[0]; /* 0x1d18 */
|
||||||
unsigned char pc_drive_last_sector; /* 0x1d1c */
|
char pc_drive_base_table[11]; /* 0x1d18 */
|
||||||
unsigned short pc_drive_last_cylinder; /* 0x1d1e */
|
unsigned char pc_drive_type; /* 0x1d23 */
|
||||||
unsigned char pc_drives_attached; /* 0x1d20 */
|
unsigned char pc_drive_last_sector; /* 0x1d24 */
|
||||||
unsigned char pc_drive_last_head; /* 0x1d21 */
|
unsigned short pc_drive_last_cylinder; /* 0x1d26 */
|
||||||
unsigned char pc_drive; /* 0x1d22 */
|
unsigned char pc_drives_attached; /* 0x1d28 */
|
||||||
char bad_idt[6]; /* 0x1d23 */
|
unsigned char pc_drive_last_head; /* 0x1d29 */
|
||||||
unsigned char pc_video_type; /* 0x1d29 */
|
unsigned char pc_drive; /* 0x1d2a */
|
||||||
unsigned short pc_video_stride; /* 0x1d2a — line width, including any
|
char bad_idt[6]; /* 0x1d2b */
|
||||||
|
unsigned char pc_video_type; /* 0x1d31 */
|
||||||
|
unsigned short pc_video_stride; /* 0x1d32 — line width, including any
|
||||||
invisible "pixels" — in
|
invisible "pixels" — in
|
||||||
bytes (NOTE) */
|
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) */
|
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) */
|
or pixels (graphics) */
|
||||||
uint64_t pc_video_framebuffer; /* 0x1d30 — physical address of
|
uint64_t pc_video_framebuffer; /* 0x1d38 — physical address of
|
||||||
video frame buffer */
|
video frame buffer */
|
||||||
uint64_t pc_video_framebuffer_size; /* 0x1d38 */
|
uint64_t pc_video_framebuffer_size; /* 0x1d40 */
|
||||||
struct { /* 0x1d40 — starting cursor pos. */
|
struct { /* 0x1d48 — starting cursor pos. */
|
||||||
unsigned short y, x;
|
unsigned short y, x;
|
||||||
} pc_video_curs_info;
|
} 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
|
for setting cursor shape
|
||||||
in text mode) */
|
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,
|
void __invert_memory_area(struct mman *, uint64_t *, uint64_t, uint64_t,
|
||||||
uint64_t);
|
uint64_t);
|
||||||
void __map_phdrs(struct mman *, 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) {
|
forceinline unsigned char inb(unsigned short port) {
|
||||||
unsigned char al;
|
unsigned char al;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue