Browse Source

Plan 9 from Bell Labs 2005-02-26

David du Colombier 19 years ago
parent
commit
18d26e55c3

+ 4 - 4
dist/replica/_plan9.db

@@ -6482,14 +6482,14 @@ sys/src/boot/pc/8250.c - 664 sys sys 1015007947 5727
 sys/src/boot/pc/alarm.c - 664 sys sys 1015007947 1668
 sys/src/boot/pc/apm.c - 664 sys sys 1015007947 289
 sys/src/boot/pc/bcom.c - 664 sys sys 1032215919 6421
-sys/src/boot/pc/boot.c - 664 sys sys 1021579983 3353
+sys/src/boot/pc/boot.c - 664 sys sys 1109364490 8418
 sys/src/boot/pc/bootld.c - 664 sys sys 1015007948 1801
 sys/src/boot/pc/bootp.c - 664 sys sys 1107882190 12147
 sys/src/boot/pc/cga.c - 664 sys sys 1015007948 1362
 sys/src/boot/pc/clock.c - 664 sys sys 1103641772 6425
 sys/src/boot/pc/conf.c - 664 sys sys 1094674484 10217
 sys/src/boot/pc/console.c - 664 sys sys 1094674483 3388
-sys/src/boot/pc/dat.h - 664 sys sys 1094674488 3518
+sys/src/boot/pc/dat.h - 664 sys sys 1109364490 3565
 sys/src/boot/pc/devfloppy.c - 664 sys sys 1032215913 15505
 sys/src/boot/pc/devfloppy.h - 664 sys sys 1032409559 4081
 sys/src/boot/pc/devi82365.c - 664 sys sys 1019533020 23202
@@ -6520,7 +6520,7 @@ sys/src/boot/pc/etherigbe.c - 664 sys sys 1096379796 39825
 sys/src/boot/pc/ethermii.c - 664 sys sys 1103641771 4413
 sys/src/boot/pc/ethermii.h - 664 sys sys 1071175087 3259
 sys/src/boot/pc/etherrhine.c - 664 sys sys 1071175087 12403
-sys/src/boot/pc/fns.h - 664 sys sys 1094674488 4146
+sys/src/boot/pc/fns.h - 664 sys sys 1109364490 4221
 sys/src/boot/pc/fs.c - 664 sys sys 1094674483 1509
 sys/src/boot/pc/fs.h - 664 sys sys 1094674488 653
 sys/src/boot/pc/ilock.c - 664 sys sys 1015007952 303
@@ -6532,7 +6532,7 @@ sys/src/boot/pc/kfs.h - 664 sys sys 1032215924 861
 sys/src/boot/pc/kfsboot.c - 664 sys sys 1032215914 4788
 sys/src/boot/pc/l.s - 664 sys sys 1103641771 13843
 sys/src/boot/pc/lib.h - 664 sys sys 1094674487 2794
-sys/src/boot/pc/load.c - 664 sys sys 1094674484 8635
+sys/src/boot/pc/load.c - 664 sys sys 1109364491 8903
 sys/src/boot/pc/mbr.s - 664 sys sys 1015007953 6234
 sys/src/boot/pc/mem.h - 664 sys sys 1103641771 3371
 sys/src/boot/pc/memory.c - 664 sys sys 1019533021 10272

+ 4 - 4
dist/replica/plan9.db

@@ -6482,14 +6482,14 @@ sys/src/boot/pc/8250.c - 664 sys sys 1015007947 5727
 sys/src/boot/pc/alarm.c - 664 sys sys 1015007947 1668
 sys/src/boot/pc/apm.c - 664 sys sys 1015007947 289
 sys/src/boot/pc/bcom.c - 664 sys sys 1032215919 6421
-sys/src/boot/pc/boot.c - 664 sys sys 1021579983 3353
+sys/src/boot/pc/boot.c - 664 sys sys 1109364490 8418
 sys/src/boot/pc/bootld.c - 664 sys sys 1015007948 1801
 sys/src/boot/pc/bootp.c - 664 sys sys 1107882190 12147
 sys/src/boot/pc/cga.c - 664 sys sys 1015007948 1362
 sys/src/boot/pc/clock.c - 664 sys sys 1103641772 6425
 sys/src/boot/pc/conf.c - 664 sys sys 1094674484 10217
 sys/src/boot/pc/console.c - 664 sys sys 1094674483 3388
-sys/src/boot/pc/dat.h - 664 sys sys 1094674488 3518
+sys/src/boot/pc/dat.h - 664 sys sys 1109364490 3565
 sys/src/boot/pc/devfloppy.c - 664 sys sys 1032215913 15505
 sys/src/boot/pc/devfloppy.h - 664 sys sys 1032409559 4081
 sys/src/boot/pc/devi82365.c - 664 sys sys 1019533020 23202
