[syslinux:pathbased] Merge syslinux/extlinux patch code and core code

syslinux-bot for H. Peter Anvin hpa at zytor.com
Sun Jun 20 17:09:22 PDT 2010


Commit-ID:  2ef260d392537d22c927735e6b9e78b02d36bb7b
Gitweb:     http://syslinux.zytor.com/commit/2ef260d392537d22c927735e6b9e78b02d36bb7b
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Sun, 20 Jun 2010 17:01:15 -0700
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Sun, 20 Jun 2010 17:07:52 -0700

Merge syslinux/extlinux patch code and core code

Merge the SYSLINUX and EXTLINUX patching code and core code, removing
EXTLINUX as a separate derivative.  All the disk-based systems now use
the same code.

Signed-off-by: H. Peter Anvin <hpa at zytor.com>


---
 core/Makefile           |    7 --
 core/extlinux.asm       |   38 ---------
 core/ldlinux.asm        |    4 +
 dos/Makefile            |    1 +
 dos/syslinux.c          |    2 +-
 dosutil/mdiskchk.com    |  Bin 8184 -> 8246 bytes
 extlinux/Makefile       |    5 +-
 extlinux/fat.h          |   57 +-------------
 extlinux/main.c         |  210 ++++++----------------------------------------
 libinstaller/Makefile   |    7 --
 libinstaller/fat.c      |  129 +++++++++++++++++++++++++++++
 libinstaller/syslinux.h |    3 +-
 libinstaller/syslxint.h |    2 +-
 libinstaller/syslxmod.c |  114 +++-----------------------
 linux/Makefile          |    5 +-
 linux/syslinux.c        |    2 +-
 mtools/Makefile         |    1 +
 mtools/syslinux.c       |    2 +-
 win32/Makefile          |    1 +
 win32/syslinux.c        |    2 +-
 20 files changed, 190 insertions(+), 402 deletions(-)

diff --git a/core/Makefile b/core/Makefile
index 166f0e4..1330fb9 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -33,7 +33,6 @@ CODEPAGE = cp865
 
 # The targets to build in this directory...
 BTARGET  = kwdhash.gen \
-	   extlinux.bin extlinux.bss extlinux.sys \
 	   ldlinux.bss ldlinux.sys ldlinux.bin \
 	   isolinux.bin isolinux-debug.bin pxelinux.0
 
@@ -109,12 +108,6 @@ ldlinux.bss: ldlinux.bin
 ldlinux.sys: ldlinux.bin
 	dd if=$< of=$@ bs=512 skip=1
 
-extlinux.bss: extlinux.bin
-	dd if=$< of=$@ bs=512 count=1
-
-extlinux.sys: extlinux.bin
-	dd if=$< of=$@ bs=512 skip=1
-
 codepage.cp: ../codepage/$(CODEPAGE).cp
 	cp -f $< $@
 
diff --git a/core/extlinux.asm b/core/extlinux.asm
deleted file mode 100644
index 9538576..0000000
--- a/core/extlinux.asm
+++ /dev/null
@@ -1,38 +0,0 @@
-; -*- fundamental -*- (asm-mode sucks)
-; ****************************************************************************
-;
-;  extlinux.asm
-;
-;  A program to boot Linux kernels off an ext2/ext3 filesystem.
-;
-;   Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
-;   Copyright 2009 Intel Corporation; author: H. Peter Anvin
-;
-;  This program is free software; you can redistribute it and/or modify
-;  it under the terms of the GNU General Public License as published by
-;  the Free Software Foundation, Inc., 53 Temple Place Ste 330,
-;  Boston MA 02111-1307, USA; either version 2 of the License, or
-;  (at your option) any later version; incorporated herein by reference.
-;
-; ****************************************************************************
-
-%define IS_EXTLINUX 1
-%include "head.inc"
-
-;
-; Some semi-configurable constants... change on your own risk.
-;
-my_id		equ extlinux_id
-
-		section .rodata
-		alignz 4
-ROOT_FS_OPS:
-		extern vfat_fs_ops
-		dd vfat_fs_ops
-		extern ext2_fs_ops
-		dd ext2_fs_ops
-		extern btrfs_fs_ops
-		dd btrfs_fs_ops
-		dd 0
-
-%include "diskfs.inc"
diff --git a/core/ldlinux.asm b/core/ldlinux.asm
index 23540ea..f62f55b 100644
--- a/core/ldlinux.asm
+++ b/core/ldlinux.asm
@@ -35,6 +35,10 @@ my_id		equ syslinux_id
 ROOT_FS_OPS:
 		extern vfat_fs_ops
 		dd vfat_fs_ops
+		extern ext2_fs_ops
+		dd ext2_fs_ops
+		extern btrfs_fs_ops
+		dd btrfs_fs_ops
 		dd 0
 
 %include "diskfs.inc"
diff --git a/dos/Makefile b/dos/Makefile
index 7392571..d4d20c7 100644
--- a/dos/Makefile
+++ b/dos/Makefile
@@ -26,6 +26,7 @@ INCLUDES = -include code16.h -nostdinc -iwithprefix include \
 	   -I. -I.. -I../libfat -I ../libinstaller
 
 SRCS     = syslinux.c \
