svn commit: r263537 - user/marcel/mkimg

Marcel Moolenaar marcel at FreeBSD.org
Fri Mar 21 19:40:08 UTC 2014


Author: marcel
Date: Fri Mar 21 19:40:05 2014
New Revision: 263537
URL: http://svnweb.freebsd.org/changeset/base/263537

Log:
  Handle the -b option for specifying boot code that lives in the
  partitioning scheme's meta data. Implement it for GPT.

Modified:
  user/marcel/mkimg/apm.c
  user/marcel/mkimg/bsd.c
  user/marcel/mkimg/ebr.c
  user/marcel/mkimg/gpt.c
  user/marcel/mkimg/mbr.c
  user/marcel/mkimg/mkimg.c
  user/marcel/mkimg/pc98.c
  user/marcel/mkimg/scheme.c
  user/marcel/mkimg/scheme.h
  user/marcel/mkimg/vtoc8.c

Modified: user/marcel/mkimg/apm.c
==============================================================================
--- user/marcel/mkimg/apm.c	Fri Mar 21 19:24:51 2014	(r263536)
+++ user/marcel/mkimg/apm.c	Fri Mar 21 19:40:05 2014	(r263537)
@@ -50,7 +50,7 @@ apm_metadata(u_int where, u_int parts, u
 
 static int
 apm_write(int fd __unused, off_t imgsz __unused, u_int parts __unused,
-    u_int secsz __unused)
+    u_int secsz __unused, void *bootcode __unused)
 {
 	return (ENOSYS);
 }

Modified: user/marcel/mkimg/bsd.c
==============================================================================
--- user/marcel/mkimg/bsd.c	Fri Mar 21 19:24:51 2014	(r263536)
+++ user/marcel/mkimg/bsd.c	Fri Mar 21 19:40:05 2014	(r263537)
@@ -50,7 +50,7 @@ bsd_metadata(u_int where, u_int parts __
 
 static int
 bsd_write(int fd __unused, off_t imgsz __unused, u_int parts __unused, 
-    u_int secsz __unused)
+    u_int secsz __unused, void *bootcode __unused)
 {
 	return (ENOSYS);
 }

Modified: user/marcel/mkimg/ebr.c
==============================================================================
--- user/marcel/mkimg/ebr.c	Fri Mar 21 19:24:51 2014	(r263536)
+++ user/marcel/mkimg/ebr.c	Fri Mar 21 19:40:05 2014	(r263537)
@@ -50,7 +50,7 @@ ebr_metadata(u_int where, u_int parts __
 
 static int
 ebr_write(int fd __unused, off_t imgsz __unused, u_int parts __unused, 
-    u_int secsz __unused)
+    u_int secsz __unused, void *bootcode __unused)
 {
 	return (ENOSYS);
 }

Modified: user/marcel/mkimg/gpt.c
==============================================================================
--- user/marcel/mkimg/gpt.c	Fri Mar 21 19:24:51 2014	(r263536)
+++ user/marcel/mkimg/gpt.c	Fri Mar 21 19:40:05 2014	(r263537)
@@ -157,7 +157,7 @@ gpt_filewrite(int fd, off_t ofs, void *b
 }
 
 static int
