1 /* main.c - the kernel main routine */
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2002,2003,2005,2006,2008,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/kernel.h>
21 #include <grub/misc.h>
22 #include <grub/symbol.h>
24 #include <grub/term.h>
25 #include <grub/file.h>
26 #include <grub/device.h>
29 #include <grub/command.h>
30 #include <grub/reader.h>
31 #include <grub/parser.h>
33 /* This is actualy platform-independant but used only on loongson and sparc. */
34 #if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_SPARC64)
36 grub_modules_get_end (void)
38 struct grub_module_info
*modinfo
;
40 modinfo
= (struct grub_module_info
*) grub_modbase
;
42 /* Check if there are any modules. */
43 if ((modinfo
== 0) || modinfo
->magic
!= GRUB_MODULE_MAGIC
)
46 return grub_modbase
+ modinfo
->size
;
50 /* Load all modules in core. */
52 grub_load_modules (void)
54 struct grub_module_header
*header
;
57 /* Not an ELF module, skip. */
58 if (header
->type
!= OBJ_TYPE_ELF
)
61 if (! grub_dl_load_core ((char *) header
+ sizeof (struct grub_module_header
),
62 (header
->size
- sizeof (struct grub_module_header
))))
63 grub_fatal ("%s", grub_errmsg
);
71 grub_load_config (void)
73 struct grub_module_header
*header
;
76 /* Not an embedded config, skip. */
77 if (header
->type
!= OBJ_TYPE_CONFIG
)
80 grub_parser_execute ((char *) header
+
81 sizeof (struct grub_module_header
));
86 /* Write hook for the environment variables of root. Remove surrounding
87 parentheses, if any. */
89 grub_env_write_root (struct grub_env_var
*var
__attribute__ ((unused
)),
92 /* XXX Is it better to check the existence of the device? */
93 grub_size_t len
= grub_strlen (val
);
95 if (val
[0] == '(' && val
[len
- 1] == ')')
96 return grub_strndup (val
+ 1, len
- 2);
98 return grub_strdup (val
);
102 grub_set_prefix_and_root (void)
106 char *fwdevice
= NULL
;
109 struct grub_module_header
*header
;
112 if (header
->type
== OBJ_TYPE_PREFIX
)
113 prefix
= (char *) header
+ sizeof (struct grub_module_header
);
115 grub_register_variable_hook ("root", 0, grub_env_write_root
);
120 if (prefix
[0] == '(')
122 pptr
= grub_strrchr (prefix
, ')');
125 device
= grub_strndup (prefix
+ 1, pptr
- prefix
- 1);
132 path
= grub_strdup (pptr
);
134 if ((!device
|| device
[0] == ',' || !device
[0]) || !path
)
135 grub_machine_get_bootlocation (&fwdevice
, &fwpath
);
137 if (!device
&& fwdevice
)
139 else if (fwdevice
&& (device
[0] == ',' || !device
[0]))
141 /* We have a partition, but still need to fill in the drive. */
142 char *comma
, *new_device
;
144 for (comma
= fwdevice
; *comma
; )
146 if (comma
[0] == '\\' && comma
[1] == ',')
157 char *drive
= grub_strndup (fwdevice
, comma
- fwdevice
);
158 new_device
= grub_xasprintf ("%s%s", drive
, device
);
162 new_device
= grub_xasprintf ("%s%s", fwdevice
, device
);
164 grub_free (fwdevice
);
169 grub_free (fwdevice
);
178 prefix_set
= grub_xasprintf ("(%s)%s", device
, path
? : "");
181 grub_env_set ("prefix", prefix_set
);
182 grub_free (prefix_set
);
184 grub_env_set ("root", device
);
192 /* Load the normal mode module and execute the normal mode if possible. */
194 grub_load_normal_mode (void)
196 /* Load the module. */
197 grub_dl_load ("normal");
199 /* Print errors if any. */
203 grub_command_execute ("normal", 0, 0);
206 /* The main routine. */
207 void __attribute__ ((noreturn
))
210 /* First of all, initialize the machine. */
211 grub_machine_init ();
214 grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT
);
215 grub_printf ("Welcome to GRUB!\n\n");
216 grub_setcolorstate (GRUB_TERM_COLOR_STANDARD
);
218 /* Load pre-loaded modules and free the space. */
219 grub_register_exported_symbols ();
220 #ifdef GRUB_LINKER_HAVE_INIT
221 grub_arch_dl_init_linker ();
223 grub_load_modules ();
225 /* It is better to set the root device as soon as possible,
227 grub_set_prefix_and_root ();
228 grub_env_export ("root");
229 grub_env_export ("prefix");
231 grub_register_core_commands ();
234 grub_load_normal_mode ();