mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-09 11:20:30 +00:00
Bare metal: tweaks pertaining to physical memory handling
- Factor __invert_memory() into two routines, to make it easier for other libc routines to create their own negative address mappings - Tweak __invert_memory() to map only the usable memory as given in the 0xe820 memory map, and no more - Arrange for VGA console initialization to map video memory separately into virtual memory (in case needed) - Rename libc/vga/vga-init.S to libc/vga/rlinit-vga.S, to reduce confusion as to the module's purpose
This commit is contained in:
parent
87708c5d6e
commit
8089876c51
4 changed files with 28 additions and 7 deletions
|
@ -112,19 +112,34 @@ static noasan textreal void __normalize_e820(struct mman *mm) {
|
||||||
mm->e820n = n;
|
mm->e820n = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identity maps an area of physical memory to its negative address.
|
||||||
|
*/
|
||||||
|
noasan textreal void __invert_memory_area(struct mman *mm, uint64_t *pml4t,
|
||||||
|
uint64_t ps, uint64_t size,
|
||||||
|
uint64_t pte_flags) {
|
||||||
|
uint64_t pe = ps + size, p, *m;
|
||||||
|
ps = ROUNDDOWN(ps, 4096);
|
||||||
|
pe = ROUNDUP(pe, 4096);
|
||||||
|
for (p = ps; p != pe; p += 4096) {
|
||||||
|
m = __get_virtual(mm, pml4t, BANE + p, true);
|
||||||
|
if (m && !(*m & PAGE_V)) {
|
||||||
|
*m = p | PAGE_V | pte_flags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identity maps all usable physical memory to its negative address.
|
* Identity maps all usable physical memory to its negative address.
|
||||||
*/
|
*/
|
||||||
static noasan textreal void __invert_memory(struct mman *mm, uint64_t *pml4t) {
|
static noasan textreal void __invert_memory(struct mman *mm, uint64_t *pml4t) {
|
||||||
uint64_t i, j, *m, p, pe;
|
uint64_t i, j, *m, p, pe;
|
||||||
for (i = 0; i < mm->e820n; ++i) {
|
for (i = 0; i < mm->e820n; ++i) {
|
||||||
for (p = mm->e820[i].addr, pe = mm->e820[i].addr + mm->e820[i].size;
|
uint64_t ps = mm->e820[i].addr, size = mm->e820[i].size;
|
||||||
p != pe + 0x200000; p += 4096) {
|
/* ape/ape.S has already mapped the first 2 MiB of physical memory. */
|
||||||
m = __get_virtual(mm, pml4t, BANE + p, true);
|
if (ps < 0x200000 && ps + size <= 0x200000)
|
||||||
if (m && !(*m & PAGE_V)) {
|
continue;
|
||||||
*m = p | PAGE_V | PAGE_RW;
|
__invert_memory_area(mm, pml4t, ps, size, PAGE_RW);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -185,6 +185,8 @@ struct IdtDescriptor {
|
||||||
uint64_t *__get_virtual(struct mman *, uint64_t *, int64_t, bool);
|
uint64_t *__get_virtual(struct mman *, uint64_t *, int64_t, bool);
|
||||||
uint64_t __clear_page(uint64_t);
|
uint64_t __clear_page(uint64_t);
|
||||||
uint64_t __new_page(struct mman *);
|
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);
|
void __map_phdrs(struct mman *, uint64_t *, uint64_t);
|
||||||
|
|
||||||
forceinline unsigned char inb(unsigned short port) {
|
forceinline unsigned char inb(unsigned short port) {
|
||||||
|
|
|
@ -60,6 +60,7 @@ ssize_t sys_writev_vga(struct Fd *fd, const struct iovec *iov, int iovlen) {
|
||||||
|
|
||||||
__attribute__((__constructor__)) static textstartup void _vga_init(void) {
|
__attribute__((__constructor__)) static textstartup void _vga_init(void) {
|
||||||
if (IsMetal()) {
|
if (IsMetal()) {
|
||||||
|
struct mman *mm = (struct mman *)(BANE + 0x0500);
|
||||||
void * const vid_buf = (void *)(BANE + 0xb8000ull);
|
void * const vid_buf = (void *)(BANE + 0xb8000ull);
|
||||||
/*
|
/*
|
||||||
* Get the initial cursor position from the BIOS data area. Also get
|
* Get the initial cursor position from the BIOS data area. Also get
|
||||||
|
@ -74,6 +75,9 @@ __attribute__((__constructor__)) static textstartup void _vga_init(void) {
|
||||||
chr_ht_hi = *(uint8_t *)(BANE + 0x0486ull);
|
chr_ht_hi = *(uint8_t *)(BANE + 0x0486ull);
|
||||||
if (chr_ht_hi != 0 || chr_ht > 32)
|
if (chr_ht_hi != 0 || chr_ht > 32)
|
||||||
chr_ht = 32;
|
chr_ht = 32;
|
||||||
|
/* Make sure the video buffer is mapped into virtual memory. */
|
||||||
|
__invert_memory_area(mm, __get_pml4t(), (uint64_t)vid_buf,
|
||||||
|
2 * VGA_TTY_HEIGHT * VGA_TTY_WIDTH, PAGE_RW);
|
||||||
/*
|
/*
|
||||||
* Initialize our tty structure from the current screen contents,
|
* Initialize our tty structure from the current screen contents,
|
||||||
* current cursor position, & character height.
|
* current cursor position, & character height.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue