Load kernels at non-standard base addresses. Also real-mode assembly.
[rsc] --rw-rw-r-- M 140560 glenda sys 8421 Nov 1 18:20 sys/src/boot/pc/boot.c
/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/boot.c:149,155 -
/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/boot.c:149,155
if(php->type != LOAD)
continue;
offset = php->offset;
- paddr = (char*)(php->paddr & ~0xF0000000);
+ paddr = (char*)PADDR(php->paddr);
if(offset < curoff){
/*
* Can't (be bothered to) rewind the
/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/boot.c:215,221 -
/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/boot.c:215,221
if(php->filesz < php->memsz){
print("%lud", php->memsz-php->filesz);
elftotal += php->memsz-php->filesz;
- memset((char*)((php->paddr & ~0xF0000000)+php->filesz), 0, php->memsz-php->filesz);
+ memset((char*)(PADDR(php->paddr)+php->filesz), 0, php->memsz-php->filesz);
}
curoff = php->offset+php->filesz;
curphdr++;
/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/boot.c:326,332 -
/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/boot.c:326,332
case READ9TEXT:
ep = &b->exec;
b->state = READ9DATA;
- b->bp = (char*)PGROUND(GLLONG(ep->entry)+GLLONG(ep->text));
+ b->bp = (char*)PGROUND(PADDR(GLLONG(ep->entry))+GLLONG(ep->text));
b->wp = b->bp;
b->ep = b->wp + GLLONG(ep->data);
print("+%ld", GLLONG(ep->data));
/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/boot.c:432,438 -
/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/boot.c:432,438
}
/* relocate data to start at page boundary */
- memmove((void*)PGROUND(entry+text), (void*)(entry+text), data);
+ memmove((void*)PGROUND(PADDR(entry+text)), (void*)(PADDR(entry+text)), data);
print("entry: %lux\n", entry);
warp9(PADDR(entry));
[rsc] --rw-rw-r-- M 140560 glenda sys 4273 Nov 1 18:20 sys/src/boot/pc/fns.h
/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/fns.h:106,111 -
/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/fns.h:106,113
int spllo(void);
void splx(int);
void trapinit(void);
+ void trapdisable(void);
+ void trapenable(void);
void uartdrain(void);
void uartspecial(int, void (*)(int), int (*)(void), int);
void uartputs(IOQ*, char*, int);
/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/fns.h:130,136 -
/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/fns.h:132,138
#define PLLONG(p,v) (p)[3]=(v);(p)[2]=(v)>>8;(p)[1]=(v)>>16;(p)[0]=(v)>>24
#define KADDR(a) ((void*)((ulong)(a)|KZERO))
- #define PADDR(a) ((ulong)(a)&~KZERO)
+ #define PADDR(a) ((ulong)(a)&~0xF0000000)
#define HOWMANY(x, y) (((x)+((y)-1))/(y))
#define ROUNDUP(x, y) (HOWMANY((x), (y))*(y))
[rsc] --rw-rw-r-- M 140560 glenda sys 18115 Nov 1 18:20 sys/src/boot/pc/l.s
/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/l.s:356,367 -
/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/l.s:356,370
LONG $(0xFFFF)
LONG $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
+ /* exec segment descriptor for 4 gigabytes (PL 0) 16-bit */
+ LONG $(0xFFFF)
+ LONG $(SEGG|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
+
/*
* pointer to initial gdt
*/
TEXT tgdtptr(SB),$0
-
- WORD $(3*8)
+ WORD $(4*8)
LONG $tgdt-KZERO(SB)
/*
/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/l.s:847,849 -
/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/l.s:850,1079
#else
DATA pxe+0(SB)/4, $0
#endif /* PXE */
+
+ /*
+ * Save registers.
+ */
+ TEXT saveregs(SB), $0
+ /* appease 8l */
+ SUBL $32, SP
+ POPL AX
+ POPL AX
+ POPL AX
+ POPL AX
+ POPL AX
+ POPL AX
+ POPL AX
+ POPL AX
+
+ PUSHL AX
+ PUSHL BX
+ PUSHL CX
+ PUSHL DX
+ PUSHL BP
+ PUSHL DI
+ PUSHL SI
+ PUSHFL
+
+ XCHGL 32(SP), AX /* swap return PC and saved flags */
+ XCHGL 0(SP), AX
+ XCHGL 32(SP), AX
+ RET
+
+ TEXT restoreregs(SB), $0
+ /* appease 8l */
+ PUSHL AX
+ PUSHL AX
+ PUSHL AX
+ PUSHL AX
+ PUSHL AX
+ PUSHL AX
+ PUSHL AX
+ PUSHL AX
+ ADDL $32, SP
+
+ XCHGL 32(SP), AX /* swap return PC and saved flags */
+ XCHGL 0(SP), AX
+ XCHGL 32(SP), AX
+
+ POPFL
+ POPL SI
+ POPL DI
+ POPL BP
+ POPL DX
+ POPL CX
+ POPL BX
+ POPL AX
+ RET
+
+ /*
+ * Assumed to be in protected mode at time of call.
+ * Switch to real mode, execute an interrupt, and
+ * then switch back to protected mode.
+ *
+ * Assumes:
+ *
+ * - no device interrupts are going to come in
+ * - 0-16MB is identity mapped in page tables
+ * - can use code segment 0x1000 in real mode
+ * to get at l.s code
+ */
+ TEXT realmodeidtptr(SB), $0
+ WORD $(4*256-1)
+ LONG $0
+
+ TEXT realmode0(SB), $0
+ CALL saveregs(SB)
+
+ /* switch to low code address */
+ LEAL physcode-KZERO(SB), AX
+ JMP *AX
+
+ TEXT physcode(SB), $0
+
+ /* switch to low stack */
+ MOVL SP, AX
+ MOVL $0x7C00, SP
+ PUSHL AX
+
+ /* load IDT with real-mode version; GDT already fine */
+ MOVL realmodeidtptr(SB), IDTR
+
+ /* edit INT $0x00 instruction below */
+ MOVL realmodeintr(SB), AX
+ MOVB AX, realmodeintrinst+1(SB)
+
+ /* disable paging */
+ MOVL CR0, AX
+ ANDL $0x7FFFFFFF, AX
+ MOVL AX, CR0
+ /* JMP .+2 to clear prefetch queue*/
+ BYTE $0xEB; BYTE $0x00
+
+ /* jump to 16-bit code segment */
+ /* JMPFAR SELECTOR(3, SELGDT, 0):$again16bit(SB) /**/
+ BYTE $0xEA
+ LONG $again16bit-KZERO(SB)
+ WORD $SELECTOR(3, SELGDT, 0)
+
+ TEXT again16bit(SB), $0
+ /*
+ * Now in 16-bit compatibility mode.
+ * These are 32-bit instructions being interpreted
+ * as 16-bit instructions. I'm being lazy and
+ * not using the macros because I know when
+ * the 16- and 32-bit instructions look the same
+ * or close enough.
+ */
+
+ /* disable protected mode and jump to real mode cs */
+ OPSIZE; MOVL CR0, AX
+ OPSIZE; XORL BX, BX
+ OPSIZE; INCL BX
+ OPSIZE; XORL BX, AX
+ OPSIZE; MOVL AX, CR0
+
+ /* JMPFAR 0x1000:now16real */
+ BYTE $0xEA
+ WORD $now16real-KZERO(SB)
+ WORD $0x1000
+
+ TEXT now16real(SB), $0
+ /* copy the registers for the bios call */
+ LWI(0x1000, rAX)
+ MOVW AX,SS
+ LWI(realmoderegs(SB), rBP)
+
+ /* offsets are in Ureg */
+ LXW(44, xBP, rAX)
+ MOVW AX, DS
+ LXW(40, xBP, rAX)
+ MOVW AX, ES
+
+ OPSIZE; LXW(0, xBP, rDI)
+ OPSIZE; LXW(4, xBP, rSI)
+ OPSIZE; LXW(16, xBP, rBX)
+ OPSIZE; LXW(20, xBP, rDX)
+ OPSIZE; LXW(24, xBP, rCX)
+ OPSIZE; LXW(28, xBP, rAX)
+
+ CLC
+
+ TEXT realmodeintrinst(SB), $0
+ INT $0x00
+
+ /* save the registers after the call */
+
+ LWI(0x7bfc, rSP)
+ OPSIZE; PUSHFL
+ OPSIZE; PUSHL AX
+
+ LWI(0x1000, rAX)
+ MOVW AX,SS
+ LWI(realmoderegs(SB), rBP)
+
+ OPSIZE; SXW(rDI, 0, xBP)
+ OPSIZE; SXW(rSI, 4, xBP)
+ OPSIZE; SXW(rBX, 16, xBP)
+ OPSIZE; SXW(rDX, 20, xBP)
+ OPSIZE; SXW(rCX, 24, xBP)
+ OPSIZE; POPL AX
+ OPSIZE; SXW(rAX, 28, xBP)
+
+ MOVW DS, AX
+ OPSIZE; SXW(rAX, 44, xBP)
+ MOVW ES, AX
+ OPSIZE; SXW(rAX, 40, xBP)
+
+ OPSIZE; POPL AX
+ OPSIZE; SXW(rAX, 64, xBP) /* flags */
+
+ /* re-enter protected mode and jump to 32-bit code */
+ OPSIZE; MOVL $1, AX
+ OPSIZE; MOVL AX, CR0
+
+ /* JMPFAR SELECTOR(2, SELGDT, 0):$again32bit(SB) /**/
+ OPSIZE
+ BYTE $0xEA
+ LONG $again32bit-KZERO(SB)
+ WORD $SELECTOR(2, SELGDT, 0)
+
+ TEXT again32bit(SB), $0
+ MOVW $SELECTOR(1, SELGDT, 0),AX
+ MOVW AX,DS
+ MOVW AX,SS
+ MOVW AX,ES
+ MOVW AX,FS
+ MOVW AX,GS
+
+ /* enable paging and jump to kzero-address code */
+ MOVL CR0, AX
+ ORL $0x80000000, AX
+ MOVL AX, CR0
+ LEAL again32kzero(SB), AX
+ JMP* AX
+
+ TEXT again32kzero(SB), $0
+ /* breathe a sigh of relief - back in 32-bit protected mode */
+
+ /* switch to old stack */
+ PUSHL AX /* match popl below for 8l */
+ MOVL $0x7BFC, SP
+ POPL SP
+
+ /* restore idt */
+ MOVL idtptr(SB),IDTR
+
+ CALL restoreregs(SB)
+ RET
+
+ TEXT realmoderegs(SB), $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 realmodeintr(SB), $0
+ LONG $0
+
[rsc] --rw-rw-r-- M 140560 glenda sys 8932 Nov 1 18:20 sys/src/boot/pc/load.c
/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/load.c:548,553 -
/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/load.c:548,557
sddetach();
consdrain();
+
+ splhi();
+ trapdisable();
+
/*
* This is where to push things on the stack to
* boot *BSD systems, e.g.
[rsc] --rw-rw-r-- M 140560 glenda sys 3371 Nov 1 18:20 sys/src/boot/pc/mem.h
/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/mem.h:6,17 -
/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/mem.h:6,17
* Sizes
*/
#define BI2BY 8 /* bits per byte */
- #define BI2WD 32 /* bits per word */
+ #define BI2WD 32 /* bits per word */
#define BY2WD 4 /* bytes per word */
#define BY2PG 4096 /* bytes per page */
#define WD2PG (BY2PG/BY2WD) /* words per page */
#define PGSHIFT 12 /* log(BY2PG) */
- #define PGROUND(s) (((s)+(BY2PG-1))&~(BY2PG-1))
+ #define PGROUND(s) (((s)+(BY2PG-1))&~(BY2PG-1))
#define MAXMACH 1 /* max # cpus system can run */
/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/mem.h:102,112 -
/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/mem.h:102,112
*/
#define PTEVALID (1<<0)
#define PTEUNCACHED 0 /* everything is uncached */
- #define PTEWRITE (1<<1)
+ #define PTEWRITE (1<<1)
#define PTERONLY (0<<1)
#define PTEKERNEL (0<<2)
#define PTEUSER (1<<2)
- #define PTESIZE (1<<7)
+ #define PTESIZE (1<<7)
/*
* flag register bits that we care about
[rsc] --rw-rw-r-- M 140560 glenda sys 7501 Nov 1 18:20 sys/src/boot/pc/trap.c
/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/trap.c:99,104 -
/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/trap.c:99,119
}
}
+ void
+ trapdisable(void)
+ {
+ outb(Int0aux, 0xFF);
+ outb(Int1aux, 0xFF);
+ }
+
+ void
+ trapenable(void)
+ {
+ outb(Int0aux, int0mask);
+ outb(Int1aux, int1mask);
+ }
+
+
/*
* set up the interrupt/trap gates
*/
/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/trap.c:298,301 -
/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/trap.c:313,331
(*h->r)(ur, h->arg);
h = h->next;
} while(h);
+ }
+
+ void
+ realmode(int intr, Ureg *ureg)
+ {
+ extern void realmode0(void); /* in l.s */
+ extern int realmodeintr;
+ extern Ureg realmoderegs;
+
+ realmoderegs = *ureg;
+ realmodeintr = intr;
+ trapdisable();
+ realmode0();
+ trapenable();
+ *ureg = realmoderegs;
}
|