2018-07-12 14:56:34 +00:00
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
2018-07-10 19:08:14 +00:00
|
|
|
From: "C. Masloch" <pushbx@38.de>
|
|
|
|
Date: Thu, 1 Feb 2018 15:51:55 +0100
|
|
|
|
Subject: [PATCH] chainloader: patch in BPB's sectors_per_track and num_heads
|
|
|
|
|
|
|
|
These fields must reflect the ROM-BIOS's geometry for CHS-based
|
|
|
|
loaders to correctly load their next stage. Most loaders do not
|
|
|
|
query the ROM-BIOS (Int13.08), relying on the BPB fields to hold
|
|
|
|
the correct values already.
|
|
|
|
|
|
|
|
Tested with lDebug booted in qemu via grub2's
|
|
|
|
FreeDOS direct loading support, refer to
|
|
|
|
https://bitbucket.org/ecm/ldosboot + https://bitbucket.org/ecm/ldebug
|
|
|
|
(For this test, lDebug's iniload.asm must be assembled with
|
|
|
|
-D_QUERY_GEOMETRY=0 to leave the BPB values provided by grub.)
|
|
|
|
|
|
|
|
Signed-off-by: C. Masloch <pushbx@38.de>
|
|
|
|
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
|
|
---
|
|
|
|
grub-core/loader/i386/pc/chainloader.c | 20 ++++++++++++++++++--
|
|
|
|
1 file changed, 18 insertions(+), 2 deletions(-)
|
|
|
|
|
|
|
|
diff --git a/grub-core/loader/i386/pc/chainloader.c b/grub-core/loader/i386/pc/chainloader.c
|
|
|
|
index 18220b7aaab..ef3a322b78c 100644
|
|
|
|
--- a/grub-core/loader/i386/pc/chainloader.c
|
|
|
|
+++ b/grub-core/loader/i386/pc/chainloader.c
|
|
|
|
@@ -19,6 +19,7 @@
|
|
|
|
|
|
|
|
#include <grub/loader.h>
|
|
|
|
#include <grub/machine/chainloader.h>
|
|
|
|
+#include <grub/machine/biosdisk.h>
|
|
|
|
#include <grub/machine/memory.h>
|
|
|
|
#include <grub/file.h>
|
|
|
|
#include <grub/err.h>
|
|
|
|
@@ -86,9 +87,16 @@ grub_chainloader_unload (void)
|
|
|
|
void
|
|
|
|
grub_chainloader_patch_bpb (void *bs, grub_device_t dev, grub_uint8_t dl)
|
|
|
|
{
|
|
|
|
- grub_uint32_t part_start = 0;
|
|
|
|
+ grub_uint32_t part_start = 0, heads = 0, sectors = 0;
|
|
|
|
if (dev && dev->disk)
|
|
|
|
- part_start = grub_partition_get_start (dev->disk->partition);
|
|
|
|
+ {
|
|
|
|
+ part_start = grub_partition_get_start (dev->disk->partition);
|
|
|
|
+ if (dev->disk->data)
|
|
|
|
+ {
|
|
|
|
+ heads = ((struct grub_biosdisk_data *)(dev->disk->data))->heads;
|
|
|
|
+ sectors = ((struct grub_biosdisk_data *)(dev->disk->data))->sectors;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
if (grub_memcmp ((char *) &((struct grub_ntfs_bpb *) bs)->oem_name,
|
|
|
|
"NTFS", 4) == 0)
|
|
|
|
{
|
|
|
|
@@ -127,12 +135,20 @@ grub_chainloader_patch_bpb (void *bs, grub_device_t dev, grub_uint8_t dl)
|
|
|
|
{
|
|
|
|
bpb->num_hidden_sectors = grub_cpu_to_le32 (part_start);
|
|
|
|
bpb->version_specific.fat12_or_fat16.num_ph_drive = dl;
|
|
|
|
+ if (sectors)
|
|
|
|
+ bpb->sectors_per_track = grub_cpu_to_le16 (sectors);
|
|
|
|
+ if (heads)
|
|
|
|
+ bpb->num_heads = grub_cpu_to_le16 (heads);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (bpb->version_specific.fat32.sectors_per_fat_32)
|
|
|
|
{
|
|
|
|
bpb->num_hidden_sectors = grub_cpu_to_le32 (part_start);
|
|
|
|
bpb->version_specific.fat32.num_ph_drive = dl;
|
|
|
|
+ if (sectors)
|
|
|
|
+ bpb->sectors_per_track = grub_cpu_to_le16 (sectors);
|
|
|
|
+ if (heads)
|
|
|
|
+ bpb->num_heads = grub_cpu_to_le16 (heads);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
break;
|