main.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /* main.c - the kernel main routine */
  2. /*
  3. * GRUB -- GRand Unified Bootloader
  4. * Copyright (C) 2002,2003,2005,2006,2008,2009 Free Software Foundation, Inc.
  5. *
  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.
  10. *
  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.
  15. *
  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/>.
  18. */
  19. #include <grub/kernel.h>
  20. #include <grub/misc.h>
  21. #include <grub/symbol.h>
  22. #include <grub/dl.h>
  23. #include <grub/term.h>
  24. #include <grub/file.h>
  25. #include <grub/device.h>
  26. #include <grub/env.h>
  27. #include <grub/mm.h>
  28. #include <grub/command.h>
  29. #include <grub/reader.h>
  30. #include <grub/parser.h>
  31. #include <grub/controller.h>
  32. #include <grub/menu.h>
  33. GRUB_EXPORT(grub_module_iterate);
  34. GRUB_EXPORT(grub_machine_fini);
  35. GRUB_EXPORT(grub_controller_class);
  36. struct grub_handler_class grub_controller_class =
  37. {
  38. .name = "controller"
  39. };
  40. void
  41. grub_module_iterate (int (*hook) (struct grub_module_header *header))
  42. {
  43. struct grub_module_info *info;
  44. struct grub_module_header *header;
  45. info = &grub_modinfo;
  46. /* Check if there are any modules. */
  47. if (info->magic != GRUB_MODULE_MAGIC)
  48. return;
  49. for (header = (struct grub_module_header *) (info + 1);
  50. header < (struct grub_module_header *) ((char *) info + info->size);
  51. header = (struct grub_module_header *) ((char *) header + header->size))
  52. {
  53. if (hook (header))
  54. break;
  55. }
  56. }
  57. static int
  58. grub_load_modules_hook (struct grub_module_header *header)
  59. {
  60. grub_dl_t mod;
  61. struct grub_module_object *obj;
  62. char *code_start = &grub_code_start[0];
  63. char *name, *sym;
  64. grub_uint32_t *sym_value;
  65. /* Not a module, skip. */
  66. if (header->type != OBJ_TYPE_OBJECT)
  67. return 0;
  68. obj = (struct grub_module_object *) (header + 1);
  69. mod = (grub_dl_t) grub_zalloc (sizeof (*mod));
  70. if (! mod)
  71. grub_fatal ("can't init module");
  72. name = obj->name;
  73. mod->name = grub_strdup (name);
  74. mod->ref_count++;
  75. grub_dl_resolve_dependencies (mod, name);
  76. sym = name + obj->symbol_name;
  77. sym_value = (grub_uint32_t *) (name + obj->symbol_value);
  78. while (*sym)
  79. {
  80. grub_dl_register_symbol (sym, code_start + *(sym_value++), mod);
  81. sym += grub_strlen (sym) + 1;
  82. }
  83. if (obj->init_func)
  84. {
  85. mod->init = (void (*) (grub_dl_t)) (code_start + obj->init_func);
  86. (mod->init) (mod);
  87. }
  88. if (obj->fini_func)
  89. mod->fini = (void (*) (void)) (code_start + obj->fini_func);
  90. grub_dl_add (mod);
  91. return 0;
  92. }
  93. /* Load all modules in core. */
  94. static inline void
  95. grub_load_modules (void)
  96. {
  97. grub_module_iterate (grub_load_modules_hook);
  98. }
  99. static int
  100. grub_load_config_hook (struct grub_module_header *header)
  101. {
  102. /* Not a config, skip. */
  103. if (header->type != OBJ_TYPE_CONFIG)
  104. return 0;
  105. grub_parser_execute ((char *) header +
  106. sizeof (struct grub_module_header));
  107. return 1;
  108. }
  109. static inline void
  110. grub_load_config (void)
  111. {
  112. char *p = grub_arch_menu_addr ();
  113. if (p)
  114. grub_parser_execute (p);
  115. else
  116. grub_module_iterate (grub_load_config_hook);
  117. }
  118. /* Write hook for the environment variables of root. Remove surrounding
  119. parentheses, if any. */
  120. static char *
  121. grub_env_write_root (struct grub_env_var *var __attribute__ ((unused)),
  122. const char *val)
  123. {
  124. /* XXX Is it better to check the existence of the device? */
  125. grub_size_t len = grub_strlen (val);
  126. if (val[0] == '(' && val[len - 1] == ')')
  127. return grub_strndup (val + 1, len - 2);
  128. return grub_strdup (val);
  129. }
  130. /* Set the root device according to the dl prefix. */
  131. static void
  132. grub_set_root_dev (void)
  133. {
  134. const char *prefix;
  135. grub_register_variable_hook ("root", 0, grub_env_write_root);
  136. prefix = grub_env_get ("prefix");
  137. if (prefix)
  138. {
  139. char *dev;
  140. dev = grub_file_get_device_name (prefix);
  141. if (dev)
  142. {
  143. grub_env_set ("root", dev);
  144. grub_free (dev);
  145. }
  146. }
  147. }
  148. /* Load the normal mode module and execute the normal mode if possible. */
  149. static void
  150. grub_load_normal_mode (void)
  151. {
  152. /* Load the module. */
  153. grub_dl_load ("normal");
  154. /* Something went wrong. Print errors here to let user know why we're entering rescue mode. */
  155. grub_print_error ();
  156. grub_errno = 0;
  157. grub_command_execute ("normal", 0, 0);
  158. }
  159. /* The main routine. */
  160. void
  161. grub_main (void)
  162. {
  163. /* First of all, initialize the machine. */
  164. grub_machine_init ();
  165. grub_env_set_menu (grub_zalloc (sizeof (struct grub_menu)));
  166. #if 0
  167. /* Hello. */
  168. grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
  169. grub_printf ("Welcome to GRUB!\n\n");
  170. grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
  171. #endif
  172. /* Load pre-loaded modules and free the space. */
  173. #ifdef GRUB_LINKER_HAVE_INIT
  174. grub_arch_dl_init_linker ();
  175. #endif
  176. grub_load_modules ();
  177. /* It is better to set the root device as soon as possible,
  178. for convenience. */
  179. grub_machine_set_prefix ();
  180. grub_set_root_dev ();
  181. grub_register_core_commands ();
  182. grub_register_rescue_parser ();
  183. grub_load_config ();
  184. grub_load_normal_mode ();
  185. grub_rescue_run ();
  186. }