Merge syslinux/extlinux patch code and core code
authorH. Peter Anvin <hpa@zytor.com>
Mon, 21 Jun 2010 00:01:15 +0000 (17:01 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Mon, 21 Jun 2010 00:07:52 +0000 (17:07 -0700)
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@zytor.com>
20 files changed:
core/Makefile
core/extlinux.asm [deleted file]
core/ldlinux.asm
dos/Makefile
dos/syslinux.c
dosutil/mdiskchk.com
extlinux/Makefile
extlinux/fat.h
extlinux/main.c
libinstaller/Makefile
libinstaller/fat.c [new file with mode: 0644]
libinstaller/syslinux.h
libinstaller/syslxint.h
libinstaller/syslxmod.c
linux/Makefile
linux/syslinux.c
mtools/Makefile
mtools/syslinux.c
win32/Makefile
win32/syslinux.c

index 166f0e4..1330fb9 100644 (file)
@@ -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 (file)
index 9538576..0000000
+++ /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"
index 23540ea..f62f55b 100644 (file)
@@ -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"
index 7392571..d4d20c7 100644 (file)
@@ -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 \
index 94517e8..5dc3483 100644 (file)
@@ -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;
 
     /*
index 5a6cc8e..b18a187 100644 (file)
Binary files a/dosutil/mdiskchk.com and b/dosutil/mdiskchk.com differ
index ab92c2c..2501a45 100644 (file)
@@ -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
index dd5a362..5d13402 100644 (file)
@@ -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
index cf9840d..c0a37ef 100644 (file)
@@ -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;
     }
index 82c1990..2beb931 100644 (file)
@@ -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 (file)
index 0000000..e210135
--- /dev/null
@@ -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;
+}
index bf2b716..710d30e 100644 (file)
@@ -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
index 3af7c3d..f16c2e5 100644 (file)
@@ -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))
index 6f5adca..a68f19f 100644 (file)
 #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);
 
index 9bf56d1..c3877f2 100644 (file)
 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
index 20de62a..7152d2b 100644 (file)
@@ -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;
 
     /*
index 91b6852..5f08b2d 100644 (file)
@@ -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 \
index 2b82b33..0f4ccf9 100644 (file)
@@ -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 */
index a0be1d4..af95b2e 100644 (file)
@@ -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 \
index bd04273..297b97b 100644 (file)
@@ -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