+	   ../libinstaller/fat.c \
 	   ../libinstaller/syslxmod.c \
 	   ../libinstaller/bootsect_bin.c \
 	   ../libinstaller/ldlinux_bin.c \
diff --git a/dos/syslinux.c b/dos/syslinux.c
index 94517e8..5dc3483 100644
--- a/dos/syslinux.c
+++ b/dos/syslinux.c
@@ -755,7 +755,7 @@ int main(int argc, char *argv[])
     /*
      * Patch ldlinux.sys and the boot sector
      */
-    i = syslinux_patch(sectors, nsectors, stupid, raid_mode, subdir);
+    i = syslinux_patch(sectors, nsectors, stupid, raid_mode, subdir, NULL);
     patch_sectors = (i + SECTOR_SIZE - 1) >> SECTOR_SHIFT;
 
     /*
diff --git a/dosutil/mdiskchk.com b/dosutil/mdiskchk.com
index 5a6cc8e..b18a187 100644
Binary files a/dosutil/mdiskchk.com and b/dosutil/mdiskchk.com differ
diff --git a/extlinux/Makefile b/extlinux/Makefile
index ab92c2c..2501a45 100644
--- a/extlinux/Makefile
+++ b/extlinux/Makefile
@@ -24,11 +24,12 @@ CFLAGS	 = $(GCCWARN) -Wno-sign-compare -D_FILE_OFFSET_BITS=64 \
 LDFLAGS	 = # -s
 
 SRCS     = main.c \
+	   ../libinstaller/syslxmod.c \
 	   ../libinstaller/syslxopt.c \
 	   ../libinstaller/syslxcom.c \
 	   ../libinstaller/setadv.c \
-	   ../libinstaller/extlinux_bss_bin.c \
-	   ../libinstaller/extlinux_sys_bin.c
+	   ../libinstaller/bootsect_bin.c \
+	   ../libinstaller/ldlinux_bin.c
 OBJS	 = $(patsubst %.c,%.o,$(notdir $(SRCS)))
 
 .SUFFIXES: .c .o .i .s .S
diff --git a/extlinux/fat.h b/extlinux/fat.h
index dd5a362..5d13402 100644
--- a/extlinux/fat.h
+++ b/extlinux/fat.h
@@ -2,61 +2,6 @@
 #define _H_FAT_
 
 #define MSDOS_SUPER_MAGIC       0x4d44          /* MD */
-#if 0
-/* FAT bootsector format, also used by other disk-based derivatives */
-struct boot_sector {
-    uint8_t bsJump[3];
-    char bsOemName[8];
-    uint16_t bsBytesPerSec;
-    uint8_t bsSecPerClust;
-    uint16_t bsResSectors;
-    uint8_t bsFATs;
-    uint16_t bsRootDirEnts;
-    uint16_t bsSectors;
-    uint8_t bsMedia;
-    uint16_t bsFATsecs;
-    uint16_t bsSecPerTrack;
-    uint16_t bsHeads;
-    uint32_t bsHiddenSecs;
-    uint32_t bsHugeSectors;
+/* The rest is defined in syslxint.h */
 
-    union {
-        struct {
-            uint8_t DriveNumber;
-            uint8_t Reserved1;
-            uint8_t BootSignature;
-            uint32_t VolumeID;
-            char VolumeLabel[11];
-            char FileSysType[8];
-            uint8_t Code[442];
-        } __attribute__ ((packed)) bs16;
-        struct {
-            uint32_t FATSz32; 
-            uint16_t ExtFlags;
-            uint16_t FSVer;
-            uint32_t RootClus;
-            uint16_t FSInfo;
-            uint16_t BkBootSec;
-            uint8_t Reserved0[12];
-            uint8_t DriveNumber;
-            uint8_t Reserved1;
-            uint8_t BootSignature;
-            uint32_t VolumeID;
-            char VolumeLabel[11];
-            char FileSysType[8];
-            uint8_t Code[414];
-        } __attribute__ ((packed)) bs32;
-    } __attribute__ ((packed));
-    
-    uint32_t NextSector;        /* Pointer to the first unused sector */
-    uint16_t MaxTransfer;       /* Max sectors per transfer */
-    uint16_t bsSignature;
-} __attribute__ ((packed));
-
-#define bsHead      bsJump
-#define bsHeadLen   offsetof(struct boot_sector, bsOemName)
-#define bsCode      bs32.Code   /* The common safe choice */
-#define bsCodeLen   (offsetof(struct boot_sector, bsSignature) - \
-                     offsetof(struct boot_sector, bsCode))
-#endif
 #endif
diff --git a/extlinux/main.c b/extlinux/main.c
index cf9840d..c0a37ef 100644
--- a/extlinux/main.c
+++ b/extlinux/main.c
@@ -14,7 +14,7 @@
 /*
  * extlinux.c
  *
- * Install the extlinux boot block on an fat, ext2/3/4 and btrfs filesystem
+ * Install the syslinux boot block on an fat, ext2/3/4 and btrfs filesystem
  */
 
 #define  _GNU_SOURCE		/* Enable everything */
@@ -73,26 +73,6 @@ typedef uint64_t u64;
 #define BTRFS_SUBVOL_MAX 256	/* By btrfs specification */
 static char subvol[BTRFS_SUBVOL_MAX];
 
