diff options
author | H. Peter Anvin <hpa@zytor.com> | 2010-06-20 17:01:15 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2010-06-20 17:07:52 -0700 |
commit | 2ef260d392537d22c927735e6b9e78b02d36bb7b (patch) | |
tree | 2613b5e58834702827a0523df98b2fc24683f9b2 /libinstaller | |
parent | 8cf2a1fb42a61f6d19afee86f52ff260fabd1cfa (diff) | |
download | syslinux-2ef260d392537d22c927735e6b9e78b02d36bb7b.tar.gz |
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@zytor.com>
Diffstat (limited to 'libinstaller')
-rw-r--r-- | libinstaller/Makefile | 7 | ||||
-rw-r--r-- | libinstaller/fat.c | 129 | ||||
-rw-r--r-- | libinstaller/syslinux.h | 3 | ||||
-rw-r--r-- | libinstaller/syslxint.h | 2 | ||||
-rw-r--r-- | libinstaller/syslxmod.c | 114 |
5 files changed, 144 insertions, 111 deletions
diff --git a/libinstaller/Makefile b/libinstaller/Makefile index 82c1990e..2beb9315 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 00000000..e2101353 --- /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(§buf->bsMedia) != 0xF0 && get_8(§buf->bsMedia) < 0xF8) + return "invalid media signature (not a FAT filesystem?)"; + + sectorsize = get_16(§buf->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(§buf->bsSecPerClust); + if (clustersize == 0 || (clustersize & (clustersize - 1))) + return "impossible cluster size"; + + sectors = get_16(§buf->bsSectors); + sectors = sectors ? sectors : get_32(§buf->bsHugeSectors); + + dsectors = sectors - get_16(§buf->bsResSectors); + + fatsectors = get_16(§buf->bsFATsecs); + fatsectors = fatsectors ? fatsectors : get_32(§buf->bs32.FATSz32); + fatsectors *= get_8(§buf->bsFATs); + dsectors -= fatsectors; + + rootdirents = get_16(§buf->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(§buf->bsFATsecs)) + return "zero FAT sectors (FAT12/16)"; + + if (get_8(§buf->bs16.BootSignature) == 0x29) { + if (!memcmp(§buf->bs16.FileSysType, "FAT12 ", 8)) { + if (clusters >= 0xFF5) + return "more than 4084 clusters but claims FAT12"; + } else if (!memcmp(§buf->bs16.FileSysType, "FAT16 ", 8)) { + if (clusters < 0xFF5) + return "less than 4084 clusters but claims FAT16"; + } else if (!memcmp(§buf->bs16.FileSysType, "FAT32 ", 8)) { + return "less than 65525 clusters but claims FAT32"; + } else if (memcmp(§buf->bs16.FileSysType, "FAT ", 8)) { + static char fserr[] = + "filesystem type \"????????\" not supported"; + memcpy(fserr + 17, §buf->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(§buf->bs32.BootSignature) != 0x29 || + memcmp(§buf->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 bf2b716a..710d30e5 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 3af7c3d7..f16c2e5c 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 6f5adca5..a68f19fb 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(§buf->bsMedia) != 0xF0 && get_8(§buf->bsMedia) < 0xF8) - return "invalid media signature (not a FAT filesystem?)"; - - sectorsize = get_16(§buf->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(§buf->bsSecPerClust); - if (clustersize == 0 || (clustersize & (clustersize - 1))) - return "impossible cluster size"; - - sectors = get_16(§buf->bsSectors); - sectors = sectors ? sectors : get_32(§buf->bsHugeSectors); - - dsectors = sectors - get_16(§buf->bsResSectors); - - fatsectors = get_16(§buf->bsFATsecs); - fatsectors = fatsectors ? fatsectors : get_32(§buf->bs32.FATSz32); - fatsectors *= get_8(§buf->bsFATs); - dsectors -= fatsectors; - - rootdirents = get_16(§buf->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(§buf->bsFATsecs)) - return "zero FAT sectors (FAT12/16)"; - - if (get_8(§buf->bs16.BootSignature) == 0x29) { - if (!memcmp(§buf->bs16.FileSysType, "FAT12 ", 8)) { - if (clusters >= 0xFF5) - return "more than 4084 clusters but claims FAT12"; - } else if (!memcmp(§buf->bs16.FileSysType, "FAT16 ", 8)) { - if (clusters < 0xFF5) - return "less than 4084 clusters but claims FAT16"; - } else if (!memcmp(§buf->bs16.FileSysType, "FAT32 ", 8)) { - return "less than 65525 clusters but claims FAT32"; - } else if (memcmp(§buf->bs16.FileSysType, "FAT ", 8)) { - static char fserr[] = - "filesystem type \"????????\" not supported"; - memcpy(fserr + 17, §buf->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(§buf->bs32.BootSignature) != 0x29 || - memcmp(§buf->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); |