From aa7ca7c9f7266c432b5dad65302ae7cfa7a1c050 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Fri, 19 Nov 2010 11:25:00 -0500
Subject: [PATCH] Make most SECTOR_SIZE checks use functions.
Most uses of SECTOR_SIZE or SECTOR_BITS are changed to get_sector_size()
or get_sector_bits(), respectively.
---
efi/efidisk.c | 62 ++++++++++++++++++++++++++++++++++++++++----
efi/ia32/loader/linux.c | 9 ++++++-
efi/x86_64/loader/linux.c | 9 ++++++-
grub/asmstub.c | 25 +++++++++++++-----
lib/device.c | 3 ++
stage2/boot.c | 11 ++++---
stage2/builtins.c | 20 ++++++++++----
stage2/disk_io.c | 50 ++++++++++++++++++++++-------------
stage2/fsys_ext2fs.c | 5 ++-
stage2/fsys_fat.c | 20 +++++++++-----
stage2/fsys_jfs.c | 12 +++++---
stage2/fsys_reiserfs.c | 24 +++++++++--------
stage2/fsys_xfs.c | 2 +-
stage2/gpt.h | 9 +++---
stage2/shared.h | 12 ++++++---
15 files changed, 194 insertions(+), 79 deletions(-)
diff --git a/efi/efidisk.c b/efi/efidisk.c
index 145ed16..edd830e 100644
--- a/efi/efidisk.c
+++ b/efi/efidisk.c
@@ -44,6 +44,10 @@ static struct grub_efidisk_data *fd_devices;
static struct grub_efidisk_data *hd_devices;
static struct grub_efidisk_data *cd_devices;
+static int get_device_sector_bits(struct grub_efidisk_data *device);
+static int get_device_sector_size(struct grub_efidisk_data *device);
+static struct grub_efidisk_data *get_device_from_drive (int drive);
+
static struct grub_efidisk_data *
make_devices (void)
{
@@ -190,7 +194,9 @@ name_devices (struct grub_efidisk_data *devices)
m = d->block_io->media;
if (GRUB_EFI_DEVICE_PATH_TYPE(dp) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE)
{
- if (m->read_only && m->block_size > SECTOR_SIZE)
+ /* XXX FIXME this won't work if we see write-protected disks with
+ * 4k sectors */
+ if (m->read_only && m->block_size > 0x200)
{
add_device (&cd_devices, d);
} else
@@ -253,11 +259,15 @@ grub_efidisk_read (struct grub_efidisk_data *d, grub_disk_addr_t sector,
grub_efi_disk_io_t *dio;
grub_efi_block_io_t *bio;
grub_efi_status_t status;
- grub_efi_uint64_t sector_size;
+ grub_efi_uint64_t sector_size = get_device_sector_size(d);
dio = d->disk_io;
bio = d->block_io;
- sector_size = d->block_io->media->block_size;
+
+#if 0
+ grub_printf("read(%d, %d) -> read(%d, %d)\n", sector, size,
+ sector * sector_size, size * sector_size);
+#endif
status = Call_Service_5 (dio->read ,
dio, bio->media->media_id,
@@ -278,11 +288,10 @@ grub_efidisk_write (struct grub_efidisk_data *d, grub_disk_addr_t sector,
grub_efi_disk_io_t *dio;
grub_efi_block_io_t *bio;
grub_efi_status_t status;
- grub_efi_uint64_t sector_size;
+ grub_efi_uint64_t sector_size = get_device_sector_size(d);
dio = d->disk_io;
bio = d->block_io;
- sector_size = d->block_io->media->block_size;
grub_dprintf ("efidisk",
"writing 0x%x sectors at the sector 0x%x to ??\n",
@@ -313,6 +322,47 @@ grub_efidisk_fini (void)
free_devices (cd_devices);
}
+static int
+get_device_sector_size(struct grub_efidisk_data *device)
+{
+ return device->block_io->media->block_size;
+}
+
+int
+get_sector_size(int drive)
+{
+ struct grub_efidisk_data *device = get_device_from_drive(drive);
+ return get_device_sector_size(device);
+}
+
+/*
+ * ffz = Find First Zero in word. Undefined if no zero exists,
+ * so code should check against ~0UL first..
+ */
+static __inline__ unsigned int
+ffz (unsigned int word)
+{
+ __asm__ ("bsfl %1,%0"
+: "=r" (word)
+: "r" (~word));
+ return word;
+}
+#define log2(n) ffz(~(n))
+
+static int
+get_device_sector_bits(struct grub_efidisk_data *device)
+{
+ int sector_size = get_device_sector_size(device);
+ return log2(sector_size);
+}
+
+int
+get_sector_bits(int drive)
+{
+ int sector_size = get_sector_size(drive);
+ return log2(sector_size);
+}
+
static struct grub_efidisk_data *
get_device_from_drive (int drive)
{
@@ -456,7 +506,6 @@ grub_get_drive_partition_from_bdev_handle (grub_efi_handle_t handle,
unsigned long partition_start, partition_len, part_offset, part_extoffset;
unsigned long gpt_offset;
int gpt_count, gpt_size;
- char buf[SECTOR_SIZE];
auto int find_bdev (struct grub_efidisk_data *c);
int find_bdev (struct grub_efidisk_data *c)
@@ -541,6 +590,7 @@ grub_get_drive_partition_from_bdev_handle (grub_efi_handle_t handle,
if (! found)
return 0;
+ char buf[get_sector_size(drv)];
part = 0xFFFFFF;
while (next_partition (drv, 0, &part, &part_type,
&partition_start, &partition_len,
diff --git a/efi/ia32/loader/linux.c b/efi/ia32/loader/linux.c
index eb6b5de..eaaeb38 100644
--- a/efi/ia32/loader/linux.c
+++ b/efi/ia32/loader/linux.c
@@ -37,6 +37,13 @@
#define PTR_HI(x) ((grub_uint32_t) ((unsigned long long)((unsigned long)(x)) >> 32))
+#ifndef SECTOR_SIZE
+#define SECTOR_SIZE 0x200
+#endif /* defined(SECTOR_SIZE) */
+#ifndef SECTOR_BITS
+#define SECTOR_BITS 9
+#endif /* defined(SECTOR_BITS) */
+
static unsigned long linux_mem_size;
static int loaded;
static void *real_mode_mem;
diff --git a/efi/x86_64/loader/linux.c b/efi/x86_64/loader/linux.c
index 18746ea..93a0377 100644
--- a/efi/x86_64/loader/linux.c
+++ b/efi/x86_64/loader/linux.c
@@ -37,6 +37,13 @@
#define PTR_HI(x) ((grub_uint32_t) ((unsigned long long)((unsigned long)(x)) >> 32))
+#ifndef SECTOR_SIZE
+#define SECTOR_SIZE 0x200
+#endif /* defined(SECTOR_SIZE) */
+#ifndef SECTOR_BITS
+#define SECTOR_BITS 9
+#endif /* defined(SECTOR_BITS) */
+
static unsigned long linux_mem_size;
static int loaded;
static void *real_mode_mem;
diff --git a/grub/asmstub.c b/grub/asmstub.c
index f420074..818be75 100644
--- a/grub/asmstub.c
+++ b/grub/asmstub.c
@@ -107,6 +107,17 @@ static char *serial_device = 0;
static unsigned int serial_speed;
#endif /* SIMULATE_SLOWNESS_OF_SERIAL */
+#ifdef GRUB_UTIL
+int get_sector_size (int drive)
+{
+ return 0x200;
+}
+int get_sector_bits (int drive)
+{
+ return 9;
+}
+#endif /* GRUB_UTIL */
+
/* This allocates page-aligned storage of the specified size, which must be
* a multiple of the page size as determined by calling sysconf(_SC_PAGESIZE)
*/
@@ -1063,13 +1074,13 @@ biosdisk (int subfunc, int drive, struct geometry *geometry,
_syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo,
loff_t *, res, uint, wh);
- offset = (loff_t) sector * (loff_t) SECTOR_SIZE;
+ offset = (loff_t) sector * (loff_t) get_sector_size(drive);
if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET))
return -1;
}
#else
{
- off_t offset = (off_t) sector * (off_t) SECTOR_SIZE;
+ off_t offset = (off_t) sector * (off_t) get_sector_size(drive);
if (lseek (fd, offset, SEEK_SET) != offset)
return -1;
@@ -1088,13 +1099,13 @@ biosdisk (int subfunc, int drive, struct geometry *geometry,
sectors that are read together with the MBR in one read. It
should only remap the MBR, so we split the read in two
parts. -jochen */
- if (nread (fd, buf, SECTOR_SIZE) != SECTOR_SIZE)
+ if (nread (fd, buf, get_sector_size(drive)) != get_sector_size(drive))
return -1;
- buf += SECTOR_SIZE;
+ buf += get_sector_size(drive);
nsec--;
}
#endif
- if (nread (fd, buf, nsec * SECTOR_SIZE) != nsec * SECTOR_SIZE)
+ if (nread (fd, buf, nsec * get_sector_size(drive)) != nsec * get_sector_size(drive))
return -1;
break;
@@ -1104,10 +1115,10 @@ biosdisk (int subfunc, int drive, struct geometry *geometry,
grub_printf ("Write %d sectors starting from %d sector"
" to drive 0x%x (%s)\n",
nsec, sector, drive, device_map[drive]);
- hex_dump (buf, nsec * SECTOR_SIZE);
+ hex_dump (buf, nsec * get_sector_size(drive));
}
if (! read_only)
- if (nwrite (fd, buf, nsec * SECTOR_SIZE) != nsec * SECTOR_SIZE)
+ if (nwrite (fd, buf, nsec * get_sector_size(drive)) != nsec * get_sector_size(drive))
return -1;
break;
diff --git a/lib/device.c b/lib/device.c
index 45a300e..45e4001 100644
--- a/lib/device.c
+++ b/lib/device.c
@@ -36,6 +36,9 @@
#include <limits.h>
#include <stdarg.h>
+#define SECTOR_SIZE 0x200
+#define SECTOR_BITS 9
+
#ifdef __linux__
# if !defined(__GLIBC__) || \
((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)))
diff --git a/stage2/boot.c b/stage2/boot.c
index 247b8c9..e30daf8 100644
--- a/stage2/boot.c
+++ b/stage2/boot.c
@@ -281,7 +281,7 @@ load_image (char *kernel, char *arg, kernel_t suggested_type,
setup_sects = LINUX_DEFAULT_SETUP_SECTS;
data_len = setup_sects << 9;
- text_len = filemax - data_len - SECTOR_SIZE;
+ text_len = filemax - data_len - get_sector_size(current_drive);
linux_data_tmp_addr = (char *) LINUX_BZIMAGE_ADDR + text_len;
@@ -395,14 +395,15 @@ load_image (char *kernel, char *arg, kernel_t suggested_type,
/* It is possible that DATA_LEN + SECTOR_SIZE is greater than
MULTIBOOT_SEARCH, so the data may have been read partially. */
- if (data_len + SECTOR_SIZE <= MULTIBOOT_SEARCH)
+ if (data_len + get_sector_size(current_drive) <= MULTIBOOT_SEARCH)
grub_memmove (linux_data_tmp_addr, buffer,
- data_len + SECTOR_SIZE);
+ data_len + get_sector_size(current_drive));
else
{
grub_memmove (linux_data_tmp_addr, buffer, MULTIBOOT_SEARCH);
grub_read (linux_data_tmp_addr + MULTIBOOT_SEARCH,
- data_len + SECTOR_SIZE - MULTIBOOT_SEARCH);
+ data_len + get_sector_size(current_drive)
+ - MULTIBOOT_SEARCH);
}
if (lh->header != LINUX_MAGIC_SIGNATURE ||
@@ -461,7 +462,7 @@ load_image (char *kernel, char *arg, kernel_t suggested_type,
}
/* offset into file */
- grub_seek (data_len + SECTOR_SIZE);
+ grub_seek (data_len + get_sector_size(current_drive));
cur_addr = (int) linux_data_tmp_addr + LINUX_SETUP_MOVE_SIZE;
grub_read ((char *) LINUX_BZIMAGE_ADDR, text_len);
diff --git a/stage2/builtins.c b/stage2/builtins.c
index c90c527..178c889 100644
--- a/stage2/builtins.c
+++ b/stage2/builtins.c
@@ -195,11 +195,12 @@ blocklist_read_helper (int sector, int offset, int length)
int *num_sectors = &blocklist_func_context.num_sectors;
int *num_entries = &blocklist_func_context.num_entries;
int *last_length = &blocklist_func_context.last_length;
+ int sector_size = get_sector_size(current_drive);
if (*num_sectors > 0)
{
if (*start_sector + *num_sectors == sector
- && offset == 0 && *last_length == SECTOR_SIZE)
+ && offset == 0 && *last_length == sector_size)
{
*num_sectors++;
*last_length = length;
@@ -207,7 +208,7 @@ blocklist_read_helper (int sector, int offset, int length)
}
else
{
- if (*last_length == SECTOR_SIZE)
+ if (*last_length == sector_size)
grub_printf ("%s%d+%d", *num_entries ? "," : "",
*start_sector - part_start, *num_sectors);
else if (*num_sectors > 1)
@@ -1512,7 +1513,8 @@ find_func (char *arg, int flags)
unsigned long part = 0xFFFFFF;
unsigned long start, len, offset, ext_offset, gpt_offset;
int type, entry, gpt_count, gpt_size;
- char buf[SECTOR_SIZE];
+ int sector_size = get_sector_size(drive);
+ char buf[sector_size];
current_drive = drive;
while (next_partition (drive, 0xFFFFFF, &part, &type,
@@ -3012,7 +3014,6 @@ partnew_func (char *arg, int flags)
int start_cl, start_ch, start_dh;
int end_cl, end_ch, end_dh;
int entry;
- char mbr[512];
/* Convert a LBA address to a CHS address in the INT 13 format. */
auto void lba_to_chs (int lba, int *cl, int *ch, int *dh);
@@ -3043,6 +3044,9 @@ partnew_func (char *arg, int flags)
return 1;
}
+ int sector_size = get_sector_size(current_drive);
+ char mbr[sector_size];
+
/* The partition must a primary partition. */
if ((current_partition >> 16) > 3
|| (current_partition & 0xFFFF) != 0xFFFF)
@@ -3076,7 +3080,7 @@ partnew_func (char *arg, int flags)
return 1;
/* Read the MBR. */
- if (! rawread (current_drive, 0, 0, SECTOR_SIZE, mbr))
+ if (! rawread (current_drive, 0, 0, sector_size, mbr))
return 1;
/* Check if the new partition will fit in the disk. */
@@ -3131,7 +3135,6 @@ parttype_func (char *arg, int flags)
unsigned long part = 0xFFFFFF;
unsigned long start, len, offset, ext_offset, gpt_offset;
int entry, type, gpt_count, gpt_size;
- char mbr[512];
/* Get the drive and the partition. */
if (! set_device (arg))
@@ -3143,6 +3146,9 @@ parttype_func (char *arg, int flags)
errnum = ERR_BAD_ARGUMENT;
return 1;
}
+
+ int sector_size = get_sector_size(current_drive);
+ char mbr[sector_size];
/* The partition must be a PC slice. */
if ((current_partition >> 16) == 0xFF
@@ -3597,6 +3603,7 @@ savedefault_helper(int new_default)
#endif
#if !defined(SUPPORT_DISKLESS) && defined(GRUB_UTIL)
+#define SECTOR_SIZE 0x200
/*
* Full implementation of new `savedefault' for GRUB shell.
* XXX This needs fixing for stage2 files which aren't accessible
@@ -3694,6 +3701,7 @@ savedefault_shell(char *arg, int flags)
fclose (fp);
return 0;
}
+#undef SECTOR_SIZE
#endif
/* savedefault */
diff --git a/stage2/disk_io.c b/stage2/disk_io.c
index d54864f..308b291 100644
--- a/stage2/disk_io.c
+++ b/stage2/disk_io.c
@@ -305,7 +305,7 @@ devread (int sector, int byte_offset, int byte_len, char *buf)
* Check partition boundaries
*/
if (sector < 0
- || ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS))
+ || ((sector + ((byte_offset + byte_len - 1) >> get_sector_bits(current_drive)))
>= part_length))
{
errnum = ERR_OUTSIDE_PART;
@@ -315,8 +315,8 @@ devread (int sector, int byte_offset, int byte_len, char *buf)
/*
* Get the read to the beginning of a partition.
*/
- sector += byte_offset >> SECTOR_BITS;
- byte_offset &= SECTOR_SIZE - 1;
+ sector += byte_offset >> get_sector_bits(current_drive);
+ byte_offset &= get_sector_size(current_drive) - 1;
#if !defined(STAGE1_5)
if (disk_read_hook && debug)
@@ -355,7 +355,7 @@ rawwrite (int drive, int sector, char *buf)
sector = 1;
}
- memmove ((char *) SCRATCHADDR, buf, SECTOR_SIZE);
+ memmove ((char *) SCRATCHADDR, buf, get_sector_size(drive));
if (biosdisk (BIOSDISK_WRITE, drive, &buf_geom,
sector, 1, SCRATCHSEG))
{
@@ -392,7 +392,7 @@ devwrite (int sector, int sector_count, char *buf)
for (i = 0; i < sector_count; i++)
{
if (! rawwrite (current_drive, part_start + sector + i,
- buf + (i << SECTOR_BITS)))
+ buf + (i << get_sector_bits(current_drive))))
return 0;
}
@@ -466,7 +466,7 @@ make_saved_active (void)
}
/* Read the MBR in the scratch space. */
- if (! rawread (saved_drive, 0, 0, SECTOR_SIZE, mbr))
+ if (! rawread (saved_drive, 0, 0, get_sector_size(saved_drive), mbr))
return 0;
/* If the partition is an extended partition, setting the active
@@ -619,7 +619,7 @@ next_partition (unsigned long drive, unsigned long dest,
/* Read the BSD label. */
if (! rawread (drive, *start + BSD_LABEL_SECTOR,
- 0, SECTOR_SIZE, buf))
+ 0, get_sector_size(drive), buf))
return 0;
/* Check if it is valid. */
@@ -674,7 +674,7 @@ next_partition (unsigned long drive, unsigned long dest,
}
/* Read the MBR or the boot sector of the extended partition. */
- if (! rawread (drive, *offset, 0, SECTOR_SIZE, buf))
+ if (! rawread (drive, *offset, 0, get_sector_size(drive), buf))
return 0;
/* Check if it is valid. */
@@ -690,7 +690,7 @@ next_partition (unsigned long drive, unsigned long dest,
struct grub_gpt_header *hdr = (struct grub_gpt_header *) buf;
/* Read in the GPT Partition table header. */
- if (! rawread (drive, 1, 0, SECTOR_SIZE, buf))
+ if (! rawread (drive, 1, 0, get_sector_size(drive), buf))
return 0;
if (hdr->magic == GPT_HEADER_MAGIC && hdr->version == 0x10000)
@@ -710,7 +710,7 @@ next_partition (unsigned long drive, unsigned long dest,
/* This is not a valid header for a GPT partition table.
Re-read the MBR or the boot sector of the extended
partition. */
- if (! rawread (drive, *offset, 0, SECTOR_SIZE, buf))
+ if (! rawread (drive, *offset, 0, get_sector_size(drive), buf))
return 0;
}
}
@@ -785,7 +785,7 @@ next_partition (unsigned long drive, unsigned long dest,
return 0;
}
/* Read in the GPT Partition table entry. */
- if (! rawread (drive, (*gpt_offset) + GPT_ENTRY_SECTOR (*gpt_size, *entry), GPT_ENTRY_INDEX (*gpt_size, *entry), *gpt_size, buf))
+ if (! rawread (drive, (*gpt_offset) + GPT_ENTRY_SECTOR (drive, *gpt_size, *entry), GPT_ENTRY_INDEX (drive, *gpt_size, *entry), *gpt_size, buf))
return 0;
} while (! (gptentry->type1 && gptentry->type2));
@@ -851,7 +851,7 @@ real_open_partition (int flags)
int gpt_count;
int gpt_size;
int entry;
- char buf[SECTOR_SIZE];
+ char buf[4096];
int bsd_part, pc_slice;
/* For simplicity. */
@@ -1022,6 +1022,17 @@ open_partition (void)
return real_open_partition (0);
}
+#if !defined(PLATFORM_EFI) && !defined(GRUB_UTIL)
+int get_sector_size (int drive)
+{
+ return SECTOR_SIZE;
+}
+int get_sector_bits (int drive)
+{
+ return SECTOR_BITS;
+}
+#endif /* !defined(PLATFORM_EFI) && !defined(GRUB_UTIL) */
+
#ifndef STAGE1_5
/* XX used for device completion in 'set_device' and 'print_completions' */
@@ -1227,7 +1238,7 @@ set_bootdev (int hdbias)
if ((saved_drive & 0x80) && cur_part_addr)
{
if (rawread (saved_drive, cur_part_offset,
- 0, SECTOR_SIZE, (char *) SCRATCHADDR))
+ 0, get_sector_size(saved_drive), (char *) SCRATCHADDR))
{
char *dst, *src;
@@ -1692,7 +1703,7 @@ grub_open (char *filename)
BLK_BLKLENGTH (list_addr) = tmp;
- filemax += (tmp * SECTOR_SIZE);
+ filemax += (tmp * get_sector_size(current_drive));
list_addr += BLK_BLKLIST_INC_VAL;
if (*ptr != ',')
@@ -1769,6 +1780,7 @@ grub_read (char *buf, int len)
if (block_file)
{
int size, off, ret = 0;
+ int sector_size = get_sector_size(current_drive);
while (len && !errnum)
{
@@ -1783,10 +1795,10 @@ grub_read (char *buf, int len)
/* run BLK_CUR_FILEPOS up to filepos */
while (filepos > BLK_CUR_FILEPOS)
{
- if ((filepos - (BLK_CUR_FILEPOS & ~(SECTOR_SIZE - 1)))
- >= SECTOR_SIZE)
+ if ((filepos - (BLK_CUR_FILEPOS & ~(sector_size - 1)))
+ >= sector_size)
{
- BLK_CUR_FILEPOS += SECTOR_SIZE;
+ BLK_CUR_FILEPOS += sector_size;
BLK_CUR_BLKNUM++;
if (BLK_CUR_BLKNUM >= BLK_BLKLENGTH (BLK_CUR_BLKLIST))
@@ -1799,9 +1811,9 @@ grub_read (char *buf, int len)
BLK_CUR_FILEPOS = filepos;
}
- off = filepos & (SECTOR_SIZE - 1);
+ off = filepos & (sector_size - 1);
size = ((BLK_BLKLENGTH (BLK_CUR_BLKLIST) - BLK_CUR_BLKNUM)
- * SECTOR_SIZE) - off;
+ * sector_size) - off;
if (size > len)
size = len;
diff --git a/stage2/fsys_ext2fs.c b/stage2/fsys_ext2fs.c
index 810ac5f..01386d1 100644
--- a/stage2/fsys_ext2fs.c
+++ b/stage2/fsys_ext2fs.c
@@ -25,7 +25,7 @@
static int mapblock1, mapblock2;
/* sizes are always in bytes, BLOCK values are always in DEV_BSIZE (sectors) */
-#define DEV_BSIZE 512
+#define DEV_BSIZE get_sector_size(current_drive)
/* include/linux/fs.h */
#define BLOCK_SIZE 1024 /* initial block size for superblock read */
@@ -33,6 +33,7 @@ static int mapblock1, mapblock2;
#define WHICH_SUPER 1
/* kind of from fs/ext2/super.c */
#define SBLOCK (WHICH_SUPER * BLOCK_SIZE / DEV_BSIZE) /* = 2 */
+#define SBOFF ((WHICH_SUPER * BLOCK_SIZE) % DEV_BSIZE)
/* include/asm-i386/types.h */
typedef __signed__ char __s8;
@@ -413,7 +414,7 @@ ext2fs_mount (void)
&& (! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_EXT2FS))
&& (! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_OTHER)))
|| part_length < (SBLOCK + (sizeof (struct ext2_super_block) / DEV_BSIZE))
- || !devread (SBLOCK, 0, sizeof (struct ext2_super_block),
+ || !devread (SBLOCK, SBOFF, sizeof (struct ext2_super_block),
(char *) SUPERBLOCK)
|| SUPERBLOCK->s_magic != EXT2_SUPER_MAGIC)
retval = 0;
diff --git a/stage2/fsys_fat.c b/stage2/fsys_fat.c
index 266ec03..7e82266 100644
--- a/stage2/fsys_fat.c
+++ b/stage2/fsys_fat.c
@@ -49,10 +49,10 @@ struct fat_superblock
/* pointer(s) into filesystem info buffer for DOS stuff */
#define FAT_SUPER ( (struct fat_superblock *) \
( FSYS_BUF + 32256) )/* 512 bytes long */
-#define FAT_BUF ( FSYS_BUF + 30208 ) /* 4 sector FAT buffer */
-#define NAME_BUF ( FSYS_BUF + 29184 ) /* Filename buffer (833 bytes) */
+#define FAT_BUF ( FSYS_BUF + 28160 ) /* 4 sector FAT buffer */
+#define NAME_BUF ( FSYS_BUF + 27136 ) /* Filename buffer (833 bytes) */
-#define FAT_CACHE_SIZE 2048
+#define FAT_CACHE_SIZE 4096
static __inline__ unsigned int
grub_log2 (unsigned int word)
@@ -68,6 +68,7 @@ fat_mount (void)
{
struct fat_bpb bpb;
__u32 magic, first_fat;
+ int sector_size;
/* Check partition type for harddisk */
if (((current_drive & 0x80) || (current_slice != 0))
@@ -81,6 +82,8 @@ fat_mount (void)
if (! devread (0, 0, sizeof (bpb), (char *) &bpb))
return 0;
+ sector_size = get_sector_size(current_drive);
+
/* Check if the number of sectors per cluster is zero here, to avoid
zero division. */
if (bpb.sects_per_clust == 0)
@@ -155,11 +158,11 @@ fat_mount (void)
/* Now do some sanity checks */
if (FAT_CVT_U16(bpb.bytes_per_sect) != (1 << FAT_SUPER->sectsize_bits)
- || FAT_CVT_U16(bpb.bytes_per_sect) != SECTOR_SIZE
+ || FAT_CVT_U16(bpb.bytes_per_sect) != sector_size
|| bpb.sects_per_clust != (1 << (FAT_SUPER->clustsize_bits
- FAT_SUPER->sectsize_bits))
|| FAT_SUPER->num_clust <= 2
- || (FAT_SUPER->fat_size * FAT_SUPER->num_clust / (2 * SECTOR_SIZE)
+ || (FAT_SUPER->fat_size * FAT_SUPER->num_clust / (2 * sector_size)
> FAT_SUPER->fat_length))
return 0;
@@ -203,6 +206,7 @@ fat_read (char *buf, int len)
int offset;
int ret = 0;
int size;
+ int sector_size = get_sector_size(current_drive);
if (FAT_SUPER->file_cluster < 0)
{
@@ -238,10 +242,10 @@ fat_read (char *buf, int len)
if (cached_pos < 0 ||
(cached_pos + FAT_SUPER->fat_size) > 2*FAT_CACHE_SIZE)
{
- FAT_SUPER->cached_fat = (fat_entry & ~(2*SECTOR_SIZE - 1));
+ FAT_SUPER->cached_fat = (fat_entry & ~(2*sector_size - 1));
cached_pos = (fat_entry - FAT_SUPER->cached_fat);
sector = FAT_SUPER->fat_offset
- + FAT_SUPER->cached_fat / (2*SECTOR_SIZE);
+ + FAT_SUPER->cached_fat / (2*sector_size);
if (!devread (sector, 0, FAT_CACHE_SIZE, (char*) FAT_BUF))
return 0;
}
@@ -259,6 +263,8 @@ fat_read (char *buf, int len)
return ret;
if (next_cluster < 2 || next_cluster >= FAT_SUPER->num_clust)
{
+ grub_printf("next_cluster: %d FAT_SUPER->num_clust: %d\n",
+ next_cluster, FAT_SUPER->num_clust);
errnum = ERR_FSYS_CORRUPT;
return 0;
}
diff --git a/stage2/fsys_jfs.c b/stage2/fsys_jfs.c
index 307f836..d63b1de 100644
--- a/stage2/fsys_jfs.c
+++ b/stage2/fsys_jfs.c
@@ -207,19 +207,20 @@ int
jfs_mount (void)
{
struct jfs_superblock super;
+ int sector_bits = get_sector_bits(current_drive);
- if (part_length < MINJFS >> SECTOR_BITS
- || !devread (SUPER1_OFF >> SECTOR_BITS, 0,
+ if (part_length < MINJFS >> sector_bits
+ || !devread (SUPER1_OFF >> sector_bits, 0,
sizeof(struct jfs_superblock), (char *)&super)
|| (super.s_magic != JFS_MAGIC)
- || !devread ((AITBL_OFF >> SECTOR_BITS) + FILESYSTEM_I,
+ || !devread ((AITBL_OFF >> sector_bits) + FILESYSTEM_I,
0, DISIZE, (char*)fileset)) {
return 0;
}
jfs.bsize = super.s_bsize;
jfs.l2bsize = super.s_l2bsize;
- jfs.bdlog = jfs.l2bsize - SECTOR_BITS;
+ jfs.bdlog = jfs.l2bsize - sector_bits;
return 1;
}
@@ -387,9 +388,10 @@ int
jfs_embed (int *start_sector, int needed_sectors)
{
struct jfs_superblock super;
+ int sector_bits = get_sector_bits(current_drive);
if (needed_sectors > 63
- || !devread (SUPER1_OFF >> SECTOR_BITS, 0,
+ || !devread (SUPER1_OFF >> sector_bits, 0,
sizeof (struct jfs_superblock),
(char *)&super)
|| (super.s_magic != JFS_MAGIC)) {
diff --git a/stage2/fsys_reiserfs.c b/stage2/fsys_reiserfs.c
index 441cb3f..aebd716 100644
--- a/stage2/fsys_reiserfs.c
+++ b/stage2/fsys_reiserfs.c
@@ -292,7 +292,6 @@ struct reiserfs_de_head
/* The size of the node cache */
#define FSYSREISER_CACHE_SIZE 24*1024
-#define FSYSREISER_MIN_BLOCKSIZE SECTOR_SIZE
#define FSYSREISER_MAX_BLOCKSIZE FSYSREISER_CACHE_SIZE / 3
/* Info about currently opened file */
@@ -569,9 +568,11 @@ int
reiserfs_mount (void)
{
struct reiserfs_super_block super;
- int superblock = REISERFS_DISK_OFFSET_IN_BYTES >> SECTOR_BITS;
+ int sector_bits = get_sector_bits(current_drive);
+ int sector_size = get_sector_size(current_drive);
+ int superblock = REISERFS_DISK_OFFSET_IN_BYTES >> sector_bits;
- if (part_length < superblock + (sizeof (super) >> SECTOR_BITS)
+ if (part_length < superblock + (sizeof (super) >> sector_bits)
|| ! devread (superblock, 0, sizeof (struct reiserfs_super_block),
(char *) &super)
|| (substring (REISER3FS_SUPER_MAGIC_STRING, super.s_magic) > 0
@@ -582,8 +583,8 @@ reiserfs_mount (void)
<= REISERFS_DISK_OFFSET_IN_BYTES))
{
/* Try old super block position */
- superblock = REISERFS_OLD_DISK_OFFSET_IN_BYTES >> SECTOR_BITS;
- if (part_length < superblock + (sizeof (super) >> SECTOR_BITS)
+ superblock = REISERFS_OLD_DISK_OFFSET_IN_BYTES >> sector_bits;
+ if (part_length < superblock + (sizeof (super) >> sector_bits)
|| ! devread (superblock, 0, sizeof (struct reiserfs_super_block),
(char *) &super))
return 0;
@@ -610,7 +611,7 @@ reiserfs_mount (void)
INFO->version = super.s_version;
INFO->blocksize = super.s_blocksize;
INFO->fullblocksize_shift = grub_log2 (super.s_blocksize);
- INFO->blocksize_shift = INFO->fullblocksize_shift - SECTOR_BITS;
+ INFO->blocksize_shift = INFO->fullblocksize_shift - sector_bits;
INFO->cached_slots =
(FSYSREISER_CACHE_SIZE >> INFO->fullblocksize_shift) - 1;
@@ -622,9 +623,9 @@ reiserfs_mount (void)
/* Clear node cache. */
memset (INFO->blocks, 0, sizeof (INFO->blocks));
- if (super.s_blocksize < FSYSREISER_MIN_BLOCKSIZE
+ if (super.s_blocksize < get_sector_size(current_drive)
|| super.s_blocksize > FSYSREISER_MAX_BLOCKSIZE
- || (SECTOR_SIZE << INFO->blocksize_shift) != super.s_blocksize)
+ || (sector_size << INFO->blocksize_shift) != super.s_blocksize)
return 0;
/* Initialize journal code. If something fails we end with zero
@@ -1215,9 +1216,10 @@ int
reiserfs_embed (int *start_sector, int needed_sectors)
{
struct reiserfs_super_block super;
+ int sector_bits = get_sector_bits(current_drive);
int num_sectors;
- if (! devread (REISERFS_DISK_OFFSET_IN_BYTES >> SECTOR_BITS, 0,
+ if (! devread (REISERFS_DISK_OFFSET_IN_BYTES >> sector_bits, 0,
sizeof (struct reiserfs_super_block), (char *) &super))
return 0;
@@ -1229,9 +1231,9 @@ reiserfs_embed (int *start_sector, int needed_sectors)
* the journal log */
super.s_journal_block * super.s_blocksize
> REISERFS_DISK_OFFSET_IN_BYTES))
- num_sectors = (REISERFS_DISK_OFFSET_IN_BYTES >> SECTOR_BITS) - 1;
+ num_sectors = (REISERFS_DISK_OFFSET_IN_BYTES >> sector_bits) - 1;
else
- num_sectors = (REISERFS_OLD_DISK_OFFSET_IN_BYTES >> SECTOR_BITS) - 1;
+ num_sectors = (REISERFS_OLD_DISK_OFFSET_IN_BYTES >> sector_bits) - 1;
return (needed_sectors <= num_sectors);
}
diff --git a/stage2/fsys_xfs.c b/stage2/fsys_xfs.c
index d5214d3..226e343 100644
--- a/stage2/fsys_xfs.c
+++ b/stage2/fsys_xfs.c
@@ -469,7 +469,7 @@ xfs_mount (void)
xfs.bsize = le32 (super.sb_blocksize);
xfs.blklog = super.sb_blocklog;
- xfs.bdlog = xfs.blklog - SECTOR_BITS;
+ xfs.bdlog = xfs.blklog - get_sector_bits(current_drive);
xfs.rootino = le64 (super.sb_rootino);
xfs.isize = le16 (super.sb_inodesize);
xfs.agblocks = le32 (super.sb_agblocks);
diff --git a/stage2/gpt.h b/stage2/gpt.h
index 71ed0b8..ad6d8f1 100644
--- a/stage2/gpt.h
+++ b/stage2/gpt.h
@@ -60,9 +60,10 @@ struct grub_gpt_partentry
#define GPT_HEADER_MAGIC 0x5452415020494645ULL
-#define GPT_ENTRY_SECTOR(size,entry) \
- ((((entry) * (size) + 1) & ~(SECTOR_SIZE - 1)) >> SECTOR_BITS)
-#define GPT_ENTRY_INDEX(size,entry) \
- ((((entry) * (size) + 1) & (SECTOR_SIZE - 1)) - 1)
+#define GPT_ENTRY_SECTOR(drive,size,entry) \
+ ((((entry) * (size) + 1) & ~(get_sector_size(drive) - 1)) \
+ >> get_sector_bits(drive))
+#define GPT_ENTRY_INDEX(drive, size,entry) \
+ ((((entry) * (size) + 1) & (get_sector_size(drive) - 1)) - 1)
#endif /* _GPT_H */
diff --git a/stage2/shared.h b/stage2/shared.h
index 9405556..7a77744 100644
--- a/stage2/shared.h
+++ b/stage2/shared.h
@@ -57,15 +57,15 @@ extern void *grub_scratch_mem;
#define NEW_HEAPSIZE 1500
/* 512-byte scratch area */
-#define SCRATCHADDR RAW_ADDR (0x77e00)
-#define SCRATCHSEG RAW_SEG (0x77e0)
+#define SCRATCHADDR RAW_ADDR (0x77000)
+#define SCRATCHSEG RAW_SEG (0x7700)
/*
- * This is the location of the raw device buffer. It is 31.5K
+ * This is the location of the raw device buffer. It is 28K
* in size.
*/
-#define BUFFERLEN 0x7e00
+#define BUFFERLEN 0x7000
#define BUFFERADDR RAW_ADDR (0x70000)
#define BUFFERSEG RAW_SEG (0x7000)
@@ -169,8 +169,10 @@ extern void *grub_scratch_mem;
* General disk stuff
*/
+#ifndef PLATFORM_EFI
#define SECTOR_SIZE 0x200
#define SECTOR_BITS 9
+#endif /* PLATFORM_EFI */
#define BIOS_FLAG_FIXED_DISK 0x80
#define BOOTSEC_LOCATION RAW_ADDR (0x7C00)
@@ -840,6 +842,8 @@ int get_diskinfo (int drive, struct geometry *geometry);
int biosdisk (int subfunc, int drive, struct geometry *geometry,
int sector, int nsec, int segment);
void stop_floppy (void);
+int get_sector_size (int drive);
+int get_sector_bits (int drive);
/* Command-line interface functions. */
#ifndef STAGE1_5
--
1.7.2.2