aboutsummaryrefslogtreecommitdiffstats
path: root/libinstaller
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2009-05-14 16:33:37 -0700
committerH. Peter Anvin <hpa@zytor.com>2009-05-14 16:33:37 -0700
commit0046660e3849bef9d922ba69d07c5bc639d1d133 (patch)
tree0d60efb691e622912682b7bab367a51ce8ead76e /libinstaller
parent1c7146a2eeaaf0021cc15e682e12609a652ed870 (diff)
downloadlwip-0046660e3849bef9d922ba69d07c5bc639d1d133.tar.gz
lwip-0046660e3849bef9d922ba69d07c5bc639d1d133.tar.xz
lwip-0046660e3849bef9d922ba69d07c5bc639d1d133.zip
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.c13
-rw-r--r--libinstaller/syslxint.h78
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 */