-/*
- * Boot block
- */
-extern unsigned char extlinux_bootsect[];
-extern unsigned int extlinux_bootsect_len;
-#undef  boot_block
-#undef  boot_block_len
-#define boot_block	extlinux_bootsect
-#define boot_block_len  extlinux_bootsect_len
-
-/*
- * Image file
- */
-extern unsigned char extlinux_image[];
-extern unsigned int extlinux_image_len;
-#undef  boot_image
-#undef  boot_image_len
-#define boot_image	extlinux_image
-#define boot_image_len  extlinux_image_len
-
 #define BTRFS_ADV_OFFSET (BTRFS_EXTLINUX_OFFSET + boot_image_len)
 
 /*
@@ -185,61 +165,6 @@ int get_geometry(int devfd, uint64_t totalbytes, struct hd_geometry *geo)
 }
 
 /*
- * Generate sector extents
- */
-static void generate_extents(struct syslinux_extent *ex, int nptrs,
-			     const sector_t *sectp, int nsect)
-{
-    uint32_t addr = 0x7c00 + 2*SECTOR_SIZE;
-    uint32_t base;
-    sector_t sect, lba;
-    unsigned int len;
-
-    len = lba = base = 0;
-
-    memset(ex, 0, nptrs * sizeof *ex);
-
-    while (nsect) {
-	sect = *sectp++;
-
-	if (len && sect == lba + len &&
-	    ((addr ^ (base + len * SECTOR_SIZE)) & 0xffff0000) == 0) {
-	    /* We can add to the current extent */
-	    len++;
-	    goto next;
-	}
-
-	if (len) {
-	    set_64_sl(&ex->lba, lba);
-	    set_16_sl(&ex->len, len);
-	    ex++;
-	}
-
-	base = addr;
-	lba  = sect;
-	len  = 1;
-
-    next:
-	addr += SECTOR_SIZE;
-	nsect--;
-    }
-
-    if (len) {
-	set_64_sl(&ex->lba, lba);
-	set_16_sl(&ex->len, len);
-	ex++;
-    }
-}
-
-/*
- * Form a pointer based on a 16-bit patcharea/epa field
- */
-static inline void *ptr(void *img, uint16_t *offset_p)
-{
-    return (char *)img + get_16_sl(offset_p);
-}
-
-/*
  * Query the device geometry and put it into the boot sector.
  * Map the file and put the map in the boot sector and file.
  * Stick the "current directory" inode number into the file.
@@ -253,15 +178,9 @@ int patch_file_and_bootblock(int fd, const char *dir, int devfd)
     sector_t *sectp;
     uint64_t totalbytes, totalsectors;
     int nsect;
-    uint32_t *wp;
     struct boot_sector *sbs;
-    struct patch_area *patcharea;
-    struct ext_patch_area *epa;
-    struct syslinux_extent *ex;
-    int i, dw, nptrs;
-    uint32_t csum;
     char *dirpath, *subpath, *xdirpath, *xsubpath;
-    uint64_t *advptrs;
+    int rv;
 
     dirpath = realpath(dir, NULL);
     if (!dirpath || stat(dir, &dirst)) {
@@ -318,7 +237,7 @@ int patch_file_and_bootblock(int fd, const char *dir, int devfd)
        early bootstrap share code with the FAT version. */
     dprintf("heads = %u, sect = %u\n", geo.heads, geo.sectors);
 
-    sbs = (struct boot_sector *)boot_block;
+    sbs = (struct boot_sector *)syslinux_bootsect;
 
     totalsectors = totalbytes >> SECTOR_SHIFT;
     if (totalsectors >= 65536) {
@@ -333,7 +252,7 @@ int patch_file_and_bootblock(int fd, const char *dir, int devfd)
     set_16(&sbs->bsHeads, geo.heads);
     set_32(&sbs->bsHiddenSecs, geo.start);
 
-    /* Construct the boot file */
+    /* Construct the boot file map */
 
     dprintf("directory inode = %lu\n", (unsigned long)dirst.st_ino);
     nsect = (boot_image_len + SECTOR_SIZE - 1) >> SECTOR_SHIFT;
@@ -348,92 +267,15 @@ int patch_file_and_bootblock(int fd, const char *dir, int devfd)
 	int i;
 
 	for (i = 0; i < nsect; i++)
-		*(sectp + i) = BTRFS_EXTLINUX_OFFSET/SECTOR_SIZE + i;
+	    sectp[i] = BTRFS_EXTLINUX_OFFSET/SECTOR_SIZE + i;
     }
 
