shithub: riscv

Download patch

ref: 2cfbc3c1cbf918e6154d86ed697d74e583efc529
parent: 4bfa18a5d173dc3b9615153e54b95a6178150a49
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Thu Oct 30 23:06:09 EDT 2014

mk9660: add -E option to create EFI boot entry

--- a/sys/man/8/mk9660
+++ b/sys/man/8/mk9660
@@ -18,6 +18,10 @@
 .I bootfile
 ]
 [
+.B -E
+.I bootfile
+]
+[
 .B -p
 .I proto
 ]
@@ -192,6 +196,17 @@
 boot block.
 This gives the program in the boot block full (ATA) LBA access
 to the CD filesystem, not just the initial blocks that would fit on a floppy.
+.PP
+In addition to
+.B -b
+and
+.B -B
+a boot entry for UEFI systems can be created with the
+.B -E
+option and with
+.I bootfile
+pointing to a FAT image containing the contents of
+the efi system partition.
 .PP
 The
 .B -D
--- a/sys/src/cmd/disk/9660/boot.c
+++ b/sys/src/cmd/disk/9660/boot.c
@@ -149,23 +149,16 @@
 	Emusectsz	= 512,		/* bytes per emulated sector */
 };
 
-void
-Cupdatebootcat(Cdimg *cd)
+static void
+Caddbootentry(Cdimg *cd, Direc *bootrec, int bios)
 {
-	uvlong o;
 	int n;
 
-	if(cd->bootdirec == nil)
-		return;
-
-	o = Cwoffset(cd);
-	Cwseek(cd, cd->bootimageptr);
 	Cputc(cd, 0x88);
-
 	if(cd->flags & CDbootnoemu)
 		Cputc(cd, 0);			/* no disk emulation */
 	else
-		switch(cd->bootdirec->length){
+		switch(bootrec->length){
 		default:
 			fprint(2, "warning: boot image is not 1.44MB or 2.88MB; "
 				"pretending 1.44MB\n");
@@ -183,8 +176,8 @@
 
 	n = 1;
 	if(cd->flags & CDbootnoemu){
-		n = (cd->bootdirec->length + Emusectsz - 1) / Emusectsz;
-		if(n > 4){
+		n = (bootrec->length + Emusectsz - 1) / Emusectsz;
+		if(bios && n > 4){
 			fprint(2, "warning: boot image too big; "
 				"will only load the first 2K\n");
 			n = 4;
@@ -191,20 +184,45 @@
 		}
 	}
 	Cputnl(cd, n, 2);	/* Emusectsz-byte sector count for load */
-	Cputnl(cd, cd->bootdirec->block, 4);	/* ptr to disk image */
-	Cwseek(cd, o);
+	Cputnl(cd, bootrec->block, 4);	/* ptr to disk image */
 }
 
 void
-findbootimage(Cdimg *cd, Direc *root)
+Cupdatebootcat(Cdimg *cd, Direc *root)
 {
-	Direc *d;
+	Direc *bootrec;
+	uvlong o;
 
-	d = walkdirec(root, cd->bootimage);
-	if(d == nil){
+	bootrec = nil;
+	if(cd->bootimage)
+		bootrec = walkdirec(root, cd->bootimage);
+	else if(cd->efibootimage)
+		bootrec = walkdirec(root, cd->efibootimage);
+	if(bootrec == nil){
 		fprint(2, "warning: did not encounter boot image\n");
 		return;
 	}
 
-	cd->bootdirec = d;
+	o = Cwoffset(cd);
+
+	Cwseek(cd, cd->bootimageptr);
+	Caddbootentry(cd, bootrec, cd->bootimage != nil);
+
+	bootrec = nil;
+	if(cd->efibootimage && cd->bootimage){
+		bootrec = walkdirec(root, cd->efibootimage);
+		if(bootrec == nil)
+			fprint(2, "warning: did not encounter efi boot image\n");
+	}
+	if(bootrec != nil) {
+		Crepeat(cd, 0, 20);	/* Unused */
+		Cputc(cd, 0x91);
+		Cputc(cd, 0xef);	/* platform id */
+		Cputnl(cd, 1, 2);	/* num entries */
+		Crepeat(cd, 0, 28);	/* ID string */
+		Caddbootentry(cd, bootrec, 0);
+		Crepeat(cd, 0, 20);	/* vendor unique selection criteria. */
+	}
+
+	Cwseek(cd, o);
 }
--- a/sys/src/cmd/disk/9660/cdrdwr.c
+++ b/sys/src/cmd/disk/9660/cdrdwr.c
@@ -44,6 +44,7 @@
 	Cputisopvd(cd, info);
 	if(info.flags & CDbootable){
 		cd->bootimage = info.bootimage;
+		cd->efibootimage = info.efibootimage;
 		cd->flags |= info.flags & (CDbootable|CDbootnoemu);
 		Cputbootvol(cd);
 	}
--- a/sys/src/cmd/disk/9660/dump9660.c
+++ b/sys/src/cmd/disk/9660/dump9660.c
@@ -23,7 +23,7 @@
 usage(void)
 {
 	if(mk9660)
-		fprint(2, "usage: disk/mk9660 [-D:] [-9cjr] [-b bootfile] [-o offset blocksize] [-p proto] [-s src] cdimage\n");
+		fprint(2, "usage: disk/mk9660 [-D:] [-9cjr] [-[EBb] bootfile] [-o offset blocksize] [-p proto] [-s src] cdimage\n");
 	else
 		fprint(2, "usage: disk/dump9660 [-D:] [-9cjr] [-m maxsize] [-n now] [-p proto] [-s src] cdimage\n");
 	exits("usage");
@@ -86,6 +86,14 @@
 		info.flags |= CDbootable;
 		info.bootimage = EARGF(usage());
 		break;
+	case 'E':
+		/* efi fat image */
+		if(!mk9660)
+			usage();
+		info.flags |= CDbootable;
+		info.flags |= CDbootnoemu;
+		info.efibootimage = EARGF(usage());
+		break;
 	case 'c':
 		info.flags |= CDconform;
 		break;
@@ -204,10 +212,8 @@
 	Cwseek(cd, (vlong)cd->nextblock * Blocksize);
 	writefiles(dump, cd, &iroot);
 
-	if(cd->bootimage){
-		findbootimage(cd, &iroot);
-		Cupdatebootcat(cd);
-	}
+	if(cd->bootimage || cd->efibootimage)
+		Cupdatebootcat(cd, &iroot);
 		
 	/* create Joliet tree */
 	if(cd->flags & CDjoliet)
--- a/sys/src/cmd/disk/9660/iso9660.h
+++ b/sys/src/cmd/disk/9660/iso9660.h
@@ -114,8 +114,8 @@
 	uvlong bootcatptr;
 	ulong bootcatblock;
 	uvlong bootimageptr;
-	Direc *bootdirec;
 	char *bootimage;
+	char *efibootimage;
 	
 	Biobuf brd;
 	Biobuf bwr;
@@ -157,12 +157,9 @@
 	char *preparer;
 	char *application;
 	char *bootimage;
+	char *efibootimage;
 };
 
-//enum {
-//	Blocklen = 2048,		/* unused */
-//};
-
 /*
  * This is a doubly binary tree.
  * We have a tree keyed on the MD5 values
@@ -293,8 +290,7 @@
 void Cputbootvol(Cdimg*);
 void Cputbootcat(Cdimg*);
 void Cupdatebootvol(Cdimg*);
-void Cupdatebootcat(Cdimg*);
-void findbootimage(Cdimg*, Direc*);
+void Cupdatebootcat(Cdimg*, Direc*);
 
 /* cdrdwr.c */
 Cdimg *createcd(char*, Cdinfo);