@@ -6520,7 +6520,7 @@ sys/src/boot/pc/etherigbe.c - 664 sys sys 1096379796 39825
 sys/src/boot/pc/ethermii.c - 664 sys sys 1103641771 4413
 sys/src/boot/pc/ethermii.h - 664 sys sys 1071175087 3259
 sys/src/boot/pc/etherrhine.c - 664 sys sys 1071175087 12403
-sys/src/boot/pc/fns.h - 664 sys sys 1094674488 4146
+sys/src/boot/pc/fns.h - 664 sys sys 1109364490 4221
 sys/src/boot/pc/fs.c - 664 sys sys 1094674483 1509
 sys/src/boot/pc/fs.h - 664 sys sys 1094674488 653
 sys/src/boot/pc/ilock.c - 664 sys sys 1015007952 303
@@ -6532,7 +6532,7 @@ sys/src/boot/pc/kfs.h - 664 sys sys 1032215924 861
 sys/src/boot/pc/kfsboot.c - 664 sys sys 1032215914 4788
 sys/src/boot/pc/l.s - 664 sys sys 1103641771 13843
 sys/src/boot/pc/lib.h - 664 sys sys 1094674487 2794
-sys/src/boot/pc/load.c - 664 sys sys 1094674484 8635
+sys/src/boot/pc/load.c - 664 sys sys 1109364491 8903
 sys/src/boot/pc/mbr.s - 664 sys sys 1015007953 6234
 sys/src/boot/pc/mem.h - 664 sys sys 1103641771 3371
 sys/src/boot/pc/memory.c - 664 sys sys 1019533021 10272

+ 4 - 0
dist/replica/plan9.log

@@ -13810,3 +13810,7 @@
 1109304125 1 c sys/man/1/2c - 664 sys sys 1109303821 8237
 1109304125 2 c sys/src/9/pc/pcmkfile - 664 sys sys 1109303822 101
 1109304125 3 c sys/src/cmd/cc/lex.c - 664 sys sys 1109303822 23826
+1109365217 0 c sys/src/boot/pc/boot.c - 664 sys sys 1109364490 8418
+1109365217 1 c sys/src/boot/pc/dat.h - 664 sys sys 1109364490 3565
+1109365217 2 c sys/src/boot/pc/fns.h - 664 sys sys 1109364490 4221
+1109365217 3 c sys/src/boot/pc/load.c - 664 sys sys 1109364491 8903

+ 290 - 6
sys/src/boot/pc/boot.c

@@ -5,6 +5,241 @@
 #include "fns.h"
 #include "io.h"
 