-    /* Search for LDLINUX_MAGIC to find the patch area */
-    for (wp = (uint32_t *) boot_image; get_32_sl(wp) != LDLINUX_MAGIC;
-	 wp++)
-	;
-    patcharea = (struct patch_area *)wp;
-    epa = ptr(boot_image, &patcharea->epaoffset);
-
-    /* First sector need pointer in boot sector */
-    set_32(ptr(sbs, &epa->sect1ptr0), sectp[0]);
-    set_32(ptr(sbs, &epa->sect1ptr1), sectp[0] >> 32);
-    sectp++;
-
-    /* Handle RAID mode */
-    if (opt.raid_mode) {
-	/* Patch in INT 18h = CD 18 */
-	set_16(ptr(sbs, &epa->raidpatch), 0x18CD);
-    }
-
-    /* Set up the totals */
-    dw = boot_image_len >> 2;	/* COMPLETE dwords, excluding ADV */
-    set_16_sl(&patcharea->data_sectors, nsect - 2); /* Not including ADVs */
-    set_16_sl(&patcharea->adv_sectors, 2);	/* ADVs need 2 sectors */
-    set_32_sl(&patcharea->dwords, dw);
-
-    /* Stupid mode? */
-    if (opt.stupid_mode) {
-	/* Access only one sector at a time */
-	set_16_sl(&patcharea->maxtransfer, 1);
-    }
-
-    /* Set the sector extents */
-    ex = ptr(boot_image, &epa->secptroffset);
-    nptrs = get_16_sl(&epa->secptrcnt);
-
-    if (nsect > nptrs) {
-	/* Not necessarily an error in this case, but a general problem */
-	fprintf(stderr, "Insufficient extent space, build error!\n");
-	exit(1);
-    }
-
-    /* -1 for the pointer in the boot sector, -2 for the two ADVs */
-    generate_extents(ex, nptrs, sectp, nsect-1-2);
-
-    /* ADV pointers */
-    advptrs = ptr(boot_image, &epa->advptroffset);
-    set_64_sl(&advptrs[0], sectp[nsect-1-2]);
-    set_64_sl(&advptrs[1], sectp[nsect-1-1]);
+    /* Create the modified image in memory */
+    rv = syslinux_patch(sectp, nsect, opt.stupid_mode,
+			opt.raid_mode, subpath, subvol);
 
-    /* Poke in the base directory path */
-    if (subpath) {
-	int sublen = strlen(subpath) + 1;
-	if (get_16_sl(&epa->dirlen) < sublen) {
-	    fprintf(stderr, "Subdirectory path too long... aborting install!\n");
-	    exit(1);
-	}
-	memcpy_to_sl(ptr(boot_image, &epa->diroffset), subpath, sublen);
-    }
     free(dirpath);
-
-    /* Poke in the subvolume information */
-    if (1 /* subvol */) {
-	int sublen = strlen(subvol) + 1;
-	if (get_16_sl(&epa->subvollen) < sublen) {
-	    fprintf(stderr, "Subvol name too long... aborting install!\n");
-	    exit(1);
-	}
-	memcpy_to_sl(ptr(boot_image, &epa->subvoloffset), subvol, sublen);
-    }
-
-    /* Now produce a checksum */
-    set_32_sl(&patcharea->checksum, 0);
-
-    csum = LDLINUX_MAGIC;
-    for (i = 0, wp = (uint32_t *) boot_image; i < dw; i++, wp++)
-	csum -= get_32_sl(wp);	/* Negative checksum */
-
-    set_32_sl(&patcharea->checksum, csum);
-
-    /*
-     * Assume all bytes modified.  This can be optimized at the expense
-     * of keeping track of what the highest modified address ever was.
-     */
-    return dw << 2;
+    return rv;
 }
 
 /*
@@ -503,7 +345,7 @@ int install_bootblock(int fd, const char *device)
 	return 1;
     }
     if (fs_type == VFAT) {
-	struct boot_sector *sbs = (struct boot_sector *)extlinux_bootsect;
+	struct boot_sector *sbs = (struct boot_sector *)syslinux_bootsect;
         if (xpwrite(fd, &sbs->bsHead, bsHeadLen, 0) != bsHeadLen ||
 	    xpwrite(fd, &sbs->bsCode, bsCodeLen,
 		    offsetof(struct boot_sector, bsCode)) != bsCodeLen) {
@@ -511,7 +353,8 @@ int install_bootblock(int fd, const char *device)
 	    return 1;
 	}
     } else {
-	if (xpwrite(fd, boot_block, boot_block_len, 0) != boot_block_len) {
+	if (xpwrite(fd, syslinux_bootsect, syslinux_bootsect_len, 0)
+	    != syslinux_bootsect_len) {
 	    perror("writing bootblock");
 	    return 1;
 	}
@@ -526,7 +369,7 @@ int ext2_fat_install_file(const char *path, int devfd, struct stat *rst)
     int fd = -1, dirfd = -1;
     int modbytes;
 
-    asprintf(&file, "%s%sextlinux.sys",
+    asprintf(&file, "%s%sldlinux.sys",
 	     path, path[0] && path[strlen(path) - 1] == '/' ? "" : "/");
     if (!file) {
 	perror(program);
@@ -597,9 +440,9 @@ bail:
     return 1;
 }
 
-/* btrfs has to install the extlinux.sys in the first 64K blank area, which
+/* btrfs has to install the ldlinux.sys in the first 64K blank area, which
    is not managered by btrfs tree, so actually this is not installed as files.
-   since the cow feature of btrfs will move the extlinux.sys every where */
+   since the cow feature of btrfs will move the ldlinux.sys every where */
 int btrfs_install_file(const char *path, int devfd, struct stat *rst)
 {
     patch_file_and_bootblock(-1, path, devfd);
@@ -631,14 +474,17 @@ int install_file(const char *path, int devfd, struct stat *rst)
 	return 1;
 }
 
