mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-01 03:53:33 +00:00
0da47c51de
* [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>
126 lines
4.3 KiB
ArmAsm
126 lines
4.3 KiB
ArmAsm
/*-*- 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
|