static grub_err_t grub_cmd_chain (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) { grub_err_t err; grub_file_t file; grub_elf_t elf; if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); grub_loader_unset (); file = grub_file_open (argv[0]); if (!file) return grub_errno; relocator = grub_relocator_new (); if (!relocator) { grub_file_close (file); return grub_errno; } elf = grub_elf_file (file, argv[0]); if (!elf) { grub_relocator_unload (relocator); relocator = 0; grub_file_close (file); } if (!grub_elf_is_elf32 (elf)) { grub_relocator_unload (relocator); relocator = 0; grub_elf_close (elf); } entry = elf->ehdr.ehdr32.e_entry & 0xFFFFFF; err = grub_elf32_load (elf, argv[0], grub_chain_elf32_hook, 0, 0); grub_elf_close (elf); if (err) return err; grub_loader_set (grub_chain_boot, grub_chain_unload, 0); return GRUB_ERR_NONE; }
static grub_err_t grub_cmd_multiboot (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) { grub_file_t file = 0; grub_err_t err; grub_loader_unset (); highest_load = 0; #ifndef GRUB_USE_MULTIBOOT2 grub_multiboot_quirks = GRUB_MULTIBOOT_QUIRKS_NONE; int option_found = 0; do { option_found = 0; if (argc != 0 && grub_strcmp (argv[0], "--quirk-bad-kludge") == 0) { argc--; argv++; option_found = 1; grub_multiboot_quirks |= GRUB_MULTIBOOT_QUIRK_BAD_KLUDGE; } if (argc != 0 && grub_strcmp (argv[0], "--quirk-modules-after-kernel") == 0) { argc--; argv++; option_found = 1; grub_multiboot_quirks |= GRUB_MULTIBOOT_QUIRK_MODULES_AFTER_KERNEL; } } while (option_found); #endif if (argc == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); file = grub_file_open (argv[0]); if (! file) return grub_errno; grub_dl_ref (my_mod); /* Skip filename. */ grub_multiboot_init_mbi (argc - 1, argv + 1); grub_relocator_unload (grub_multiboot_relocator); grub_multiboot_relocator = grub_relocator_new (); if (!grub_multiboot_relocator) goto fail; err = grub_multiboot_load (file, argv[0]); if (err) goto fail; grub_multiboot_set_bootdev (); grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 0); fail: if (file) grub_file_close (file); if (grub_errno != GRUB_ERR_NONE) { grub_relocator_unload (grub_multiboot_relocator); grub_multiboot_relocator = NULL; grub_dl_unref (my_mod); } else { /* Begin TCG Extension */ grub_TPM_measure_file( argv[0], TPM_LOADER_MEASUREMENT_PCR ); /* End TCG Extension */ } return grub_errno; }
void grub_multiboot2 (int argc, char *argv[]) { char *buffer; grub_file_t file = 0; grub_elf_t elf = 0; struct multiboot_header *header = 0; char *p; grub_ssize_t len; grub_err_t err; int header_found = 0; grub_loader_unset (); if (argc == 0) { grub_error (GRUB_ERR_BAD_ARGUMENT, "No kernel specified"); goto fail; } file = grub_gzfile_open (argv[0], 1); if (! file) { grub_error (GRUB_ERR_BAD_ARGUMENT, "Couldn't open file"); goto fail; } buffer = grub_malloc (MULTIBOOT2_HEADER_SEARCH); if (! buffer) return; len = grub_file_read (file, buffer, MULTIBOOT2_HEADER_SEARCH); if (len < 32) { grub_error (GRUB_ERR_BAD_OS, "File too small"); goto fail; } /* Look for the multiboot header in the buffer. The header should be at least 8 bytes and aligned on a 8-byte boundary. */ for (p = buffer; p <= buffer + len - 8; p += 8) { header = (struct multiboot_header *) p; if (header->magic == MULTIBOOT2_HEADER_MAGIC) { header_found = 1; break; } } if (! header_found) grub_dprintf ("loader", "No multiboot 2 header found.\n"); /* Create the basic tags. */ grub_dprintf ("loader", "Creating multiboot 2 tags\n"); grub_mb2_tags_create (); /* Load the kernel and create its tag. */ elf = grub_elf_file (file); if (elf) { grub_dprintf ("loader", "Loading ELF multiboot 2 file.\n"); err = grub_mb2_load_elf (elf, argc-1, &argv[1]); grub_elf_close (elf); } else { grub_errno = 0; grub_dprintf ("loader", "Loading non-ELF multiboot 2 file.\n"); if (header) err = grub_mb2_load_other (file, header); else err = grub_error (GRUB_ERR_BAD_OS, "Need multiboot 2 header to load non-ELF files."); grub_file_close (file); } grub_free (buffer); if (err) goto fail; /* Good to go. */ grub_loader_set (grub_mb2_boot, grub_mb2_unload, 1); return; fail: grub_mb2_tags_free (); grub_dl_unref (my_mod); }