diff --git a/sys/src/9/pc64/l.s b/sys/src/9/pc64/l.s index 18c6f7320..a1c17aa91 100644 --- a/sys/src/9/pc64/l.s +++ b/sys/src/9/pc64/l.s @@ -30,6 +30,49 @@ TEXT _protected<>(SB), 1, $-4 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 diff --git a/sys/src/9/pc64/main.c b/sys/src/9/pc64/main.c index 9cec7f8f9..f3f94e5b2 100644 --- a/sys/src/9/pc64/main.c +++ b/sys/src/9/pc64/main.c @@ -32,13 +32,62 @@ uchar *sp; /* user stack of init proc */ 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