-gpt_write_pmbr(int fd, off_t nblocks, u_int secsz)
+gpt_write_pmbr(int fd, off_t nblocks, u_int secsz, void *bootcode)
 {
 	u_char *pmbr;
 	uint32_t secs;
@@ -168,7 +168,11 @@ gpt_write_pmbr(int fd, off_t nblocks, u_
 	pmbr = malloc(secsz);
 	if (pmbr == NULL)
 		return (errno);
-	memset(pmbr, 0, secsz);
+	if (bootcode != NULL) {
+		memcpy(pmbr, bootcode, DOSPARTOFF);
+		memset(pmbr + DOSPARTOFF, 0, secsz - DOSPARTOFF);
+	} else
+		memset(pmbr, 0, secsz);
 	pmbr[DOSPARTOFF + 2] = 2;
 	pmbr[DOSPARTOFF + 4] = 0xee;
 	pmbr[DOSPARTOFF + 5] = 0xff;
@@ -230,7 +234,7 @@ gpt_write_hdr(int fd, struct gpt_hdr *hd
 }
 
 static int
-gpt_write(int fd, off_t imgsz, u_int parts, u_int secsz)
+gpt_write(int fd, off_t imgsz, u_int parts, u_int secsz, void *bootcode)
 {
 	uuid_t uuid;
 	struct gpt_ent *tbl;
@@ -243,7 +247,7 @@ gpt_write(int fd, off_t imgsz, u_int par
 	nblocks = imgsz / secsz;
 
 	/* PMBR */
-	error = gpt_write_pmbr(fd, nblocks, secsz);
+	error = gpt_write_pmbr(fd, nblocks, secsz, bootcode);
 	if (error)
 		return (error);
 
@@ -296,7 +300,8 @@ static struct mkimg_scheme gpt_scheme = 
 	.metadata = gpt_metadata,
 	.write = gpt_write,
 	.nparts = 4096,
-	.labellen = 36
+	.labellen = 36,
+	.bootcode = 512
 };
 
 SCHEME_DEFINE(gpt_scheme);

Modified: user/marcel/mkimg/mbr.c
==============================================================================
--- user/marcel/mkimg/mbr.c	Fri Mar 21 19:24:51 2014	(r263536)
+++ user/marcel/mkimg/mbr.c	Fri Mar 21 19:40:05 2014	(r263537)
@@ -50,7 +50,7 @@ mbr_metadata(u_int where, u_int parts __
 
 static int
 mbr_write(int fd __unused, off_t imgsz __unused, u_int parts __unused, 
-    u_int secsz __unused)
+    u_int secsz __unused, void *bootcode __unused)
 {
 	return (ENOSYS);
 }

Modified: user/marcel/mkimg/mkimg.c
==============================================================================
--- user/marcel/mkimg/mkimg.c	Fri Mar 21 19:24:51 2014	(r263536)
+++ user/marcel/mkimg/mkimg.c	Fri Mar 21 19:40:05 2014	(r263537)
@@ -49,7 +49,7 @@ __FBSDID("$FreeBSD$");
 struct partlisthead partlist = STAILQ_HEAD_INITIALIZER(partlist);
 u_int nparts = 0;
 
-static int bcfd = 0;
+static int bcfd = -1;
 static int outfd = 0;
 static int tmpfd = -1;
 
@@ -222,7 +222,7 @@ fdcopy(int src, int dst, uint64_t *count
 }
 
 static void
-mkimg(void)
+mkimg(int bfd)
 {
 	FILE *fp;
 	struct part *part;
@@ -234,6 +234,10 @@ mkimg(void)
 		errc(EX_DATAERR, ENOSPC, "only %d partitions are supported",
 		    scheme_max_parts());
 
+	error = scheme_bootcode(bfd);
+	if (error)
+		errc(EX_DATAERR, error, "boot code");
+
 	/* First check partition information */
 	STAILQ_FOREACH(part, &partlist, link) {
 		error = scheme_check_part(part);
@@ -288,7 +292,7 @@ main(int argc, char *argv[])
 	while ((c = getopt(argc, argv, "b:h:o:p:s:t:z")) != -1) {
 		switch (c) {
 		case 'b':	/* BOOT CODE */
-			if (bcfd != 0)
+			if (bcfd != -1)
 				usage("multiple bootcode given");
 			bcfd = open(optarg, O_RDONLY, 0);
 			if (bcfd == -1)
@@ -341,7 +345,7 @@ main(int argc, char *argv[])
 	} else
 		tmpfd = outfd;
 
-	mkimg();
+	mkimg(bcfd);
 
 	if (tmpfd != outfd) {
 		if (lseek(tmpfd, 0, SEEK_SET) == 0)

Modified: user/marcel/mkimg/pc98.c
==============================================================================
--- user/marcel/mkimg/pc98.c	Fri Mar 21 19:24:51 2014	(r263536)
+++ user/marcel/mkimg/pc98.c	Fri Mar 21 19:40:05 2014	(r263537)
@@ -50,7 +50,7 @@ pc98_metadata(u_int where, u_int parts _
 
 static int
 pc98_write(int fd __unused, off_t imgsz __unused, u_int parts __unused, 
-    u_int secsz __unused)
+    u_int secsz __unused, void *bootcode __unused)
 {
 	return (ENOSYS);
 }

Modified: user/marcel/mkimg/scheme.c
==============================================================================
--- user/marcel/mkimg/scheme.c	Fri Mar 21 19:24:51 2014	(r263536)
+++ user/marcel/mkimg/scheme.c	Fri Mar 21 19:40:05 2014	(r263537)
@@ -30,9 +30,11 @@ __FBSDID("$FreeBSD$");
 #include <sys/types.h>
 #include <sys/linker_set.h>
 #include <sys/queue.h>
+#include <sys/stat.h>
 #include <err.h>
 #include <errno.h>
 #include <stdint.h>
+#include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
@@ -57,6 +59,7 @@ static struct {
 
 static struct mkimg_scheme *scheme;
 static u_int secsz = 512;
+static void *bootcode;
 
 static enum alias
 scheme_parse_alias(const char *name)
@@ -95,6 +98,35 @@ scheme_selected(void)
 }
 
 int
+scheme_bootcode(int fd)
+{
+	struct stat sb;
+	int error;
+
+	if (fd == -1)
+		return (0);
+	if (scheme->bootcode == 0)
+		return (ENXIO);
+
+	error = fstat(fd, &sb);
+	if (error)
+		return (error);
+	if (sb.st_size > scheme->bootcode)
+		return (EFBIG);
+
+	bootcode = malloc(scheme->bootcode);
+	if (bootcode == NULL)
+		return (ENOMEM);
+	memset(bootcode, 0, scheme->bootcode);
+	if (read(fd, bootcode, sb.st_size) != sb.st_size) {
+		free(bootcode);
+		bootcode = NULL;
+		return (errno);
+	}
+	return (0);
+}
+
+int
 scheme_check_part(struct part *p)
 {
 	struct mkimg_alias *iter;
@@ -179,6 +211,6 @@ scheme_write(int fd, off_t off)
 	if (ftruncate(fd, off) == -1)
 		return (errno);
 
-	error = scheme->write(fd, off, nparts, secsz);
+	error = scheme->write(fd, off, nparts, secsz, bootcode);
 	return (error);
 }

Modified: user/marcel/mkimg/scheme.h
==============================================================================
--- user/marcel/mkimg/scheme.h	Fri Mar 21 19:24:51 2014	(r263536)
+++ user/marcel/mkimg/scheme.h	Fri Mar 21 19:40:05 2014	(r263537)
@@ -65,9 +65,10 @@ struct mkimg_scheme {
 #define	SCHEME_META_IMG_END	2
 #define	SCHEME_META_PART_BEFORE	3
 #define	SCHEME_META_PART_AFTER	4
-	int		(*write)(int, off_t, u_int, u_int);
+	int		(*write)(int, off_t, u_int, u_int, void *);
 	u_int		nparts;
 	u_int		labellen;
+	u_int		bootcode;
 };
 
 SET_DECLARE(schemes, struct mkimg_scheme);
@@ -76,6 +77,7 @@ SET_DECLARE(schemes, struct mkimg_scheme
 int	scheme_select(const char *);
 struct mkimg_scheme *scheme_selected(void);
 
+int scheme_bootcode(int fd);
 int scheme_check_part(struct part *);
 u_int scheme_max_parts(void);
 uint64_t scheme_round(uint64_t);

Modified: user/marcel/mkimg/vtoc8.c
==============================================================================
--- user/marcel/mkimg/vtoc8.c	Fri Mar 21 19:24:51 2014	(r263536)
+++ user/marcel/mkimg/vtoc8.c	Fri Mar 21 19:40:05 2014	(r263537)
@@ -50,7 +50,7 @@ vtoc8_metadata(u_int where, u_int parts 
 
 static int
 vtoc8_write(int fd __unused, off_t imgsz __unused, u_int parts __unused, 
-    u_int secsz __unused)
+    u_int secsz __unused, void *bootcode __unused)
 {
 	return (ENOSYS);
 }


More information about the svn-src-user mailing list