Many shipped Windows created it's first partition aligned in 63
(cylinder) and therefore can't offer enough room for core.img. Even
worse the partitions has been created as logical.

 > sudo /sbin/fdisk -l 
Disk /dev/sda: 64.4 GB, 64424509440 bytes, 125829120 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x0001c622

   Device Boot      Start         End      Blocks   Id  System
   /dev/sda1              63     2056319     1028128+   b  W95 FAT32
   /dev/sda2   *     2058240   125829119    61885440    f  W95 Ext'd
   (LBA)
   /dev/sda5         2060288     5302271     1620992   82  Linux swap /
   Solaris
   /dev/sda6         5304320    47247359    20971520   83  Linux
   /dev/sda7        47249408   125804543    39277568   83  Linux

This leaves us currently no option to succeed in installation if boot is
on btrfs, or any other filesystems that block lists can't be used and
core.img must be embedded in order to be reliably addressed.

The attached patch try to workaround this scenario by placing the core.img
in filesystem's (btrfs) bootloader embedding area if available to overcome
the too small MBR gap which gets loaded by boot.img placed in MBR.

Please kindly review the patch or suggests for how to fix this scenario
sanely.

Thanks.
Michael
Index: grub-2.02~beta2/util/setup.c
===================================================================
--- grub-2.02~beta2.orig/util/setup.c
+++ grub-2.02~beta2/util/setup.c
@@ -501,8 +501,44 @@ SETUP (const char *dir,
       err = grub_util_ldm_embed (dest_dev->disk, &nsec, maxsec,
 				 GRUB_EMBED_PCBIOS, &sectors);
     else if (ctx.dest_partmap)
-      err = ctx.dest_partmap->embed (dest_dev->disk, &nsec, maxsec,
-				     GRUB_EMBED_PCBIOS, &sectors);
+      {
+        err = ctx.dest_partmap->embed (dest_dev->disk, &nsec, maxsec,
+				       GRUB_EMBED_PCBIOS, &sectors);
+#ifdef GRUB_SETUP_BIOS
+	if (err == GRUB_ERR_OUT_OF_RANGE
+	    && strcmp (ctx.dest_partmap->name, "msdos") == 0
+	    && dest_dev->disk->id == root_dev->disk->id
+	    && dest_dev->disk->dev->id == root_dev->disk->dev->id)
+	  {
+	    grub_fs_t root_fs;
+
+	    root_fs = grub_fs_probe (root_dev);
+	    if (root_fs && root_fs->embed)
+	      {
+		grub_disk_addr_t *fs_sectors;
+		unsigned int fs_nsec;
+
+		fs_sectors = NULL;
+		fs_nsec = core_sectors;
+		err = root_fs->embed (root_dev, &fs_nsec, maxsec,
+				      GRUB_EMBED_PCBIOS, &fs_sectors);
+		if (!err && fs_nsec >= core_sectors)
+		  {
+		    grub_util_info ("Your msdos embedding area is too small, will use file system embedding area instead");
+		    sectors = fs_sectors;
+		    nsec = fs_nsec;
+		    ctx.container = root_dev->disk->partition;
+		    core_dev = root_dev;
+		  }
+		else
+		  {
+		    if (fs_sectors)
+		      grub_free (fs_sectors);
+		  }
+	      }
+	  }
+#endif
+      }
     else
       err = fs->embed (dest_dev, &nsec, maxsec,
 		       GRUB_EMBED_PCBIOS, &sectors);
@@ -584,7 +620,7 @@ SETUP (const char *dir,
 
     /* Write the core image onto the disk.  */
     for (i = 0; i < nsec; i++)
-      grub_disk_write (dest_dev->disk, sectors[i], 0,
+      grub_disk_write (core_dev->disk, sectors[i], 0,
 		       GRUB_DISK_SECTOR_SIZE,
 		       core_img + i * GRUB_DISK_SECTOR_SIZE);
 
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to