grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Workaround for usb boot failure on some mainboards


From: Thomas Frauendorfer | Miray Software
Subject: [PATCH] Workaround for usb boot failure on some mainboards
Date: Wed, 22 Sep 2010 11:07:48 +0200
User-agent: Thunderbird 2.0.0.24 (Windows/20100228)

Hi,

On some boards, like the AsRock K7S41GX, Grub fails to boot from superfloppy fat32 formated usb sticks.

The reason for the boot failure is that the bios of the mentioned board replaces byte 0x24 of the bpb with the value 0x00 when it's read through the bios function. In fat16 this byte contains the Disc unit number, so this causes no real harm there. In fat32 this byte is part of the sectors per FAT information, so by modifying this value the bios makes Grub unable to read the fat system.

The attached workaround reads the backup bpb information from the fat32 filesystem and uses the sectors per fat information stored there.


--- ../grub2-upstream/grub2-upstream/grub-core/fs/fat.c 2010-09-21 
12:13:17.154835710 +0200
+++ grub2-merge/grub-core/fs/fat.c      2010-09-22 10:23:27.935482451 +0200
@@ -214,6 +214,29 @@ grub_fat_mount (grub_disk_t disk)
                            ? grub_le_to_cpu16 (bpb.sectors_per_fat_16)
                            : grub_le_to_cpu32 
(bpb.version_specific.fat32.sectors_per_fat_32))
                           << data->logical_sector_bits);
+  if (bpb.sectors_per_fat_16)
+    data->sectors_per_fat = grub_le_to_cpu16 (bpb.sectors_per_fat_16) << 
data->logical_sector_bits;
+  else
+    {
+      /* Workaround for buggy BIOSes which replace offset 0x24 in the bpb 
+         with the drive number. This offset is part of sectors_per_fat_32 in
+         the fat32 structure. 
+         We read the backup bpb (if available) and use the value there */
+      struct grub_fat_bpb backup_bpb;
+      grub_uint32_t backup_bpb_address = grub_le_to_cpu16 
(bpb.version_specific.fat32.backup_boot_sector) << data->logical_sector_bits;
+      if (bpb.version_specific.fat32.backup_boot_sector && 
+         (! grub_disk_read (disk,
+                            backup_bpb_address,
+                            0,
+                            sizeof (backup_bpb),
+                            &backup_bpb)))
+       data->sectors_per_fat = grub_le_to_cpu32 
(backup_bpb.version_specific.fat32.sectors_per_fat_32) << 
data->logical_sector_bits;
+
+      if (data->sectors_per_fat == 0)
+       data->sectors_per_fat = grub_le_to_cpu32 
(bpb.version_specific.fat32.sectors_per_fat_32) << data->logical_sector_bits;
+    }
+
+
   if (data->sectors_per_fat == 0)
     goto fail;
 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]