Terminate UNDI and PXE before launching the payload to avoid problems
with DMA. * grub-core/commands/boot.c (grub_loader_noreturn): Rename to ... (grub_loader_flags): ... this. All users updated. (grub_loader_boot): Check for GRUB_LOADER_FLAG_NORETURN. * grub-core/loader/i386/pc/pxechainloader.c (grub_cmd_pxechain): Mark loader as GRUB_LOADER_FLAG_PXE_NOT_UNLOAD. * grub-core/net/drivers/i386/pc/pxe.c (grub_pxe_shutdown): New function. (grub_pxe_restore): Likewise. (fini_hnd): New var. (GRUB_MOD_INIT): Register shutdown hook. (GRUB_MOD_FINI): Shutdown and unregister shutdown hook. * include/grub/loader.h (GRUB_LOADER_FLAG_NORETURN): New const. (GRUB_LOADER_FLAG_PXE_NOT_UNLOAD): Likewise. (grub_loader_set): Rename second argument to flags.
This commit is contained in:
parent
851ffadac2
commit
3c491b479c
5 changed files with 75 additions and 12 deletions
20
ChangeLog
20
ChangeLog
|
@ -1,3 +1,23 @@
|
||||||
|
2012-04-11 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Terminate UNDI and PXE before launching the payload to avoid problems
|
||||||
|
with DMA.
|
||||||
|
|
||||||
|
* grub-core/commands/boot.c (grub_loader_noreturn): Rename to ...
|
||||||
|
(grub_loader_flags): ... this. All users updated.
|
||||||
|
(grub_loader_boot): Check for GRUB_LOADER_FLAG_NORETURN.
|
||||||
|
* grub-core/loader/i386/pc/pxechainloader.c (grub_cmd_pxechain): Mark
|
||||||
|
loader as GRUB_LOADER_FLAG_PXE_NOT_UNLOAD.
|
||||||
|
* grub-core/net/drivers/i386/pc/pxe.c (grub_pxe_shutdown): New
|
||||||
|
function.
|
||||||
|
(grub_pxe_restore): Likewise.
|
||||||
|
(fini_hnd): New var.
|
||||||
|
(GRUB_MOD_INIT): Register shutdown hook.
|
||||||
|
(GRUB_MOD_FINI): Shutdown and unregister shutdown hook.
|
||||||
|
* include/grub/loader.h (GRUB_LOADER_FLAG_NORETURN): New const.
|
||||||
|
(GRUB_LOADER_FLAG_PXE_NOT_UNLOAD): Likewise.
|
||||||
|
(grub_loader_set): Rename second argument to flags.
|
||||||
|
|
||||||
2012-04-07 Vladimir Serbinenko <phcoder@gmail.com>
|
2012-04-07 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
* grub-core/normal/charset.c (grub_ucs4_to_utf8): Return number of
|
* grub-core/normal/charset.c (grub_ucs4_to_utf8): Return number of
|
||||||
|
|
|
@ -29,7 +29,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
static grub_err_t (*grub_loader_boot_func) (void);
|
static grub_err_t (*grub_loader_boot_func) (void);
|
||||||
static grub_err_t (*grub_loader_unload_func) (void);
|
static grub_err_t (*grub_loader_unload_func) (void);
|
||||||
static int grub_loader_noreturn;
|
static int grub_loader_flags;
|
||||||
|
|
||||||
struct grub_preboot
|
struct grub_preboot
|
||||||
{
|
{
|
||||||
|
@ -52,7 +52,7 @@ grub_loader_is_loaded (void)
|
||||||
|
|
||||||
/* Register a preboot hook. */
|
/* Register a preboot hook. */
|
||||||
struct grub_preboot *
|
struct grub_preboot *
|
||||||
grub_loader_register_preboot_hook (grub_err_t (*preboot_func) (int noreturn),
|
grub_loader_register_preboot_hook (grub_err_t (*preboot_func) (int flags),
|
||||||
grub_err_t (*preboot_rest_func) (void),
|
grub_err_t (*preboot_rest_func) (void),
|
||||||
grub_loader_preboot_hook_prio_t prio)
|
grub_loader_preboot_hook_prio_t prio)
|
||||||
{
|
{
|
||||||
|
@ -112,14 +112,14 @@ grub_loader_unregister_preboot_hook (struct grub_preboot *hnd)
|
||||||
void
|
void
|
||||||
grub_loader_set (grub_err_t (*boot) (void),
|
grub_loader_set (grub_err_t (*boot) (void),
|
||||||
grub_err_t (*unload) (void),
|
grub_err_t (*unload) (void),
|
||||||
int noreturn)
|
int flags)
|
||||||
{
|
{
|
||||||
if (grub_loader_loaded && grub_loader_unload_func)
|
if (grub_loader_loaded && grub_loader_unload_func)
|
||||||
grub_loader_unload_func ();
|
grub_loader_unload_func ();
|
||||||
|
|
||||||
grub_loader_boot_func = boot;
|
grub_loader_boot_func = boot;
|
||||||
grub_loader_unload_func = unload;
|
grub_loader_unload_func = unload;
|
||||||
grub_loader_noreturn = noreturn;
|
grub_loader_flags = flags;
|
||||||
|
|
||||||
grub_loader_loaded = 1;
|
grub_loader_loaded = 1;
|
||||||
}
|
}
|
||||||
|
@ -146,12 +146,12 @@ grub_loader_boot (void)
|
||||||
return grub_error (GRUB_ERR_NO_KERNEL,
|
return grub_error (GRUB_ERR_NO_KERNEL,
|
||||||
N_("you need to load the kernel first"));
|
N_("you need to load the kernel first"));
|
||||||
|
|
||||||
if (grub_loader_noreturn)
|
if (grub_loader_flags & GRUB_LOADER_FLAG_NORETURN)
|
||||||
grub_machine_fini ();
|
grub_machine_fini ();
|
||||||
|
|
||||||
for (cur = preboots_head; cur; cur = cur->next)
|
for (cur = preboots_head; cur; cur = cur->next)
|
||||||
{
|
{
|
||||||
err = cur->preboot_func (grub_loader_noreturn);
|
err = cur->preboot_func (grub_loader_flags);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
for (cur = cur->prev; cur; cur = cur->prev)
|
for (cur = cur->prev; cur; cur = cur->prev)
|
||||||
|
|
|
@ -139,7 +139,8 @@ grub_cmd_pxechain (grub_command_t cmd __attribute__ ((unused)),
|
||||||
if (grub_file_read (file, image, imagesize) != (grub_ssize_t) imagesize)
|
if (grub_file_read (file, image, imagesize) != (grub_ssize_t) imagesize)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
grub_loader_set (grub_pxechain_boot, grub_pxechain_unload, 1);
|
grub_loader_set (grub_pxechain_boot, grub_pxechain_unload,
|
||||||
|
GRUB_LOADER_FLAG_NORETURN | GRUB_LOADER_FLAG_PXE_NOT_UNLOAD);
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/env.h>
|
#include <grub/env.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/loader.h>
|
||||||
|
|
||||||
#include <grub/machine/pxe.h>
|
#include <grub/machine/pxe.h>
|
||||||
#include <grub/machine/int.h>
|
#include <grub/machine/int.h>
|
||||||
|
@ -311,6 +312,36 @@ struct grub_net_card grub_pxe_card =
|
||||||
.name = "pxe"
|
.name = "pxe"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_pxe_shutdown (int flags)
|
||||||
|
{
|
||||||
|
if (flags & GRUB_LOADER_FLAG_PXE_NOT_UNLOAD)
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
if (!pxe_rm_entry)
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
|
||||||
|
grub_pxe_call (GRUB_PXENV_UNDI_CLOSE,
|
||||||
|
(void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR,
|
||||||
|
pxe_rm_entry);
|
||||||
|
grub_pxe_call (GRUB_PXENV_UNDI_SHUTDOWN,
|
||||||
|
(void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR,
|
||||||
|
pxe_rm_entry);
|
||||||
|
grub_pxe_call (GRUB_PXENV_UNLOAD_STACK,
|
||||||
|
(void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR,
|
||||||
|
pxe_rm_entry);
|
||||||
|
pxe_rm_entry = 0;
|
||||||
|
grub_net_card_unregister (&grub_pxe_card);
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Nothing we can do. */
|
||||||
|
static grub_err_t
|
||||||
|
grub_pxe_restore (void)
|
||||||
|
{
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
grub_pxe_get_cached (grub_uint16_t type)
|
grub_pxe_get_cached (grub_uint16_t type)
|
||||||
{
|
{
|
||||||
|
@ -340,6 +371,8 @@ grub_pc_net_config_real (char **device, char **path)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct grub_preboot *fini_hnd;
|
||||||
|
|
||||||
GRUB_MOD_INIT(pxe)
|
GRUB_MOD_INIT(pxe)
|
||||||
{
|
{
|
||||||
struct grub_pxe_bangpxe *pxenv;
|
struct grub_pxe_bangpxe *pxenv;
|
||||||
|
@ -374,10 +407,14 @@ GRUB_MOD_INIT(pxe)
|
||||||
|
|
||||||
grub_net_card_register (&grub_pxe_card);
|
grub_net_card_register (&grub_pxe_card);
|
||||||
grub_pc_net_config = grub_pc_net_config_real;
|
grub_pc_net_config = grub_pc_net_config_real;
|
||||||
|
fini_hnd = grub_loader_register_preboot_hook (grub_pxe_shutdown,
|
||||||
|
grub_pxe_restore,
|
||||||
|
GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK);
|
||||||
}
|
}
|
||||||
|
|
||||||
GRUB_MOD_FINI(pxe)
|
GRUB_MOD_FINI(pxe)
|
||||||
{
|
{
|
||||||
grub_pc_net_config = 0;
|
grub_pc_net_config = 0;
|
||||||
grub_net_card_unregister (&grub_pxe_card);
|
grub_pxe_shutdown (0);
|
||||||
|
grub_loader_unregister_preboot_hook (fini_hnd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,11 +28,16 @@
|
||||||
/* Check if a loader is loaded. */
|
/* Check if a loader is loaded. */
|
||||||
int EXPORT_FUNC (grub_loader_is_loaded) (void);
|
int EXPORT_FUNC (grub_loader_is_loaded) (void);
|
||||||
|
|
||||||
/* Set loader functions. NORETURN must be set to true, if BOOT won't return
|
/* Set loader functions. */
|
||||||
to the original state. */
|
enum
|
||||||
|
{
|
||||||
|
GRUB_LOADER_FLAG_NORETURN = 1,
|
||||||
|
GRUB_LOADER_FLAG_PXE_NOT_UNLOAD = 2,
|
||||||
|
};
|
||||||
|
|
||||||
void EXPORT_FUNC (grub_loader_set) (grub_err_t (*boot) (void),
|
void EXPORT_FUNC (grub_loader_set) (grub_err_t (*boot) (void),
|
||||||
grub_err_t (*unload) (void),
|
grub_err_t (*unload) (void),
|
||||||
int noreturn);
|
int flags);
|
||||||
|
|
||||||
/* Unset current loader, if any. */
|
/* Unset current loader, if any. */
|
||||||
void EXPORT_FUNC (grub_loader_unset) (void);
|
void EXPORT_FUNC (grub_loader_unset) (void);
|
||||||
|
|
Loading…
Reference in a new issue