From 7c4acb25398883f9cd474b32f0cde084d9b30f38 Mon Sep 17 00:00:00 2001 From: okuji Date: Wed, 16 Feb 2000 11:14:36 +0000 Subject: [PATCH] pass the boot partition information to a chain-loader, in the partition table area of the loader. --- ChangeLog | 26 ++++++++++++++++++++++++++ stage2/builtins.c | 31 ++++++++++++++++++++++++++----- stage2/disk_io.c | 29 +++++++++++++++++------------ stage2/shared.h | 2 ++ 4 files changed, 71 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index f3cd4c590..99024d595 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +2000-02-16 OKUJI Yoshinori + + Pass the boot partition information to a chain-loader, in the + partition table area of the loader, instead of right before the + loaded address. Reported by takehiro@coral.ocn.ne.jp (Takehiro + Suzuki). + + * stage2/builtins.c (chainloader_func): Embed the partition + table of the boot drive in the partition table area of the + chain-loader, if the boot drive is a hard disk drive. + Pass BOOT_PART_ADDR instead of (BOOTSEC_LOCATION - 16) as the + third argument for the function chain_stage1. + * stage2/disk_io.c [!STAGE1_5] (boot_part_addr): New variable. + [!STAGE1_5] (boot_part_offset): Likewise. + [!STAGE1_5] (cur_part_offset): Likewise. + [!STAGE1_5] (cur_part_addr): Likewise. + [!STAGE1_5] (cur_part_desc): Removed. + (real_open_partition) [!STAGE1_5]: Set CUR_PART_OFFSET and + CUR_PART_ADDR to PART_OFFSET and (BOOTSEC_LOCATION + + PC_SLICE_OFFSET + (i << 4)), respectively. + [!STAGE1_5] (set_bootdev): Set BOOT_PART_OFFSET and + BOOT_PART_ADDR to CUR_PART_OFFSET and CUR_PART_ADDR, + respectively. + * stage2/shared.h (boot_part_addr): Declared. + (boot_part_offset): Likewise. + 2000-02-12 OKUJI Yoshinori * stage2/builtins.c (geometry_func): Attempt to read the first diff --git a/stage2/builtins.c b/stage2/builtins.c index d4d8caa24..590599116 100644 --- a/stage2/builtins.c +++ b/stage2/builtins.c @@ -192,12 +192,12 @@ boot_func (char *arg, int flags) case KERNEL_TYPE_CHAINLOADER: /* Chainloader */ - + /* Check if we should set the int13 handler. */ if (bios_drive_map[0] != 0) { int i; - + /* Search for SAVED_DRIVE. */ for (i = 0; i < DRIVE_MAP_SIZE; i++) { @@ -210,14 +210,35 @@ boot_func (char *arg, int flags) break; } } - + /* Set the handler. This is somewhat dangerous. */ set_int13_handler (bios_drive_map); } - + gateA20 (0); boot_drive = saved_drive; - chain_stage1 (0, BOOTSEC_LOCATION, BOOTSEC_LOCATION - 16); + + /* Copy the boot partition information to the chain-loader, if + BOOT_DRIVE is a hard disk drive. */ + if (boot_drive & 0x80) + { + /* Read the MBR here, because it might be modified + after opening the partition. */ + if (! rawread (boot_drive, boot_part_offset, + 0, SECTOR_SIZE, (char *) SCRATCHADDR)) + { + /* This should never happen. */ + errnum = ERR_READ; + return 0; + } + + /* Need only the partition table. */ + grub_memmove ((char *) BOOTSEC_LOCATION + BOOTSEC_PART_OFFSET, + (char *) SCRATCHADDR + BOOTSEC_PART_OFFSET, + BOOTSEC_PART_LENGTH); + } + + chain_stage1 (0, BOOTSEC_LOCATION, boot_part_addr); break; case KERNEL_TYPE_MULTIBOOT: diff --git a/stage2/disk_io.c b/stage2/disk_io.c index 9343642a1..9c6ece9dd 100644 --- a/stage2/disk_io.c +++ b/stage2/disk_io.c @@ -67,6 +67,13 @@ struct fsys_entry fsys_table[NUM_FSYS + 1] = unsigned long current_drive = 0xFF; unsigned long current_partition; +#ifndef STAGE1_5 +/* The register ESI should contain the address of the partition to be + used for loading a chain-loader when chain-loading the loader. */ +unsigned long boot_part_addr; +unsigned long boot_part_offset; +#endif + /* * Global variables describing details of the filesystem */ @@ -451,17 +458,17 @@ check_BSD_parts (int flags) return 0; } - #ifndef STAGE1_5 -static char cur_part_desc[16]; +static unsigned long cur_part_offset; +static unsigned long cur_part_addr; #endif int real_open_partition (int flags) { - char mbr_buf[SECTOR_SIZE]; int i, part_no, slice_no, ext = 0; - + char mbr_buf[SECTOR_SIZE]; + #ifndef STAGE1_5 /* network drive */ if (current_drive == NETWORK_DRIVE) @@ -527,9 +534,8 @@ real_open_partition (int flags) part_start = part_offset + PC_SLICE_START (mbr_buf, i); part_length = PC_SLICE_LENGTH (mbr_buf, i); #ifndef STAGE1_5 - grub_memmove (cur_part_desc, - mbr_buf + PC_SLICE_OFFSET + (i << 4), - 16); + cur_part_offset = part_offset; + cur_part_addr = BOOTSEC_LOCATION + PC_SLICE_OFFSET + (i << 4); #endif /* @@ -848,11 +854,10 @@ set_bootdev (int hdbias) { int i, j; - /* - * Set chainloader boot device. - */ - memmove ((char *) (BOOTSEC_LOCATION - 16), cur_part_desc, 16); - + /* Save the boot partition for chain-loading. */ + boot_part_offset = cur_part_offset; + boot_part_addr = cur_part_addr; + /* * Set BSD boot device. */ diff --git a/stage2/shared.h b/stage2/shared.h index 3d0a49a69..971d01e5c 100644 --- a/stage2/shared.h +++ b/stage2/shared.h @@ -415,6 +415,8 @@ typedef enum extern unsigned long install_partition; extern unsigned long boot_drive; +extern unsigned long boot_part_addr; +extern unsigned long boot_part_offset; extern char version_string[]; extern char config_file[];