+#include "/sys/src/libmach/elf.h"
+
+static uchar elfident[7] = {
+	'\177', 'E', 'L', 'F', '\1', '\1', '\1'
+};
+static Ehdr ehdr, rehdr;
+static Phdr *phdr;
+static int curphdr;
+static ulong curoff;
+static ulong elftotal;
+static long (*swal)(long);
+static ushort (*swab)(ushort);
+
+/*
+ * big-endian short
+ */
+ushort
+beswab(ushort s)
+{
+	uchar *p;
+
+	p = (uchar*)&s;
+	return (p[0]<<8) | p[1];
+}
+
+/*
+ * big-endian long
+ */
+long
+beswal(long l)
+{
+	uchar *p;
+
+	p = (uchar*)&l;
+	return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
+}
+
+/*
+ * little-endian short
+ */
+ushort
+leswab(ushort s)
+{
+	uchar *p;
+
+	p = (uchar*)&s;
+	return (p[1]<<8) | p[0];
+}
+
+/*
+ * little-endian long
+ */
+long
+leswal(long l)
+{
+	uchar *p;
+
+	p = (uchar*)&l;
+	return (p[3]<<24) | (p[2]<<16) | (p[1]<<8) | p[0];
+}
+
+/*
+ * Convert header to canonical form
+ */
+static void
+hswal(long *lp, int n, long (*swap) (long))
+{
+	while (n--) {
+		*lp = (*swap) (*lp);
+		lp++;
+	}
+}
+
+static int
+readehdr(Boot *b)
+{
+	int i;
+
+	/* bitswap the header according to the DATA format */
+	if(ehdr.ident[CLASS] != ELFCLASS32) {
+		print("bad ELF class - not 32 bit\n");
+		return 0;
+	}
+	if(ehdr.ident[DATA] == ELFDATA2LSB) {
+		swab = leswab;
+		swal = leswal;
+	} else if(ehdr.ident[DATA] == ELFDATA2MSB) {
+		swab = beswab;
+		swal = beswal;
+	} else {
+		print("bad ELF encoding - not big or little endian\n");
+		return 0;
+	}
+	memmove(&rehdr, &ehdr, sizeof(Ehdr));
+
+	ehdr.type = swab(ehdr.type);
+	ehdr.machine = swab(ehdr.machine);
+	ehdr.version = swal(ehdr.version);
+	ehdr.elfentry = swal(ehdr.elfentry);
+	ehdr.phoff = swal(ehdr.phoff);
+	ehdr.shoff = swal(ehdr.shoff);
+	ehdr.flags = swal(ehdr.flags);
+	ehdr.ehsize = swab(ehdr.ehsize);
+	ehdr.phentsize = swab(ehdr.phentsize);
+	ehdr.phnum = swab(ehdr.phnum);
+	ehdr.shentsize = swab(ehdr.shentsize);
+	ehdr.shnum = swab(ehdr.shnum);
+	ehdr.shstrndx = swab(ehdr.shstrndx);
+	if(ehdr.type != EXEC || ehdr.version != CURRENT)
+		return 0;
+	if(ehdr.phentsize != sizeof(Phdr))
+		return 0;
+
+	if(debug)
+		print("readehdr OK entry 0x%lux\n", ehdr.elfentry);
+
+	curoff = sizeof(Ehdr);
+	i = ehdr.phoff+ehdr.phentsize*ehdr.phnum - curoff;
+	b->state = READPHDR;
+	b->bp = (char*)malloc(i);
+	b->wp = b->bp;
+	b->ep = b->wp + i;
+	phdr = (Phdr*)(b->bp + ehdr.phoff-sizeof(Ehdr));
+	if(debug)
+		print("phdr...");
+
+	return 1;
+}
+
+static int
+nextphdr(Boot *b)
+{
+	Phdr *php;
+	ulong entry, offset;
+	char *paddr;
+
+	if(debug)
+		print("readedata %d\n", curphdr);
+
+	for(; curphdr < ehdr.phnum; curphdr++){
+		php = phdr+curphdr;
+		if(php->type != LOAD)
+			continue;
+		offset = php->offset;
+		paddr = (char*)(php->paddr & ~0xF0000000);
+		if(offset < curoff){
+			/*
+			 * Can't (be bothered to) rewind the
+			 * input, it might be from tftp. If we
+			 * did then we could boot FreeBSD kernels
+			 * too maybe.
+			 */
+			return 0;
+		}
+		if(php->offset > curoff){
+			b->state = READEPAD;
+			b->bp = (char*)malloc(offset - curoff);
+			b->wp = b->bp;
+			b->ep = b->wp + offset - curoff;
+			if(debug)
+				print("nextphdr %lud...\n", offset - curoff);
+			return 1;
+		}
+		b->state = READEDATA;
+		b->bp = paddr;
+		b->wp = b->bp;
+		b->ep = b->wp+php->filesz;
+		print("%ud+", php->filesz);
+		elftotal += php->filesz;
+		if(debug)
+			print("nextphdr %ud@0x%p\n", php->filesz, paddr);
+
+		return 1;
+	}
+
+	if(curphdr != 0){
+		print("=%lud\n", elftotal);
+		b->state = TRYBOOT;
+		entry = ehdr.elfentry & ~0xF0000000;
+		PLLONG(b->exec.entry, entry);
+		return 1;
+	}
+
+	return 0;
+}
+
+static int
+readepad(Boot *b)
+{
+	Phdr *php;
+
+	php = phdr+curphdr;
+	if(debug)
+		print("readepad %d\n", curphdr);
+	curoff = php->offset;
+
+	return nextphdr(b);
+}
+
+static int
+readedata(Boot *b)
+{
+	Phdr *php;
+
+	php = phdr+curphdr;
+	if(debug)
+		print("readedata %d\n", curphdr);
+	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);
+	}
+	curoff = php->offset+php->filesz;
+	curphdr++;
+
+	return nextphdr(b);
+}
+
+static int
+readphdr(Boot *b)
+{
+	Phdr *php;
+
+	php = phdr;
+	hswal((long*)php, ehdr.phentsize*ehdr.phnum/sizeof(long), swal);
+	if(debug)
+		print("phdr curoff %lud vaddr 0x%lux paddr 0x%lux\n",
+			curoff, php->vaddr, php->paddr);
+
+	curoff = ehdr.phoff+ehdr.phentsize*ehdr.phnum;
+	curphdr = 0;
+
+	return nextphdr(b);
+}
+
 static int
 addbytes(char **dbuf, char *edbuf, char **sbuf, char *esbuf)
 {
@@ -50,7 +285,7 @@ bootpass(Boot *b, void *vbuf, int nbuf)
 		case READEXEC:
 			ep = &b->exec;
 			if(GLLONG(ep->magic) == I_MAGIC) {
-				b->state = READTEXT;
+				b->state = READ9TEXT;
 				b->bp = (char*)PADDR(GLLONG(ep->entry));
 				b->wp = b->bp;
 				b->ep = b->wp+GLLONG(ep->text);
@@ -70,20 +305,34 @@ bootpass(Boot *b, void *vbuf, int nbuf)
 				break;
 			}
 
+			/*
+			 * Check for ELF.
+			 */
+			if(memcmp(b->bp, elfident, 4) == 0){
+				b->state = READEHDR;
+				b->bp = (char*)&ehdr;
+				b->wp = b->bp;
+				b->ep = b->wp + sizeof(Ehdr);
+				memmove(b->bp, &b->exec, sizeof(Exec));
+				b->wp += sizeof(Exec);
+				print("elf...");
+				break;
+			}
+
 			print("bad kernel format\n");
 			b->state = FAILED;
 			return FAIL;
 
-		case READTEXT:
+		case READ9TEXT:
 			ep = &b->exec;
-			b->state = READDATA;
+			b->state = READ9DATA;
 			b->bp = (char*)PGROUND(GLLONG(ep->entry)+GLLONG(ep->text));
 			b->wp = b->bp;
 			b->ep = b->wp + GLLONG(ep->data);
 			print("+%ld", GLLONG(ep->data));
 			break;
 	
-		case READDATA:
+		case READ9DATA:
 			ep = &b->exec;
 			bss = GLLONG(ep->bss);
 			print("+%ld=%ld\n",
@@ -91,6 +340,37 @@ bootpass(Boot *b, void *vbuf, int nbuf)
 			b->state = TRYBOOT;
 			return ENOUGH;
 
+		case READEHDR:
+			if(!readehdr(b)){
+				print("readehdr failed\n");
+				b->state = FAILED;
+				return FAIL;
+			}
+			break;
+
+		case READPHDR:
+			if(!readphdr(b)){
+				b->state = FAILED;
+				return FAIL;
+			}
+			break;
+
+		case READEPAD:
+			if(!readepad(b)){
+				b->state = FAILED;
+				return FAIL;
+			}
+			break;
+
+		case READEDATA:
+			if(!readedata(b)){
+				b->state = FAILED;
+				return FAIL;
+			}
+			if(b->state == TRYBOOT)
+				return ENOUGH;
+			break;
+
 		case TRYBOOT:
 		case READGZIP:
 			return ENOUGH;
@@ -111,8 +391,12 @@ Endofinput:
 	switch(b->state) {
 	case INITKERNEL:
 	case READEXEC:
-	case READDATA:
-	case READTEXT:
+	case READ9TEXT:
+	case READ9DATA:
+	case READEHDR:
+	case READPHDR:
+	case READEPAD:
+	case READEDATA:
 		print("premature EOF\n");
 		b->state = FAILED;
 		return FAIL;

+ 6 - 2
sys/src/boot/pc/dat.h

@@ -183,9 +183,13 @@ enum {	/* returned by bootpass */
 enum {
 	INITKERNEL,
 	READEXEC,
-	READTEXT,
-	READDATA,
+	READ9TEXT,
+	READ9DATA,
 	READGZIP,
+	READEHDR,
+	READPHDR,
+	READEPAD,
+	READEDATA,
 	TRYBOOT,
 	INIT9LOAD,
 	READ9LOAD,

+ 1 - 0
sys/src/boot/pc/fns.h

@@ -127,6 +127,7 @@ void*	xspanalloc(ulong, int, ulong);
 #define	GLONG(p)	((GSHORT(p+2)<<16)|GSHORT(p))
 #define	GLSHORT(p)	(((p)[0]<<8)|(p)[1])
 #define	GLLONG(p)	(((ulong)GLSHORT(p)<<16)|GLSHORT(p+2))
+#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)

+ 7 - 0
sys/src/boot/pc/load.c

@@ -548,5 +548,12 @@ warp9(ulong entry)
 		sddetach();
 
 	consdrain();
+	/*
+	 * This is where to push things on the stack to
+	 * boot *BSD systems, e.g.
+	(*(void(*)(void*, void*, void*, void*, ulong, ulong))(PADDR(entry)))(0, 0, 0, 0, 8196, 640);
+	 * will enable NetBSD boot (the real memory size needs to
+	 * go in the 5th argument).
+	 */
 	(*(void(*)(void))(PADDR(entry)))();
 }