Index: grub-2.00/grub-core/loader/i386/pc/chainloader.c =================================================================== --- grub-2.00.orig/grub-core/loader/i386/pc/chainloader.c +++ grub-2.00/grub-core/loader/i386/pc/chainloader.c @@ -39,6 +39,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -149,6 +150,7 @@ grub_chainloader_cmd (const char *filena int drive = -1; grub_addr_t part_addr = 0; grub_uint8_t *bs, *ptable; + const char *biosnum; rel = grub_relocator_new (); if (!rel) @@ -198,11 +200,28 @@ grub_chainloader_cmd (const char *filena goto fail; } - grub_file_close (file); - /* Obtain the partition table from the root device. */ - drive = grub_get_root_biosnumber (); - dev = grub_device_open (0); + /* Obtain the partition table from the loaded device. */ + dev = file->device; + biosnum = grub_env_get ("biosnum"); + + if (biosnum) + { + drive = grub_strtoul (biosnum, 0, 0); + } + else + { + if (dev->disk && dev->disk->dev + && dev->disk->dev->id == GRUB_DISK_DEVICE_BIOSDISK_ID) + drive = (int) dev->disk->id; + } + + if (drive == -1) + { + grub_error (GRUB_ERR_BAD_NUMBER, "invalid biosnum"); + goto fail; + } + if (dev && dev->disk && dev->disk->partition) { grub_disk_t disk = dev->disk; @@ -225,15 +244,14 @@ grub_chainloader_cmd (const char *filena if (flags & GRUB_CHAINLOADER_BPB) grub_chainloader_patch_bpb ((void *) 0x7C00, dev, drive); - if (dev) - grub_device_close (dev); - /* Ignore errors. Perhaps it's not fatal. */ grub_errno = GRUB_ERR_NONE; boot_drive = drive; boot_part_addr = part_addr; + grub_file_close (file); + grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 1); return;