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_ntldr_boot (void) { struct grub_relocator16_state state = { .cs = GRUB_NTLDR_SEGMENT, .ip = 0, .ds = 0, .es = 0, .fs = 0, .gs = 0, .ss = 0, .sp = 0x7c00, .edx = edx }; grub_video_set_mode ("text", 0, 0); return grub_relocator16_boot (rel, state); } static grub_err_t grub_ntldr_unload (void) { grub_relocator_unload (rel); rel = NULL; grub_dl_unref (my_mod); return GRUB_ERR_NONE; }
static grub_err_t grub_freedos_boot (void) { struct grub_relocator16_state state = { .cs = GRUB_FREEDOS_SEGMENT, .ip = 0, .ds = GRUB_FREEDOS_STACK_SEGMENT, .es = 0, .fs = 0, .gs = 0, .ss = GRUB_FREEDOS_STACK_SEGMENT, .sp = GRUB_FREEDOS_STACK_POINTER, .ebp = GRUB_FREEDOS_STACK_BPB_POINTER, .ebx = ebx, .edx = ebx, .a20 = 1 }; grub_video_set_mode ("text", 0, 0); return grub_relocator16_boot (rel, state); } static grub_err_t grub_freedos_unload (void) { grub_relocator_unload (rel); rel = NULL; grub_dl_unref (my_mod); return GRUB_ERR_NONE; }
static void free_pages (void) { grub_relocator_unload (relocator); relocator = NULL; prot_mode_mem = initrd_mem = 0; prot_mode_target = initrd_mem_target = 0; }
static grub_err_t grub_chain_unload (void) { grub_relocator_unload (relocator); relocator = NULL; return GRUB_ERR_NONE; }
static grub_err_t grub_multiboot_unload (void) { grub_multiboot_free_mbi (); grub_relocator_unload (grub_multiboot_relocator); grub_multiboot_relocator = NULL; grub_dl_unref (my_mod); return GRUB_ERR_NONE; }
static grub_err_t grub_pxechain_boot (void) { struct grub_relocator16_state state = { .cs = 0, .ip = 0x7c00, .ds = 0, .es = 0, .fs = 0, .gs = 0, .ss = 0, .sp = 0x7c00, .edx = edx }; struct grub_net_bootp_packet *bp; bp = grub_pxe_get_cached (GRUB_PXENV_PACKET_TYPE_DHCP_ACK); grub_video_set_mode ("text", 0, 0); if (bp && boot_file[0]) grub_memcpy (bp->boot_file, boot_file, sizeof (bp->boot_file)); if (bp && server_name[0]) grub_memcpy (bp->server_name, server_name, sizeof (bp->server_name)); return grub_relocator16_boot (rel, state); } static grub_err_t grub_pxechain_unload (void) { grub_relocator_unload (rel); rel = NULL; grub_dl_unref (my_mod); 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; }