-/* EXTLINUX installs the string 'EXTLINUX' at offset 3 in the boot
-   sector; this is consistent with FAT filesystems. */
+/*
+ * SYSLINUX installs the string 'SYSLINUX' at offset 3 in the boot
+ * sector; this is consistent with FAT filesystems.  Earlier versions
+ * would install the string "EXTLINUX" instead, handle both.
+ */
 int already_installed(int devfd)
 {
     char buffer[8];
 
     xpread(devfd, buffer, 8, 3);
-    return !memcmp(buffer, "EXTLINUX", 8);
+    return !memcmp(buffer, "SYSLINUX", 8) || !memcmp(buffer, "EXTLINUX", 8);
 }
 
 #ifdef __KLIBC__
@@ -843,7 +689,7 @@ static int open_device(const char *path, struct stat *st, const char **_devname)
 
 static int ext_read_adv(const char *path, const char *cfg, int devfd)
 {
-    if (fs_type == BTRFS) { /* btrfs "extlinux.sys" is in 64k blank area */
+    if (fs_type == BTRFS) { /* btrfs "ldlinux.sys" is in 64k blank area */
 	if (xpread(devfd, syslinux_adv, 2 * ADV_SIZE,
 		BTRFS_ADV_OFFSET) != 2 * ADV_SIZE) {
 		perror("btrfs writing adv");
@@ -856,7 +702,7 @@ static int ext_read_adv(const char *path, const char *cfg, int devfd)
 
 static int ext_write_adv(const char *path, const char *cfg, int devfd)
 {
-    if (fs_type == BTRFS) { /* btrfs "extlinux.sys" is in 64k blank area */
+    if (fs_type == BTRFS) { /* btrfs "ldlinux.sys" is in 64k blank area */
 	if (xpwrite(devfd, syslinux_adv, 2 * ADV_SIZE,
 		BTRFS_ADV_OFFSET) != 2 * ADV_SIZE) {
 		perror("writing adv");
@@ -878,7 +724,7 @@ int install_loader(const char *path, int update_only)
 	return 1;
 
     if (update_only && !already_installed(devfd)) {
-	fprintf(stderr, "%s: no previous extlinux boot sector found\n",
+	fprintf(stderr, "%s: no previous syslinux boot sector found\n",
 		program);
 	close(devfd);
 	return 1;
@@ -887,7 +733,7 @@ int install_loader(const char *path, int update_only)
     /* Read a pre-existing ADV, if already installed */
     if (opt.reset_adv)
 	syslinux_reset_adv(syslinux_adv);
-    else if (ext_read_adv(path, "extlinux.sys", devfd) < 0) {
+    else if (ext_read_adv(path, "ldlinux.sys", devfd) < 0) {
 	close(devfd);
 	return 1;
     }
@@ -896,7 +742,7 @@ int install_loader(const char *path, int update_only)
 	return 1;
     }
 
-    /* Install extlinux.sys */
+    /* Install ldlinux.sys */
     if (install_file(path, devfd, &fst)) {
 	close(devfd);
 	return 1;
@@ -929,7 +775,7 @@ int modify_existing_adv(const char *path)
 
     if (opt.reset_adv)
 	syslinux_reset_adv(syslinux_adv);
-    else if (ext_read_adv(path, "extlinux.sys", devfd) < 0) {
+    else if (ext_read_adv(path, "ldlinux.sys", devfd) < 0) {
 	close(devfd);
 	return 1;
     }
@@ -937,7 +783,7 @@ int modify_existing_adv(const char *path)
 	close(devfd);
 	return 1;
     }
-    if (ext_write_adv(path, "extlinux.sys", devfd) < 0) {
+    if (ext_write_adv(path, "ldlinux.sys", devfd) < 0) {
 	close(devfd);
 	return 1;
     }
diff --git a/libinstaller/Makefile b/libinstaller/Makefile
index 82c1990..2beb931 100644
--- a/libinstaller/Makefile
+++ b/libinstaller/Makefile
@@ -1,6 +1,5 @@
 # _bin.c files required by both BTARGET and ITARGET installers
 BINFILES = bootsect_bin.c ldlinux_bin.c \
-	   extlinux_bss_bin.c extlinux_sys_bin.c \
 	   mbr_bin.c gptmbr_bin.c
 
 PERL	 = perl
@@ -13,12 +12,6 @@ bootsect_bin.c: ../core/ldlinux.bss bin2c.pl
 ldlinux_bin.c: ../core/ldlinux.sys bin2c.pl
 	$(PERL) bin2c.pl syslinux_ldlinux 512 < $< > $@
 
-extlinux_bss_bin.c: ../core/extlinux.bss bin2c.pl
-	$(PERL) bin2c.pl extlinux_bootsect < $< > $@
-
-extlinux_sys_bin.c: ../core/extlinux.sys bin2c.pl
-	$(PERL) bin2c.pl extlinux_image 512 < $< > $@
-
 mbr_bin.c: ../mbr/mbr.bin bin2c.pl
 	$(PERL) bin2c.pl syslinux_mbr < $< > $@
 
diff --git a/libinstaller/fat.c b/libinstaller/fat.c
new file mode 100644
index 0000000..e210135
--- /dev/null
+++ b/libinstaller/fat.c
@@ -0,0 +1,129 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 1998-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 Intel Corporation; author H. Peter Anvin
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * fat.c - Initial sanity check for FAT-based installers
+ */
+
+#define _XOPEN_SOURCE 500	/* Required on glibc 2.x */
+#define _BSD_SOURCE
+#include <stdio.h>
+#include <inttypes.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "syslinux.h"
+#include "syslxint.h"
+
+void syslinux_make_bootsect(void *bs)
+{
+    struct boot_sector *bootsect = bs;
+    const struct boot_sector *sbs =
+	(const struct boot_sector *)boot_sector;
+
+    memcpy(&bootsect->bsHead, &sbs->bsHead, bsHeadLen);
+    memcpy(&bootsect->bsCode, &sbs->bsCode, bsCodeLen);
+}
+
+/*
+ * Check to see that what we got was indeed an MS-DOS boot sector/superblock;
+ * Return NULL if OK and otherwise an error message;
+ */
+const char *syslinux_check_bootsect(const void *bs)
+{
+    int veryold;
+    int sectorsize;
+    long long sectors, fatsectors, dsectors;
+    long long clusters;
+    int rootdirents, clustersize;
+    const struct boot_sector *sectbuf = bs;
+
+    veryold = 0;
+
+    /* Must be 0xF0 or 0xF8..0xFF */
+    if (get_8(&sectbuf->bsMedia) != 0xF0 && get_8(&sectbuf->bsMedia) < 0xF8)
+	return "invalid media signature (not a FAT filesystem?)";
+
+    sectorsize = get_16(&sectbuf->bsBytesPerSec);
+    if (sectorsize == SECTOR_SIZE)
+	;			/* ok */
+    else if (sectorsize >= 512 && sectorsize <= 4096 &&
+	     (sectorsize & (sectorsize - 1)) == 0)
+	return "unsupported sectors size";
+    else
+	return "impossible sector size";
+
+    clustersize = get_8(&sectbuf->bsSecPerClust);
+    if (clustersize == 0 || (clustersize & (clustersize - 1)))
+	return "impossible cluster size";
+
+    sectors = get_16(&sectbuf->bsSectors);
+    sectors = sectors ? sectors : get_32(&sectbuf->bsHugeSectors);
+
+    dsectors = sectors - get_16(&sectbuf->bsResSectors);
+
+    fatsectors = get_16(&sectbuf->bsFATsecs);
+    fatsectors = fatsectors ? fatsectors : get_32(&sectbuf->bs32.FATSz32);
+    fatsectors *= get_8(&sectbuf->bsFATs);
+    dsectors -= fatsectors;
+
+    rootdirents = get_16(&sectbuf->bsRootDirEnts);
+    dsectors -= (rootdirents + sectorsize / 32 - 1) / sectorsize;
+
+    if (dsectors < 0)
+	return "negative number of data sectors";
+
+    if (fatsectors == 0)
+	return "zero FAT sectors";
+
+    clusters = dsectors / clustersize;
+
+    if (clusters < 0xFFF5) {
+	/* FAT12 or FAT16 */
+
+	if (!get_16(&sectbuf->bsFATsecs))
+	    return "zero FAT sectors (FAT12/16)";
+
+	if (get_8(&sectbuf->bs16.BootSignature) == 0x29) {
+	    if (!memcmp(&sectbuf->bs16.FileSysType, "FAT12   ", 8)) {
+		if (clusters >= 0xFF5)
+		    return "more than 4084 clusters but claims FAT12";
+	    } else if (!memcmp(&sectbuf->bs16.FileSysType, "FAT16   ", 8)) {
+		if (clusters < 0xFF5)
+		    return "less than 4084 clusters but claims FAT16";
+	    } else if (!memcmp(&sectbuf->bs16.FileSysType, "FAT32   ", 8)) {
+		    return "less than 65525 clusters but claims FAT32";
+	    } else if (memcmp(&sectbuf->bs16.FileSysType, "FAT     ", 8)) {
+		static char fserr[] =
+		    "filesystem type \"????????\" not supported";
+		memcpy(fserr + 17, &sectbuf->bs16.FileSysType, 8);
+		return fserr;
+	    }
+	}
+    } else if (clusters < 0x0FFFFFF5) {
+	/*
+	 * FAT32...
+	 *
+	 * Moving the FileSysType and BootSignature was a lovely stroke
+	 * of M$ idiocy...
+	 */
+	if (get_8(&sectbuf->bs32.BootSignature) != 0x29 ||
+	    memcmp(&sectbuf->bs32.FileSysType, "FAT32   ", 8))
+	    return "missing FAT32 signature";
+    } else {
+	return "impossibly large number of clusters";
+    }
+
+    return NULL;
+}
diff --git a/libinstaller/syslinux.h b/libinstaller/syslinux.h
index bf2b716..710d30e 100644
--- a/libinstaller/syslinux.h
+++ b/libinstaller/syslinux.h
@@ -48,6 +48,7 @@ const char *syslinux_check_bootsect(const void *bs);
 /* This patches the boot sector and ldlinux.sys based on a sector map */
 typedef uint64_t sector_t;
 int syslinux_patch(const sector_t *sectors, int nsectors,
-		   int stupid, int raid_mode, const char *subdir);
+		   int stupid, int raid_mode,
+		   const char *subdir, const char *subvol);
 
 #endif
diff --git a/libinstaller/syslxint.h b/libinstaller/syslxint.h
index 3af7c3d..f16c2e5 100644
--- a/libinstaller/syslxint.h
+++ b/libinstaller/syslxint.h
@@ -238,7 +238,7 @@ struct boot_sector {
 } __attribute__ ((packed));
 
 #define bsHead      bsJump
-#define bsHeadLen   offsetof(struct boot_sector, bsOemName)
+#define bsHeadLen   offsetof(struct boot_sector, bsBytesPerSec)
 #define bsCode	    bs32.Code	/* The common safe choice */
 #define bsCodeLen   (offsetof(struct boot_sector, bsSignature) - \
 		     offsetof(struct boot_sector, bsCode))
diff --git a/libinstaller/syslxmod.c b/libinstaller/syslxmod.c
index 6f5adca..a68f19f 100644
--- a/libinstaller/syslxmod.c
+++ b/libinstaller/syslxmod.c
@@ -26,107 +26,6 @@
 #include "syslinux.h"
 #include "syslxint.h"
 
-void syslinux_make_bootsect(void *bs)
-{
-    struct boot_sector *bootsect = bs;
-    const struct boot_sector *sbs =
-	(const struct boot_sector *)boot_sector;
-
-    memcpy(&bootsect->bsHead, &sbs->bsHead, bsHeadLen);
-    memcpy(&bootsect->bsCode, &sbs->bsCode, bsCodeLen);
-}
-
-/*
- * Check to see that what we got was indeed an MS-DOS boot sector/superblock;
- * Return NULL if OK and otherwise an error message;
- */
-const char *syslinux_check_bootsect(const void *bs)
-{
-    int veryold;
-    int sectorsize;
-    long long sectors, fatsectors, dsectors;
-    long long clusters;
-    int rootdirents, clustersize;
-    const struct boot_sector *sectbuf = bs;
-
-    veryold = 0;
-
-    /* Must be 0xF0 or 0xF8..0xFF */
-    if (get_8(&sectbuf->bsMedia) != 0xF0 && get_8(&sectbuf->bsMedia) < 0xF8)
-	return "invalid media signature (not a FAT filesystem?)";
-
-    sectorsize = get_16(&sectbuf->bsBytesPerSec);
-    if (sectorsize == SECTOR_SIZE)
-	;			/* ok */
-    else if (sectorsize >= 512 && sectorsize <= 4096 &&
-	     (sectorsize & (sectorsize - 1)) == 0)
-	return "unsupported sectors size";
-    else
-	return "impossible sector size";
-
-    clustersize = get_8(&sectbuf->bsSecPerClust);
-    if (clustersize == 0 || (clustersize & (clustersize - 1)))
-	return "impossible cluster size";
-
-    sectors = get_16(&sectbuf->bsSectors);
-    sectors = sectors ? sectors : get_32(&sectbuf->bsHugeSectors);
-
-    dsectors = sectors - get_16(&sectbuf->bsResSectors);
-
-    fatsectors = get_16(&sectbuf->bsFATsecs);
-    fatsectors = fatsectors ? fatsectors : get_32(&sectbuf->bs32.FATSz32);
-    fatsectors *= get_8(&sectbuf->bsFATs);
-    dsectors -= fatsectors;
-
-    rootdirents = get_16(&sectbuf->bsRootDirEnts);
-    dsectors -= (rootdirents + sectorsize / 32 - 1) / sectorsize;
-
-    if (dsectors < 0)
-	return "negative number of data sectors";
-
-    if (fatsectors == 0)
-	return "zero FAT sectors";
-
-    clusters = dsectors / clustersize;
-
-    if (clusters < 0xFFF5) {
-	/* FAT12 or FAT16 */
-
-	if (!get_16(&sectbuf->bsFATsecs))
-	    return "zero FAT sectors (FAT12/16)";
-
-	if (get_8(&sectbuf->bs16.BootSignature) == 0x29) {
-	    if (!memcmp(&sectbuf->bs16.FileSysType, "FAT12   ", 8)) {
-		if (clusters >= 0xFF5)
-		    return "more than 4084 clusters but claims FAT12";
-	    } else if (!memcmp(&sectbuf->bs16.FileSysType, "FAT16   ", 8)) {
-		if (clusters < 0xFF5)
-		    return "less than 4084 clusters but claims FAT16";
-	    } else if (!memcmp(&sectbuf->bs16.FileSysType, "FAT32   ", 8)) {
-		    return "less than 65525 clusters but claims FAT32";
-	    } else if (memcmp(&sectbuf->bs16.FileSysType, "FAT     ", 8)) {
-		static char fserr[] =
-		    "filesystem type \"????????\" not supported";
-		memcpy(fserr + 17, &sectbuf->bs16.FileSysType, 8);
-		return fserr;
-	    }
-	}
-    } else if (clusters < 0x0FFFFFF5) {
-	/*
-	 * FAT32...
-	 *
-	 * Moving the FileSysType and BootSignature was a lovely stroke
-	 * of M$ idiocy...
-	 */
-	if (get_8(&sectbuf->bs32.BootSignature) != 0x29 ||
-	    memcmp(&sectbuf->bs32.FileSysType, "FAT32   ", 8))
-	    return "missing FAT32 signature";
-    } else {
-	return "impossibly large number of clusters";
-    }
-
-    return NULL;
-}
 
 /*
  * Generate sector extents
@@ -197,7 +96,8 @@ static inline void *ptr(void *img, uint16_t *offset_p)
 #define NADV 2
 
 int syslinux_patch(const sector_t *sectp, int nsectors,
-		   int stupid, int raid_mode, const char *subdir)
+		   int stupid, int raid_mode,
+		   const char *subdir, const char *subvol)
 {
     struct patch_area *patcharea;
     struct ext_patch_area *epa;
@@ -270,6 +170,16 @@ int syslinux_patch(const sector_t *sectp, int nsectors,
 	memcpy_to_sl(ptr(boot_image, &epa->diroffset), subdir, sublen);
     }
 
+    /* Poke in the subvolume information */
+    if (subvol) {
+	int sublen = strlen(subvol) + 1;
+	if (get_16_sl(&epa->subvollen) < sublen) {
+	    fprintf(stderr, "Subvol name too long... aborting install!\n");
+	    exit(1);
+	}
+	memcpy_to_sl(ptr(boot_image, &epa->subvoloffset), subvol, sublen);
+    }
+
     /* Now produce a checksum */
     set_32_sl(&patcharea->checksum, 0);
 
diff --git a/linux/Makefile b/linux/Makefile
index 9bf56d1..c3877f2 100644
--- a/linux/Makefile
+++ b/linux/Makefile
@@ -17,15 +17,16 @@
 topdir = ..
 include $(topdir)/MCONFIG
 
-OPTFLAGS = -g -Os
+OPTFLAGS = -g -O0 -Dalloca=malloc
 INCLUDES = -I. -I.. -I../libinstaller
 CFLAGS	 = $(GCCWARN) -D_FILE_OFFSET_BITS=64 $(OPTFLAGS) $(INCLUDES)
-LDFLAGS	 = -s
+LDFLAGS	 = 
 
 SRCS     = syslinux.c \
 	   ../libinstaller/syslxopt.c \
 	   ../libinstaller/syslxcom.c \
 	   ../libinstaller/setadv.c \
+           ../libinstaller/fat.c \
            ../libinstaller/syslxmod.c \
 	   ../libinstaller/bootsect_bin.c \
 	   ../libinstaller/ldlinux_bin.c
diff --git a/linux/syslinux.c b/linux/syslinux.c
index 20de62a..7152d2b 100644
--- a/linux/syslinux.c
+++ b/linux/syslinux.c
@@ -474,7 +474,7 @@ umount:
      * Patch ldlinux.sys and the boot sector
      */
     i = syslinux_patch(sectors, ldlinux_sectors, opt.stupid_mode,
-		       opt.raid_mode, subdir);
+		       opt.raid_mode, subdir, NULL);
     patch_sectors = (i + SECTOR_SIZE - 1) >> SECTOR_SHIFT;
 
     /*
diff --git a/mtools/Makefile b/mtools/Makefile
index 91b6852..5f08b2d 100644
--- a/mtools/Makefile
+++ b/mtools/Makefile
@@ -7,6 +7,7 @@ CFLAGS	 = $(GCCWARN) -D_FILE_OFFSET_BITS=64 $(OPTFLAGS) $(INCLUDES)
 LDFLAGS	 = -s
 
 SRCS     = syslinux.c \
+	   ../libinstaller/fat.c \
 	   ../libinstaller/syslxmod.c \
 	   ../libinstaller/bootsect_bin.c \
 	   ../libinstaller/ldlinux_bin.c \
diff --git a/mtools/syslinux.c b/mtools/syslinux.c
index 2b82b33..0f4ccf9 100644
--- a/mtools/syslinux.c
+++ b/mtools/syslinux.c
@@ -267,7 +267,7 @@ int main(int argc, char *argv[])
     libfat_close(fs);
 
     /* Patch ldlinux.sys and the boot sector */
-    i = syslinux_patch(sectors, nsectors, stupid, raid_mode, subdir);
+    i = syslinux_patch(sectors, nsectors, stupid, raid_mode, subdir, NULL);
     patch_sectors = (i + SECTOR_SIZE - 1) >> SECTOR_SHIFT;
 
     /* Write the now-patched first sectors of ldlinux.sys */
diff --git a/win32/Makefile b/win32/Makefile
index a0be1d4..af95b2e 100644
--- a/win32/Makefile
+++ b/win32/Makefile
@@ -45,6 +45,7 @@ WINCC_IS_GOOD := $(shell $(WINCC) $(WINCFLAGS) $(WINLDFLAGS) -o hello.exe hello.
 .SUFFIXES: .c .o .i .s .S
 
 SRCS     = syslinux.c \
+	   ../libinstaller/fat.c \
 	   ../libinstaller/syslxmod.c \
 	   ../libinstaller/bootsect_bin.c \
 	   ../libinstaller/ldlinux_bin.c \
diff --git a/win32/syslinux.c b/win32/syslinux.c
index bd04273..297b97b 100644
--- a/win32/syslinux.c
+++ b/win32/syslinux.c
@@ -433,7 +433,7 @@ int main(int argc, char *argv[])
     /*
      * Patch ldlinux.sys and the boot sector
      */
-    syslinux_patch(sectors, nsectors, stupid, raid_mode, subdir);
+    syslinux_patch(sectors, nsectors, stupid, raid_mode, subdir, NULL);
 
     /*
      * Rewrite the file



More information about the Syslinux-commits mailing list