Move grub_chainloader_real_boot out of the kernel.
* grub-core/Makefile.am: Remove machine/loader.h. * grub-core/kern/i386/pc/startup.S (grub_chainloader_real_boot): Removed. * grub-core/lib/i386/relocator.c (grub_relocator16_esi): New extern variable. (grub_relocator16_keep_a20_enabled): Likewise. (grub_relocator16_boot): Fill new variables. * grub-core/lib/i386/relocator16.S: Add gate a20 handling. * grub-core/loader/i386/pc/chainloader.c (grub_chainloader_boot): Use relocator. (grub_chainloader_unload): Likewise. (grub_chainloader_cmd): Likewise. * include/grub/i386/pc/loader.h: Removed. * include/grub/i386/relocator.h (grub_relocator16_state): Add a20 and esi. All initialisers updated.
This commit is contained in:
commit
678f4b6713
12 changed files with 168 additions and 69 deletions
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
|
||||
#include <grub/loader.h>
|
||||
#include <grub/machine/loader.h>
|
||||
#include <grub/machine/chainloader.h>
|
||||
#include <grub/machine/memory.h>
|
||||
#include <grub/file.h>
|
||||
|
@ -39,12 +38,14 @@
|
|||
#include <grub/mm.h>
|
||||
#include <grub/fat.h>
|
||||
#include <grub/ntfs.h>
|
||||
#include <grub/i386/relocator.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static grub_dl_t my_mod;
|
||||
static int boot_drive;
|
||||
static void *boot_part_addr;
|
||||
static grub_addr_t boot_part_addr;
|
||||
static struct grub_relocator *rel;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -55,16 +56,29 @@ typedef enum
|
|||
static grub_err_t
|
||||
grub_chainloader_boot (void)
|
||||
{
|
||||
struct grub_relocator16_state state = {
|
||||
.edx = boot_drive,
|
||||
.esi = boot_part_addr,
|
||||
.ds = 0,
|
||||
.es = 0,
|
||||
.fs = 0,
|
||||
.gs = 0,
|
||||
.ss = 0,
|
||||
.cs = 0,
|
||||
.sp = GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR,
|
||||
.ip = GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR,
|
||||
.a20 = 0
|
||||
};
|
||||
grub_video_set_mode ("text", 0, 0);
|
||||
grub_chainloader_real_boot (boot_drive, boot_part_addr);
|
||||
|
||||
/* Never reach here. */
|
||||
return GRUB_ERR_NONE;
|
||||
return grub_relocator16_boot (rel, state);
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_chainloader_unload (void)
|
||||
{
|
||||
grub_relocator_unload (rel);
|
||||
rel = NULL;
|
||||
grub_dl_unref (my_mod);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
@ -133,7 +147,12 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags)
|
|||
grub_uint16_t signature;
|
||||
grub_device_t dev;
|
||||
int drive = -1;
|
||||
void *part_addr = 0;
|
||||
grub_addr_t part_addr = 0;
|
||||
grub_uint8_t *bs, *ptable;
|
||||
|
||||
rel = grub_relocator_new ();
|
||||
if (!rel)
|
||||
goto fail;
|
||||
|
||||
grub_dl_ref (my_mod);
|
||||
|
||||
|
@ -142,8 +161,25 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags)
|
|||
if (! file)
|
||||
goto fail;
|
||||
|
||||
{
|
||||
grub_relocator_chunk_t ch;
|
||||
grub_err_t err;
|
||||
|
||||
err = grub_relocator_alloc_chunk_addr (rel, &ch, 0x7C00,
|
||||
GRUB_DISK_SECTOR_SIZE);
|
||||
if (err)
|
||||
goto fail;
|
||||
bs = get_virtual_current_address (ch);
|
||||
err = grub_relocator_alloc_chunk_addr (rel, &ch,
|
||||
GRUB_MEMORY_MACHINE_PART_TABLE_ADDR,
|
||||
64);
|
||||
if (err)
|
||||
goto fail;
|
||||
ptable = get_virtual_current_address (ch);
|
||||
}
|
||||
|
||||
/* Read the first block. */
|
||||
if (grub_file_read (file, (void *) 0x7C00, GRUB_DISK_SECTOR_SIZE)
|
||||
if (grub_file_read (file, bs, GRUB_DISK_SECTOR_SIZE)
|
||||
!= GRUB_DISK_SECTOR_SIZE)
|
||||
{
|
||||
if (grub_errno == GRUB_ERR_NONE)
|
||||
|
@ -153,7 +189,7 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags)
|
|||
}
|
||||
|
||||
/* Check the signature. */
|
||||
signature = *((grub_uint16_t *) (0x7C00 + GRUB_DISK_SECTOR_SIZE - 2));
|
||||
signature = *((grub_uint16_t *) (bs + GRUB_DISK_SECTOR_SIZE - 2));
|
||||
if (signature != grub_le_to_cpu16 (0xaa55)
|
||||
&& ! (flags & GRUB_CHAINLOADER_FORCE))
|
||||
{
|
||||
|
@ -177,10 +213,9 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags)
|
|||
if (p && grub_strcmp (p->partmap->name, "msdos") == 0)
|
||||
{
|
||||
disk->partition = p->parent;
|
||||
grub_disk_read (disk, p->offset, 446, 64,
|
||||
(void *) GRUB_MEMORY_MACHINE_PART_TABLE_ADDR);
|
||||
part_addr = (void *) (GRUB_MEMORY_MACHINE_PART_TABLE_ADDR
|
||||
+ (p->index << 4));
|
||||
grub_disk_read (disk, p->offset, 446, 64, ptable);
|
||||
part_addr = (GRUB_MEMORY_MACHINE_PART_TABLE_ADDR
|
||||
+ (p->index << 4));
|
||||
disk->partition = p;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,8 @@ grub_freedos_boot (void)
|
|||
.ss = GRUB_FREEDOS_STACK_SEGMENT,
|
||||
.sp = GRUB_FREEDOS_STACK_POINTER,
|
||||
.ebx = ebx,
|
||||
.edx = 0
|
||||
.edx = 0,
|
||||
.a20 = 1
|
||||
};
|
||||
grub_video_set_mode ("text", 0, 0);
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
|
||||
#include <grub/loader.h>
|
||||
#include <grub/machine/loader.h>
|
||||
#include <grub/file.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/device.h>
|
||||
|
@ -61,6 +60,7 @@ grub_linux16_boot (void)
|
|||
state.sp = GRUB_LINUX_SETUP_STACK;
|
||||
state.cs = segment + 0x20;
|
||||
state.ip = 0;
|
||||
state.a20 = 1;
|
||||
|
||||
grub_video_set_mode ("text", 0, 0);
|
||||
|
||||
|
|
|
@ -54,7 +54,8 @@ grub_ntldr_boot (void)
|
|||
.gs = 0,
|
||||
.ss = 0,
|
||||
.sp = 0x7c00,
|
||||
.edx = edx
|
||||
.edx = edx,
|
||||
.a20 = 1
|
||||
};
|
||||
grub_video_set_mode ("text", 0, 0);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue