aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Schmitt <scdbackup@gmx.net>2014-06-22 22:24:22 +0200
committerH. Peter Anvin <hpa@zytor.com>2014-06-23 19:48:59 -0700
commit9b32a80b97e1ad976d304c3940f50e8d66c158b8 (patch)
tree82701a001d0a9e5240aa290d7f107715f3eaa7e8
parent8b7a805803bd5247a15dfcd60df8a22586b07fd0 (diff)
downloadsyslinux-9b32a80b97e1ad976d304c3940f50e8d66c158b8.tar.gz
syslinux-9b32a80b97e1ad976d304c3940f50e8d66c158b8.tar.xz
syslinux-9b32a80b97e1ad976d304c3940f50e8d66c158b8.zip
utils/isohybrid.c: Introduce option --mbr and make isohybrid.c compilable standalone
Although isohybrid.c is supposed to be a companion of the local SYSLINUX installation, there may be situations where the file isolinux.bin and the matching MBR template do not stem directly from such an installation. This change adds an option --mbr, which allows to load an MBR template file. This may be an isohdp[fp]x*.bin MBR template from the local SYSLINUX installation, or the first 512 bytes of the isohybrid-capable ISO image from which isolinux.bin and the other ISOLINUX files are taken. If macro ISOHYBRID_C_STANDALONE is defined, then the hardcoded MBR templates are not accessible and isohdpfx.o is not needed at compile time. In this case, option --mbr becomes mandatory. I used this for testing my changes with Fedora-Live-Desktop-x86_64-20-1.iso. isohybrid.c is then compilable without further components of ISOLINUX by: cc -DISOHYBRID_C_STANDALONE -Wall -o isohybrid isohybrid.c -luuid Test run: cp Fedora-Live-Desktop-x86_64-20-1.iso \ Fedora-Live-Desktop-x86_64-20-1-rehybrid.iso valgrind ./isohybrid --uefi --mac \ --mbr Fedora-Live-Desktop-x86_64-20-1.mbr \ Fedora-Live-Desktop-x86_64-20-1-rehybrid.iso yields: ==13828== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 1) ... ==13828== LEAK SUMMARY: ==13828== definitely lost: 2,048 bytes in 1 blocks. (Not that valgrind would have detected the memcpy() abuse of patch 001. But at least i seem to have not introduced more obvious sins.) Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--utils/isohybrid.c48
1 files changed, 46 insertions, 2 deletions
diff --git a/utils/isohybrid.c b/utils/isohybrid.c
index 072402f7..0011b78a 100644
--- a/utils/isohybrid.c
+++ b/utils/isohybrid.c
@@ -63,6 +63,8 @@ uint32_t id = 0; /* MBR: 0 <= id <= 0xFFFFFFFF(4294967296) */
uint8_t hd0 = 0; /* 0 <= hd0 <= 2 */
uint8_t partok = 0; /* 0 <= partok <= 1 */
+char mbr_template_path[1024] = {0}; /* Path to MBR template */
+
uint16_t ve[16];
uint32_t catoffset = 0;
uint32_t c = 0, cc = 0, cs = 0;
@@ -223,7 +225,7 @@ usage(void)
void
printh(void)
{
-#define FMT "%-18s %s\n"
+#define FMT "%-20s %s\n"
usage();
@@ -237,6 +239,7 @@ printh(void)
printf(FMT, " -i --id", "Specify MBR ID (default random)");
printf(FMT, " -u --uefi", "Build EFI bootable image");
printf(FMT, " -m --mac", "Add AFP table support");
+ printf(FMT, " -b --mbr <PATH>", "Load MBR from PATH");
printf("\n");
printf(FMT, " --forcehd0", "Assume we are loaded as disk ID 0");
@@ -272,6 +275,7 @@ check_option(int argc, char *argv[])
{ "partok", no_argument, NULL, 'p'},
{ "uefi", no_argument, NULL, 'u'},
{ "mac", no_argument, NULL, 'm'},
+ { "mbr", required_argument, NULL, 'b' },
{ "help", no_argument, NULL, '?' },
{ "verbose", no_argument, NULL, 'v' },
@@ -347,6 +351,12 @@ check_option(int argc, char *argv[])
errx(1, "setting an entry is unsupported with EFI or Mac");
break;
+ case 'b':
+ if (strlen(optarg) >= sizeof(mbr_template_path))
+ errx(1, "--mbr : Path too long");
+ strcpy(mbr_template_path, optarg);
+ break;
+
case 'v':
mode |= VERBOSE;
break;
@@ -571,6 +581,24 @@ display_catalogue(void)
printf("de_mbz2: %hu\n", de_mbz2);
}
+
+void
+read_mbr_template(char *path, uint8_t *mbr)
+{
+ FILE *fp;
+ int ret;
+
+ fp = fopen(path, "rb");
+ if (fp == NULL)
+ err(1, "could not open MBR template file `%s'", path);
+ clearerr(fp);
+ ret = fread(mbr, 1, MBRSIZE, fp);
+ if (ferror(fp))
+ err(1, "error while reading MBR template file `%s'", path);
+ fclose(fp);
+}
+
+
int
initialise_mbr(uint8_t *mbr)
{
@@ -580,9 +608,25 @@ initialise_mbr(uint8_t *mbr)
uint8_t bhead = 0, bsect = 0, bcyle = 0;
uint8_t ehead = 0, esect = 0, ecyle = 0;
+#ifndef ISOHYBRID_C_STANDALONE
extern unsigned char isohdpfx[][MBRSIZE];
+#endif
+
+ if (mbr_template_path[0]) {
+ read_mbr_template(mbr_template_path, mbr);
+ } else {
+
+#ifdef ISOHYBRID_C_STANDALONE
+
+ err(1, "This is a standalone binary. You must specify --mbr. E.g with /usr/lib/syslinux/isohdpfx.bin");
- memcpy(mbr, &isohdpfx[hd0 + 3 * partok], MBRSIZE);
+#else
+
+ memcpy(mbr, &isohdpfx[hd0 + 3 * partok], MBRSIZE);
+
+#endif /* ! ISOHYBRID_C_STANDALONE */
+
+ }
if (mode & MAC) {
memcpy(mbr, afp_header, sizeof(afp_header));