From 146c34a2632a4295b1aef44ef79e84b4d4b9cf7e Mon Sep 17 00:00:00 2001 From: Alek Du Date: Tue, 8 Jun 2010 22:28:33 -0700 Subject: [PATCH] Make syslinux installer real "pathbased" The previous merging extlinux/syslinux patch is not sufficient, the syslinux is not real "patchbased", hence: * fill currentdir in patcharea * search "extlinux.conf" and "syslinux.cfg" for generic_load_config * define boot_image and boot_sector macro for ldsyslinux this could make further merging extlinux and syslinux possible Signed-off-by: Alek Du Signed-off-by: H. Peter Anvin --- core/fs/fat/fat.c | 2 +- core/fs/lib/loadconfig.c | 16 +++++++++++----- dos/syslinux.c | 2 +- libinstaller/syslinux.h | 7 ++++++- libinstaller/syslxmod.c | 32 +++++++++++++++++++++----------- linux/syslinux.c | 2 +- mtools/syslinux.c | 2 +- win32/syslinux.c | 2 +- 8 files changed, 43 insertions(+), 22 deletions(-) diff --git a/core/fs/fat/fat.c b/core/fs/fat/fat.c index a21f431..9877a4d 100644 --- a/core/fs/fat/fat.c +++ b/core/fs/fat/fat.c @@ -708,7 +708,7 @@ static int vfat_load_config(void) com32sys_t regs; int i; - /* If installed by extlinux, try the extlinux filename */ + /* If path filled by installer, then use that to load config*/ if (*CurrentDirName && !generic_load_config()) return 0; diff --git a/core/fs/lib/loadconfig.c b/core/fs/lib/loadconfig.c index 9318c1c..d84bdef 100644 --- a/core/fs/lib/loadconfig.c +++ b/core/fs/lib/loadconfig.c @@ -5,20 +5,26 @@ #include /* - * Standard version of load_config for extlinux-installed filesystems + * Standard version of load_config for extlinux/syslinux filesystems */ int generic_load_config(void) { com32sys_t regs; chdir(CurrentDirName); + /* try extlinux.conf first */ realpath(ConfigName, "extlinux.conf", FILENAME_MAX); - - dprintf("Config = %s\n", ConfigName); - + dprintf("Try config = %s\n", ConfigName); memset(®s, 0, sizeof regs); regs.edi.w[0] = OFFS_WRT(ConfigName, 0); call16(core_open, ®s, ®s); - + /* give syslinux.cfg a chance ? */ + if (regs.eflags.l & EFLAGS_ZF) { + realpath(ConfigName, "syslinux.cfg", FILENAME_MAX); + dprintf("Then try config = %s\n", ConfigName); + memset(®s, 0, sizeof regs); + regs.edi.w[0] = OFFS_WRT(ConfigName, 0); + call16(core_open, ®s, ®s); + } return (regs.eflags.l & EFLAGS_ZF) ? -1 : 0; } diff --git a/dos/syslinux.c b/dos/syslinux.c index 61020a1..94517e8 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); + i = syslinux_patch(sectors, nsectors, stupid, raid_mode, subdir); patch_sectors = (i + SECTOR_SIZE - 1) >> SECTOR_SHIFT; /* diff --git a/libinstaller/syslinux.h b/libinstaller/syslinux.h index 8d0212c..311b9f2 100644 --- a/libinstaller/syslinux.h +++ b/libinstaller/syslinux.h @@ -26,6 +26,11 @@ extern unsigned char syslinux_ldlinux[]; extern const unsigned int syslinux_ldlinux_len; extern const int syslinux_ldlinux_mtime; +#define boot_sector syslinux_bootsect +#define boot_sector_len syslinux_bootsect_len +#define boot_image syslinux_ldlinux +#define boot_image_len syslinux_ldlinux_len + extern unsigned char syslinux_mbr[]; extern const unsigned int syslinux_mbr_len; extern const int syslinux_mbr_mtime; @@ -42,6 +47,6 @@ const char *syslinux_check_bootsect(const void *bs); /* This patches the boot sector and ldlinux.sys based on a sector map */ int syslinux_patch(const uint32_t * sectors, int nsectors, - int stupid, int raid_mode); + int stupid, int raid_mode, const char *subdir); #endif diff --git a/libinstaller/syslxmod.c b/libinstaller/syslxmod.c index 9ab139c..b28a443 100644 --- a/libinstaller/syslxmod.c +++ b/libinstaller/syslxmod.c @@ -29,7 +29,7 @@ void syslinux_make_bootsect(void *bs) { struct boot_sector *bootsect = bs; const struct boot_sector *sbs = - (const struct boot_sector *)syslinux_bootsect; + (const struct boot_sector *)boot_sector; memcpy(&bootsect->bsHead, &sbs->bsHead, bsHeadLen); memcpy(&bootsect->bsCode, &sbs->bsCode, bsCodeLen); @@ -227,14 +227,15 @@ static __noinline void set_32_sl(uint32_t * p, uint32_t v) * otherwise -1. */ int syslinux_patch(const uint32_t * sectors, int nsectors, - int stupid, int raid_mode) + int stupid, int raid_mode, const char *subdir) { struct patch_area *patcharea; uint32_t *wp; - int nsect = (syslinux_ldlinux_len + 511) >> 9; + int nsect = (boot_image_len + 511) >> 9; uint32_t csum; int i, dw, nptrs, rv; - struct boot_sector *sbs = (struct boot_sector *)syslinux_bootsect; + struct boot_sector *sbs = (struct boot_sector *)boot_sector; + int diroffset, dirlen; if (nsectors < nsect) return -1; @@ -254,18 +255,29 @@ int syslinux_patch(const uint32_t * sectors, int nsectors, set_32(&sbs->NextSector, *sectors++); /* Search for LDLINUX_MAGIC to find the patch area */ - for (wp = (uint32_t *) syslinux_ldlinux; get_32_sl(wp) != LDLINUX_MAGIC; + for (wp = (uint32_t *)boot_image; get_32_sl(wp) != LDLINUX_MAGIC; wp++) ; patcharea = (struct patch_area *)wp; /* Set up the totals */ - dw = syslinux_ldlinux_len >> 2; /* COMPLETE dwords, excluding ADV */ + dw = boot_image_len >> 2; /* COMPLETE dwords, excluding ADV */ set_16_sl(&patcharea->data_sectors, nsect); /* Not including ADVs */ set_16_sl(&patcharea->adv_sectors, 2); /* ADVs need 2 sectors */ set_32_sl(&patcharea->dwords, dw); + /* Poke in the base directory path */ + if (subdir) { + diroffset = get_16(&patcharea->diroffset); + dirlen = get_16(&patcharea->dirlen); + if (dirlen <= strlen(subdir)) { + fprintf(stderr, "Subdirectory path too long... aborting install!\n"); + exit(1); + } + memcpy((char *)boot_image + diroffset, subdir, strlen(subdir) + 1); + } + /* Set the sector pointers */ - wp = (uint32_t *) ((char *)syslinux_ldlinux + + wp = (uint32_t *) ((char *)boot_image + get_16_sl(&patcharea->secptroffset)); nptrs = get_16_sl(&patcharea->secptrcnt); @@ -277,16 +289,14 @@ int syslinux_patch(const uint32_t * sectors, int nsectors, while (nptrs--) set_32_sl(wp++, 0); - rv = (char *)wp - (char *)syslinux_ldlinux; - /* Now produce a checksum */ set_32_sl(&patcharea->checksum, 0); csum = LDLINUX_MAGIC; - for (i = 0, wp = (uint32_t *) syslinux_ldlinux; i < dw; i++, wp++) + 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); - return rv; + return dw << 2; } diff --git a/linux/syslinux.c b/linux/syslinux.c index 3032edc..1194fbb 100644 --- a/linux/syslinux.c +++ b/linux/syslinux.c @@ -465,7 +465,7 @@ umount: /* * Patch ldlinux.sys and the boot sector */ - i = syslinux_patch(sectors, ldlinux_sectors, opt.stupid_mode, opt.raid_mode); + i = syslinux_patch(sectors, ldlinux_sectors, opt.stupid_mode, opt.raid_mode, subdir); patch_sectors = (i + SECTOR_SIZE - 1) >> SECTOR_SHIFT; /* diff --git a/mtools/syslinux.c b/mtools/syslinux.c index 2c5387e..2b82b33 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); + i = syslinux_patch(sectors, nsectors, stupid, raid_mode, subdir); patch_sectors = (i + SECTOR_SIZE - 1) >> SECTOR_SHIFT; /* Write the now-patched first sectors of ldlinux.sys */ diff --git a/win32/syslinux.c b/win32/syslinux.c index d8c6c82..bd04273 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); + syslinux_patch(sectors, nsectors, stupid, raid_mode, subdir); /* * Rewrite the file -- 2.7.4