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
20
ChangeLog
20
ChangeLog
|
@ -1,3 +1,23 @@
|
||||||
|
2011-11-12 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
2011-11-12 Vladimir Serbinenko <phcoder@gmail.com>
|
2011-11-12 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
2011-11-12 Colin Watson <cjwatson@ubuntu.com>
|
2011-11-12 Colin Watson <cjwatson@ubuntu.com>
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,6 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/memory.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/memory.h
|
||||||
|
|
||||||
if COND_i386_pc
|
if COND_i386_pc
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/loader.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pxe.h
|
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pxe.h
|
||||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h
|
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h
|
||||||
|
|
|
@ -464,31 +464,6 @@ FUNCTION(grub_exit)
|
||||||
ljmp $0xf000, $0xfff0
|
ljmp $0xf000, $0xfff0
|
||||||
.code32
|
.code32
|
||||||
|
|
||||||
/*
|
|
||||||
* void grub_chainloader_real_boot (int drive, void *part_addr)
|
|
||||||
*
|
|
||||||
* This starts another boot loader.
|
|
||||||
*/
|
|
||||||
|
|
||||||
FUNCTION(grub_chainloader_real_boot)
|
|
||||||
pushl %edx
|
|
||||||
pushl %eax
|
|
||||||
|
|
||||||
/* Turn off Gate A20 */
|
|
||||||
xorl %eax, %eax
|
|
||||||
call grub_gate_a20
|
|
||||||
|
|
||||||
/* set up to pass boot drive */
|
|
||||||
popl %edx
|
|
||||||
|
|
||||||
/* ESI must point to a partition table entry */
|
|
||||||
popl %esi
|
|
||||||
|
|
||||||
call prot_to_real
|
|
||||||
.code16
|
|
||||||
ljmp $0, $GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR
|
|
||||||
.code32
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* void grub_console_putchar (int c)
|
* void grub_console_putchar (int c)
|
||||||
*
|
*
|
||||||
|
|
|
@ -49,6 +49,7 @@ grub_reboot (void)
|
||||||
state.sp = 0;
|
state.sp = 0;
|
||||||
state.cs = segment;
|
state.cs = segment;
|
||||||
state.ip = 0;
|
state.ip = 0;
|
||||||
|
state.a20 = 0;
|
||||||
|
|
||||||
grub_stop_floppy ();
|
grub_stop_floppy ();
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,9 @@ extern grub_uint16_t grub_relocator16_ss;
|
||||||
extern grub_uint16_t grub_relocator16_sp;
|
extern grub_uint16_t grub_relocator16_sp;
|
||||||
extern grub_uint32_t grub_relocator16_edx;
|
extern grub_uint32_t grub_relocator16_edx;
|
||||||
extern grub_uint32_t grub_relocator16_ebx;
|
extern grub_uint32_t grub_relocator16_ebx;
|
||||||
|
extern grub_uint32_t grub_relocator16_esi;
|
||||||
|
|
||||||
|
extern grub_uint16_t grub_relocator16_keep_a20_enabled;
|
||||||
|
|
||||||
extern grub_uint8_t grub_relocator32_start;
|
extern grub_uint8_t grub_relocator32_start;
|
||||||
extern grub_uint8_t grub_relocator32_end;
|
extern grub_uint8_t grub_relocator32_end;
|
||||||
|
@ -195,7 +198,8 @@ grub_relocator16_boot (struct grub_relocator *rel,
|
||||||
void *relst;
|
void *relst;
|
||||||
grub_relocator_chunk_t ch;
|
grub_relocator_chunk_t ch;
|
||||||
|
|
||||||
err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
|
/* Put it higher than the byte it checks for A20 check. */
|
||||||
|
err = grub_relocator_alloc_chunk_align (rel, &ch, 0x8010,
|
||||||
0xa0000 - RELOCATOR_SIZEOF (16),
|
0xa0000 - RELOCATOR_SIZEOF (16),
|
||||||
RELOCATOR_SIZEOF (16), 16,
|
RELOCATOR_SIZEOF (16), 16,
|
||||||
GRUB_RELOCATOR_PREFERENCE_NONE);
|
GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||||
|
@ -215,6 +219,9 @@ grub_relocator16_boot (struct grub_relocator *rel,
|
||||||
|
|
||||||
grub_relocator16_ebx = state.ebx;
|
grub_relocator16_ebx = state.ebx;
|
||||||
grub_relocator16_edx = state.edx;
|
grub_relocator16_edx = state.edx;
|
||||||
|
grub_relocator16_esi = state.esi;
|
||||||
|
|
||||||
|
grub_relocator16_keep_a20_enabled = state.a20;
|
||||||
|
|
||||||
grub_memmove (get_virtual_current_address (ch), &grub_relocator16_start,
|
grub_memmove (get_virtual_current_address (ch), &grub_relocator16_start,
|
||||||
RELOCATOR_SIZEOF (16));
|
RELOCATOR_SIZEOF (16));
|
||||||
|
|
|
@ -93,6 +93,85 @@ LOCAL(segment):
|
||||||
.word 0
|
.word 0
|
||||||
|
|
||||||
LOCAL(cont3):
|
LOCAL(cont3):
|
||||||
|
|
||||||
|
/* movw imm16, %ax. */
|
||||||
|
.byte 0xb8
|
||||||
|
VARIABLE(grub_relocator16_keep_a20_enabled)
|
||||||
|
.word 0
|
||||||
|
test %ax, %ax
|
||||||
|
jnz LOCAL(gate_a20_done)
|
||||||
|
|
||||||
|
/* first of all, test if already in a good state */
|
||||||
|
call LOCAL(gate_a20_check_state)
|
||||||
|
testb %al, %al
|
||||||
|
jz LOCAL(gate_a20_done)
|
||||||
|
|
||||||
|
/* second, try a BIOS call */
|
||||||
|
movw $0x2400, %ax
|
||||||
|
int $0x15
|
||||||
|
|
||||||
|
call LOCAL(gate_a20_check_state)
|
||||||
|
testb %al, %al
|
||||||
|
jz LOCAL(gate_a20_done)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In macbook, the keyboard test would hang the machine, so we move
|
||||||
|
* this forward.
|
||||||
|
*/
|
||||||
|
/* fourth, try the system control port A */
|
||||||
|
inb $0x92
|
||||||
|
andb $(~0x03), %al
|
||||||
|
outb $0x92
|
||||||
|
|
||||||
|
/* When turning off Gate A20, do not check the state strictly,
|
||||||
|
because a failure is not fatal usually, and Gate A20 is always
|
||||||
|
on some modern machines. */
|
||||||
|
jmp LOCAL(gate_a20_done)
|
||||||
|
|
||||||
|
LOCAL(gate_a20_check_state):
|
||||||
|
/* iterate the checking for a while */
|
||||||
|
movw $100, %cx
|
||||||
|
1:
|
||||||
|
call 3f
|
||||||
|
testb %al, %al
|
||||||
|
jz 2f
|
||||||
|
loop 1b
|
||||||
|
2:
|
||||||
|
ret
|
||||||
|
|
||||||
|
3:
|
||||||
|
xorw %ax, %ax
|
||||||
|
movw %ax, %ds
|
||||||
|
decw %ax
|
||||||
|
movw %ax, %es
|
||||||
|
xorw %ax, %ax
|
||||||
|
|
||||||
|
movw $0x8000, %ax
|
||||||
|
/* compare the byte at ADDR with that at 0x100000 + ADDR */
|
||||||
|
movw %ax, %si
|
||||||
|
addw $0x10, %ax
|
||||||
|
movw %ax, %di
|
||||||
|
|
||||||
|
/* save the original byte in DL */
|
||||||
|
movb %ds:(%si), %dl
|
||||||
|
movb %es:(%di), %al
|
||||||
|
/* try to set one less value at ADDR */
|
||||||
|
movb %al, %dh
|
||||||
|
decb %dh
|
||||||
|
movb %dh, %ds:(%si)
|
||||||
|
/* serialize */
|
||||||
|
outb %al, $0x80
|
||||||
|
outb %al, $0x80
|
||||||
|
/* obtain the value at 0x100000 + ADDR in CH */
|
||||||
|
movb %es:(%di), %dh
|
||||||
|
/* this result is 1 if A20 is on or 0 if it is off */
|
||||||
|
subb %dh, %al
|
||||||
|
xorb $1, %al
|
||||||
|
/* restore the original */
|
||||||
|
movb %dl, %es:(%di)
|
||||||
|
ret
|
||||||
|
|
||||||
|
LOCAL(gate_a20_done):
|
||||||
/* we are in real mode now
|
/* we are in real mode now
|
||||||
* set up the real mode segment registers : DS, SS, ES
|
* set up the real mode segment registers : DS, SS, ES
|
||||||
*/
|
*/
|
||||||
|
@ -132,6 +211,12 @@ VARIABLE(grub_relocator16_sp)
|
||||||
.word 0
|
.word 0
|
||||||
movzwl %ax, %esp
|
movzwl %ax, %esp
|
||||||
|
|
||||||
|
/* movw imm32, %eax. */
|
||||||
|
.byte 0x66, 0xb8
|
||||||
|
VARIABLE(grub_relocator16_esi)
|
||||||
|
.long 0
|
||||||
|
movl %eax, %esi
|
||||||
|
|
||||||
/* movw imm32, %edx. */
|
/* movw imm32, %edx. */
|
||||||
.byte 0x66, 0xba
|
.byte 0x66, 0xba
|
||||||
VARIABLE(grub_relocator16_edx)
|
VARIABLE(grub_relocator16_edx)
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <grub/loader.h>
|
#include <grub/loader.h>
|
||||||
#include <grub/machine/loader.h>
|
|
||||||
#include <grub/machine/chainloader.h>
|
#include <grub/machine/chainloader.h>
|
||||||
#include <grub/machine/memory.h>
|
#include <grub/machine/memory.h>
|
||||||
#include <grub/file.h>
|
#include <grub/file.h>
|
||||||
|
@ -39,12 +38,14 @@
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/fat.h>
|
#include <grub/fat.h>
|
||||||
#include <grub/ntfs.h>
|
#include <grub/ntfs.h>
|
||||||
|
#include <grub/i386/relocator.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
static grub_dl_t my_mod;
|
static grub_dl_t my_mod;
|
||||||
static int boot_drive;
|
static int boot_drive;
|
||||||
static void *boot_part_addr;
|
static grub_addr_t boot_part_addr;
|
||||||
|
static struct grub_relocator *rel;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
@ -55,16 +56,29 @@ typedef enum
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_chainloader_boot (void)
|
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_video_set_mode ("text", 0, 0);
|
||||||
grub_chainloader_real_boot (boot_drive, boot_part_addr);
|
|
||||||
|
|
||||||
/* Never reach here. */
|
return grub_relocator16_boot (rel, state);
|
||||||
return GRUB_ERR_NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_chainloader_unload (void)
|
grub_chainloader_unload (void)
|
||||||
{
|
{
|
||||||
|
grub_relocator_unload (rel);
|
||||||
|
rel = NULL;
|
||||||
grub_dl_unref (my_mod);
|
grub_dl_unref (my_mod);
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
@ -133,7 +147,12 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags)
|
||||||
grub_uint16_t signature;
|
grub_uint16_t signature;
|
||||||
grub_device_t dev;
|
grub_device_t dev;
|
||||||
int drive = -1;
|
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);
|
grub_dl_ref (my_mod);
|
||||||
|
|
||||||
|
@ -142,8 +161,25 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags)
|
||||||
if (! file)
|
if (! file)
|
||||||
goto fail;
|
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. */
|
/* 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)
|
!= GRUB_DISK_SECTOR_SIZE)
|
||||||
{
|
{
|
||||||
if (grub_errno == GRUB_ERR_NONE)
|
if (grub_errno == GRUB_ERR_NONE)
|
||||||
|
@ -153,7 +189,7 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the signature. */
|
/* 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)
|
if (signature != grub_le_to_cpu16 (0xaa55)
|
||||||
&& ! (flags & GRUB_CHAINLOADER_FORCE))
|
&& ! (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)
|
if (p && grub_strcmp (p->partmap->name, "msdos") == 0)
|
||||||
{
|
{
|
||||||
disk->partition = p->parent;
|
disk->partition = p->parent;
|
||||||
grub_disk_read (disk, p->offset, 446, 64,
|
grub_disk_read (disk, p->offset, 446, 64, ptable);
|
||||||
(void *) GRUB_MEMORY_MACHINE_PART_TABLE_ADDR);
|
part_addr = (GRUB_MEMORY_MACHINE_PART_TABLE_ADDR
|
||||||
part_addr = (void *) (GRUB_MEMORY_MACHINE_PART_TABLE_ADDR
|
+ (p->index << 4));
|
||||||
+ (p->index << 4));
|
|
||||||
disk->partition = p;
|
disk->partition = p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,8 @@ grub_freedos_boot (void)
|
||||||
.ss = GRUB_FREEDOS_STACK_SEGMENT,
|
.ss = GRUB_FREEDOS_STACK_SEGMENT,
|
||||||
.sp = GRUB_FREEDOS_STACK_POINTER,
|
.sp = GRUB_FREEDOS_STACK_POINTER,
|
||||||
.ebx = ebx,
|
.ebx = ebx,
|
||||||
.edx = 0
|
.edx = 0,
|
||||||
|
.a20 = 1
|
||||||
};
|
};
|
||||||
grub_video_set_mode ("text", 0, 0);
|
grub_video_set_mode ("text", 0, 0);
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <grub/loader.h>
|
#include <grub/loader.h>
|
||||||
#include <grub/machine/loader.h>
|
|
||||||
#include <grub/file.h>
|
#include <grub/file.h>
|
||||||
#include <grub/err.h>
|
#include <grub/err.h>
|
||||||
#include <grub/device.h>
|
#include <grub/device.h>
|
||||||
|
@ -61,6 +60,7 @@ grub_linux16_boot (void)
|
||||||
state.sp = GRUB_LINUX_SETUP_STACK;
|
state.sp = GRUB_LINUX_SETUP_STACK;
|
||||||
state.cs = segment + 0x20;
|
state.cs = segment + 0x20;
|
||||||
state.ip = 0;
|
state.ip = 0;
|
||||||
|
state.a20 = 1;
|
||||||
|
|
||||||
grub_video_set_mode ("text", 0, 0);
|
grub_video_set_mode ("text", 0, 0);
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,8 @@ grub_ntldr_boot (void)
|
||||||
.gs = 0,
|
.gs = 0,
|
||||||
.ss = 0,
|
.ss = 0,
|
||||||
.sp = 0x7c00,
|
.sp = 0x7c00,
|
||||||
.edx = edx
|
.edx = edx,
|
||||||
|
.a20 = 1
|
||||||
};
|
};
|
||||||
grub_video_set_mode ("text", 0, 0);
|
grub_video_set_mode ("text", 0, 0);
|
||||||
|
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
/*
|
|
||||||
* GRUB -- GRand Unified Bootloader
|
|
||||||
* Copyright (C) 2002,2003,2004,2007 Free Software Foundation, Inc.
|
|
||||||
*
|
|
||||||
* GRUB is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* GRUB is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef GRUB_LOADER_MACHINE_HEADER
|
|
||||||
#define GRUB_LOADER_MACHINE_HEADER 1
|
|
||||||
|
|
||||||
#include <grub/symbol.h>
|
|
||||||
|
|
||||||
/* This is an asm part of the chainloader. */
|
|
||||||
void EXPORT_FUNC(grub_chainloader_real_boot) (int drive, void *part_addr) __attribute__ ((noreturn));
|
|
||||||
|
|
||||||
#endif /* ! GRUB_LOADER_MACHINE_HEADER */
|
|
|
@ -48,6 +48,8 @@ struct grub_relocator16_state
|
||||||
grub_uint16_t ip;
|
grub_uint16_t ip;
|
||||||
grub_uint32_t ebx;
|
grub_uint32_t ebx;
|
||||||
grub_uint32_t edx;
|
grub_uint32_t edx;
|
||||||
|
grub_uint32_t esi;
|
||||||
|
int a20;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct grub_relocator64_state
|
struct grub_relocator64_state
|
||||||
|
|
Loading…
Reference in a new issue