multiboot_mbi2.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119
  1. /*
  2. * GRUB -- GRand Unified Bootloader
  3. * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
  4. *
  5. * GRUB is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * GRUB is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include <grub/memory.h>
  19. #ifdef GRUB_MACHINE_PCBIOS
  20. #include <grub/machine/biosnum.h>
  21. #include <grub/machine/apm.h>
  22. #include <grub/machine/memory.h>
  23. #endif
  24. #include <grub/multiboot2.h>
  25. #include <grub/cpu/multiboot.h>
  26. #include <grub/cpu/relocator.h>
  27. #include <grub/disk.h>
  28. #include <grub/device.h>
  29. #include <grub/partition.h>
  30. #include <grub/mm.h>
  31. #include <grub/misc.h>
  32. #include <grub/env.h>
  33. #include <grub/video.h>
  34. #include <grub/acpi.h>
  35. #include <grub/i18n.h>
  36. #include <grub/net.h>
  37. #include <grub/lib/cmdline.h>
  38. #if defined (GRUB_MACHINE_EFI)
  39. #include <grub/efi/efi.h>
  40. #endif
  41. #if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU)
  42. #include <grub/i386/pc/vbe.h>
  43. #define HAS_VGA_TEXT 1
  44. #else
  45. #define HAS_VGA_TEXT 0
  46. #endif
  47. struct module
  48. {
  49. struct module *next;
  50. grub_addr_t start;
  51. grub_size_t size;
  52. char *cmdline;
  53. int cmdline_size;
  54. };
  55. static struct module *modules, *modules_last;
  56. static grub_size_t cmdline_size;
  57. static grub_size_t total_modcmd;
  58. static unsigned modcnt;
  59. static char *cmdline = NULL;
  60. static int bootdev_set;
  61. static grub_uint32_t biosdev, slice, part;
  62. static grub_size_t elf_sec_num, elf_sec_entsize;
  63. static unsigned elf_sec_shstrndx;
  64. static void *elf_sections;
  65. static int keep_bs = 0;
  66. static grub_uint32_t load_base_addr;
  67. void
  68. grub_multiboot2_add_elfsyms (grub_size_t num, grub_size_t entsize,
  69. unsigned shndx, void *data)
  70. {
  71. elf_sec_num = num;
  72. elf_sec_shstrndx = shndx;
  73. elf_sec_entsize = entsize;
  74. elf_sections = data;
  75. }
  76. static struct multiboot_header *
  77. find_header (grub_properly_aligned_t *buffer, grub_ssize_t len)
  78. {
  79. struct multiboot_header *header;
  80. /* Look for the multiboot header in the buffer. The header should
  81. be at least 12 bytes and aligned on a 4-byte boundary. */
  82. for (header = (struct multiboot_header *) buffer;
  83. ((char *) header <= (char *) buffer + len - 12);
  84. header = (struct multiboot_header *) ((grub_uint32_t *) header + MULTIBOOT_HEADER_ALIGN / 4))
  85. {
  86. if (header->magic == MULTIBOOT2_HEADER_MAGIC
  87. && !(header->magic + header->architecture
  88. + header->header_length + header->checksum)
  89. && header->architecture == MULTIBOOT2_ARCHITECTURE_CURRENT)
  90. return header;
  91. }
  92. return NULL;
  93. }
  94. grub_err_t
  95. grub_multiboot2_load (grub_file_t file, const char *filename)
  96. {
  97. grub_ssize_t len;
  98. struct multiboot_header *header;
  99. grub_err_t err;
  100. struct multiboot_header_tag *tag;
  101. struct multiboot_header_tag_address *addr_tag = NULL;
  102. struct multiboot_header_tag_relocatable *rel_tag;
  103. int entry_specified = 0, efi_entry_specified = 0;
  104. grub_addr_t entry = 0, efi_entry = 0;
  105. grub_uint32_t console_required = 0;
  106. struct multiboot_header_tag_framebuffer *fbtag = NULL;
  107. int accepted_consoles = GRUB_MULTIBOOT2_CONSOLE_EGA_TEXT;
  108. mbi_load_data_t mld;
  109. mld.mbi_ver = 2;
  110. mld.relocatable = 0;
  111. mld.buffer = grub_malloc (MULTIBOOT_SEARCH);
  112. if (!mld.buffer)
  113. return grub_errno;
  114. len = grub_file_read (file, mld.buffer, MULTIBOOT_SEARCH);
  115. if (len < 32)
  116. {
  117. grub_free (mld.buffer);
  118. return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), filename);
  119. }
  120. COMPILE_TIME_ASSERT (MULTIBOOT_HEADER_ALIGN % 4 == 0);
  121. header = find_header (mld.buffer, len);
  122. if (header == 0)
  123. {
  124. grub_free (mld.buffer);
  125. return grub_error (GRUB_ERR_BAD_ARGUMENT, "no multiboot header found");
  126. }
  127. COMPILE_TIME_ASSERT (MULTIBOOT_TAG_ALIGN % 4 == 0);
  128. keep_bs = 0;
  129. for (tag = (struct multiboot_header_tag *) (header + 1);
  130. tag->type != MULTIBOOT_TAG_TYPE_END;
  131. tag = (struct multiboot_header_tag *) ((grub_uint32_t *) tag + ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) / 4))
  132. switch (tag->type)
  133. {
  134. case MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST:
  135. {
  136. unsigned i;
  137. struct multiboot_header_tag_information_request *request_tag
  138. = (struct multiboot_header_tag_information_request *) tag;
  139. if (request_tag->flags & MULTIBOOT_HEADER_TAG_OPTIONAL)
  140. break;
  141. for (i = 0; i < (request_tag->size - sizeof (*request_tag))
  142. / sizeof (request_tag->requests[0]); i++)
  143. switch (request_tag->requests[i])
  144. {
  145. case MULTIBOOT_TAG_TYPE_END:
  146. case MULTIBOOT_TAG_TYPE_CMDLINE:
  147. case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME:
  148. case MULTIBOOT_TAG_TYPE_MODULE:
  149. case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO:
  150. case MULTIBOOT_TAG_TYPE_BOOTDEV:
  151. case MULTIBOOT_TAG_TYPE_MMAP:
  152. case MULTIBOOT_TAG_TYPE_FRAMEBUFFER:
  153. case MULTIBOOT_TAG_TYPE_VBE:
  154. case MULTIBOOT_TAG_TYPE_ELF_SECTIONS:
  155. case MULTIBOOT_TAG_TYPE_APM:
  156. case MULTIBOOT_TAG_TYPE_EFI32:
  157. case MULTIBOOT_TAG_TYPE_EFI64:
  158. case MULTIBOOT_TAG_TYPE_ACPI_OLD:
  159. case MULTIBOOT_TAG_TYPE_ACPI_NEW:
  160. case MULTIBOOT_TAG_TYPE_NETWORK:
  161. case MULTIBOOT_TAG_TYPE_EFI_MMAP:
  162. case MULTIBOOT_TAG_TYPE_EFI_BS:
  163. case MULTIBOOT_TAG_TYPE_EFI32_IH:
  164. case MULTIBOOT_TAG_TYPE_EFI64_IH:
  165. case MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR:
  166. break;
  167. default:
  168. grub_free (mld.buffer);
  169. return grub_error (GRUB_ERR_UNKNOWN_OS,
  170. "unsupported information tag: 0x%x",
  171. request_tag->requests[i]);
  172. }
  173. break;
  174. }
  175. case MULTIBOOT_HEADER_TAG_ADDRESS:
  176. addr_tag = (struct multiboot_header_tag_address *) tag;
  177. break;
  178. case MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS:
  179. entry_specified = 1;
  180. entry = ((struct multiboot_header_tag_entry_address *) tag)->entry_addr;
  181. break;
  182. case MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64:
  183. #if defined (GRUB_MACHINE_EFI) && defined (__x86_64__)
  184. efi_entry_specified = 1;
  185. efi_entry = ((struct multiboot_header_tag_entry_address *) tag)->entry_addr;
  186. #endif
  187. break;
  188. case MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS:
  189. if (!(((struct multiboot_header_tag_console_flags *) tag)->console_flags
  190. & MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED))
  191. accepted_consoles &= ~GRUB_MULTIBOOT2_CONSOLE_EGA_TEXT;
  192. if (((struct multiboot_header_tag_console_flags *) tag)->console_flags
  193. & MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED)
  194. console_required = 1;
  195. break;
  196. case MULTIBOOT_HEADER_TAG_FRAMEBUFFER:
  197. fbtag = (struct multiboot_header_tag_framebuffer *) tag;
  198. accepted_consoles |= GRUB_MULTIBOOT2_CONSOLE_FRAMEBUFFER;
  199. break;
  200. case MULTIBOOT_HEADER_TAG_RELOCATABLE:
  201. mld.relocatable = 1;
  202. rel_tag = (struct multiboot_header_tag_relocatable *) tag;
  203. mld.min_addr = rel_tag->min_addr;
  204. mld.max_addr = rel_tag->max_addr;
  205. mld.align = rel_tag->align;
  206. switch (rel_tag->preference)
  207. {
  208. case MULTIBOOT_LOAD_PREFERENCE_LOW:
  209. mld.preference = GRUB_RELOCATOR_PREFERENCE_LOW;
  210. break;
  211. case MULTIBOOT_LOAD_PREFERENCE_HIGH:
  212. mld.preference = GRUB_RELOCATOR_PREFERENCE_HIGH;
  213. break;
  214. default:
  215. mld.preference = GRUB_RELOCATOR_PREFERENCE_NONE;
  216. }
  217. break;
  218. /* GRUB always page-aligns modules. */
  219. case MULTIBOOT_HEADER_TAG_MODULE_ALIGN:
  220. break;
  221. case MULTIBOOT_HEADER_TAG_EFI_BS:
  222. #ifdef GRUB_MACHINE_EFI
  223. keep_bs = 1;
  224. #endif
  225. break;
  226. default:
  227. if (! (tag->flags & MULTIBOOT_HEADER_TAG_OPTIONAL))
  228. {
  229. grub_free (mld.buffer);
  230. return grub_error (GRUB_ERR_UNKNOWN_OS,
  231. "unsupported tag: 0x%x", tag->type);
  232. }
  233. break;
  234. }
  235. if (addr_tag && !entry_specified && !(keep_bs && efi_entry_specified))
  236. {
  237. grub_free (mld.buffer);
  238. return grub_error (GRUB_ERR_UNKNOWN_OS,
  239. "load address tag without entry address tag");
  240. }
  241. if (addr_tag)
  242. {
  243. grub_uint64_t load_addr = (addr_tag->load_addr + 1)
  244. ? addr_tag->load_addr : (addr_tag->header_addr
  245. - ((char *) header - (char *) mld.buffer));
  246. int offset = ((char *) header - (char *) mld.buffer -
  247. (addr_tag->header_addr - load_addr));
  248. int load_size = ((addr_tag->load_end_addr == 0) ? file->size - offset :
  249. addr_tag->load_end_addr - addr_tag->load_addr);
  250. grub_size_t code_size;
  251. void *source;
  252. grub_relocator_chunk_t ch;
  253. if (addr_tag->bss_end_addr)
  254. code_size = (addr_tag->bss_end_addr - load_addr);
  255. else
  256. code_size = load_size;
  257. if (mld.relocatable)
  258. {
  259. if (code_size > mld.max_addr || mld.min_addr > mld.max_addr - code_size)
  260. {
  261. grub_free (mld.buffer);
  262. return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size");
  263. }
  264. err = grub_relocator_alloc_chunk_align (grub_multiboot2_relocator, &ch,
  265. mld.min_addr, mld.max_addr - code_size,
  266. code_size, mld.align ? mld.align : 1,
  267. mld.preference, keep_bs);
  268. }
  269. else
  270. err = grub_relocator_alloc_chunk_addr (grub_multiboot2_relocator,
  271. &ch, load_addr, code_size);
  272. if (err)
  273. {
  274. grub_dprintf ("multiboot_loader", "Error loading aout kludge\n");
  275. grub_free (mld.buffer);
  276. return err;
  277. }
  278. mld.link_base_addr = load_addr;
  279. mld.load_base_addr = get_physical_target_address (ch);
  280. source = get_virtual_current_address (ch);
  281. grub_dprintf ("multiboot_loader", "link_base_addr=0x%x, load_base_addr=0x%x, "
  282. "load_size=0x%lx, relocatable=%d\n", mld.link_base_addr,
  283. mld.load_base_addr, (long) code_size, mld.relocatable);
  284. if (mld.relocatable)
  285. grub_dprintf ("multiboot_loader", "align=0x%lx, preference=0x%x, avoid_efi_boot_services=%d\n",
  286. (long) mld.align, mld.preference, keep_bs);
  287. if ((grub_file_seek (file, offset)) == (grub_off_t) -1)
  288. {
  289. grub_free (mld.buffer);
  290. return grub_errno;
  291. }
  292. grub_file_read (file, source, load_size);
  293. if (grub_errno)
  294. {
  295. grub_free (mld.buffer);
  296. return grub_errno;
  297. }
  298. if (addr_tag->bss_end_addr)
  299. grub_memset ((grub_uint8_t *) source + load_size, 0,
  300. addr_tag->bss_end_addr - load_addr - load_size);
  301. }
  302. else
  303. {
  304. mld.file = file;
  305. mld.filename = filename;
  306. mld.avoid_efi_boot_services = keep_bs;
  307. err = grub_multiboot2_load_elf (&mld);
  308. if (err)
  309. {
  310. grub_free (mld.buffer);
  311. return err;
  312. }
  313. }
  314. load_base_addr = mld.load_base_addr;
  315. if (keep_bs && efi_entry_specified)
  316. grub_multiboot2_payload_eip = efi_entry;
  317. else if (entry_specified)
  318. grub_multiboot2_payload_eip = entry;
  319. if (mld.relocatable)
  320. {
  321. /*
  322. * Both branches are mathematically equivalent. However, it looks
  323. * that real life (C?) is more complicated. I am trying to avoid
  324. * wrap around here if mld.load_base_addr < mld.link_base_addr.
  325. * If you look at C operator precedence then everything should work.
  326. * However, I am not 100% sure that a given compiler will not
  327. * optimize/break this stuff. So, maybe we should use signed
  328. * 64-bit int here.
  329. */
  330. if (mld.load_base_addr >= mld.link_base_addr)
  331. grub_multiboot2_payload_eip += mld.load_base_addr - mld.link_base_addr;
  332. else
  333. grub_multiboot2_payload_eip -= mld.link_base_addr - mld.load_base_addr;
  334. }
  335. if (fbtag)
  336. err = grub_multiboot2_set_console (GRUB_MULTIBOOT2_CONSOLE_FRAMEBUFFER,
  337. accepted_consoles,
  338. fbtag->width, fbtag->height,
  339. fbtag->depth, console_required);
  340. else
  341. err = grub_multiboot2_set_console (GRUB_MULTIBOOT2_CONSOLE_EGA_TEXT,
  342. accepted_consoles,
  343. 0, 0, 0, console_required);
  344. return err;
  345. }
  346. static grub_size_t
  347. acpiv2_size (void)
  348. {
  349. #if GRUB_MACHINE_HAS_ACPI
  350. struct grub_acpi_rsdp_v20 *p = grub_acpi_get_rsdpv2 ();
  351. if (!p)
  352. return 0;
  353. return ALIGN_UP (sizeof (struct multiboot_tag_old_acpi)
  354. + p->length, MULTIBOOT_TAG_ALIGN);
  355. #else
  356. return 0;
  357. #endif
  358. }
  359. #ifdef GRUB_MACHINE_EFI
  360. static grub_efi_uintn_t efi_mmap_size = 0;
  361. #endif
  362. static grub_size_t
  363. net_size (void)
  364. {
  365. struct grub_net_network_level_interface *net;
  366. grub_size_t ret = 0;
  367. FOR_NET_NETWORK_LEVEL_INTERFACES(net)
  368. if (net->dhcp_ack)
  369. ret += ALIGN_UP (sizeof (struct multiboot_tag_network) + net->dhcp_acklen,
  370. MULTIBOOT_TAG_ALIGN);
  371. return ret;
  372. }
  373. static grub_size_t
  374. grub_multiboot2_get_mbi_size (void)
  375. {
  376. #ifdef GRUB_MACHINE_EFI
  377. if (!keep_bs && !efi_mmap_size)
  378. efi_mmap_size = grub_efi_find_mmap_size ();
  379. #endif
  380. return 2 * sizeof (grub_uint32_t) + sizeof (struct multiboot_tag)
  381. + sizeof (struct multiboot_tag)
  382. + (sizeof (struct multiboot_tag_string)
  383. + ALIGN_UP (cmdline_size, MULTIBOOT_TAG_ALIGN))
  384. + (sizeof (struct multiboot_tag_string)
  385. + ALIGN_UP (sizeof (PACKAGE_STRING), MULTIBOOT_TAG_ALIGN))
  386. + (modcnt * sizeof (struct multiboot_tag_module) + total_modcmd)
  387. + ALIGN_UP (sizeof (struct multiboot_tag_basic_meminfo),
  388. MULTIBOOT_TAG_ALIGN)
  389. + ALIGN_UP (sizeof (struct multiboot_tag_bootdev), MULTIBOOT_TAG_ALIGN)
  390. + ALIGN_UP (sizeof (struct multiboot_tag_elf_sections), MULTIBOOT_TAG_ALIGN)
  391. + ALIGN_UP (elf_sec_entsize * elf_sec_num, MULTIBOOT_TAG_ALIGN)
  392. + ALIGN_UP ((sizeof (struct multiboot_tag_mmap)
  393. + grub_multiboot2_get_mmap_count ()
  394. * sizeof (struct multiboot_mmap_entry)), MULTIBOOT_TAG_ALIGN)
  395. + ALIGN_UP (sizeof (struct multiboot_tag_framebuffer), MULTIBOOT_TAG_ALIGN)
  396. + ALIGN_UP (sizeof (struct multiboot_tag_old_acpi)
  397. + sizeof (struct grub_acpi_rsdp_v10), MULTIBOOT_TAG_ALIGN)
  398. + ALIGN_UP (sizeof (struct multiboot_tag_load_base_addr), MULTIBOOT_TAG_ALIGN)
  399. + acpiv2_size ()
  400. + net_size ()
  401. #ifdef GRUB_MACHINE_EFI
  402. + ALIGN_UP (sizeof (struct multiboot_tag_efi32), MULTIBOOT_TAG_ALIGN)
  403. + ALIGN_UP (sizeof (struct multiboot_tag_efi32_ih), MULTIBOOT_TAG_ALIGN)
  404. + ALIGN_UP (sizeof (struct multiboot_tag_efi64), MULTIBOOT_TAG_ALIGN)
  405. + ALIGN_UP (sizeof (struct multiboot_tag_efi64_ih), MULTIBOOT_TAG_ALIGN)
  406. + ALIGN_UP (sizeof (struct multiboot_tag_efi_mmap)
  407. + efi_mmap_size, MULTIBOOT_TAG_ALIGN)
  408. #endif
  409. + sizeof (struct multiboot_tag_vbe) + MULTIBOOT_TAG_ALIGN - 1
  410. + sizeof (struct multiboot_tag_apm) + MULTIBOOT_TAG_ALIGN - 1;
  411. }
  412. /* Helper for grub_fill_multiboot_mmap. */
  413. static int
  414. grub_fill_multiboot_mmap_iter (grub_uint64_t addr, grub_uint64_t size,
  415. grub_memory_type_t type, void *data)
  416. {
  417. struct multiboot_mmap_entry **mmap_entry = data;
  418. (*mmap_entry)->addr = addr;
  419. (*mmap_entry)->len = size;
  420. (*mmap_entry)->type = type;
  421. (*mmap_entry)->zero = 0;
  422. (*mmap_entry)++;
  423. return 0;
  424. }
  425. /* Fill previously allocated Multiboot mmap. */
  426. static void
  427. grub_fill_multiboot_mmap (struct multiboot_tag_mmap *tag)
  428. {
  429. struct multiboot_mmap_entry *mmap_entry = tag->entries;
  430. tag->type = MULTIBOOT_TAG_TYPE_MMAP;
  431. tag->size = sizeof (struct multiboot_tag_mmap)
  432. + sizeof (struct multiboot_mmap_entry) * grub_multiboot2_get_mmap_count ();
  433. tag->entry_size = sizeof (struct multiboot_mmap_entry);
  434. tag->entry_version = 0;
  435. grub_mmap_iterate (grub_fill_multiboot_mmap_iter, &mmap_entry);
  436. }
  437. #if defined (GRUB_MACHINE_PCBIOS)
  438. static void
  439. fill_vbe_tag (struct multiboot_tag_vbe *tag)
  440. {
  441. grub_vbe_status_t status;
  442. void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
  443. tag->type = MULTIBOOT_TAG_TYPE_VBE;
  444. tag->size = 0;
  445. status = grub_vbe_bios_get_controller_info (scratch);
  446. if (status != GRUB_VBE_STATUS_OK)
  447. return;
  448. grub_memcpy (&tag->vbe_control_info, scratch,
  449. sizeof (struct grub_vbe_info_block));
  450. status = grub_vbe_bios_get_mode (scratch);
  451. tag->vbe_mode = *(grub_uint32_t *) scratch;
  452. if (status != GRUB_VBE_STATUS_OK)
  453. return;
  454. /* get_mode_info isn't available for mode 3. */
  455. if (tag->vbe_mode == 3)
  456. {
  457. struct grub_vbe_mode_info_block *mode_info = (void *) &tag->vbe_mode_info;
  458. grub_memset (mode_info, 0,
  459. sizeof (struct grub_vbe_mode_info_block));
  460. mode_info->memory_model = GRUB_VBE_MEMORY_MODEL_TEXT;
  461. mode_info->x_resolution = 80;
  462. mode_info->y_resolution = 25;
  463. }
  464. else
  465. {
  466. status = grub_vbe_bios_get_mode_info (tag->vbe_mode, scratch);
  467. if (status != GRUB_VBE_STATUS_OK)
  468. return;
  469. grub_memcpy (&tag->vbe_mode_info, scratch,
  470. sizeof (struct grub_vbe_mode_info_block));
  471. }
  472. grub_vbe_bios_get_pm_interface (&tag->vbe_interface_seg,
  473. &tag->vbe_interface_off,
  474. &tag->vbe_interface_len);
  475. tag->size = sizeof (*tag);
  476. }
  477. #endif
  478. static grub_err_t
  479. retrieve_video_parameters (grub_properly_aligned_t **ptrorig)
  480. {
  481. grub_err_t err;
  482. struct grub_video_mode_info mode_info;
  483. void *framebuffer;
  484. grub_video_driver_id_t driv_id;
  485. struct grub_video_palette_data palette[256];
  486. struct multiboot_tag_framebuffer *tag
  487. = (struct multiboot_tag_framebuffer *) *ptrorig;
  488. err = grub_multiboot2_set_video_mode ();
  489. if (err)
  490. {
  491. grub_print_error ();
  492. grub_errno = GRUB_ERR_NONE;
  493. }
  494. grub_video_get_palette (0, ARRAY_SIZE (palette), palette);
  495. driv_id = grub_video_get_driver_id ();
  496. #if HAS_VGA_TEXT
  497. if (driv_id == GRUB_VIDEO_DRIVER_NONE)
  498. {
  499. struct grub_vbe_mode_info_block vbe_mode_info;
  500. grub_uint32_t vbe_mode;
  501. #if defined (GRUB_MACHINE_PCBIOS)
  502. {
  503. grub_vbe_status_t status;
  504. void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
  505. status = grub_vbe_bios_get_mode (scratch);
  506. vbe_mode = *(grub_uint32_t *) scratch;
  507. if (status != GRUB_VBE_STATUS_OK)
  508. return GRUB_ERR_NONE;
  509. }
  510. #else
  511. vbe_mode = 3;
  512. #endif
  513. /* get_mode_info isn't available for mode 3. */
  514. if (vbe_mode == 3)
  515. {
  516. grub_memset (&vbe_mode_info, 0,
  517. sizeof (struct grub_vbe_mode_info_block));
  518. vbe_mode_info.memory_model = GRUB_VBE_MEMORY_MODEL_TEXT;
  519. vbe_mode_info.x_resolution = 80;
  520. vbe_mode_info.y_resolution = 25;
  521. }
  522. #if defined (GRUB_MACHINE_PCBIOS)
  523. else
  524. {
  525. grub_vbe_status_t status;
  526. void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
  527. status = grub_vbe_bios_get_mode_info (vbe_mode, scratch);
  528. if (status != GRUB_VBE_STATUS_OK)
  529. return GRUB_ERR_NONE;
  530. grub_memcpy (&vbe_mode_info, scratch,
  531. sizeof (struct grub_vbe_mode_info_block));
  532. }
  533. #endif
  534. if (vbe_mode_info.memory_model == GRUB_VBE_MEMORY_MODEL_TEXT)
  535. {
  536. tag = (struct multiboot_tag_framebuffer *) *ptrorig;
  537. tag->common.type = MULTIBOOT_TAG_TYPE_FRAMEBUFFER;
  538. tag->common.size = 0;
  539. tag->common.framebuffer_addr = 0xb8000;
  540. tag->common.framebuffer_pitch = 2 * vbe_mode_info.x_resolution;
  541. tag->common.framebuffer_width = vbe_mode_info.x_resolution;
  542. tag->common.framebuffer_height = vbe_mode_info.y_resolution;
  543. tag->common.framebuffer_bpp = 16;
  544. tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT;
  545. tag->common.size = sizeof (tag->common);
  546. tag->common.reserved = 0;
  547. *ptrorig += ALIGN_UP (tag->common.size, MULTIBOOT_TAG_ALIGN)
  548. / sizeof (grub_properly_aligned_t);
  549. }
  550. return GRUB_ERR_NONE;
  551. }
  552. #else
  553. if (driv_id == GRUB_VIDEO_DRIVER_NONE)
  554. return GRUB_ERR_NONE;
  555. #endif
  556. #if GRUB_MACHINE_HAS_VBE
  557. {
  558. struct multiboot_tag_vbe *tag_vbe = (struct multiboot_tag_vbe *) *ptrorig;
  559. fill_vbe_tag (tag_vbe);
  560. *ptrorig += ALIGN_UP (tag_vbe->size, MULTIBOOT_TAG_ALIGN)
  561. / sizeof (grub_properly_aligned_t);
  562. }
  563. #endif
  564. err = grub_video_get_info_and_fini (&mode_info, &framebuffer);
  565. if (err)
  566. return err;
  567. tag = (struct multiboot_tag_framebuffer *) *ptrorig;
  568. tag->common.type = MULTIBOOT_TAG_TYPE_FRAMEBUFFER;
  569. tag->common.size = 0;
  570. tag->common.framebuffer_addr = (grub_addr_t) framebuffer;
  571. tag->common.framebuffer_pitch = mode_info.pitch;
  572. tag->common.framebuffer_width = mode_info.width;
  573. tag->common.framebuffer_height = mode_info.height;
  574. tag->common.framebuffer_bpp = mode_info.bpp;
  575. tag->common.reserved = 0;
  576. if (mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR)
  577. {
  578. unsigned i;
  579. tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED;
  580. tag->framebuffer_palette_num_colors = mode_info.number_of_colors;
  581. if (tag->framebuffer_palette_num_colors > ARRAY_SIZE (palette))
  582. tag->framebuffer_palette_num_colors = ARRAY_SIZE (palette);
  583. tag->common.size = sizeof (struct multiboot_tag_framebuffer_common)
  584. + sizeof (multiboot_uint16_t) + tag->framebuffer_palette_num_colors
  585. * sizeof (struct multiboot_color);
  586. for (i = 0; i < tag->framebuffer_palette_num_colors; i++)
  587. {
  588. tag->framebuffer_palette[i].red = palette[i].r;
  589. tag->framebuffer_palette[i].green = palette[i].g;
  590. tag->framebuffer_palette[i].blue = palette[i].b;
  591. }
  592. }
  593. else
  594. {
  595. tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_RGB;
  596. tag->framebuffer_red_field_position = mode_info.red_field_pos;
  597. tag->framebuffer_red_mask_size = mode_info.red_mask_size;
  598. tag->framebuffer_green_field_position = mode_info.green_field_pos;
  599. tag->framebuffer_green_mask_size = mode_info.green_mask_size;
  600. tag->framebuffer_blue_field_position = mode_info.blue_field_pos;
  601. tag->framebuffer_blue_mask_size = mode_info.blue_mask_size;
  602. tag->common.size = sizeof (struct multiboot_tag_framebuffer_common) + 6;
  603. }
  604. *ptrorig += ALIGN_UP (tag->common.size, MULTIBOOT_TAG_ALIGN)
  605. / sizeof (grub_properly_aligned_t);
  606. return GRUB_ERR_NONE;
  607. }
  608. grub_err_t
  609. grub_multiboot2_make_mbi (grub_uint32_t *target)
  610. {
  611. grub_properly_aligned_t *ptrorig;
  612. grub_properly_aligned_t *mbistart;
  613. grub_err_t err;
  614. grub_size_t bufsize;
  615. grub_relocator_chunk_t ch;
  616. bufsize = grub_multiboot2_get_mbi_size ();
  617. COMPILE_TIME_ASSERT (MULTIBOOT_TAG_ALIGN % sizeof (grub_properly_aligned_t) == 0);
  618. err = grub_relocator_alloc_chunk_align (grub_multiboot2_relocator, &ch,
  619. 0, 0xffffffff - bufsize,
  620. bufsize, MULTIBOOT_TAG_ALIGN,
  621. GRUB_RELOCATOR_PREFERENCE_NONE, 1);
  622. if (err)
  623. return err;
  624. ptrorig = get_virtual_current_address (ch);
  625. #if defined (__i386__) || defined (__x86_64__)
  626. *target = get_physical_target_address (ch);
  627. #elif defined (__mips)
  628. *target = get_physical_target_address (ch) | 0x80000000;
  629. #else
  630. #error Please complete this
  631. #endif
  632. mbistart = ptrorig;
  633. COMPILE_TIME_ASSERT ((2 * sizeof (grub_uint32_t))
  634. % sizeof (grub_properly_aligned_t) == 0);
  635. COMPILE_TIME_ASSERT (MULTIBOOT_TAG_ALIGN
  636. % sizeof (grub_properly_aligned_t) == 0);
  637. ptrorig += (2 * sizeof (grub_uint32_t)) / sizeof (grub_properly_aligned_t);
  638. {
  639. struct multiboot_tag_load_base_addr *tag = (struct multiboot_tag_load_base_addr *) ptrorig;
  640. tag->type = MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR;
  641. tag->size = sizeof (struct multiboot_tag_load_base_addr);
  642. tag->load_base_addr = load_base_addr;
  643. ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
  644. / sizeof (grub_properly_aligned_t);
  645. }
  646. {
  647. struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig;
  648. tag->type = MULTIBOOT_TAG_TYPE_CMDLINE;
  649. tag->size = sizeof (struct multiboot_tag_string) + cmdline_size;
  650. grub_memcpy (tag->string, cmdline, cmdline_size);
  651. ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
  652. / sizeof (grub_properly_aligned_t);
  653. }
  654. {
  655. struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig;
  656. tag->type = MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME;
  657. tag->size = sizeof (struct multiboot_tag_string) + sizeof (PACKAGE_STRING);
  658. grub_memcpy (tag->string, PACKAGE_STRING, sizeof (PACKAGE_STRING));
  659. ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
  660. / sizeof (grub_properly_aligned_t);
  661. }
  662. #ifdef GRUB_MACHINE_PCBIOS
  663. {
  664. struct grub_apm_info info;
  665. if (grub_apm_get_info (&info))
  666. {
  667. struct multiboot_tag_apm *tag = (struct multiboot_tag_apm *) ptrorig;
  668. tag->type = MULTIBOOT_TAG_TYPE_APM;
  669. tag->size = sizeof (struct multiboot_tag_apm);
  670. tag->cseg = info.cseg;
  671. tag->offset = info.offset;
  672. tag->cseg_16 = info.cseg_16;
  673. tag->dseg = info.dseg;
  674. tag->flags = info.flags;
  675. tag->cseg_len = info.cseg_len;
  676. tag->dseg_len = info.dseg_len;
  677. tag->cseg_16_len = info.cseg_16_len;
  678. tag->version = info.version;
  679. ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
  680. / sizeof (grub_properly_aligned_t);
  681. }
  682. }
  683. #endif
  684. {
  685. unsigned i;
  686. struct module *cur;
  687. for (i = 0, cur = modules; i < modcnt; i++, cur = cur->next)
  688. {
  689. struct multiboot_tag_module *tag
  690. = (struct multiboot_tag_module *) ptrorig;
  691. tag->type = MULTIBOOT_TAG_TYPE_MODULE;
  692. tag->size = sizeof (struct multiboot_tag_module) + cur->cmdline_size;
  693. tag->mod_start = cur->start;
  694. tag->mod_end = tag->mod_start + cur->size;
  695. grub_memcpy (tag->cmdline, cur->cmdline, cur->cmdline_size);
  696. ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
  697. / sizeof (grub_properly_aligned_t);
  698. }
  699. }
  700. if (!keep_bs)
  701. {
  702. struct multiboot_tag_mmap *tag = (struct multiboot_tag_mmap *) ptrorig;
  703. grub_fill_multiboot_mmap (tag);
  704. ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
  705. / sizeof (grub_properly_aligned_t);
  706. }
  707. {
  708. struct multiboot_tag_elf_sections *tag
  709. = (struct multiboot_tag_elf_sections *) ptrorig;
  710. tag->type = MULTIBOOT_TAG_TYPE_ELF_SECTIONS;
  711. tag->size = sizeof (struct multiboot_tag_elf_sections)
  712. + elf_sec_entsize * elf_sec_num;
  713. grub_memcpy (tag->sections, elf_sections, elf_sec_entsize * elf_sec_num);
  714. tag->num = elf_sec_num;
  715. tag->entsize = elf_sec_entsize;
  716. tag->shndx = elf_sec_shstrndx;
  717. ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
  718. / sizeof (grub_properly_aligned_t);
  719. }
  720. if (!keep_bs)
  721. {
  722. struct multiboot_tag_basic_meminfo *tag
  723. = (struct multiboot_tag_basic_meminfo *) ptrorig;
  724. tag->type = MULTIBOOT_TAG_TYPE_BASIC_MEMINFO;
  725. tag->size = sizeof (struct multiboot_tag_basic_meminfo);
  726. /* Convert from bytes to kilobytes. */
  727. tag->mem_lower = grub_mmap_get_lower () / 1024;
  728. tag->mem_upper = grub_mmap_get_upper () / 1024;
  729. ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
  730. / sizeof (grub_properly_aligned_t);
  731. }
  732. {
  733. struct grub_net_network_level_interface *net;
  734. FOR_NET_NETWORK_LEVEL_INTERFACES(net)
  735. if (net->dhcp_ack)
  736. {
  737. struct multiboot_tag_network *tag
  738. = (struct multiboot_tag_network *) ptrorig;
  739. tag->type = MULTIBOOT_TAG_TYPE_NETWORK;
  740. tag->size = sizeof (struct multiboot_tag_network) + net->dhcp_acklen;
  741. grub_memcpy (tag->dhcpack, net->dhcp_ack, net->dhcp_acklen);
  742. ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
  743. / sizeof (grub_properly_aligned_t);
  744. }
  745. }
  746. if (bootdev_set)
  747. {
  748. struct multiboot_tag_bootdev *tag
  749. = (struct multiboot_tag_bootdev *) ptrorig;
  750. tag->type = MULTIBOOT_TAG_TYPE_BOOTDEV;
  751. tag->size = sizeof (struct multiboot_tag_bootdev);
  752. tag->biosdev = biosdev;
  753. tag->slice = slice;
  754. tag->part = part;
  755. ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
  756. / sizeof (grub_properly_aligned_t);
  757. }
  758. {
  759. err = retrieve_video_parameters (&ptrorig);
  760. if (err)
  761. {
  762. grub_print_error ();
  763. grub_errno = GRUB_ERR_NONE;
  764. }
  765. }
  766. #if defined (GRUB_MACHINE_EFI) && defined (__x86_64__)
  767. {
  768. struct multiboot_tag_efi64 *tag = (struct multiboot_tag_efi64 *) ptrorig;
  769. tag->type = MULTIBOOT_TAG_TYPE_EFI64;
  770. tag->size = sizeof (*tag);
  771. tag->pointer = (grub_addr_t) grub_efi_system_table;
  772. ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
  773. / sizeof (grub_properly_aligned_t);
  774. }
  775. #endif
  776. #if defined (GRUB_MACHINE_EFI) && defined (__i386__)
  777. {
  778. struct multiboot_tag_efi32 *tag = (struct multiboot_tag_efi32 *) ptrorig;
  779. tag->type = MULTIBOOT_TAG_TYPE_EFI32;
  780. tag->size = sizeof (*tag);
  781. tag->pointer = (grub_addr_t) grub_efi_system_table;
  782. ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
  783. / sizeof (grub_properly_aligned_t);
  784. }
  785. #endif
  786. #if GRUB_MACHINE_HAS_ACPI
  787. {
  788. struct multiboot_tag_old_acpi *tag = (struct multiboot_tag_old_acpi *)
  789. ptrorig;
  790. struct grub_acpi_rsdp_v10 *a = grub_acpi_get_rsdpv1 ();
  791. if (a)
  792. {
  793. tag->type = MULTIBOOT_TAG_TYPE_ACPI_OLD;
  794. tag->size = sizeof (*tag) + sizeof (*a);
  795. grub_memcpy (tag->rsdp, a, sizeof (*a));
  796. ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
  797. / sizeof (grub_properly_aligned_t);
  798. }
  799. }
  800. {
  801. struct multiboot_tag_new_acpi *tag = (struct multiboot_tag_new_acpi *)
  802. ptrorig;
  803. struct grub_acpi_rsdp_v20 *a = grub_acpi_get_rsdpv2 ();
  804. if (a)
  805. {
  806. tag->type = MULTIBOOT_TAG_TYPE_ACPI_NEW;
  807. tag->size = sizeof (*tag) + a->length;
  808. grub_memcpy (tag->rsdp, a, a->length);
  809. ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
  810. / sizeof (grub_properly_aligned_t);
  811. }
  812. }
  813. #endif
  814. #ifdef GRUB_MACHINE_EFI
  815. {
  816. struct multiboot_tag_efi_mmap *tag = (struct multiboot_tag_efi_mmap *) ptrorig;
  817. grub_efi_uintn_t efi_desc_size;
  818. grub_efi_uint32_t efi_desc_version;
  819. if (!keep_bs)
  820. {
  821. tag->type = MULTIBOOT_TAG_TYPE_EFI_MMAP;
  822. tag->size = sizeof (*tag) + efi_mmap_size;
  823. err = grub_efi_finish_boot_services (&efi_mmap_size, tag->efi_mmap, NULL,
  824. &efi_desc_size, &efi_desc_version);
  825. if (err)
  826. return err;
  827. tag->descr_size = efi_desc_size;
  828. tag->descr_vers = efi_desc_version;
  829. tag->size = sizeof (*tag) + efi_mmap_size;
  830. ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
  831. / sizeof (grub_properly_aligned_t);
  832. }
  833. }
  834. if (keep_bs)
  835. {
  836. {
  837. struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig;
  838. tag->type = MULTIBOOT_TAG_TYPE_EFI_BS;
  839. tag->size = sizeof (struct multiboot_tag);
  840. ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
  841. / sizeof (grub_properly_aligned_t);
  842. }
  843. #ifdef __i386__
  844. {
  845. struct multiboot_tag_efi32_ih *tag = (struct multiboot_tag_efi32_ih *) ptrorig;
  846. tag->type = MULTIBOOT_TAG_TYPE_EFI32_IH;
  847. tag->size = sizeof (struct multiboot_tag_efi32_ih);
  848. tag->pointer = (grub_addr_t) grub_efi_image_handle;
  849. ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
  850. / sizeof (grub_properly_aligned_t);
  851. }
  852. #endif
  853. #ifdef __x86_64__
  854. {
  855. struct multiboot_tag_efi64_ih *tag = (struct multiboot_tag_efi64_ih *) ptrorig;
  856. tag->type = MULTIBOOT_TAG_TYPE_EFI64_IH;
  857. tag->size = sizeof (struct multiboot_tag_efi64_ih);
  858. tag->pointer = (grub_addr_t) grub_efi_image_handle;
  859. ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
  860. / sizeof (grub_properly_aligned_t);
  861. }
  862. #endif
  863. }
  864. #endif
  865. {
  866. struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig;
  867. tag->type = MULTIBOOT_TAG_TYPE_END;
  868. tag->size = sizeof (struct multiboot_tag);
  869. ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
  870. / sizeof (grub_properly_aligned_t);
  871. }
  872. ((grub_uint32_t *) mbistart)[0] = (char *) ptrorig - (char *) mbistart;
  873. ((grub_uint32_t *) mbistart)[1] = 0;
  874. return GRUB_ERR_NONE;
  875. }
  876. void
  877. grub_multiboot2_free_mbi (void)
  878. {
  879. struct module *cur, *next;
  880. cmdline_size = 0;
  881. total_modcmd = 0;
  882. modcnt = 0;
  883. grub_free (cmdline);
  884. cmdline = NULL;
  885. bootdev_set = 0;
  886. for (cur = modules; cur; cur = next)
  887. {
  888. next = cur->next;
  889. grub_free (cur->cmdline);
  890. grub_free (cur);
  891. }
  892. modules = NULL;
  893. modules_last = NULL;
  894. }
  895. grub_err_t
  896. grub_multiboot2_init_mbi (int argc, char *argv[])
  897. {
  898. grub_ssize_t len = 0;
  899. grub_multiboot2_free_mbi ();
  900. len = grub_loader_cmdline_size (argc, argv);
  901. cmdline = grub_malloc (len);
  902. if (! cmdline)
  903. return grub_errno;
  904. cmdline_size = len;
  905. return grub_create_loader_cmdline (argc, argv, cmdline, cmdline_size,
  906. GRUB_VERIFY_KERNEL_CMDLINE);
  907. }
  908. grub_err_t
  909. grub_multiboot2_add_module (grub_addr_t start, grub_size_t size,
  910. int argc, char *argv[])
  911. {
  912. struct module *newmod;
  913. grub_size_t len = 0;
  914. grub_err_t err;
  915. newmod = grub_malloc (sizeof (*newmod));
  916. if (!newmod)
  917. return grub_errno;
  918. newmod->start = start;
  919. newmod->size = size;
  920. len = grub_loader_cmdline_size (argc, argv);
  921. newmod->cmdline = grub_malloc (len);
  922. if (! newmod->cmdline)
  923. {
  924. grub_free (newmod);
  925. return grub_errno;
  926. }
  927. newmod->cmdline_size = len;
  928. total_modcmd += ALIGN_UP (len, MULTIBOOT_TAG_ALIGN);
  929. err = grub_create_loader_cmdline (argc, argv, newmod->cmdline,
  930. newmod->cmdline_size, GRUB_VERIFY_MODULE_CMDLINE);
  931. if (err)
  932. return err;
  933. if (modules_last)
  934. modules_last->next = newmod;
  935. else
  936. modules = newmod;
  937. modules_last = newmod;
  938. modcnt++;
  939. return GRUB_ERR_NONE;
  940. }
  941. void
  942. grub_multiboot2_set_bootdev (void)
  943. {
  944. grub_device_t dev;
  945. slice = ~0;
  946. part = ~0;
  947. #ifdef GRUB_MACHINE_PCBIOS
  948. biosdev = grub_get_root_biosnumber ();
  949. #else
  950. biosdev = 0xffffffff;
  951. #endif
  952. if (biosdev == 0xffffffff)
  953. return;
  954. dev = grub_device_open (0);
  955. if (dev && dev->disk && dev->disk->partition)
  956. {
  957. if (dev->disk->partition->parent)
  958. {
  959. part = dev->disk->partition->number;
  960. slice = dev->disk->partition->parent->number;
  961. }
  962. else
  963. slice = dev->disk->partition->number;
  964. }
  965. if (dev)
  966. grub_device_close (dev);
  967. bootdev_set = 1;
  968. }