예제 #1
0
파일: reboot.c 프로젝트: Arvian/GRUB2
void
grub_reboot (void)
{
  struct grub_relocator *relocator = NULL;
  grub_relocator_chunk_t ch;
  grub_err_t err;
  void *buf;
  struct grub_relocator16_state state;
  grub_uint16_t segment;

  relocator = grub_relocator_new ();
  if (!relocator)
    while (1);
  err = grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000, 0x1000,
					  grub_reboot_end - grub_reboot_start,
					  16, GRUB_RELOCATOR_PREFERENCE_NONE,
					  0);
  if (err)
    while (1);
  buf = get_virtual_current_address (ch);
  grub_memcpy (buf, grub_reboot_start, grub_reboot_end - grub_reboot_start);

  segment = ((grub_addr_t) get_physical_target_address (ch)) >> 4;
  state.gs = state.fs = state.es = state.ds = state.ss = segment;
  state.sp = 0;
  state.cs = segment;
  state.ip = 0;
  state.a20 = 0;

  grub_stop_floppy ();
  
  err = grub_relocator16_boot (relocator, state);

  while (1);
}
예제 #2
0
파일: chainloader.c 프로젝트: Arvian/GRUB2
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;
}
예제 #3
0
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;
}
예제 #4
0
파일: linux.c 프로젝트: VictorLowther/grub
/* Allocate pages for the real mode code and the protected mode code
   for linux as well as a memory map buffer.  */
