aboutsummaryrefslogtreecommitdiffstats
path: root/libinstaller
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2009-05-19 12:29:11 -0700
committerH. Peter Anvin <hpa@zytor.com>2009-05-19 12:29:11 -0700
commitb7cd982475b9fe9b4b2b2bb6e3b3935756ce006d (patch)
treed01ed9db27a3ab732ccb94095ed648fd4de9bcf7 /libinstaller
parent905cad0bf5201bddb99675687bab9b6666b88f71 (diff)
downloadlwip-b7cd982475b9fe9b4b2b2bb6e3b3935756ce006d.tar.gz
lwip-b7cd982475b9fe9b4b2b2bb6e3b3935756ce006d.tar.xz
lwip-b7cd982475b9fe9b4b2b2bb6e3b3935756ce006d.zip
FAT: update the FAT installers to match the new diskstart.inc
Update the FAT installers to match the new patch area format in diskstart.inc. Also, update the coding style to match extlinux; this code should eventually get unified. This does not resolve the current issues with the DOS installer when ldlinux.sys exceeds about 48K, at which point the DOS installer needs to become a segment-aware EXE program. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'libinstaller')
-rw-r--r--libinstaller/syslxint.h2
-rw-r--r--libinstaller/syslxmod.c203
2 files changed, 55 insertions, 150 deletions
diff --git a/libinstaller/syslxint.h b/libinstaller/syslxint.h
index 3cecf3c0..39098def 100644
--- a/libinstaller/syslxint.h
+++ b/libinstaller/syslxint.h
@@ -138,5 +138,7 @@ struct boot_sector {
#define bsHead bsJump
#define bsHeadLen offsetof(struct boot_sector, bsJump)
#define bsCode bs32.Code /* The common safe choice */
+#define bsCodeLen (offsetof(struct boot_sector, bsSignature) - \
+ offsetof(struct boot_sector, bsCode))
#endif /* SYSLXINT_H */
diff --git a/libinstaller/syslxmod.c b/libinstaller/syslxmod.c
index fb2f1d7a..d1cc13bf 100644
--- a/libinstaller/syslxmod.c
+++ b/libinstaller/syslxmod.c
@@ -1,6 +1,7 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1998-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 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
@@ -22,117 +23,16 @@
#include <stddef.h>
#include "syslinux.h"
+#include "syslxint.h"
-#define LDLINUX_MAGIC 0x3eb202fe
-
-enum bs_offsets {
- bsJump = 0x00,
- bsOemName = 0x03,
- bsBytesPerSec = 0x0b,
- bsSecPerClust = 0x0d,
- bsResSectors = 0x0e,
- bsFATs = 0x10,
- bsRootDirEnts = 0x11,
- bsSectors = 0x13,
- bsMedia = 0x15,
- bsFATsecs = 0x16,
- bsSecPerTrack = 0x18,
- bsHeads = 0x1a,
- bsHiddenSecs = 0x1c,
- bsHugeSectors = 0x20,
-
- /* FAT12/16 only */
- bs16DriveNumber = 0x24,
- bs16Reserved1 = 0x25,
- bs16BootSignature = 0x26,
- bs16VolumeID = 0x27,
- bs16VolumeLabel = 0x2b,
- bs16FileSysType = 0x36,
- bs16Code = 0x3e,
-
- /* FAT32 only */
- bs32FATSz32 = 36,
- bs32ExtFlags = 40,
- bs32FSVer = 42,
- bs32RootClus = 44,
- bs32FSInfo = 48,
- bs32BkBootSec = 50,
- bs32Reserved = 52,
- bs32DriveNumber = 64,
- bs32Reserved1 = 65,
- bs32BootSignature = 66,
- bs32VolumeID = 67,
- bs32VolumeLabel = 71,
- bs32FileSysType = 82,
- bs32Code = 90,
-
- bsSignature = 0x1fe
-};
-
-#define bsHead bsJump
-#define bsHeadLen (bsOemName-bsHead)
-#define bsCode bs32Code /* The common safe choice */
-#define bsCodeLen (bsSignature-bs32Code)
-
-/*
- * Access functions for littleendian numbers, possibly misaligned.
- */
-static inline uint8_t get_8(const unsigned char *p)
-{
- return *(const uint8_t *)p;
-}
-
-static inline uint16_t get_16(const unsigned char *p)
-{
-#if defined(__i386__) || defined(__x86_64__)
- /* Littleendian and unaligned-capable */
- return *(const uint16_t *)p;
-#else
- return (uint16_t)p[0] + ((uint16_t)p[1] << 8);
-#endif
-}
-
-static inline uint32_t get_32(const unsigned char *p)
-{
-#if defined(__i386__) || defined(__x86_64__)
- /* Littleendian and unaligned-capable */
- return *(const uint32_t *)p;
-#else
- return (uint32_t)p[0] + ((uint32_t)p[1] << 8) +
- ((uint32_t)p[2] << 16) + ((uint32_t)p[3] << 24);
-#endif
-}
-
-static inline void set_16(unsigned char *p, uint16_t v)
-{
-#if defined(__i386__) || defined(__x86_64__)
- /* Littleendian and unaligned-capable */
- *(uint16_t *)p = v;
-#else
- p[0] = (v & 0xff);
- p[1] = ((v >> 8) & 0xff);
-#endif
-}
-
-static inline void set_32(unsigned char *p, uint32_t v)
-{
-#if defined(__i386__) || defined(__x86_64__)
- /* Littleendian and unaligned-capable */
- *(uint32_t *)p = v;
-#else
- p[0] = (v & 0xff);
- p[1] = ((v >> 8) & 0xff);
- p[2] = ((v >> 16) & 0xff);
- p[3] = ((v >> 24) & 0xff);
-#endif
-}
+#define sbs ((struct boot_sector *)syslinux_bootsect)
void syslinux_make_bootsect(void *bs)
{
- unsigned char *bootsect = bs;
+ struct boot_sector *bootsect = bs;
- memcpy(bootsect+bsHead, syslinux_bootsect+bsHead, bsHeadLen);
- memcpy(bootsect+bsCode, syslinux_bootsect+bsCode, bsCodeLen);
+ memcpy(&bootsect->bsHead, &sbs->bsHead, bsHeadLen);
+ memcpy(&bootsect->bsCode, &sbs->bsCode, bsCodeLen);
}
/*
@@ -146,16 +46,16 @@ const char *syslinux_check_bootsect(const void *bs)
long long sectors, fatsectors, dsectors;
long long clusters;
int rootdirents, clustersize;
- const unsigned char *sectbuf = bs;
+ const struct boot_sector *sectbuf = bs;
veryold = 0;
/* Must be 0xF0 or 0xF8..0xFF */
- if ( get_8(sectbuf+bsMedia) != 0xF0 &&
- get_8(sectbuf+bsMedia) < 0xF8 )
+ if ( get_8(&sectbuf->bsMedia) != 0xF0 &&
+ get_8(&sectbuf->bsMedia) < 0xF8 )
goto invalid;
- sectorsize = get_16(sectbuf+bsBytesPerSec);
+ sectorsize = get_16(&sectbuf->bsBytesPerSec);
if ( sectorsize == 512 )
; /* ok */
else if ( sectorsize == 1024 || sectorsize == 2048 || sectorsize == 4096 )
@@ -163,21 +63,21 @@ const char *syslinux_check_bootsect(const void *bs)
else
goto invalid;
- clustersize = get_8(sectbuf+bsSecPerClust);
+ clustersize = get_8(&sectbuf->bsSecPerClust);
if ( clustersize == 0 || (clustersize & (clustersize-1)) )
goto invalid; /* Must be nonzero and a power of 2 */
- sectors = get_16(sectbuf+bsSectors);
- sectors = sectors ? sectors : get_32(sectbuf+bsHugeSectors);
+ sectors = get_16(&sectbuf->bsSectors);
+ sectors = sectors ? sectors : get_32(&sectbuf->bsHugeSectors);
- dsectors = sectors - get_16(sectbuf+bsResSectors);
+ dsectors = sectors - get_16(&sectbuf->bsResSectors);
- fatsectors = get_16(sectbuf+bsFATsecs);
- fatsectors = fatsectors ? fatsectors : get_32(sectbuf+bs32FATSz32);
- fatsectors *= get_8(sectbuf+bsFATs);
+ fatsectors = get_16(&sectbuf->bsFATsecs);
+ fatsectors = fatsectors ? fatsectors : get_32(&sectbuf->bs32.FATSz32);
+ fatsectors *= get_8(&sectbuf->bsFATs);
dsectors -= fatsectors;
- rootdirents = get_16(sectbuf+bsRootDirEnts);
+ rootdirents = get_16(&sectbuf->bsRootDirEnts);
dsectors -= (rootdirents+sectorsize/32-1)/sectorsize;
if ( dsectors < 0 || fatsectors == 0 )
@@ -188,27 +88,27 @@ const char *syslinux_check_bootsect(const void *bs)
if ( clusters < 0xFFF5 ) {
/* FAT12 or FAT16 */
- if ( !get_16(sectbuf+bsFATsecs) )
+ if ( !get_16(&sectbuf->bsFATsecs) )
goto invalid;
- if ( get_8(sectbuf+bs16BootSignature) == 0x29 ) {
- if ( !memcmp(sectbuf+bs16FileSysType, "FAT12 ", 8) ) {
+ if ( get_8(&sectbuf->bs16.BootSignature) == 0x29 ) {
+ if ( !memcmp(&sectbuf->bs16.FileSysType, "FAT12 ", 8) ) {
if ( clusters >= 0xFF5 )
return "more than 4084 clusters but claims FAT12";
- } else if ( !memcmp(sectbuf+bs16FileSysType, "FAT16 ", 8) ) {
+ } else if ( !memcmp(&sectbuf->bs16.FileSysType, "FAT16 ", 8) ) {
if ( clusters < 0xFF5 )
return "less than 4084 clusters but claims FAT16";
- } else if ( memcmp(sectbuf+bs16FileSysType, "FAT ", 8) ) {
+ } else if ( memcmp(&sectbuf->bs16.FileSysType, "FAT ", 8) ) {
static char fserr[] = "filesystem type \"????????\" not supported";
- memcpy(fserr+17, sectbuf+bs16FileSysType, 8);
+ memcpy(fserr+17, &sectbuf->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(sectbuf+bs32BootSignature) != 0x29 ||
- memcmp(sectbuf+bs32FileSysType, "FAT32 ", 8) )
+ if ( get_8(&sectbuf->bs32.BootSignature) != 0x29 ||
+ memcmp(&sectbuf->bs32.FileSysType, "FAT32 ", 8) )
goto invalid;
} else {
goto invalid;
@@ -221,7 +121,7 @@ const char *syslinux_check_bootsect(const void *bs)
}
/*
- * This patches the boot sector and the first sector of ldlinux.sys
+ * This patches the boot sector and the beginning of ldlinux.sys
* based on an ldlinux.sys sector map passed in. Typically this is
* handled by writing ldlinux.sys, mapping it, and then overwrite it
* with the patched version. If this isn't safe to do because of
@@ -233,10 +133,11 @@ const char *syslinux_check_bootsect(const void *bs)
int syslinux_patch(const uint32_t *sectors, int nsectors,
int stupid, int raid_mode)
{
- unsigned char *patcharea, *p;
+ struct patch_area *patcharea;
+ uint32_t *wp;
int nsect = (syslinux_ldlinux_len+511) >> 9;
uint32_t csum;
- int i, dw;
+ int i, dw, nptrs;
if ( nsectors < nsect )
return -1;
@@ -244,44 +145,46 @@ int syslinux_patch(const uint32_t *sectors, int nsectors,
/* Patch in options, as appropriate */
if (stupid) {
/* Access only one sector at a time */
- set_16(syslinux_bootsect+0x1FC, 1);
+ set_16(&sbs->MaxTransfer, 1);
}
- i = get_16(syslinux_bootsect+0x1FE);
+ i = get_16(&sbs->bsSignature);
if (raid_mode)
- set_16(syslinux_bootsect+i, 0x18CD); /* INT 18h */
- set_16(syslinux_bootsect+0x1FE, 0xAA55);
+ set_16((uint16_t *)((char *)sbs+i), 0x18CD); /* INT 18h */
+ set_16(&sbs->bsSignature, 0xAA55);
/* First sector need pointer in boot sector */
- set_32(syslinux_bootsect+0x1F8, *sectors++);
+ set_32(&sbs->NextSector, *sectors++);
nsect--;
/* Search for LDLINUX_MAGIC to find the patch area */
- for ( p = syslinux_ldlinux ; get_32(p) != LDLINUX_MAGIC ; p += 4 );
- patcharea = p+8;
+ for (wp = (uint32_t *)syslinux_ldlinux; get_32(wp) != LDLINUX_MAGIC; wp++)
+ ;
+ patcharea = (struct patch_area *)wp;
/* Set up the totals */
- dw = syslinux_ldlinux_len >> 2; /* COMPLETE dwords! */
- set_16(patcharea, dw);
- set_16(patcharea+2, nsect); /* Does not include the first sector! */
+ dw = syslinux_ldlinux_len >> 2; /* COMPLETE dwords, excluding ADV */
+ set_16(&patcharea->data_sectors, nsect); /* Not including ADVs */
+ set_16(&patcharea->adv_sectors, 0); /* ADVs not supported yet */
+ set_32(&patcharea->dwords, dw);
+ set_32(&patcharea->currentdir, 0);
/* Set the sector pointers */
- p = patcharea+8;
+ wp = (uint32_t *)((char *)syslinux_ldlinux+get_16(&patcharea->secptroffset));
+ nptrs = get_16(&patcharea->secptrcnt);
- memset(p, 0, 64*4);
- while ( nsect-- ) {
- set_32(p, *sectors++);
- p += 4;
- }
+ memset(wp, 0, nptrs*4);
+ while ( nsect-- )
+ set_32(wp++, *sectors++);
/* Now produce a checksum */
- set_32(patcharea+4, 0);
+ set_32(&patcharea->checksum, 0);
csum = LDLINUX_MAGIC;
- for ( i = 0, p = syslinux_ldlinux ; i < dw ; i++, p += 4 )
- csum -= get_32(p); /* Negative checksum */
+ for (i = 0, wp = (uint32_t *)syslinux_ldlinux; i < dw; i++, wp++)
+ csum -= get_32(wp); /* Negative checksum */
- set_32(patcharea+4, csum);
+ set_32(&patcharea->checksum, csum);
- return 0;
+ return 0;
}