diff options
author | H. Peter Anvin <hpa@zytor.com> | 2009-05-14 16:33:37 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2009-05-14 16:33:37 -0700 |
commit | 0046660e3849bef9d922ba69d07c5bc639d1d133 (patch) | |
tree | 0d60efb691e622912682b7bab367a51ce8ead76e /libinstaller | |
parent | 1c7146a2eeaaf0021cc15e682e12609a652ed870 (diff) | |
download | syslinux-0046660e3849bef9d922ba69d07c5bc639d1d133.tar.gz |
core: handle more than 32K of code for disk-based derivatives
Handle more than 32K worth of code for disk-based derivatives. We do
this by allowing the sector pointers to overflow past sector 1; this
is OK because we limit a run to be based on only the pointers that we
have read so far.
XXX: This is implemented for EXTLINUX, but breaks SYSLINUX. Need to
update (and unify!) the SYSLINUX installers to cope.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'libinstaller')
-rw-r--r-- | libinstaller/setadv.c | 13 | ||||
-rw-r--r-- | libinstaller/syslxint.h | 78 |
2 files changed, 80 insertions, 11 deletions
diff --git a/libinstaller/setadv.c b/libinstaller/setadv.c index c768d1b1..c57f0974 100644 --- a/libinstaller/setadv.c +++ b/libinstaller/setadv.c @@ -36,14 +36,14 @@ static void cleanup_adv(unsigned char *advbuf) uint32_t csum; /* Make sure both copies agree, and update the checksum */ - set_32(advbuf, ADV_MAGIC1); + set_32((uint32_t *)advbuf, ADV_MAGIC1); csum = ADV_MAGIC2; for (i = 8; i < ADV_SIZE-4; i += 4) - csum -= get_32(advbuf+i); + csum -= get_32((uint32_t *)(advbuf+i)); - set_32(advbuf+4, csum); - set_32(advbuf+ADV_SIZE-4, ADV_MAGIC3); + set_32((uint32_t *)(advbuf+4), csum); + set_32((uint32_t *)(advbuf+ADV_SIZE-4), ADV_MAGIC3); memcpy(advbuf+ADV_SIZE, advbuf, ADV_SIZE); } @@ -130,12 +130,13 @@ static int adv_consistent(const unsigned char *p) int i; uint32_t csum; - if (get_32(p) != ADV_MAGIC1 || get_32(p+ADV_SIZE-4) != ADV_MAGIC3) + if (get_32((uint32_t *)p) != ADV_MAGIC1 || + get_32((uint32_t *)(p+ADV_SIZE-4)) != ADV_MAGIC3) return 0; csum = 0; for (i = 4; i < ADV_SIZE-4; i += 4) - csum += get_32(p+i); + csum += get_32((uint32_t *)(p+i)); return csum == ADV_MAGIC2; } diff --git a/libinstaller/syslxint.h b/libinstaller/syslxint.h index 120026de..3cecf3c0 100644 --- a/libinstaller/syslxint.h +++ b/libinstaller/syslxint.h @@ -18,12 +18,12 @@ /* * Access functions for littleendian numbers, possibly misaligned. */ -static inline uint8_t get_8(const unsigned char *p) +static inline uint8_t get_8(const uint8_t *p) { return *(const uint8_t *)p; } -static inline uint16_t get_16(const unsigned char *p) +static inline uint16_t get_16(const uint16_t *p) { #if defined(__i386__) || defined(__x86_64__) /* Littleendian and unaligned-capable */ @@ -33,7 +33,7 @@ static inline uint16_t get_16(const unsigned char *p) #endif } -static inline uint32_t get_32(const unsigned char *p) +static inline uint32_t get_32(const uint32_t *p) { #if defined(__i386__) || defined(__x86_64__) /* Littleendian and unaligned-capable */ @@ -44,7 +44,7 @@ static inline uint32_t get_32(const unsigned char *p) #endif } -static inline void set_16(unsigned char *p, uint16_t v) +static inline void set_16(uint16_t *p, uint16_t v) { #if defined(__i386__) || defined(__x86_64__) /* Littleendian and unaligned-capable */ @@ -55,7 +55,7 @@ static inline void set_16(unsigned char *p, uint16_t v) #endif } -static inline void set_32(unsigned char *p, uint32_t v) +static inline void set_32(uint32_t *p, uint32_t v) { #if defined(__i386__) || defined(__x86_64__) /* Littleendian and unaligned-capable */ @@ -71,4 +71,72 @@ static inline void set_32(unsigned char *p, uint32_t v) #define SECTOR_SHIFT 9 /* 512-byte sectors */ #define SECTOR_SIZE (1 << SECTOR_SHIFT) +#define LDLINUX_MAGIC 0x3eb202fe + +/* Patch area for disk-based installers */ +struct patch_area { + uint32_t magic; /* LDLINUX_MAGIC */ + uint32_t instance; /* Per-version value */ + uint16_t data_sectors; + uint16_t adv_sectors; + uint32_t dwords; + uint32_t checksum; + uint32_t currentdir; + uint16_t secptroffset; + uint16_t secptrcnt; +}; + + /* 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; + + 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 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, bsJump) +#define bsCode bs32.Code /* The common safe choice */ + #endif /* SYSLXINT_H */ |