static grub_err_t
allocate_pages (grub_size_t prot_size, grub_size_t *align,
		grub_size_t min_align, int relocatable,
		grub_uint64_t preferred_address)
{
  grub_err_t err;

  if (prot_size == 0)
    prot_size = 1;

  prot_size = page_align (prot_size);

  /* Initialize the memory pointers with NULL for convenience.  */
  free_pages ();

  relocator = grub_relocator_new ();
  if (!relocator)
    {
      err = grub_errno;
      goto fail;
    }

  /* FIXME: Should request low memory from the heap when this feature is
     implemented.  */

  {
    grub_relocator_chunk_t ch;
    if (relocatable)
      {
	err = grub_relocator_alloc_chunk_align (relocator, &ch,
						preferred_address,
						preferred_address,
						prot_size, 1,
						GRUB_RELOCATOR_PREFERENCE_LOW,
						1);
	for (; err && *align + 1 > min_align; (*align)--)
	  {
	    grub_errno = GRUB_ERR_NONE;
	    err = grub_relocator_alloc_chunk_align (relocator, &ch,
						    0x1000000,
						    0xffffffff & ~prot_size,
						    prot_size, 1 << *align,
						    GRUB_RELOCATOR_PREFERENCE_LOW,
						    1);
	  }
	if (err)
	  goto fail;
      }
    else
      err = grub_relocator_alloc_chunk_addr (relocator, &ch,
					     preferred_address,
					     prot_size);
    if (err)
      goto fail;
    prot_mode_mem = get_virtual_current_address (ch);
    prot_mode_target = get_physical_target_address (ch);
  }

  grub_dprintf ("linux", "prot_mode_mem = %p, prot_mode_target = %lx, prot_size = %x\n",
                prot_mode_mem, (unsigned long) prot_mode_target,
		(unsigned) prot_size);
  return GRUB_ERR_NONE;

 fail:
  free_pages ();
  return err;
}
예제 #5
0
파일: ntldr.c 프로젝트: Spacy/grub-fuse
static grub_err_t
grub_cmd_ntldr (grub_command_t cmd __attribute__ ((unused)),
		int argc, char *argv[])
{
  grub_file_t file = 0;
  grub_err_t err;
  void *bs, *ntldr;
  grub_size_t ntldrsize;
  grub_device_t dev;

  if (argc == 0)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");

  grub_dl_ref (my_mod);

  rel = grub_relocator_new ();
  if (!rel)
    goto fail;

  file = grub_file_open (argv[0]);
  if (! file)
    goto fail;

  {
    grub_relocator_chunk_t ch;
    err = grub_relocator_alloc_chunk_addr (rel, &ch, 0x7C00,
					   GRUB_DISK_SECTOR_SIZE);
    if (err)
      goto fail;
    bs = get_virtual_current_address (ch);
  }

  edx = grub_get_root_biosnumber ();
  dev = grub_device_open (0);

  if (dev && dev->disk)
    {
      err = grub_disk_read (dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, bs);
      if (err)
	{
	  grub_device_close (dev);
	  goto fail;
	}
    }

  if (dev)
    grub_device_close (dev);

  ntldrsize = grub_file_size (file);
  {
    grub_relocator_chunk_t ch;
    err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_NTLDR_SEGMENT << 4,
					   ntldrsize);
    if (err)
      goto fail;
    ntldr = get_virtual_current_address (ch);
  }

  if (grub_file_read (file, ntldr, ntldrsize)
      != (grub_ssize_t) ntldrsize)
    goto fail;
 
  grub_loader_set (grub_ntldr_boot, grub_ntldr_unload, 1);
  return GRUB_ERR_NONE;

 fail:

  if (file)
    grub_file_close (file);

  grub_ntldr_unload ();

  return grub_errno;
}
예제 #6
0
static grub_err_t
grub_cmd_pxechain (grub_command_t cmd __attribute__ ((unused)),
		int argc, char *argv[])
{
  grub_file_t file = 0;
  grub_err_t err;
  void *image;
  grub_size_t imagesize;
  char *fname;

  if (argc == 0)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));

  grub_dl_ref (my_mod);

  rel = grub_relocator_new ();
  if (!rel)
    goto fail;

  file = grub_file_open (argv[0]);
  if (! file)
    goto fail;

  if (file->device->net && file->device->net->name)
    fname = file->device->net->name;
  else
    {
      fname = argv[0];
      if (fname[0] == '(')
	{
	  fname = grub_strchr (fname, ')');
	  if (fname)
	    fname++;
	  else
	    fname = argv[0];
	}
    }

  grub_memset (boot_file, 0, sizeof (boot_file));
  grub_strncpy (boot_file, fname, sizeof (boot_file));

  grub_memset (server_name, 0, sizeof (server_name));
  if (file->device->net && file->device->net->server)
    grub_strncpy (server_name, file->device->net->server, sizeof (server_name));

  edx = grub_get_root_biosnumber ();

  imagesize = grub_file_size (file);
  {
    grub_relocator_chunk_t ch;
    err = grub_relocator_alloc_chunk_addr (rel, &ch, 0x7c00, imagesize);
    if (err)
      goto fail;
    image = get_virtual_current_address (ch);
  }

  if (grub_file_read (file, image, imagesize) != (grub_ssize_t) imagesize)
    goto fail;
 
  grub_loader_set (grub_pxechain_boot, grub_pxechain_unload,
		   GRUB_LOADER_FLAG_NORETURN | GRUB_LOADER_FLAG_PXE_NOT_UNLOAD);
  return GRUB_ERR_NONE;

 fail:

  if (file)
    grub_file_close (file);

  grub_pxechain_unload ();

  return grub_errno;
}
예제 #7
0
static grub_err_t
grub_cmd_freedos (grub_command_t cmd __attribute__ ((unused)),
		int argc, char *argv[])
{
  grub_file_t file = 0;
  grub_err_t err;
  void *bs, *kernelsys;
  grub_size_t kernelsyssize;
  grub_device_t dev;

  if (argc == 0)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));

  grub_dl_ref (my_mod);

  rel = grub_relocator_new ();
  if (!rel)
    goto fail;

  file = grub_file_open (argv[0]);
  if (! file)
    goto fail;

  {
    grub_relocator_chunk_t ch;
    err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_FREEDOS_BPB_ADDR,
					   GRUB_DISK_SECTOR_SIZE);
    if (err)
      goto fail;
    bs = get_virtual_current_address (ch);
  }

  ebx = grub_get_root_biosnumber ();
  dev = grub_device_open (0);

  if (dev && dev->disk)
    {
      err = grub_disk_read (dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, bs);
      if (err)
	{
	  grub_device_close (dev);
	  goto fail;
	}
      grub_chainloader_patch_bpb (bs, dev, ebx);
    }

  if (dev)
    grub_device_close (dev);

  kernelsyssize = grub_file_size (file);

  if (kernelsyssize > GRUB_FREEDOS_MAX_SIZE)
    {
      grub_error (GRUB_ERR_BAD_OS,
		  N_("the size of `%s' is too large"), argv[0]);
      goto fail;
    }

  {
    grub_relocator_chunk_t ch;
    err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_FREEDOS_ADDR,
					   kernelsyssize);
    if (err)
      goto fail;
    kernelsys = get_virtual_current_address (ch);
  }

  if (grub_file_read (file, kernelsys, kernelsyssize)
      != (grub_ssize_t) kernelsyssize)
    goto fail;
 
  grub_loader_set (grub_freedos_boot, grub_freedos_unload, 1);
  return GRUB_ERR_NONE;

 fail:

  if (file)
    grub_file_close (file);

  grub_freedos_unload ();

  return grub_errno;
}
예제 #8
0
파일: ntldr.c 프로젝트: ts468/TrustedGRUB2
static grub_err_t
grub_cmd_ntldr (grub_command_t cmd __attribute__ ((unused)),
		int argc, char *argv[])
{
  grub_file_t file = 0;
  grub_err_t err;
  void *bs, *ntldr;
  grub_size_t ntldrsize;
  grub_device_t dev;

  if (argc == 0)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));

  grub_dl_ref (my_mod);

  rel = grub_relocator_new ();
  if (!rel)
    goto fail;

  file = grub_file_open (argv[0]);
  if (! file)
    goto fail;

  {
    grub_relocator_chunk_t ch;
    err = grub_relocator_alloc_chunk_addr (rel, &ch, 0x7C00,
					   GRUB_DISK_SECTOR_SIZE);
    if (err)
      goto fail;
    bs = get_virtual_current_address (ch);
  }

  edx = grub_get_root_biosnumber ();
  dev = grub_device_open (0);

  if (dev && dev->disk)
    {
      err = grub_disk_read (dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, bs);
      if (err)
	{
	  grub_device_close (dev);
	  goto fail;
	}
      grub_chainloader_patch_bpb (bs, dev, edx);
    }

  if (dev)
    grub_device_close (dev);

  ntldrsize = grub_file_size (file);
  {
    grub_relocator_chunk_t ch;
    err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_NTLDR_SEGMENT << 4,
					   ntldrsize);
    if (err)
      goto fail;
    ntldr = get_virtual_current_address (ch);
  }

  if (grub_file_read (file, ntldr, ntldrsize)
      != (grub_ssize_t) ntldrsize)
    goto fail;
 
  grub_loader_set (grub_ntldr_boot, grub_ntldr_unload, 1);

  /* Begin TCG Extension */
  if (grub_TPM_isAvailable())
    grub_TPM_measureFile( argv[0], TPM_LOADED_FILES_PCR );
  /* End TCG Extension */

  return GRUB_ERR_NONE;

 fail:

  if (file)
    grub_file_close (file);

  grub_ntldr_unload ();

  return grub_errno;
}