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>
27 static grub_err_t (*grub_loader_boot_func
) (void);
28 static grub_err_t (*grub_loader_unload_func
) (void);
29 static int grub_loader_noreturn
;
33 grub_err_t (*preboot_func
) (int);
34 grub_err_t (*preboot_rest_func
) (void);
35 grub_loader_preboot_hook_prio_t prio
;
36 struct grub_preboot_t
*next
;
37 struct grub_preboot_t
*prev
;
40 static int grub_loader_loaded
;
41 static struct grub_preboot_t
*preboots_head
= 0,
45 grub_loader_is_loaded (void)
47 return grub_loader_loaded
;
50 /* Register a preboot hook. */
52 grub_loader_register_preboot_hook (grub_err_t (*preboot_func
) (int noreturn
),
53 grub_err_t (*preboot_rest_func
) (void),
54 grub_loader_preboot_hook_prio_t prio
)
56 struct grub_preboot_t
*cur
, *new_preboot
;
58 if (! preboot_func
&& ! preboot_rest_func
)
61 new_preboot
= (struct grub_preboot_t
*)
62 grub_malloc (sizeof (struct grub_preboot_t
));
65 grub_error (GRUB_ERR_OUT_OF_MEMORY
, "hook not added");
69 new_preboot
->preboot_func
= preboot_func
;
70 new_preboot
->preboot_rest_func
= preboot_rest_func
;
71 new_preboot
->prio
= prio
;
73 for (cur
= preboots_head
; cur
&& cur
->prio
> prio
; cur
= cur
->next
);
77 new_preboot
->next
= cur
;
78 new_preboot
->prev
= cur
->prev
;
79 cur
->prev
= new_preboot
;
83 new_preboot
->next
= 0;
84 new_preboot
->prev
= preboots_tail
;
85 preboots_tail
= new_preboot
;
87 if (new_preboot
->prev
)
88 new_preboot
->prev
->next
= new_preboot
;
90 preboots_head
= new_preboot
;
96 grub_loader_unregister_preboot_hook (void *hnd
)
98 struct grub_preboot_t
*preb
= hnd
;
101 preb
->next
->prev
= preb
->prev
;
103 preboots_tail
= preb
->prev
;
105 preb
->prev
->next
= preb
->next
;
107 preboots_head
= preb
->next
;
113 grub_loader_set (grub_err_t (*boot
) (void),
114 grub_err_t (*unload
) (void),
117 if (grub_loader_loaded
&& grub_loader_unload_func
)
118 grub_loader_unload_func ();
120 grub_loader_boot_func
= boot
;
121 grub_loader_unload_func
= unload
;
122 grub_loader_noreturn
= noreturn
;
124 grub_loader_loaded
= 1;
128 grub_loader_unset(void)
130 if (grub_loader_loaded
&& grub_loader_unload_func
)
131 grub_loader_unload_func ();
133 grub_loader_boot_func
= 0;
134 grub_loader_unload_func
= 0;
136 grub_loader_loaded
= 0;
140 grub_loader_boot (void)
142 grub_err_t err
= GRUB_ERR_NONE
;
143 struct grub_preboot_t
*cur
;
145 if (! grub_loader_loaded
)
146 return grub_error (GRUB_ERR_NO_KERNEL
, "no loaded kernel");
148 if (grub_loader_noreturn
)
149 grub_machine_fini ();
151 for (cur
= preboots_head
; cur
; cur
= cur
->next
)
153 err
= cur
->preboot_func (grub_loader_noreturn
);
156 for (cur
= cur
->prev
; cur
; cur
= cur
->prev
)
157 cur
->preboot_rest_func ();
161 err
= (grub_loader_boot_func
) ();
163 for (cur
= preboots_tail
; cur
; cur
= cur
->prev
)
165 err
= cur
->preboot_rest_func ();
167 cur
->preboot_rest_func ();
174 grub_cmd_boot (struct grub_command
*cmd
__attribute__ ((unused
)),
175 int argc
__attribute__ ((unused
)),
176 char *argv
[] __attribute__ ((unused
)))
178 return grub_loader_boot ();
183 static grub_command_t cmd_boot
;
188 grub_register_command ("boot", grub_cmd_boot
,
189 0, "boot an operating system");
194 grub_unregister_command (cmd_boot
);