1
/* boot.c - command to boot an operating system */
3
* GRUB -- GRand Unified Bootloader
4
* Copyright (C) 2002,2003,2004,2005,2007,2009 Free Software Foundation, Inc.
6
* GRUB is free software: you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation, either version 3 of the License, or
9
* (at your option) any later version.
11
* GRUB is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
20
#include <grub/normal.h>
22
#include <grub/misc.h>
23
#include <grub/loader.h>
24
#include <grub/kernel.h>
26
#include <grub/i18n.h>
28
static grub_err_t (*grub_loader_boot_func) (void);
29
static grub_err_t (*grub_loader_unload_func) (void);
30
static int grub_loader_noreturn;
34
grub_err_t (*preboot_func) (int);
35
grub_err_t (*preboot_rest_func) (void);
36
grub_loader_preboot_hook_prio_t prio;
37
struct grub_preboot_t *next;
38
struct grub_preboot_t *prev;
41
static int grub_loader_loaded;
42
static struct grub_preboot_t *preboots_head = 0,
46
grub_loader_is_loaded (void)
48
return grub_loader_loaded;
51
/* Register a preboot hook. */
53
grub_loader_register_preboot_hook (grub_err_t (*preboot_func) (int noreturn),
54
grub_err_t (*preboot_rest_func) (void),
55
grub_loader_preboot_hook_prio_t prio)
57
struct grub_preboot_t *cur, *new_preboot;
59
if (! preboot_func && ! preboot_rest_func)
62
new_preboot = (struct grub_preboot_t *)
63
grub_malloc (sizeof (struct grub_preboot_t));
66
grub_error (GRUB_ERR_OUT_OF_MEMORY, "hook not added");
70
new_preboot->preboot_func = preboot_func;
71
new_preboot->preboot_rest_func = preboot_rest_func;
72
new_preboot->prio = prio;
74
for (cur = preboots_head; cur && cur->prio > prio; cur = cur->next);
78
new_preboot->next = cur;
79
new_preboot->prev = cur->prev;
80
cur->prev = new_preboot;
84
new_preboot->next = 0;
85
new_preboot->prev = preboots_tail;
86
preboots_tail = new_preboot;
88
if (new_preboot->prev)
89
new_preboot->prev->next = new_preboot;
91
preboots_head = new_preboot;
97
grub_loader_unregister_preboot_hook (void *hnd)
99
struct grub_preboot_t *preb = hnd;
102
preb->next->prev = preb->prev;
104
preboots_tail = preb->prev;
106
preb->prev->next = preb->next;
108
preboots_head = preb->next;
114
grub_loader_set (grub_err_t (*boot) (void),
115
grub_err_t (*unload) (void),
118
if (grub_loader_loaded && grub_loader_unload_func)
119
grub_loader_unload_func ();
121
grub_loader_boot_func = boot;
122
grub_loader_unload_func = unload;
123
grub_loader_noreturn = noreturn;
125
grub_loader_loaded = 1;
129
grub_loader_unset(void)
131
if (grub_loader_loaded && grub_loader_unload_func)
132
grub_loader_unload_func ();
134
grub_loader_boot_func = 0;
135
grub_loader_unload_func = 0;
137
grub_loader_loaded = 0;
141
grub_loader_boot (void)
143
grub_err_t err = GRUB_ERR_NONE;
144
struct grub_preboot_t *cur;
146
if (! grub_loader_loaded)
147
return grub_error (GRUB_ERR_NO_KERNEL, "no loaded kernel");
149
if (grub_loader_noreturn)
150
grub_machine_fini ();
152
for (cur = preboots_head; cur; cur = cur->next)
154
err = cur->preboot_func (grub_loader_noreturn);
157
for (cur = cur->prev; cur; cur = cur->prev)
158
cur->preboot_rest_func ();
162
err = (grub_loader_boot_func) ();
164
for (cur = preboots_tail; cur; cur = cur->prev)
166
err = cur->preboot_rest_func ();
168
cur->preboot_rest_func ();
175
grub_cmd_boot (struct grub_command *cmd __attribute__ ((unused)),
176
int argc __attribute__ ((unused)),
177
char *argv[] __attribute__ ((unused)))
179
return grub_loader_boot ();
184
static grub_command_t cmd_boot;
189
grub_register_command ("boot", grub_cmd_boot,
190
0, N_("Boot an operating system."));
195
grub_unregister_command (cmd_boot);