ref: 1ae5fc01a6e9c6fb1a1befd4c60653a6af10a9e0
parent: 5f4e2670b4d8eb3cd1faed9808c3d0747284a288
author: Keegan Saunders <keegan@undefinedbehaviour.org>
date: Mon Sep 18 21:40:56 EDT 2023
boot/efi: add arm64 This means we can now boot kernels on arm64 EFI platforms. As well, porting additional architectures to our EFI boot should now be much simpler. Due to the nature of EFI relocations, this is a peculiar code environment for 7l and requires extra care. See rebase for more information.
--- /dev/null
+++ b/sys/src/boot/efi/aa64.s
@@ -1,0 +1,95 @@
+#define SYSREG(op0,op1,Cn,Cm,op2) SPR(((op0)<<19|(op1)<<16|(Cn)<<12|(Cm)<<8|(op2)<<5))
+#define SCTLR_EL1 SYSREG(3,0,1,0,0)
+
+#define NSH (1<<2 | 3)
+#define NSHST (1<<2 | 2)
+#define SY (3<<2 | 3)
+
+TEXT start(SB), 1, $-4
+_base:
+ MOV R0, R3
+ MOV R1, R4
+
+ MOV $setSB(SB), R0
+ BL rebase(SB)
+ MOV R0, R28
+
+ MOV $argsbuf<>(SB), R0
+ MOV R0, confaddr(SB)
+
+ MOV R3, R0
+ MOV R4, 0x08(FP)
+ B efimain(SB)
+
+TEXT rebase(SB), 1, $-4
+ ADR _base, R1
+ SUB $0x8200, R0
+ ADD R1, R0
+ RETURN
+
+TEXT eficall(SB), 1, $-4
+ MOV R0, R8
+ MOV 0x08(FP), R0
+ MOV 0x10(FP), R1
+ MOV 0x18(FP), R2
+ MOV 0x20(FP), R3
+ MOV 0x28(FP), R4
+ MOV 0x30(FP), R5
+ MOV 0x38(FP), R6
+ MOV 0x40(FP), R7
+ B (R8)
+
+TEXT mmudisable<>(SB), 1, $-4
+#define SCTLRCLR \
+ /* RES0 */ ( 3<<30 \
+ /* RES0 */ | 1<<27 \
+ /* UCI */ | 1<<26 \
+ /* EE */ | 1<<25 \
+ /* RES0 */ | 1<<21 \
+ /* E0E */ | 1<<24 \
+ /* WXN */ | 1<<19 \
+ /* nTWE */ | 1<<18 \
+ /* RES0 */ | 1<<17 \
+ /* nTWI */ | 1<<16 \
+ /* UCT */ | 1<<15 \
+ /* DZE */ | 1<<14 \
+ /* RES0 */ | 1<<13 \
+ /* RES0 */ | 1<<10 \
+ /* UMA */ | 1<<9 \
+ /* SA0 */ | 1<<4 \
+ /* SA */ | 1<<3 \
+ /* A */ | 1<<1 )
+#define SCTLRSET \
+ /* RES1 */ ( 3<<28 \
+ /* RES1 */ | 3<<22 \
+ /* RES1 */ | 1<<20 \
+ /* RES1 */ | 1<<11 )
+#define SCTLRMMU \
+ /* I */ ( 1<<12 \
+ /* C */ | 1<<2 \
+ /* M */ | 1<<0 )
+
+ /* initialise SCTLR, MMU and caches off */
+ ISB $SY
+ MRS SCTLR_EL1, R0
+ BIC $(SCTLRCLR | SCTLRMMU), R0
+ ORR $SCTLRSET, R0
+ ISB $SY
+ MSR R0, SCTLR_EL1
+ ISB $SY
+
+ DSB $NSHST
+ TLBI R0, 0,8,7,0 /* VMALLE1 */
+ DSB $NSH
+ ISB $SY
+ RETURN
+
+TEXT jump(SB), 1, $-4
+ MOV R0, R3
+ MOV R1, R4
+ BL mmudisable<>(SB)
+ MOV R4, R0
+ B (R3)
+
+GLOBL confaddr(SB), $8
+GLOBL argsbuf<>(SB), $0x1000
--- a/sys/src/boot/efi/efi.c
+++ b/sys/src/boot/efi/efi.c
@@ -10,6 +10,16 @@
int (*read)(void *f, void *data, int len);
void (*close)(void *f);
+/*
+ * on ia32 and amd64, we use IMAGE_FILE_RELOCS_STRIPPED which
+ * disables relocations, so this is a no-op.
+ *
+ * on arm64, the EFI loader can move our code, so we need to
+ * update some of our stored addresses (such as callbacks)
+ * which assume we are loaded at our requested base address.
+ */
+extern void *rebase(void *addr);
+
void
putc(int c)
{
@@ -297,6 +307,10 @@
f = nil;
if(pxeinit(&f) && isoinit(&f) && fsinit(&f))
print("no boot devices\n");
+
+ read = rebase(read);
+ close = rebase(close);
+ open = rebase(open);
for(;;){
kern = configure(f, path);
--- a/sys/src/boot/efi/fns.h
+++ b/sys/src/boot/efi/fns.h
@@ -5,7 +5,7 @@
extern char hex[];
void usleep(int t);
-void jump(void *pc);
+void jump(void *pc, void *arg);
int pxeinit(void **pf);
int isoinit(void **pf);
--- /dev/null
+++ b/sys/src/boot/efi/ia32.s
@@ -1,0 +1,47 @@
+#include "mem.h"
+
+TEXT start(SB), 1, $0
+ CALL reloc(SP)
+
+TEXT reloc(SB), 1, $0
+ MOVL 0(SP), SI
+ SUBL $reloc-IMAGEBASE(SB), SI
+ MOVL $IMAGEBASE, DI
+ MOVL $edata-IMAGEBASE(SB), CX
+ CLD
+ REP; MOVSB
+ MOVL $efimain(SB), DI
+ MOVL DI, (SP)
+ RET
+
+TEXT jump(SB), $0
+ CLI
+ MOVL 4(SP), AX
+ JMP *AX
+
+TEXT eficall(SB), 1, $0
+ MOVL SP, SI
+ MOVL SP, DI
+ MOVL $(4*16), CX
+ SUBL CX, DI
+ ANDL $~15ULL, DI
+ SUBL $8, DI
+
+ MOVL 4(SI), AX
+ LEAL 8(DI), SP
+
+ CLD
+ REP; MOVSB
+ SUBL $(4*16), SI
+
+ CALL AX
+
+ MOVL SI, SP
+ RET
+
+TEXT rebase(SB), 1, $0
+ MOVL 4(SP), AX
+ RET
+
+GLOBL confaddr(SB), $4
+DATA confaddr(SB)/4, $CONFADDR
--- a/sys/src/boot/efi/iso.c
+++ b/sys/src/boot/efi/iso.c
@@ -24,8 +24,10 @@
uchar dirlen;
uchar extlen;
- uchar lba[8];
- uchar len[8];
+ ulong lba;
+ ulong lbabe;
+ ulong len;
+ ulong lenbe;
uchar date[7];
@@ -133,8 +135,24 @@
break;
if(d.dirlen == 0)
continue; /* zero padding to next sector */
- if(read(ex, &d.dirlen + 1, Dirsz-1) != Dirsz-1)
+ if(read(ex, &d.extlen, 1) != 1)
break;
+ if(read(ex, &d.lba, 4) != 4)
+ break;
+ if(read(ex, &d.lbabe, 4) != 4)
+ break;
+ if(read(ex, &d.len, 4) != 4)
+ break;
+ if(read(ex, &d.lenbe, 4) != 4)
+ break;
+ if(read(ex, d.date, 7) != 7)
+ break;
+ if(read(ex, d.flags, 3) != 3)
+ break;
+ if(read(ex, d.seq, 4) != 4)
+ break;
+ if(read(ex, &d.namelen, 1) != 1)
+ break;
if(read(ex, name, d.namelen) != d.namelen)
break;
i = d.dirlen - (Dirsz + d.namelen);
@@ -158,8 +176,8 @@
i = end - path;
if(d.namelen == i && memcmp(name, path, i) == 0){
ex->rp = ex->ep;
- ex->lba = *((ulong*)d.lba);
- ex->len = *((ulong*)d.len);
+ ex->lba = d.lba;
+ ex->len = d.len;
if(*end == 0)
return 0;
else if(d.flags[0] & 2){
--- a/sys/src/boot/efi/mkfile
+++ b/sys/src/boot/efi/mkfile
@@ -1,4 +1,4 @@
-TARG=bootia32.efi bootx64.efi efiboot.fat
+TARG=bootia32.efi bootx64.efi bootaa64.efi efiboot.fat
HFILES=fns.h mem.h
IMAGEBASE=0x8000
CFLAGS=-FTVw
@@ -9,55 +9,37 @@
install:V: $TARG
cp $prereq /386
-bootia32.efi: pe32.8 efi.8 fs.8 pxe.8 iso.8 sub.8
- 8l -l -H3 -T$IMAGEBASE -o $target $prereq
-
-pe32.8: pe32.s
- 8a $PEFLAGS pe32.s
-
-efi.8: efi.c efi.h
- 8c $CFLAGS efi.c
-
-fs.8: fs.c efi.h
- 8c $CFLAGS fs.c
-
-pxe.8: pxe.c efi.h
- 8c $CFLAGS pxe.c
-
-iso.8: iso.c efi.h
- 8c $CFLAGS iso.c
-
-sub.8: sub.c
- 8c $CFLAGS sub.c
-
+%.8: %.s
+ 8a $PEFLAGS $stem.s
+%.8: %.c
+ 8c $CFLAGS $stem.c
+bootia32.efi: ia32.8 efi.8 fs.8 pxe.8 iso.8 sub.8
+ 8l -l -s -R1 -T0x8200 -o bootia32.out $prereq
+ aux/aout2efi -Z$IMAGEBASE -o $target bootia32.out
%.8: $HFILES
-bootx64.efi: pe64.6 efi.6 fs.6 pxe.6 iso.6 sub.6
- 6l -l -s -R1 -T$IMAGEBASE -o bootx64.out $prereq
- dd -if bootx64.out -bs 1 -iseek 40 >$target
+%.6: %.s
+ 6a $PEFLAGS $stem.s
+%.6: %.c
+ 6c $CFLAGS $stem.c
+bootx64.efi: x64.6 efi.6 fs.6 pxe.6 iso.6 sub.6
+ 6l -l -s -R1 -T0x8200 -o bootx64.out $prereq
+ aux/aout2efi -Z$IMAGEBASE -o $target bootx64.out
+%.6: $HFILES
-pe64.6: pe64.s
- 6a $PEFLAGS pe64.s
-efi.6: efi.c efi.h
- 6c $CFLAGS efi.c
+%.7: %.s
+ 7a $PEFLAGS $stem.s
+%.7: %.c
+ 7c $CFLAGS $stem.c
+bootaa64.efi: aa64.7 efi.7 fs.7 pxe.7 iso.7 sub.7
+ 7l -l -s -R1 -T0x8200 -o bootaa64.out $prereq
+ aux/aout2efi -Z$IMAGEBASE -o $target bootaa64.out
+%.7: $HFILES
-fs.6: fs.c efi.h
- 6c $CFLAGS fs.c
-pxe.6: pxe.c efi.h
- 6c $CFLAGS pxe.c
-
-iso.6: iso.c efi.h
- 6c $CFLAGS iso.c
-
-sub.6: sub.c
- 6c $CFLAGS sub.c
-
-%.6: $HFILES
-
-efiboot.fat:D: bootia32.efi bootx64.efi
+efiboot.fat:D: bootia32.efi bootx64.efi bootaa64.efi
s = $target.$pid
rm -f $target
dd -if /dev/zero -of $target -bs 1024 -count 1024
@@ -68,6 +50,7 @@
mkdir /n/esp/efi/boot
cp bootia32.efi /n/esp/efi/boot
cp bootx64.efi /n/esp/efi/boot
+ cp bootaa64.efi /n/esp/efi/boot
unmount /n/esp
rm /srv/$s
@@ -84,7 +67,7 @@
disk/mk9660 -B 386/9bootiso -E 386/efiboot.fat -p <{echo +} -s tmp $target
rm -r tmp
-test.fat:D: bootia32.efi bootx64.efi
+test.fat:D: bootia32.efi bootx64.efi bootaa64.efi
s = $target.$pid
rm -f $target
dd -if /dev/zero -of $target -bs 65536 -count 128
@@ -95,6 +78,7 @@
mkdir /n/esp/efi/boot
cp bootia32.efi /n/esp/efi/boot
cp bootx64.efi /n/esp/efi/boot
+ cp bootaa64.efi /n/esp/efi/boot
cp /386/9pc /n/esp
echo 'bootfile=9pc' >/n/esp/plan9.ini
unmount /n/esp
@@ -102,4 +86,4 @@
clean:V:
- rm -f *.[68] *.out $TARG test.*
+ rm -f *.[678] *.out $TARG test.*
--- a/sys/src/boot/efi/pe32.s
+++ /dev/null
@@ -1,159 +1,0 @@
-TEXT mzhdr(SB), 1, $0
- BYTE $'M'; BYTE $'Z'
-
- WORD $0 /* e_cblp UNUSED */
- WORD $0 /* e_cp UNUSED */
- WORD $0 /* e_crlc UNUSED */
- WORD $0 /* e_cparhdr UNUSED */
- WORD $0 /* e_minalloc UNUSED */
- WORD $0 /* e_maxalloc UNUSED */
- WORD $0 /* e_ss UNUSED */
- WORD $0 /* e_sp UNUSED */
- WORD $0 /* e_csum UNUSED */
- WORD $0 /* e_ip UNUSED */
- WORD $0 /* e_cs UNUSED */
- WORD $0 /* e_lsarlc UNUSED */
- WORD $0 /* e_ovno UNUSED */
-
- WORD $0 /* e_res UNUSED */
- WORD $0
- WORD $0
- WORD $0
- WORD $0
-
- WORD $0 /* e_oemid UNUSED */
-
- WORD $0 /* e_res2 UNUSED */
- WORD $0
- WORD $0
- WORD $0
- WORD $0
- WORD $0
- WORD $0
- WORD $0
- WORD $0
- WORD $0
-
- LONG $pehdr-IMAGEBASE(SB) /* offset to pe header */
-
-TEXT pehdr(SB), 1, $0
- BYTE $'P'; BYTE $'E'; BYTE $0; BYTE $0
-
- WORD $0x014C /* Machine (Intel 386) */
- WORD $1 /* NumberOfSections */
- LONG $0 /* TimeDateStamp UNUSED */
- LONG $0 /* PointerToSymbolTable UNUSED */
- LONG $0 /* NumberOfSymbols UNUSED */
- WORD $0xE0 /* SizeOfOptionalHeader */
- WORD $2103 /* Characteristics (no relocations, executable, 32 bit) */
-
- WORD $0x10B /* Magic (PE32) */
- BYTE $9 /* MajorLinkerVersion UNUSED */
- BYTE $0 /* MinorLinkerVersion UNUSED */
- LONG $0 /* SizeOfCode UNUSED */
- LONG $0 /* SizeOfInitializedData UNUSED */
- LONG $0 /* SizeOfUninitializedData UNUSED */
- LONG $start-IMAGEBASE(SB)/* AddressOfEntryPoint */
- LONG $0 /* BaseOfCode UNUSED */
- LONG $0 /* BaseOfData UNUSED */
- LONG $IMAGEBASE /* ImageBase */
- LONG $0x200 /* SectionAlignment */
- LONG $0x200 /* FileAlignment */
- WORD $4 /* MajorOperatingSystemVersion UNUSED */
- WORD $0 /* MinorOperatingSystemVersion UNUSED */
- WORD $0 /* MajorImageVersion UNUSED */
- WORD $0 /* MinorImageVersion UNUSED */
- WORD $4 /* MajorSubsystemVersion */
- WORD $0 /* MinorSubsystemVersion UNUSED */
- LONG $0 /* Win32VersionValue UNUSED */
- LONG $end-IMAGEBASE(SB) /* SizeOfImage */
- LONG $start-IMAGEBASE(SB)/* SizeOfHeaders */
- LONG $0 /* CheckSum UNUSED */
- WORD $10 /* Subsystem (10 = efi application) */
- WORD $0 /* DllCharacteristics UNUSED */
- LONG $0 /* SizeOfStackReserve UNUSED */
- LONG $0 /* SizeOfStackCommit UNUSED */
- LONG $0 /* SizeOfHeapReserve UNUSED */
- LONG $0 /* SizeOfHeapCommit UNUSED */
- LONG $0 /* LoaderFlags UNUSED */
- LONG $16 /* NumberOfRvaAndSizes UNUSED */
-
- LONG $0; LONG $0
- LONG $0; LONG $0
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
-
- BYTE $'.'; BYTE $'t'; BYTE $'e'; BYTE $'x'
- BYTE $'t'; BYTE $0; BYTE $0; BYTE $0
- LONG $edata-(IMAGEBASE+0x200)(SB) /* VirtualSize */
- LONG $start-IMAGEBASE(SB) /* VirtualAddress */
- LONG $edata-(IMAGEBASE+0x200)(SB) /* SizeOfData */
- LONG $start-IMAGEBASE(SB) /* PointerToRawData */
- LONG $0 /* PointerToRelocations UNUSED */
- LONG $0 /* PointerToLinenumbers UNUSED */
- WORD $0 /* NumberOfRelocations UNUSED */
- WORD $0 /* NumberOfLinenumbers UNUSED */
- LONG $0x86000020 /* Characteristics (code, execute, read, write) */
-
- /* padding to get start(SB) at IMAGEBASE+0x200 */
- LONG $0; LONG $0; LONG $0; LONG $0;
- LONG $0; LONG $0; LONG $0; LONG $0;
- LONG $0; LONG $0; LONG $0; LONG $0;
- LONG $0; LONG $0; LONG $0; LONG $0;
- LONG $0; LONG $0; LONG $0; LONG $0;
- LONG $0; LONG $0; LONG $0; LONG $0;
- LONG $0; LONG $0; LONG $0; LONG $0;
- LONG $0; LONG $0; LONG $0; LONG $0;
- LONG $0; LONG $0; LONG $0; LONG $0;
- LONG $0; LONG $0; LONG $0; LONG $0;
-
-TEXT start(SB), 1, $0
- CALL reloc(SP)
-
-TEXT reloc(SB), 1, $0
- MOVL 0(SP), SI
- SUBL $reloc-IMAGEBASE(SB), SI
- MOVL $IMAGEBASE, DI
- MOVL $edata-IMAGEBASE(SB), CX
- CLD
- REP; MOVSB
- MOVL $efimain(SB), DI
- MOVL DI, (SP)
- RET
-
-TEXT jump(SB), $0
- CLI
- MOVL 4(SP), AX
- JMP *AX
-
-TEXT eficall(SB), 1, $0
- MOVL SP, SI
- MOVL SP, DI
- MOVL $(4*16), CX
- SUBL CX, DI
- ANDL $~15ULL, DI
- SUBL $8, DI
-
- MOVL 4(SI), AX
- LEAL 8(DI), SP
-
- CLD
- REP; MOVSB
- SUBL $(4*16), SI
-
- CALL AX
-
- MOVL SI, SP
- RET
--- a/sys/src/boot/efi/pe64.s
+++ /dev/null
@@ -1,237 +1,0 @@
-TEXT mzhdr(SB), 1, $0
- BYTE $'M'; BYTE $'Z'
-
- WORD $0 /* e_cblp UNUSED */
- WORD $0 /* e_cp UNUSED */
- WORD $0 /* e_crlc UNUSED */
- WORD $0 /* e_cparhdr UNUSED */
- WORD $0 /* e_minalloc UNUSED */
- WORD $0 /* e_maxalloc UNUSED */
- WORD $0 /* e_ss UNUSED */
- WORD $0 /* e_sp UNUSED */
- WORD $0 /* e_csum UNUSED */
- WORD $0 /* e_ip UNUSED */
- WORD $0 /* e_cs UNUSED */
- WORD $0 /* e_lsarlc UNUSED */
- WORD $0 /* e_ovno UNUSED */
-
- WORD $0 /* e_res UNUSED */
- WORD $0
- WORD $0
- WORD $0
- WORD $0
-
- WORD $0 /* e_oemid UNUSED */
-
- WORD $0 /* e_res2 UNUSED */
- WORD $0
- WORD $0
- WORD $0
- WORD $0
- WORD $0
- WORD $0
- WORD $0
- WORD $0
- WORD $0
-
- LONG $pehdr-IMAGEBASE(SB) /* offset to pe header */
-
-TEXT pehdr(SB), 1, $0
- BYTE $'P'; BYTE $'E'; BYTE $0; BYTE $0
-
- WORD $0x8664 /* Machine (AMD64) */
- WORD $1 /* NumberOfSections */
- LONG $0 /* TimeDateStamp UNUSED */
- LONG $0 /* PointerToSymbolTable UNUSED */
- LONG $0 /* NumberOfSymbols UNUSED */
- WORD $0xF0 /* SizeOfOptionalHeader */
- WORD $2223 /* Characteristics */
-
- WORD $0x20B /* Magic (PE32+) */
- BYTE $9 /* MajorLinkerVersion UNUSED */
- BYTE $0 /* MinorLinkerVersion UNUSED */
- LONG $0 /* SizeOfCode UNUSED */
- LONG $0 /* SizeOfInitializedData UNUSED */
- LONG $0 /* SizeOfUninitializedData UNUSED */
- LONG $start-IMAGEBASE(SB)/* AddressOfEntryPoint */
- LONG $0 /* BaseOfCode UNUSED */
-
- QUAD $IMAGEBASE /* ImageBase */
- LONG $0x200 /* SectionAlignment */
- LONG $0x200 /* FileAlignment */
- WORD $4 /* MajorOperatingSystemVersion UNUSED */
- WORD $0 /* MinorOperatingSystemVersion UNUSED */
- WORD $0 /* MajorImageVersion UNUSED */
- WORD $0 /* MinorImageVersion UNUSED */
- WORD $4 /* MajorSubsystemVersion */
- WORD $0 /* MinorSubsystemVersion UNUSED */
- LONG $0 /* Win32VersionValue UNUSED */
- LONG $end-IMAGEBASE(SB) /* SizeOfImage */
- LONG $start-IMAGEBASE(SB)/* SizeOfHeaders */
- LONG $0 /* CheckSum UNUSED */
- WORD $10 /* Subsystem (10 = efi application) */
- WORD $0 /* DllCharacteristics UNUSED */
- QUAD $0 /* SizeOfStackReserve UNUSED */
- QUAD $0 /* SizeOfStackCommit UNUSED */
- QUAD $0 /* SizeOfHeapReserve UNUSED */
- QUAD $0 /* SizeOfHeapCommit UNUSED */
- LONG $0 /* LoaderFlags UNUSED */
- LONG $16 /* NumberOfRvaAndSizes UNUSED */
-
- LONG $0; LONG $0
- LONG $0; LONG $0
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
- LONG $0; LONG $0 /* RVA */
-
- BYTE $'.'; BYTE $'t'; BYTE $'e'; BYTE $'x'
- BYTE $'t'; BYTE $0; BYTE $0; BYTE $0
- LONG $edata-(IMAGEBASE+0x200)(SB) /* VirtualSize */
- LONG $start-IMAGEBASE(SB) /* VirtualAddress */
- LONG $edata-(IMAGEBASE+0x200)(SB) /* SizeOfData */
- LONG $start-IMAGEBASE(SB) /* PointerToRawData */
- LONG $0 /* PointerToRelocations UNUSED */
- LONG $0 /* PointerToLinenumbers UNUSED */
- WORD $0 /* NumberOfRelocations UNUSED */
- WORD $0 /* NumberOfLinenumbers UNUSED */
- LONG $0x86000020 /* Characteristics (code, execute, read, write) */
-
- /* padding to get start(SB) at IMAGEBASE+0x200 */
- LONG $0; LONG $0; LONG $0; LONG $0;
- LONG $0; LONG $0; LONG $0; LONG $0;
- LONG $0; LONG $0; LONG $0; LONG $0;
- LONG $0; LONG $0; LONG $0; LONG $0;
- LONG $0; LONG $0; LONG $0; LONG $0;
- LONG $0; LONG $0; LONG $0; LONG $0;
- LONG $0; LONG $0; LONG $0; LONG $0;
- LONG $0; LONG $0; LONG $0; LONG $0;
- LONG $0; LONG $0; LONG $0; LONG $0
-
-MODE $64
-
-TEXT start(SB), 1, $-4
- /* spill arguments */
- MOVQ CX, 8(SP)
- MOVQ DX, 16(SP)
-
- CALL reloc(SP)
-
-TEXT reloc(SB), 1, $-4
- MOVQ 0(SP), SI
- SUBQ $reloc-IMAGEBASE(SB), SI
- MOVQ $IMAGEBASE, DI
- MOVQ $edata-IMAGEBASE(SB), CX
- CLD
- REP; MOVSB
-
- MOVQ 16(SP), BP
- MOVQ $efimain(SB), DI
- MOVQ DI, (SP)
- RET
-
-TEXT eficall(SB), 1, $-4
- MOVQ SP, SI
- MOVQ SP, DI
- MOVL $(8*16), CX
- SUBQ CX, DI
- ANDQ $~15ULL, DI
- LEAQ 16(DI), SP
- CLD
- REP; MOVSB
- SUBQ $(8*16), SI
-
- MOVQ 0(SP), CX
- MOVQ 8(SP), DX
- MOVQ 16(SP), R8
- MOVQ 24(SP), R9
- CALL BP
-
- MOVQ SI, SP
- RET
-
-#include "mem.h"
-
-TEXT jump(SB), 1, $-4
- CLI
-
- /* load zero length idt */
- MOVL $_idtptr64p<>(SB), AX
- MOVL (AX), IDTR
-
- /* load temporary gdt */
- MOVL $_gdtptr64p<>(SB), AX
- MOVL (AX), GDTR
-
- /* load CS with 32bit code segment */
- PUSHQ $SELECTOR(3, SELGDT, 0)
- PUSHQ $_warp32<>(SB)
- RETFQ
-
-MODE $32
-
-TEXT _warp32<>(SB), 1, $-4
-
- /* load 32bit data segments */
- MOVL $SELECTOR(2, SELGDT, 0), AX
- MOVW AX, DS
- MOVW AX, ES
- MOVW AX, FS
- MOVW AX, GS
- MOVW AX, SS
-
- /* turn off paging */
- MOVL CR0, AX
- ANDL $0x7fffffff, AX /* ~(PG) */
- MOVL AX, CR0
-
- MOVL $0, AX
- MOVL AX, CR3
-
- /* disable long mode */
- MOVL $0xc0000080, CX /* Extended Feature Enable */
- RDMSR
- ANDL $0xfffffeff, AX /* Long Mode Disable */
- WRMSR
-
- /* diable pae */
- MOVL CR4, AX
- ANDL $0xffffff5f, AX /* ~(PAE|PGE) */
- MOVL AX, CR4
-
- JMP *BP
-
-TEXT _gdt<>(SB), 1, $-4
- /* null descriptor */
- LONG $0
- LONG $0
-
- /* (KESEG) 64 bit long mode exec segment */
- LONG $(0xFFFF)
- LONG $(SEGL|SEGG|SEGP|(0xF<<16)|SEGPL(0)|SEGEXEC|SEGR)
-
- /* 32 bit data segment descriptor for 4 gigabytes (PL 0) */
- LONG $(0xFFFF)
- LONG $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
-
- /* 32 bit exec segment descriptor for 4 gigabytes (PL 0) */
- LONG $(0xFFFF)
- LONG $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
-
-TEXT _gdtptr64p<>(SB), 1, $-4
- WORD $(4*8-1)
- QUAD $_gdt<>(SB)
-
-TEXT _idtptr64p<>(SB), 1, $-4
- WORD $0
- QUAD $0
--- a/sys/src/boot/efi/sub.c
+++ b/sys/src/boot/efi/sub.c
@@ -149,11 +149,12 @@
return 0;
}
-#define BOOTLINE ((char*)CONFADDR)
+#define BOOTLINE confaddr
#define BOOTLINELEN 64
-#define BOOTARGS ((char*)(CONFADDR+BOOTLINELEN))
+#define BOOTARGS (confaddr+BOOTLINELEN)
#define BOOTARGSLEN (4096-0x200-BOOTLINELEN)
+extern char *confaddr;
static char *confend;
static char*
@@ -329,6 +330,13 @@
return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
}
+static uvlong
+beswall(uvlong l)
+{
+ uchar *p = (uchar*)&l;
+ return ((uvlong)p[0]<<56) | ((uvlong)p[1]<<48) | ((uvlong)p[2]<<40) | ((uvlong)p[3]<<32) | ((uvlong)p[4]<<24) | ((uvlong)p[5]<<16) | ((uvlong)p[6]<<8) | (uvlong)p[7];
+}
+
char*
bootkern(void *f)
{
@@ -342,8 +350,12 @@
e = (uchar*)(beswal(ex.entry) & ~0xF0000000UL);
switch(beswal(ex.magic)){
case S_MAGIC:
- if(readn(f, e, 8) != 8)
+ case R_MAGIC:
+ if(readn(f, &e, 8) != 8)
goto Error;
+ /* load low address */
+ e = (uchar*)(beswall((uvlong)e) & 0x0FFFFFFFUL);
+ break;
case I_MAGIC:
break;
default:
@@ -371,7 +383,7 @@
memconf(findconf("*e820=")?nil:&confend);
unload();
- jump(e);
+ jump(e, BOOTARGS);
Error:
return "i/o error";
--- /dev/null
+++ b/sys/src/boot/efi/x64.s
@@ -1,0 +1,124 @@
+MODE $64
+
+TEXT start(SB), 1, $-4
+ /* spill arguments */
+ MOVQ CX, 8(SP)
+ MOVQ DX, 16(SP)
+
+ CALL reloc(SP)
+
+TEXT reloc(SB), 1, $-4
+ MOVQ 0(SP), SI
+ SUBQ $reloc-IMAGEBASE(SB), SI
+ MOVQ $IMAGEBASE, DI
+ MOVQ $edata-IMAGEBASE(SB), CX
+ CLD
+ REP; MOVSB
+
+ MOVQ 16(SP), BP
+ MOVQ $efimain(SB), DI
+ MOVQ DI, (SP)
+ RET
+
+TEXT eficall(SB), 1, $-4
+ MOVQ SP, SI
+ MOVQ SP, DI
+ MOVL $(8*16), CX
+ SUBQ CX, DI
+ ANDQ $~15ULL, DI
+ LEAQ 16(DI), SP
+ CLD
+ REP; MOVSB
+ SUBQ $(8*16), SI
+
+ MOVQ 0(SP), CX
+ MOVQ 8(SP), DX
+ MOVQ 16(SP), R8
+ MOVQ 24(SP), R9
+ CALL BP
+
+ MOVQ SI, SP
+ RET
+
+TEXT rebase(SB), 1, $-4
+ MOVQ BP, AX
+ RET
+
+#include "mem.h"
+
+TEXT jump(SB), 1, $-4
+ CLI
+
+ /* load zero length idt */
+ MOVL $_idtptr64p<>(SB), AX
+ MOVL (AX), IDTR
+
+ /* load temporary gdt */
+ MOVL $_gdtptr64p<>(SB), AX
+ MOVL (AX), GDTR
+
+ /* load CS with 32bit code segment */
+ PUSHQ $SELECTOR(3, SELGDT, 0)
+ PUSHQ $_warp32<>(SB)
+ RETFQ
+
+MODE $32
+
+TEXT _warp32<>(SB), 1, $-4
+
+ /* load 32bit data segments */
+ MOVL $SELECTOR(2, SELGDT, 0), AX
+ MOVW AX, DS
+ MOVW AX, ES
+ MOVW AX, FS
+ MOVW AX, GS
+ MOVW AX, SS
+
+ /* turn off paging */
+ MOVL CR0, AX
+ ANDL $0x7fffffff, AX /* ~(PG) */
+ MOVL AX, CR0
+
+ MOVL $0, AX
+ MOVL AX, CR3
+
+ /* disable long mode */
+ MOVL $0xc0000080, CX /* Extended Feature Enable */
+ RDMSR
+ ANDL $0xfffffeff, AX /* Long Mode Disable */
+ WRMSR
+
+ /* diable pae */
+ MOVL CR4, AX
+ ANDL $0xffffff5f, AX /* ~(PAE|PGE) */
+ MOVL AX, CR4
+
+ JMP *BP
+
+TEXT _gdt<>(SB), 1, $-4
+ /* null descriptor */
+ LONG $0
+ LONG $0
+
+ /* (KESEG) 64 bit long mode exec segment */
+ LONG $(0xFFFF)
+ LONG $(SEGL|SEGG|SEGP|(0xF<<16)|SEGPL(0)|SEGEXEC|SEGR)
+
+ /* 32 bit data segment descriptor for 4 gigabytes (PL 0) */
+ LONG $(0xFFFF)
+ LONG $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
+
+ /* 32 bit exec segment descriptor for 4 gigabytes (PL 0) */
+ LONG $(0xFFFF)
+ LONG $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
+
+TEXT _gdtptr64p<>(SB), 1, $-4
+ WORD $(4*8-1)
+ QUAD $_gdt<>(SB)
+
+TEXT _idtptr64p<>(SB), 1, $-4
+ WORD $0
+ QUAD $0
+
+GLOBL confaddr(SB), $8
+DATA confaddr(SB)/8, $CONFADDR