[grub] Fix some of the ext2 support
Peter Jones
pjones at fedoraproject.org
Wed Dec 1 20:38:01 UTC 2010
commit 7931c63fb068d0e498998f19bd584a8b223dff04
Author: Peter Jones <pjones at redhat.com>
Date: Wed Dec 1 15:37:43 2010 -0500
Fix some of the ext2 support
grub-0.97-support-4k-sector-size.patch | 925 ++++++++++++++++++++++++++++++++
1 files changed, 925 insertions(+), 0 deletions(-)
---
diff --git a/grub-0.97-support-4k-sector-size.patch b/grub-0.97-support-4k-sector-size.patch
new file mode 100644
index 0000000..4b0ccc4
--- /dev/null
+++ b/grub-0.97-support-4k-sector-size.patch
@@ -0,0 +1,925 @@
+From a39611033b8f84d5935b7e5f74dcb3150e0be86d Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones at 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 | 6 ++--
+ efi/x86_64/loader/linux.c | 6 ++--
+ 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 | 8 +++--
+ 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, 186 insertions(+), 84 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..499b852 100644
+--- a/efi/ia32/loader/linux.c
++++ b/efi/ia32/loader/linux.c
+@@ -92,7 +92,7 @@ allocate_pages (grub_size_t real_size, grub_size_t prot_size)
+ grub_efi_physical_address_t addr;
+
+ /* Make sure that each size is aligned to a page boundary. */
+- real_size = page_align (real_size + SECTOR_SIZE);
++ real_size = page_align (real_size + get_sector_size(current_drive));
+ prot_size = page_align (prot_size);
+
+ grub_dprintf ("linux", "real_size = %x, prot_size = %x, mmap_size = %x\n",
+@@ -365,7 +365,7 @@ grub_load_linux (char *kernel, char *arg)
+ setup_sects = lh->setup_sects;
+
+ real_size = 0x1000 + grub_strlen(arg);
+- prot_size = grub_file_size () - (setup_sects << SECTOR_BITS) - SECTOR_SIZE;
++ prot_size = grub_file_size () - (setup_sects << get_sector_bits(current_drive)) - get_sector_size(current_drive);
+
+ if (! allocate_pages (real_size, prot_size))
+ goto fail;
+@@ -499,7 +499,7 @@ grub_load_linux (char *kernel, char *arg)
+
+ dest = grub_stpcpy ((char *) real_mode_mem + 0x1000, skip_to(0, arg));
+
+- grub_seek ((setup_sects << SECTOR_BITS) + SECTOR_SIZE);
++ grub_seek ((setup_sects << get_sector_bits(current_drive)) + get_sector_size(current_drive));
+ len = prot_size;
+ if (grub_read ((char *) GRUB_LINUX_BZIMAGE_ADDR, len) != len)
+ grub_printf ("Couldn't read file");
+diff --git a/efi/x86_64/loader/linux.c b/efi/x86_64/loader/linux.c
+index 18746ea..e4358a3 100644
+--- a/efi/x86_64/loader/linux.c
++++ b/efi/x86_64/loader/linux.c
+@@ -87,7 +87,7 @@ allocate_pages (grub_size_t real_size, grub_size_t prot_size)
+ grub_efi_physical_address_t addr;
+
+ /* Make sure that each size is aligned to a page boundary. */
+- real_size = page_align (real_size + SECTOR_SIZE);
++ real_size = page_align (real_size + get_sector_size(current_drive));
+ prot_size = page_align (prot_size);
+
+ grub_dprintf ("linux", "real_size = %x, prot_size = %x, mmap_size = %x\n",
+@@ -316,7 +316,7 @@ grub_load_linux (char *kernel, char *arg)
+ setup_sects = lh->setup_sects;
+
+ real_size = 0x1000 + grub_strlen(arg);
+- prot_size = grub_file_size () - (setup_sects << SECTOR_BITS) - SECTOR_SIZE;
++ prot_size = grub_file_size () - (setup_sects << get_sector_bits(current_drive)) - get_sector_size(current_drive);
+ prot_kernel_size = prot_size;
+
+ if (! allocate_pages (real_size, prot_size))
+@@ -447,7 +447,7 @@ grub_load_linux (char *kernel, char *arg)
+
+ dest = grub_stpcpy ((char *) real_mode_mem + 0x1000, skip_to(0, arg));
+
+- grub_seek ((setup_sects << SECTOR_BITS) + SECTOR_SIZE);
++ grub_seek ((setup_sects << get_sector_bits(current_drive)) + get_sector_size(current_drive));
+ len = prot_size;
+ if (grub_read ((char *)prot_mode_mem, len) != len)
+ grub_printf ("Couldn't read file");
+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..80a1938 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;
+@@ -428,7 +429,8 @@ ext2_rdfsb (int fsblock, int buffer)
+ #ifdef E2DEBUG
+ printf ("fsblock %d buffer %d\n", fsblock, buffer);
+ #endif /* E2DEBUG */
+- return devread (fsblock * (EXT2_BLOCK_SIZE (SUPERBLOCK) / DEV_BSIZE), 0,
++ return devread (fsblock * (EXT2_BLOCK_SIZE (SUPERBLOCK) / DEV_BSIZE),
++ fsblock * (EXT2_BLOCK_SIZE (SUPERBLOCK) % blocksize),
+ EXT2_BLOCK_SIZE (SUPERBLOCK), (char *) (unsigned long) buffer);
+ }
+
+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
+
More information about the scm-commits
mailing list