[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