diff options
author | H. Peter Anvin <hpa@zytor.com> | 2009-05-29 15:16:22 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2009-05-29 15:16:22 -0700 |
commit | 5e6aef0b866b1e5c1c458cc8ca2a52092928fb0d (patch) | |
tree | d88795d0d3aba72776a20bf8ee4c8778815df3d0 /libinstaller | |
parent | dcd9ae222c665a56a57a560be62b407a04573e13 (diff) | |
parent | 8833b1c37f7ecfa41e0e2c26e72c2913d5eba969 (diff) | |
download | syslinux-5e6aef0b866b1e5c1c458cc8ca2a52092928fb0d.tar.gz |
Merge branch 'master' into core32
Conflicts:
com32/include/netinet/in.h
com32/include/sys/cpu.h
dos/argv.c
dos/malloc.c
dos/syslinux.c
extlinux/main.c
libinstaller/setadv.c
libinstaller/syslinux.h
libinstaller/syslxint.h
libinstaller/syslxmod.c
linux/syslinux.c
mtools/syslinux.c
win32/syslinux.c
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'libinstaller')
-rw-r--r-- | libinstaller/setadv.c | 180 | ||||
-rw-r--r-- | libinstaller/syslinux.h | 26 | ||||
-rw-r--r-- | libinstaller/syslxint.h | 164 | ||||
-rw-r--r-- | libinstaller/syslxmod.c | 347 |
4 files changed, 359 insertions, 358 deletions
diff --git a/libinstaller/setadv.c b/libinstaller/setadv.c index c57f0974..d18ac927 100644 --- a/libinstaller/setadv.c +++ b/libinstaller/setadv.c @@ -24,7 +24,7 @@ #include <errno.h> #include "syslxint.h" -unsigned char syslinux_adv[2*ADV_SIZE]; +unsigned char syslinux_adv[2 * ADV_SIZE]; #define ADV_MAGIC1 0x5a2d2fa5 /* Head signature */ #define ADV_MAGIC2 0xa3041767 /* Total checksum */ @@ -32,113 +32,113 @@ unsigned char syslinux_adv[2*ADV_SIZE]; static void cleanup_adv(unsigned char *advbuf) { - int i; - uint32_t csum; + int i; + uint32_t csum; - /* Make sure both copies agree, and update the checksum */ - set_32((uint32_t *)advbuf, ADV_MAGIC1); + /* Make sure both copies agree, and update the checksum */ + set_32((uint32_t *) advbuf, ADV_MAGIC1); - csum = ADV_MAGIC2; - for (i = 8; i < ADV_SIZE-4; i += 4) - csum -= get_32((uint32_t *)(advbuf+i)); + csum = ADV_MAGIC2; + for (i = 8; i < ADV_SIZE - 4; i += 4) + csum -= get_32((uint32_t *) (advbuf + i)); - set_32((uint32_t *)(advbuf+4), csum); - set_32((uint32_t *)(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); + memcpy(advbuf + ADV_SIZE, advbuf, ADV_SIZE); } int syslinux_setadv(int tag, size_t size, const void *data) { - uint8_t *p; - size_t left; - uint8_t advtmp[ADV_SIZE]; - - if ((unsigned)tag-1 > 254) { - errno = EINVAL; - return -1; /* Impossible tag value */ - } - - if (size > 255) { - errno = ENOSPC; /* Max 255 bytes for a data item */ - return -1; - } - - left = ADV_LEN; - p = advtmp; - memcpy(p, syslinux_adv+2*4, left); /* Make working copy */ - - while (left >= 2) { - uint8_t ptag = p[0]; - size_t plen = p[1]+2; - - if (ptag == ADV_END) - break; - - if (ptag == tag) { - /* Found our tag. Delete it. */ - - if (plen >= left) { - /* Entire remainder is our tag */ - break; - } - memmove(p, p+plen, left-plen); - } else { - /* Not our tag */ - if (plen > left) - break; /* Corrupt tag (overrun) - overwrite it */ + uint8_t *p; + size_t left; + uint8_t advtmp[ADV_SIZE]; - left -= plen; - p += plen; + if ((unsigned)tag - 1 > 254) { + errno = EINVAL; + return -1; /* Impossible tag value */ } - } - /* Now (p, left) reflects the position to write in and how much space - we have for our data. */ + if (size > 255) { + errno = ENOSPC; /* Max 255 bytes for a data item */ + return -1; + } - if (size) { - if (left < size+2) { - errno = ENOSPC; /* Not enough space for data */ - return -1; + left = ADV_LEN; + p = advtmp; + memcpy(p, syslinux_adv + 2 * 4, left); /* Make working copy */ + + while (left >= 2) { + uint8_t ptag = p[0]; + size_t plen = p[1] + 2; + + if (ptag == ADV_END) + break; + + if (ptag == tag) { + /* Found our tag. Delete it. */ + + if (plen >= left) { + /* Entire remainder is our tag */ + break; + } + memmove(p, p + plen, left - plen); + } else { + /* Not our tag */ + if (plen > left) + break; /* Corrupt tag (overrun) - overwrite it */ + + left -= plen; + p += plen; + } } - *p++ = tag; - *p++ = size; - memcpy(p, data, size); - p += size; - left -= size+2; - } + /* Now (p, left) reflects the position to write in and how much space + we have for our data. */ + + if (size) { + if (left < size + 2) { + errno = ENOSPC; /* Not enough space for data */ + return -1; + } - memset(p, 0, left); + *p++ = tag; + *p++ = size; + memcpy(p, data, size); + p += size; + left -= size + 2; + } + + memset(p, 0, left); - /* If we got here, everything went OK, commit the write */ - memcpy(syslinux_adv+2*4, advtmp, ADV_LEN); - cleanup_adv(syslinux_adv); + /* If we got here, everything went OK, commit the write */ + memcpy(syslinux_adv + 2 * 4, advtmp, ADV_LEN); + cleanup_adv(syslinux_adv); - return 0; + return 0; } void syslinux_reset_adv(unsigned char *advbuf) { - /* Create an all-zero ADV */ - memset(advbuf+2*4, 0, ADV_LEN); - cleanup_adv(advbuf); + /* Create an all-zero ADV */ + memset(advbuf + 2 * 4, 0, ADV_LEN); + cleanup_adv(advbuf); } static int adv_consistent(const unsigned char *p) { - int i; - uint32_t csum; + int i; + uint32_t csum; - if (get_32((uint32_t *)p) != ADV_MAGIC1 || - get_32((uint32_t *)(p+ADV_SIZE-4)) != ADV_MAGIC3) - return 0; + 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((uint32_t *)(p+i)); + csum = 0; + for (i = 4; i < ADV_SIZE - 4; i += 4) + csum += get_32((uint32_t *) (p + i)); - return csum == ADV_MAGIC2; + return csum == ADV_MAGIC2; } /* @@ -147,14 +147,14 @@ static int adv_consistent(const unsigned char *p) */ int syslinux_validate_adv(unsigned char *advbuf) { - if (adv_consistent(advbuf+0*ADV_SIZE)) { - memcpy(advbuf+ADV_SIZE, advbuf, ADV_SIZE); - return 0; - } else if (adv_consistent(advbuf+1*ADV_SIZE)) { - memcpy(advbuf, advbuf+ADV_SIZE, ADV_SIZE); - return 0; - } else { - syslinux_reset_adv(advbuf); - return -1; - } + if (adv_consistent(advbuf + 0 * ADV_SIZE)) { + memcpy(advbuf + ADV_SIZE, advbuf, ADV_SIZE); + return 0; + } else if (adv_consistent(advbuf + 1 * ADV_SIZE)) { + memcpy(advbuf, advbuf + ADV_SIZE, ADV_SIZE); + return 0; + } else { + syslinux_reset_adv(advbuf); + return -1; + } } diff --git a/libinstaller/syslinux.h b/libinstaller/syslinux.h index 902beaf9..8ed1edbe 100644 --- a/libinstaller/syslinux.h +++ b/libinstaller/syslinux.h @@ -17,17 +17,17 @@ #include "advconst.h" /* The standard boot sector and ldlinux image */ -extern unsigned char syslinux_bootsect[]; -extern const unsigned int syslinux_bootsect_len; -extern const int syslinux_bootsect_mtime; +extern unsigned char syslinux_bootsect[]; +extern const unsigned int syslinux_bootsect_len; +extern const int syslinux_bootsect_mtime; -extern unsigned char syslinux_ldlinux[]; -extern const unsigned int syslinux_ldlinux_len; -extern const int syslinux_ldlinux_mtime; +extern unsigned char syslinux_ldlinux[]; +extern const unsigned int syslinux_ldlinux_len; +extern const int syslinux_ldlinux_mtime; -extern unsigned char syslinux_mbr[]; -extern const unsigned int syslinux_mbr_len; -extern const int syslinux_mbr_mtime; +extern unsigned char syslinux_mbr[]; +extern const unsigned int syslinux_mbr_len; +extern const int syslinux_mbr_mtime; /* Sector size assumptions... */ #define SECTOR_SHIFT 9 @@ -40,13 +40,13 @@ void syslinux_make_bootsect(void *); 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 syslinux_patch(const uint32_t * sectors, int nsectors, int stupid, int raid_mode); /* ADV information */ -#define ADV_SIZE 512 /* Total size */ -#define ADV_LEN (ADV_SIZE-3*4) /* Usable data size */ -extern unsigned char syslinux_adv[2*ADV_SIZE]; +#define ADV_SIZE 512 /* Total size */ +#define ADV_LEN (ADV_SIZE-3*4) /* Usable data size */ +extern unsigned char syslinux_adv[2 * ADV_SIZE]; int syslinux_setadv(int tag, size_t size, const void *data); void syslinux_reset_adv(unsigned char *advbuf); diff --git a/libinstaller/syslxint.h b/libinstaller/syslxint.h index fc3932b2..e2a80724 100644 --- a/libinstaller/syslxint.h +++ b/libinstaller/syslxint.h @@ -18,62 +18,62 @@ /* * Access functions for littleendian numbers, possibly misaligned. */ -static inline uint8_t get_8(const uint8_t *p) +static inline uint8_t get_8(const uint8_t * p) { - return *p; + return *p; } -static inline uint16_t get_16(const uint16_t *p) +static inline uint16_t get_16(const uint16_t * p) { #if defined(__i386__) || defined(__x86_64__) - /* Littleendian and unaligned-capable */ - return *p; + /* Littleendian and unaligned-capable */ + return *p; #else - const uint8_t *pp = (const uint8_t *)p; - return (uint16_t)pp[0] + ((uint16_t)pp[1] << 8); + const uint8_t *pp = (const uint8_t *)p; + return (uint16_t) pp[0] + ((uint16_t) pp[1] << 8); #endif } -static inline uint32_t get_32(const uint32_t *p) +static inline uint32_t get_32(const uint32_t * p) { #if defined(__i386__) || defined(__x86_64__) - /* Littleendian and unaligned-capable */ - return *p; + /* Littleendian and unaligned-capable */ + return *p; #else - const uint8_t *pp = (const uint8_t *)p; - return (uint32_t)pp[0] + ((uint32_t)pp[1] << 8) + - ((uint32_t)pp[2] << 16) + ((uint32_t)pp[3] << 24); + const uint8_t *pp = (const uint8_t *)p; + return (uint32_t) pp[0] + ((uint32_t) pp[1] << 8) + + ((uint32_t) pp[2] << 16) + ((uint32_t) pp[3] << 24); #endif } -static inline void set_8(uint8_t *p, uint8_t v) +static inline void set_8(uint8_t * p, uint8_t v) { - *p = v; + *p = v; } -static inline void set_16(uint16_t *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 */ - *(uint16_t *)p = v; + /* Littleendian and unaligned-capable */ + *(uint16_t *) p = v; #else - uint8_t *pp = (uint8_t *)p; - pp[0] = (v & 0xff); - pp[1] = ((v >> 8) & 0xff); + uint8_t *pp = (uint8_t *) p; + pp[0] = (v & 0xff); + pp[1] = ((v >> 8) & 0xff); #endif } -static inline void set_32(uint32_t *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 */ - *(uint32_t *)p = v; + /* Littleendian and unaligned-capable */ + *(uint32_t *) p = v; #else - uint8_t *pp = (uint8_t *)p; - pp[0] = (v & 0xff); - pp[1] = ((v >> 8) & 0xff); - pp[2] = ((v >> 16) & 0xff); - pp[3] = ((v >> 24) & 0xff); + uint8_t *pp = (uint8_t *) p; + pp[0] = (v & 0xff); + pp[1] = ((v >> 8) & 0xff); + pp[2] = ((v >> 16) & 0xff); + pp[3] = ((v >> 24) & 0xff); #endif } @@ -81,65 +81,65 @@ static inline void set_32(uint32_t *p, uint32_t v) /* 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; + 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; + 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)); + 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)); + 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) diff --git a/libinstaller/syslxmod.c b/libinstaller/syslxmod.c index 1a45d03e..9e1da440 100644 --- a/libinstaller/syslxmod.c +++ b/libinstaller/syslxmod.c @@ -29,10 +29,10 @@ void syslinux_make_bootsect(void *bs) { - struct boot_sector *bootsect = bs; + struct boot_sector *bootsect = bs; - memcpy(&bootsect->bsHead, &sbs->bsHead, bsHeadLen); - memcpy(&bootsect->bsCode, &sbs->bsCode, bsCodeLen); + memcpy(&bootsect->bsHead, &sbs->bsHead, bsHeadLen); + memcpy(&bootsect->bsCode, &sbs->bsCode, bsCodeLen); } /* @@ -41,84 +41,83 @@ void syslinux_make_bootsect(void *bs) */ 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 ) - goto invalid; - - 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 - goto invalid; - - clustersize = get_8(§buf->bsSecPerClust); - if ( clustersize == 0 || (clustersize & (clustersize-1)) ) - goto invalid; /* Must be nonzero and a power of 2 */ - - 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 || fatsectors == 0 ) - goto invalid; - - clusters = dsectors/clustersize; - - if ( clusters < 0xFFF5 ) { - /* FAT12 or FAT16 */ - - if ( !get_16(§buf->bsFATsecs) ) - goto invalid; - - 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, "FAT ", 8) ) { - static char fserr[] = "filesystem type \"????????\" not supported"; - memcpy(fserr+17, §buf->bs16.FileSysType, 8); - return fserr; - } + 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) + goto invalid; + + 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 + goto invalid; + + clustersize = get_8(§buf->bsSecPerClust); + if (clustersize == 0 || (clustersize & (clustersize - 1))) + goto invalid; /* Must be nonzero and a power of 2 */ + + 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 || fatsectors == 0) + goto invalid; + + clusters = dsectors / clustersize; + + if (clusters < 0xFFF5) { + /* FAT12 or FAT16 */ + + if (!get_16(§buf->bsFATsecs)) + goto invalid; + + 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, "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)) + goto invalid; + } else { + goto invalid; } - } 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) ) - goto invalid; - } else { - goto invalid; - } - - return NULL; - - invalid: - return "this doesn't look like a valid FAT filesystem"; + + return NULL; + +invalid: + return "this doesn't look like a valid FAT filesystem"; } /* @@ -131,69 +130,70 @@ const char *syslinux_check_bootsect(const void *bs) extern uint16_t ldlinux_seg; /* Defined in dos/syslinux.c */ -static inline __attribute__((const)) uint16_t ds(void) +static inline __attribute__ ((const)) +uint16_t ds(void) { - uint16_t v; - asm("movw %%ds,%0" : "=rm" (v)); - return v; + uint16_t v; +asm("movw %%ds,%0":"=rm"(v)); + return v; } static inline void *set_fs(const void *p) { - uint16_t seg; + uint16_t seg; - seg = ldlinux_seg + ((size_t)p >> 4); - asm volatile("movw %0,%%fs" : : "rm" (seg)); - return (void *)((size_t)p & 0xf); + seg = ldlinux_seg + ((size_t) p >> 4); + asm volatile ("movw %0,%%fs"::"rm" (seg)); + return (void *)((size_t) p & 0xf); } -#if 0 /* unused */ -static __noinline uint8_t get_8_sl(const uint8_t *p) +#if 0 /* unused */ +static __noinline uint8_t get_8_sl(const uint8_t * p) { - uint8_t v; + uint8_t v; - p = set_fs(p); - asm volatile("movb %%fs:%1,%0" : "=q" (v) : "m" (*p)); - return v; + p = set_fs(p); + asm volatile ("movb %%fs:%1,%0":"=q" (v):"m"(*p)); + return v; } #endif -static __noinline uint16_t get_16_sl(const uint16_t *p) +static __noinline uint16_t get_16_sl(const uint16_t * p) { - uint16_t v; + uint16_t v; - p = set_fs(p); - asm volatile("movw %%fs:%1,%0" : "=r" (v) : "m" (*p)); - return v; + p = set_fs(p); + asm volatile ("movw %%fs:%1,%0":"=r" (v):"m"(*p)); + return v; } -static __noinline uint32_t get_32_sl(const uint32_t *p) +static __noinline uint32_t get_32_sl(const uint32_t * p) { - uint32_t v; + uint32_t v; - p = set_fs(p); - asm volatile("movl %%fs:%1,%0" : "=r" (v) : "m" (*p)); - return v; + p = set_fs(p); + asm volatile ("movl %%fs:%1,%0":"=r" (v):"m"(*p)); + return v; } -#if 0 /* unused */ -static __noinline void set_8_sl(uint8_t *p, uint8_t v) +#if 0 /* unused */ +static __noinline void set_8_sl(uint8_t * p, uint8_t v) { - p = set_fs(p); - asm volatile("movb %1,%%fs:%0" : "=m" (*p) : "qi" (v)); + p = set_fs(p); + asm volatile ("movb %1,%%fs:%0":"=m" (*p):"qi"(v)); } #endif -static __noinline void set_16_sl(uint16_t *p, uint16_t v) +static __noinline void set_16_sl(uint16_t * p, uint16_t v) { - p = set_fs(p); - asm volatile("movw %1,%%fs:%0" : "=m" (*p) : "ri" (v)); + p = set_fs(p); + asm volatile ("movw %1,%%fs:%0":"=m" (*p):"ri"(v)); } -static __noinline void set_32_sl(uint32_t *p, uint32_t v) +static __noinline void set_32_sl(uint32_t * p, uint32_t v) { - p = set_fs(p); - asm volatile("movl %1,%%fs:%0" : "=m" (*p) : "ri" (v)); + p = set_fs(p); + asm volatile ("movl %1,%%fs:%0":"=m" (*p):"ri"(v)); } #else @@ -219,65 +219,66 @@ static __noinline void set_32_sl(uint32_t *p, uint32_t v) * Returns the number of modified bytes in ldlinux.sys if successful, * otherwise -1. */ -int syslinux_patch(const uint32_t *sectors, int nsectors, +int syslinux_patch(const uint32_t * sectors, int nsectors, int stupid, int raid_mode) { - struct patch_area *patcharea; - uint32_t *wp; - int nsect = (syslinux_ldlinux_len+511) >> 9; - uint32_t csum; - int i, dw, nptrs, rv; - - if ( nsectors < nsect ) - return -1; - - /* Patch in options, as appropriate */ - if (stupid) { - /* Access only one sector at a time */ - set_16(&sbs->MaxTransfer, 1); - } - - i = get_16(&sbs->bsSignature); - if (raid_mode) - set_16((uint16_t *)((char *)sbs+i), 0x18CD); /* INT 18h */ - set_16(&sbs->bsSignature, 0xAA55); - - /* First sector need pointer in boot sector */ - 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; wp++) - ; - patcharea = (struct patch_area *)wp; - - /* Set up the totals */ - dw = syslinux_ldlinux_len >> 2; /* COMPLETE dwords, excluding ADV */ - set_16_sl(&patcharea->data_sectors, nsect); /* Not including ADVs */ - set_16_sl(&patcharea->adv_sectors, 0); /* ADVs not supported yet */ - set_32_sl(&patcharea->dwords, dw); - set_32_sl(&patcharea->currentdir, 0); - - /* Set the sector pointers */ - wp = (uint32_t *)((char *)syslinux_ldlinux+get_16_sl(&patcharea->secptroffset)); - nptrs = get_16_sl(&patcharea->secptrcnt); - - while (nsect--) { - set_32_sl(wp++, *sectors++); - nptrs--; - } - 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++) - csum -= get_32_sl(wp); /* Negative checksum */ - - set_32_sl(&patcharea->checksum, csum); - - return rv; + struct patch_area *patcharea; + uint32_t *wp; + int nsect = (syslinux_ldlinux_len + 511) >> 9; + uint32_t csum; + int i, dw, nptrs, rv; + + if (nsectors < nsect) + return -1; + + /* Patch in options, as appropriate */ + if (stupid) { + /* Access only one sector at a time */ + set_16(&sbs->MaxTransfer, 1); + } + + i = get_16(&sbs->bsSignature); + if (raid_mode) + set_16((uint16_t *) ((char *)sbs + i), 0x18CD); /* INT 18h */ + set_16(&sbs->bsSignature, 0xAA55); + + /* First sector need pointer in boot sector */ + 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; + wp++) ; + patcharea = (struct patch_area *)wp; + + /* Set up the totals */ + dw = syslinux_ldlinux_len >> 2; /* COMPLETE dwords, excluding ADV */ + set_16_sl(&patcharea->data_sectors, nsect); /* Not including ADVs */ + set_16_sl(&patcharea->adv_sectors, 0); /* ADVs not supported yet */ + set_32_sl(&patcharea->dwords, dw); + set_32_sl(&patcharea->currentdir, 0); + + /* Set the sector pointers */ + wp = (uint32_t *) ((char *)syslinux_ldlinux + + get_16_sl(&patcharea->secptroffset)); + nptrs = get_16_sl(&patcharea->secptrcnt); + + while (nsect--) { + set_32_sl(wp++, *sectors++); + nptrs--; + } + 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++) + csum -= get_32_sl(wp); /* Negative checksum */ + + set_32_sl(&patcharea->checksum, csum); + + return rv; } |