ref: 2e6234da0fbd204134ab0f66964c32a4f71b4a78
parent: d8035a86f77b7351ebdea9bad0ba77593b84ed76
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Mar 1 14:35:40 EST 2014
pc64: multiboot support
--- a/sys/src/9/pc64/l.s
+++ b/sys/src/9/pc64/l.s
@@ -30,6 +30,49 @@
pFARJMP32(SELECTOR(3, SELGDT, 0), _warp64<>-KZERO(SB))
+ BYTE $0x90 /* align */
+
+/*
+ * Must be 4-byte aligned.
+ */
+TEXT _multibootheader<>(SB), 1, $-4
+ LONG $0x1BADB002 /* magic */
+ LONG $0x00010003 /* flags */
+ LONG $-(0x1BADB002 + 0x00010003) /* checksum */
+ LONG $_multibootheader<>-KZERO(SB) /* header_addr */
+ LONG $_protected<>-KZERO(SB) /* load_addr */
+ LONG $edata-KZERO(SB) /* load_end_addr */
+ LONG $end-KZERO(SB) /* bss_end_addr */
+ LONG $_multibootentry<>-KZERO(SB) /* entry_addr */
+ LONG $0 /* mode_type */
+ LONG $0 /* width */
+ LONG $0 /* height */
+ LONG $0 /* depth */
+
+/*
+ * the kernel expects the data segment to be page-aligned
+ * multiboot bootloaders put the data segment right behind text
+ */
+TEXT _multibootentry<>(SB), 1, $-4
+ MOVL $etext-KZERO(SB), SI
+ MOVL SI, DI
+ ADDL $(BY2PG-1), DI
+ ANDL $~(BY2PG-1), DI
+ MOVL $edata-KZERO(SB), CX
+ SUBL DI, CX
+ ADDL CX, SI
+ ADDL CX, DI
+ STD
+ REP; MOVSB
+ CLD
+ MOVL BX, multibootptr-KZERO(SB)
+ MOVL $_protected<>-KZERO(SB), AX
+ JMP* AX
+
+/* multiboot structure pointer (physical address) */
+TEXT multibootptr(SB), 1, $-4
+ LONG $0
+
TEXT _gdt<>(SB), 1, $-4
/* null descriptor */
LONG $0
--- a/sys/src/9/pc64/main.c
+++ b/sys/src/9/pc64/main.c
@@ -33,12 +33,61 @@
extern void (*i8237alloc)(void);
static void
+multibootargs(void)
+{
+ extern ulong multibootptr;
+ ulong *multiboot;
+ char *cp, *ep;
+ ulong *m, l;
+
+ if(multibootptr == 0)
+ return;
+
+ multiboot = (ulong*)KADDR(multibootptr);
+ /* command line */
+ if((multiboot[0] & (1<<2)) != 0)
+ strncpy(BOOTLINE, KADDR(multiboot[4]), BOOTLINELEN-1);
+
+ cp = BOOTARGS;
+ ep = cp + BOOTARGSLEN-1;
+
+ /* memory map */
+ if((multiboot[0] & (1<<6)) != 0 && (l = multiboot[11]) >= 24){
+ cp = seprint(cp, ep, "*e820=");
+ m = KADDR(multiboot[12]);
+ while(m[0] >= 20 && m[0] <= l-4){
+ uvlong base, size;
+ m++;
+ base = ((uvlong)m[0] | (uvlong)m[1]<<32);
+ size = ((uvlong)m[2] | (uvlong)m[3]<<32);
+ cp = seprint(cp, ep, "%.1lux %.16llux %.16llux ",
+ m[4] & 0xF, base, base+size);
+ l -= m[-1]+4;
+ m = (ulong*)((uintptr)m + m[-1]);
+ }
+ cp[-1] = '\n';
+ }
+
+ /* plan9.ini passed as the first module */
+ if((multiboot[0] & (1<<3)) != 0 && multiboot[5] > 0){
+ m = KADDR(multiboot[6]);
+ l = m[1] - m[0];
+ m = KADDR(m[0]);
+ if(cp+l > ep)
+ l = ep - cp;
+ memmove(cp, m, l);
+ cp += l;
+ }
+ *cp = 0;
+}
+
+static void
options(void)
{
long i, n;
char *cp, *line[MAXCONF], *p, *q;
- // multibootargs();
+ multibootargs();
/*
* parse configuration args from dos file plan9.ini