Beispiel #1
0
void
grub_net_process_dhcp (struct grub_net_buff *nb,
		       struct grub_net_card *card)
{
  char *name;
  struct grub_net_network_level_interface *inf;

  name = grub_xasprintf ("%s:dhcp", card->name);
  if (!name)
    {
      grub_print_error ();
      return;
    }
  grub_net_configure_by_dhcp_ack (name, card,
				  0, (const struct grub_net_bootp_packet *) nb->data,
				  (nb->tail - nb->data), 0, 0, 0);
  grub_free (name);
  if (grub_errno)
    grub_print_error ();
  else
    {
      FOR_NET_NETWORK_LEVEL_INTERFACES(inf)
	if (grub_memcmp (inf->name, card->name, grub_strlen (card->name)) == 0
	    && grub_memcmp (inf->name + grub_strlen (card->name),
			    ":dhcp_tmp", sizeof (":dhcp_tmp") - 1) == 0)
	  {
	    grub_net_network_level_interface_unregister (inf);
	    break;
	  }
    }
}
Beispiel #2
0
static void
menu_init (int entry, grub_menu_t menu, int nested)
{
  struct grub_term_output *term;

  FOR_ACTIVE_TERM_OUTPUTS(term)
  {
    grub_err_t err;

    if (grub_gfxmenu_try_hook && grub_strcmp (term->name, "gfxterm") == 0)
      {
	err = grub_gfxmenu_try_hook (entry, menu, nested);
	if(!err)
	  continue;
	grub_print_error ();
	grub_errno = GRUB_ERR_NONE;
      }

    err = grub_menu_try_text (term, entry, menu, nested);
    if(!err)
      continue;
    grub_print_error ();
    grub_errno = GRUB_ERR_NONE;
  }
}
Beispiel #3
0
static void
menu_init (int entry, grub_menu_t menu, int nested)
{
  struct grub_term_output *term;
  int gfxmenu = 0;

  FOR_ACTIVE_TERM_OUTPUTS(term)
    if (grub_strcmp (term->name, "gfxterm") == 0)
      {
	if (grub_env_get ("theme"))
	  {
	    if (!grub_gfxmenu_try_hook)
	      {
		grub_dl_load ("gfxmenu");
		grub_print_error ();
	      }
	    if (grub_gfxmenu_try_hook)
	      {
		grub_err_t err;
		err = grub_gfxmenu_try_hook (entry, menu, nested);
		if(!err)
		  {
		    gfxmenu = 1;
		    break;
		  }
	      }
	    else
	      grub_error (GRUB_ERR_BAD_MODULE,
			  N_("module `%s' isn't loaded"),
			  "gfxmenu");
	    grub_print_error ();
	    grub_wait_after_message ();
	  }
	grub_errno = GRUB_ERR_NONE;
	grub_gfxterm_fullscreen ();
	break;
      }

  FOR_ACTIVE_TERM_OUTPUTS(term)
  {
    grub_err_t err;

    if (grub_strcmp (term->name, "gfxterm") == 0 && gfxmenu)
      continue;

    err = grub_menu_try_text (term, entry, menu, nested);
    if(!err)
      continue;
    grub_print_error ();
    grub_errno = GRUB_ERR_NONE;
  }
}
Beispiel #4
0
static int
iterate_device (const char *name, void *data)
{
  struct search_ctx *ctx = data;
  char *cur_uuid;

  if (get_uuid (name, &cur_uuid, 1))
    {
      if (grub_errno == GRUB_ERR_UNKNOWN_FS)
	grub_errno = 0;
      grub_print_error ();
      return 0;
    }

  grub_dprintf ("nativedisk", "checking %s: %s\n", name,
		cur_uuid);
  if (ctx->prefix_uuid && grub_strcasecmp (cur_uuid, ctx->prefix_uuid) == 0)
    {
      char *prefix;
      prefix = grub_xasprintf ("(%s)/%s", name, ctx->prefix_path);
      grub_env_set ("prefix", prefix);
      grub_free (prefix);
      ctx->prefix_found = 1;
    }
  if (ctx->root_uuid && grub_strcasecmp (cur_uuid, ctx->root_uuid) == 0)
    {
      grub_env_set ("root", name);
      ctx->root_found = 1;
    }
  return ctx->prefix_found && ctx->root_found;
}
Beispiel #5
0
/* The auto-loading hook for filesystems.  */
static int
autoload_fs_module (void)
{
  grub_named_list_t p;
  int ret = 0;
  grub_file_filter_t grub_file_filters_was[GRUB_FILE_FILTER_MAX];

  grub_memcpy (grub_file_filters_was, grub_file_filters_enabled,
	       sizeof (grub_file_filters_enabled));
  grub_memcpy (grub_file_filters_enabled, grub_file_filters_all,
	       sizeof (grub_file_filters_enabled));

  while ((p = fs_module_list) != NULL)
    {
      if (! grub_dl_get (p->name) && grub_dl_load (p->name))
	{
	  ret = 1;
	  break;
	}

      if (grub_errno)
	grub_print_error ();

      fs_module_list = p->next;
      grub_free (p->name);
      grub_free (p);
    }

  grub_memcpy (grub_file_filters_enabled, grub_file_filters_was,
	       sizeof (grub_file_filters_enabled));

  return ret;
}
Beispiel #6
0
/* Execute ENTRY from the menu MENU, falling back to entries specified
   in the environment variable "fallback" if it fails.  CALLBACK is a
   pointer to a struct of function pointers which are used to allow the
   caller provide feedback to the user.  */
static void
grub_menu_execute_with_fallback (grub_menu_t menu,
				 grub_menu_entry_t entry,
				 int autobooted,
				 grub_menu_execute_callback_t callback,
				 void *callback_data)
{
  int fallback_entry;

  callback->notify_booting (entry, callback_data);

  grub_menu_execute_entry (entry, 1);

  /* Deal with fallback entries.  */
  while ((fallback_entry = get_and_remove_first_entry_number ("fallback"))
	 >= 0)
    {
      grub_print_error ();
      grub_errno = GRUB_ERR_NONE;

      entry = grub_menu_get_entry (menu, fallback_entry);
      callback->notify_fallback (entry, callback_data);
      grub_menu_execute_entry (entry, 1);
      /* If the function call to execute the entry returns at all, then this is
	 taken to indicate a boot failure.  For menu entries that do something
	 other than actually boot an operating system, this could assume
	 incorrectly that something failed.  */
    }

  if (!autobooted)
    callback->notify_failure (callback_data);
}
Beispiel #7
0
/* Helper for scan_disk.  */
static int
scan_disk_partition_iter (grub_disk_t disk, grub_partition_t p, void *data)
{
  const char *name = data;
  struct grub_diskfilter_vg *arr;
  grub_disk_addr_t start_sector;
  struct grub_diskfilter_pv_id id;
  grub_diskfilter_t diskfilter;

  grub_dprintf ("diskfilter", "Scanning for DISKFILTER devices on disk %s\n",
		name);
#ifdef GRUB_UTIL
  grub_util_info ("Scanning for DISKFILTER devices on disk %s", name);
#endif

  disk->partition = p;
  
  for (arr = array_list; arr != NULL; arr = arr->next)
    {
      struct grub_diskfilter_pv *m;
      for (m = arr->pvs; m; m = m->next)
	if (m->disk && m->disk->id == disk->id
	    && m->disk->dev->id == disk->dev->id
	    && m->part_start == grub_partition_get_start (disk->partition)
	    && m->part_size == grub_disk_get_size (disk))
	  return 0;
    }

  for (diskfilter = grub_diskfilter_list; diskfilter; diskfilter = diskfilter->next)
    {
#ifdef GRUB_UTIL
      grub_util_info ("Scanning for %s devices on disk %s", 
		      diskfilter->name, name);
#endif
      id.uuid = 0;
      id.uuidlen = 0;
      arr = diskfilter->detect (disk, &id, &start_sector);
      if (arr &&
	  (! insert_array (disk, &id, arr, start_sector, diskfilter)))
	{
	  if (id.uuidlen)
	    grub_free (id.uuid);
	  return 0;
	}
      if (arr && id.uuidlen)
	grub_free (id.uuid);

      /* This error usually means it's not diskfilter, no need to display
	 it.  */
      if (grub_errno != GRUB_ERR_OUT_OF_RANGE)
	grub_print_error ();

      grub_errno = GRUB_ERR_NONE;
    }

  return 0;
}
Beispiel #8
0
static void
grub_ieee1275_net_config_real (const char *devpath, char **device, char **path)
{
  struct grub_net_card *card;

  /* FIXME: Check that it's the right card.  */
  FOR_NET_CARDS (card)
  {
    char *bootp_response;
    char *cardpath;
    char *canon;

    grub_ssize_t size = -1;
    unsigned int i;

    if (card->driver != &ofdriver)
      continue;

    cardpath = ((struct grub_ofnetcard_data *) card->data)->path;
    canon = grub_ieee1275_canonicalise_devname (cardpath);
    if (grub_strcmp (devpath, canon) != 0)
      {
	grub_free (canon);
	continue;
      }
    grub_free (canon);

    for (i = 0; i < ARRAY_SIZE (bootp_response_properties); i++)
      if (grub_ieee1275_get_property_length (grub_ieee1275_chosen,
					     bootp_response_properties[i].name,
					     &size) >= 0)
	break;

    if (size < 0)
      return;

    bootp_response = grub_malloc (size);
    if (!bootp_response)
      {
	grub_print_error ();
	return;
      }
    if (grub_ieee1275_get_property (grub_ieee1275_chosen,
				    bootp_response_properties[i].name,
				    bootp_response, size, 0) < 0)
      return;

    grub_net_configure_by_dhcp_ack (card->name, card, 0,
				    (struct grub_net_bootp_packet *)
				    &bootp_response
				    + bootp_response_properties[i].offset,
				    size - bootp_response_properties[i].offset,
				    1, device, path);
    return;
  }
}
Beispiel #9
0
static grub_addr_t
grub_linux_claimmap_iterate (grub_addr_t target, grub_size_t size,
			     grub_size_t align)
{
  grub_addr_t found_addr = (grub_addr_t) -1;

  auto int NESTED_FUNC_ATTR alloc_mem (grub_uint64_t addr, grub_uint64_t len,
				       grub_memory_type_t type);
  int NESTED_FUNC_ATTR alloc_mem (grub_uint64_t addr, grub_uint64_t len,
				  grub_memory_type_t type)
  {
    grub_uint64_t end = addr + len;
    addr = ALIGN_UP (addr, align);
    target = ALIGN_UP (target, align);

    /* Target above the memory chunk.  */
    if (type != GRUB_MEMORY_AVAILABLE || target > end)
      return 0;

    /* Target inside the memory chunk.  */
    if (target >= addr && target < end && size <= end - target)
      {
	if (grub_claimmap (target, size) == GRUB_ERR_NONE)
	  {
	    found_addr = target;
	    return 1;
	  }
	grub_print_error ();
      }
    /* Target below the memory chunk.  */
    if (target < addr && addr + size <= end)
      {
	if (grub_claimmap (addr, size) == GRUB_ERR_NONE)
	  {
	    found_addr = addr;
	    return 1;
	  }
	grub_print_error ();
      }
    return 0;
  }
Beispiel #10
0
/* Replace the history entry on position POS with the string S.  */
static void
grub_history_set (int pos, grub_uint32_t *s, grub_size_t len)
{
  grub_free (hist_lines[pos]);
  hist_lines[pos] = grub_malloc ((len + 1) * sizeof (grub_uint32_t));
  if (!hist_lines[pos])
    {
      grub_print_error ();
      grub_errno = GRUB_ERR_NONE;
      return ;
    }
  grub_memcpy (hist_lines[pos], s, len * sizeof (grub_uint32_t));
  hist_lines[pos][len] = 0;
}
Beispiel #11
0
static grub_device_t
find_device (struct grub_btrfs_data *data, grub_uint64_t id,
	     int do_rescan)
{
  grub_device_t dev_found = NULL;
  auto int hook (const char *name);
  int hook (const char *name)
  {
    grub_device_t dev;
    grub_err_t err;
    struct grub_btrfs_superblock sb;
    dev = grub_device_open (name);
    if (!dev)
      return 0;
    if (!dev->disk)
      {
	grub_device_close (dev);
	return 0;
      }
    err = read_sblock (dev->disk, &sb);
    if (err == GRUB_ERR_BAD_FS)
      {
	grub_device_close (dev);
	grub_errno = GRUB_ERR_NONE;
	return 0;
      }
    if (err)
      {
	grub_device_close (dev);
	grub_print_error ();
	return 0;
      }
    if (grub_memcmp (data->sblock.uuid, sb.uuid, sizeof (sb.uuid)) != 0
	|| sb.this_device.device_id != id)
      {
	grub_device_close (dev);
	return 0;
      }
    
    dev_found = dev;
    return 1;
  }
Beispiel #12
0
grub_rescue_run (void)
{
  grub_printf ("Entering rescue mode...\n");

  while (1)
    {
      char *line;

      /* Print an error, if any.  */
      grub_print_error ();
      grub_errno = GRUB_ERR_NONE;

      grub_rescue_read_line (&line, 0);
      if (! line || line[0] == '\0')
	continue;

      grub_rescue_parse_line (line, grub_rescue_read_line);
      grub_free (line);
    }
}
Beispiel #13
0
/* The auto-loading hook for filesystems.  */
static int
autoload_fs_module (void)
{
  grub_named_list_t p;

  while ((p = fs_module_list) != NULL)
    {
      if (! grub_dl_get (p->name) && grub_dl_load (p->name))
	return 1;

      if (grub_errno)
	grub_print_error ();

      fs_module_list = p->next;
      grub_free (p->name);
      grub_free (p);
    }

  return 0;
}
Beispiel #14
0
static void
insert_bootpath (void)
{
  char *bootpath;
  grub_ssize_t bootpath_size;
  char *type;

  if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, "bootpath",
					 &bootpath_size)
      || bootpath_size <= 0)
    {
      /* Should never happen.  */
      grub_printf ("/chosen/bootpath property missing!\n");
      return;
    }

  bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64);
  if (! bootpath)
    {
      grub_print_error ();
      return;
    }
  grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", bootpath,
                              (grub_size_t) bootpath_size + 1, 0);
  bootpath[bootpath_size] = '\0';

  /* Transform an OF device path to a GRUB path.  */

  type = grub_ieee1275_get_device_type (bootpath);
  if (!(type && grub_strcmp (type, "network") == 0))
    {
      struct ofdisk_hash_ent *op;
      char *device = grub_ieee1275_get_devname (bootpath);
      op = ofdisk_hash_add (device, NULL);
      op->is_boot = 1;
    }
  grub_free (type);
  grub_free (bootpath);
}
Beispiel #15
0
/* Load all modules in core.  */
static void
grub_load_modules (void)
{
  auto int hook (struct grub_module_header *);
  int hook (struct grub_module_header *header)
    {
      /* Not an ELF module, skip.  */
      if (header->type != OBJ_TYPE_ELF)
        return 0;

      if (! grub_dl_load_core ((char *) header + sizeof (struct grub_module_header),
			       (header->size - sizeof (struct grub_module_header))))
	grub_fatal ("%s", grub_errmsg);

      if (grub_errno)
	grub_print_error ();

      return 0;
    }

  grub_module_iterate (hook);
}
Beispiel #16
0
/* Run a menu entry.  */
void
grub_menu_execute_entry(grub_menu_entry_t entry)
{
  grub_err_t err = GRUB_ERR_NONE;

  if (entry->restricted)
    err = grub_normal_check_authentication (entry->users);

  if (err)
    {
      grub_print_error ();
      grub_errno = GRUB_ERR_NONE;
      return;
    }

  grub_env_set ("chosen", entry->title);

  grub_parser_execute ((char *) entry->sourcecode);

  if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
    /* Implicit execution of boot, only if something is loaded.  */
    grub_command_execute ("boot", 0, 0);
}
Beispiel #17
0
static grub_err_t
tftp_close (struct grub_file *file)
{
    tftp_data_t data = file->data;

    if (data->sock)
    {
        grub_uint8_t nbdata[512];
        grub_err_t err;
        struct grub_net_buff nb_err;
        struct tftphdr *tftph;

        nb_err.head = nbdata;
        nb_err.end = nbdata + sizeof (nbdata);

        grub_netbuff_clear (&nb_err);
        grub_netbuff_reserve (&nb_err, 512);
        err = grub_netbuff_push (&nb_err, sizeof (tftph->opcode)
                                 + sizeof (tftph->u.err.errcode)
                                 + sizeof ("closed"));
        if (!err)
        {
            tftph = (struct tftphdr *) nb_err.data;
            tftph->opcode = grub_cpu_to_be16_compile_time (TFTP_ERROR);
            tftph->u.err.errcode = grub_cpu_to_be16_compile_time (TFTP_EUNDEF);
            grub_memcpy (tftph->u.err.errmsg, "closed", sizeof ("closed"));

            err = grub_net_send_udp_packet (data->sock, &nb_err);
        }
        if (err)
            grub_print_error ();
        grub_net_udp_close (data->sock);
    }
    destroy_pq (data);
    grub_free (data);
    return GRUB_ERR_NONE;
}
Beispiel #18
0
static grub_menu_t
read_config_file (const char *config)
{
  grub_file_t file;

  auto grub_err_t getline (char **line, int cont);
  grub_err_t getline (char **line, int cont __attribute__ ((unused)))
    {
      while (1)
	{
	  char *buf;

	  *line = buf = grub_file_getline (file);
	  if (! buf)
	    return grub_errno;

	  if (buf[0] == '#')
	    grub_free (*line);
	  else
	    break;
	}

      return GRUB_ERR_NONE;
    }

  grub_menu_t newmenu;

  newmenu = grub_env_get_menu ();
  if (! newmenu)
    {
      newmenu = grub_zalloc (sizeof (*newmenu));
      if (! newmenu)
	return 0;

      grub_env_set_menu (newmenu);
    }

  /* Try to open the config file.  */
  file = grub_file_open (config);
  if (! file)
    return 0;

  while (1)
    {
      char *line;

      /* Print an error, if any.  */
      grub_print_error ();
      grub_errno = GRUB_ERR_NONE;

      if ((getline (&line, 0)) || (! line))
	break;

      grub_normal_parse_line (line, getline);
      grub_free (line);
    }

  grub_file_close (file);

  return newmenu;
}
Beispiel #19
0
static void
probe (const char *path, char **device_names, char delim)
{
  char **drives_names = NULL;
  char **curdev, **curdrive;
  char *grub_path = NULL;
  int ndev = 0;

  if (path != NULL)
    {
      grub_path = canonicalize_file_name (path);
      if (! grub_path)
	grub_util_error (_("failed to get canonical path of `%s'"), path);
      device_names = grub_guess_root_devices (grub_path);
      free (grub_path);
    }

  if (! device_names)
    grub_util_error (_("cannot find a device for %s (is /dev mounted?)"), path);

  if (print == PRINT_DEVICE)
    {
      for (curdev = device_names; *curdev; curdev++)
	{
	  printf ("%s", *curdev);
	  putchar (delim);
	}
      return;
    }

  if (print == PRINT_DISK)
    {
      for (curdev = device_names; *curdev; curdev++)
	{
	  char *disk;
	  disk = grub_util_get_os_disk (*curdev);
	  if (!disk)
	    {
	      grub_print_error ();
	      continue;
	    }
	  printf ("%s", disk);
	  putchar (delim);
	}
      return;
    }

  for (curdev = device_names; *curdev; curdev++)
    {
      grub_util_pull_device (*curdev);
      ndev++;
    }
  
  drives_names = xmalloc (sizeof (drives_names[0]) * (ndev + 1)); 

  for (curdev = device_names, curdrive = drives_names; *curdev; curdev++,
       curdrive++)
    {
      *curdrive = grub_util_get_grub_dev (*curdev);
      if (! *curdrive)
	grub_util_error (_("cannot find a GRUB drive for %s.  Check your device.map"),
			 *curdev);
    }
  *curdrive = 0;

  if (print == PRINT_DRIVE)
    {
      for (curdrive = drives_names; *curdrive; curdrive++)
	{
	  printf ("(%s)", *curdrive);
	  putchar (delim);
	}
      goto end;
    }

  if (print == PRINT_ZERO_CHECK)
    {
      for (curdev = drives_names; *curdev; curdev++)
	{
	  grub_device_t dev = NULL;
	  grub_uint32_t buffer[32768];
	  grub_disk_addr_t addr;
	  grub_disk_addr_t dsize;

	  grub_util_info ("opening %s", *curdev);
	  dev = grub_device_open (*curdev);
	  if (! dev || !dev->disk)
	    grub_util_error ("%s", grub_errmsg);

	  dsize = grub_disk_get_size (dev->disk);
	  for (addr = 0; addr < dsize;
	       addr += sizeof (buffer) / GRUB_DISK_SECTOR_SIZE)
	    {
	      grub_size_t sz = sizeof (buffer);
	      grub_uint32_t *ptr;

	      if (sizeof (buffer) / GRUB_DISK_SECTOR_SIZE > dsize - addr)
		sz = (dsize - addr) * GRUB_DISK_SECTOR_SIZE;
	      grub_disk_read (dev->disk, addr, 0, sz, buffer);

	      for (ptr = buffer; ptr < buffer + sz / sizeof (*buffer); ptr++)
		if (*ptr)
		  {
		    grub_printf ("false\n");
		    grub_device_close (dev);
		    goto end;
		  }
	    }

	  grub_device_close (dev);
	}
      grub_printf ("true\n");
    }

  if (print == PRINT_FS || print == PRINT_FS_UUID
      || print == PRINT_FS_LABEL)
    {
      grub_device_t dev = NULL;
      grub_fs_t fs;

      grub_util_info ("opening %s", drives_names[0]);
      dev = grub_device_open (drives_names[0]);
      if (! dev)
	grub_util_error ("%s", grub_errmsg);
      
      fs = grub_fs_probe (dev);
      if (! fs)
	grub_util_error ("%s", grub_errmsg);

      if (print == PRINT_FS)
	{
	  printf ("%s", fs->name);
	  putchar (delim);
	}
      else if (print == PRINT_FS_UUID)
	{
	  char *uuid;
	  if (! fs->uuid)
	    grub_util_error (_("%s does not support UUIDs"), fs->name);

	  if (fs->uuid (dev, &uuid) != GRUB_ERR_NONE)
	    grub_util_error ("%s", grub_errmsg);

	  printf ("%s", uuid);
	  putchar (delim);
	}
      else if (print == PRINT_FS_LABEL)
	{
	  char *label;
	  if (! fs->label)
	    grub_util_error (_("filesystem `%s' does not support labels"),
			     fs->name);

	  if (fs->label (dev, &label) != GRUB_ERR_NONE)
	    grub_util_error ("%s", grub_errmsg);

	  printf ("%s", label);
	  putchar (delim);
	}
      grub_device_close (dev);
      goto end;
    }

  for (curdrive = drives_names, curdev = device_names; *curdrive;
       curdrive++, curdev++)
    {
      grub_device_t dev = NULL;

      grub_util_info ("opening %s", *curdrive);
      dev = grub_device_open (*curdrive);
      if (! dev)
	grub_util_error ("%s", grub_errmsg);

      if (print == PRINT_HINT_STR)
	{
	  const char *osdev = grub_util_biosdisk_get_osdev (dev->disk);
	  const char *ofpath = osdev ? grub_util_devname_to_ofpath (osdev) : 0;
	  char *biosname, *bare, *efi;
	  const char *map;

	  if (ofpath)
	    {
	      char *tmp = xmalloc (strlen (ofpath) + sizeof ("ieee1275/"));
	      char *p;
	      p = grub_stpcpy (tmp, "ieee1275/");
	      strcpy (p, ofpath);
	      printf ("--hint-ieee1275='");
	      print_full_name (tmp, dev);
	      printf ("' ");
	      free (tmp);
	    }

	  biosname = guess_bios_drive (*curdev);
	  if (biosname)
	    {
	      printf ("--hint-bios=");
	      print_full_name (biosname, dev);
	      printf (" ");
	    }
	  free (biosname);

	  efi = guess_efi_drive (*curdev);
	  if (efi)
	    {
	      printf ("--hint-efi=");
	      print_full_name (efi, dev);
	      printf (" ");
	    }
	  free (efi);

	  bare = guess_baremetal_drive (*curdev);
	  if (bare)
	    {
	      printf ("--hint-baremetal=");
	      print_full_name (bare, dev);
	      printf (" ");
	    }
	  free (bare);

	  /* FIXME: Add ARC hint.  */

	  map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
	  if (map)
	    {
	      printf ("--hint='");
	      print_full_name (map, dev);
	      printf ("' ");
	    }
	  if (curdrive[1])
	    printf (" ");
	  else
	    printf ("\n");

	  grub_device_close (dev);
	  continue;
	}
      
      if ((print == PRINT_COMPATIBILITY_HINT || print == PRINT_BIOS_HINT
	   || print == PRINT_IEEE1275_HINT || print == PRINT_BAREMETAL_HINT
	   || print == PRINT_EFI_HINT || print == PRINT_ARC_HINT)
	  && dev->disk->dev->id != GRUB_DISK_DEVICE_HOSTDISK_ID)
	{
	  print_full_name (dev->disk->name, dev);
	  putchar (delim);
	  continue;
	}

      if (print == PRINT_COMPATIBILITY_HINT)
	{
	  const char *map;
	  char *biosname;
	  map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
	  if (map)
	    {
	      print_full_name (map, dev);
	      putchar (delim);
	      grub_device_close (dev);
	      /* Compatibility hint is one device only.  */
	      break;
	    }
	  biosname = guess_bios_drive (*curdev);
	  if (biosname)
	    {
	      print_full_name (biosname, dev);
	      putchar (delim);
	    }
	  free (biosname);
	  grub_device_close (dev);
	  /* Compatibility hint is one device only.  */
	  if (biosname)
	    break;
	  continue;
	}

      if (print == PRINT_BIOS_HINT)
	{
	  char *biosname;
	  biosname = guess_bios_drive (*curdev);
	  if (biosname)
	    {
	      print_full_name (biosname, dev);
	      putchar (delim);
	    }
	  free (biosname);
	  grub_device_close (dev);
	  continue;
	}
      if (print == PRINT_IEEE1275_HINT)
	{
	  const char *osdev = grub_util_biosdisk_get_osdev (dev->disk);
	  const char *ofpath = grub_util_devname_to_ofpath (osdev);
	  const char *map;

	  map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
	  if (map)
	    {
	      print_full_name (map, dev);
	      putchar (delim);
	    }

	  if (ofpath)
	    {
	      char *tmp = xmalloc (strlen (ofpath) + sizeof ("ieee1275/"));
	      char *p;
	      p = grub_stpcpy (tmp, "ieee1275/");
	      strcpy (p, ofpath);
	      print_full_name (tmp, dev);
	      free (tmp);
	      putchar (delim);
	    }

	  grub_device_close (dev);
	  continue;
	}
      if (print == PRINT_EFI_HINT)
	{
	  char *biosname;
	  const char *map;
	  biosname = guess_efi_drive (*curdev);

	  map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
	  if (map)
	    {
	      print_full_name (map, dev);
	      putchar (delim);
	    }
	  if (biosname)
	    {
	      print_full_name (biosname, dev);
	      putchar (delim);
	    }

	  free (biosname);
	  grub_device_close (dev);
	  continue;
	}

      if (print == PRINT_BAREMETAL_HINT)
	{
	  char *biosname;
	  const char *map;

	  biosname = guess_baremetal_drive (*curdev);

	  map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
	  if (map)
	    {
	      print_full_name (map, dev);
	      putchar (delim);
	    }
	  if (biosname)
	    {
	      print_full_name (biosname, dev);
	      putchar (delim);
	    }

	  free (biosname);
	  grub_device_close (dev);
	  continue;
	}

      if (print == PRINT_ARC_HINT)
	{
	  const char *map;

	  map = grub_util_biosdisk_get_compatibility_hint (dev->disk);
	  if (map)
	    {
	      print_full_name (map, dev);
	      putchar (delim);
	    }

	  /* FIXME */
	  grub_device_close (dev);
	  continue;
	}

      if (print == PRINT_ABSTRACTION)
	{
	  probe_abstraction (dev->disk);
	  putchar (delim);
	  grub_device_close (dev);
	  continue;
	}

      if (print == PRINT_CRYPTODISK_UUID)
	{
	  probe_cryptodisk_uuid (dev->disk);
	  putchar (delim);
	  grub_device_close (dev);
	  continue;
	}

      if (print == PRINT_PARTMAP)
	{
	  /* Check if dev->disk itself is contained in a partmap.  */
	  probe_partmap (dev->disk);
	  putchar (delim);
	  grub_device_close (dev);
	  continue;
	}

      if (print == PRINT_MSDOS_PARTTYPE)
	{
	  if (dev->disk->partition
	      && strcmp(dev->disk->partition->partmap->name, "msdos") == 0)
	    printf ("%02x", dev->disk->partition->msdostype);

	  putchar (delim);
	  grub_device_close (dev);
	  continue;
	}

      if (print == PRINT_GPT_PARTTYPE)
	{
          if (dev->disk->partition
	      && strcmp (dev->disk->partition->partmap->name, "gpt") == 0)
            {
              struct grub_gpt_partentry gptdata;
              grub_partition_t p = dev->disk->partition;
              dev->disk->partition = dev->disk->partition->parent;

              if (grub_disk_read (dev->disk, p->offset, p->index,
                                  sizeof (gptdata), &gptdata) == 0)
                {
                  grub_gpt_part_type_t gpttype;
                  gpttype.data1 = grub_le_to_cpu32 (gptdata.type.data1);
                  gpttype.data2 = grub_le_to_cpu16 (gptdata.type.data2);
                  gpttype.data3 = grub_le_to_cpu16 (gptdata.type.data3);
                  grub_memcpy (gpttype.data4, gptdata.type.data4, 8);

                  grub_printf ("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
                               gpttype.data1, gpttype.data2,
                               gpttype.data3, gpttype.data4[0], 
                               gpttype.data4[1], gpttype.data4[2],
                               gpttype.data4[3], gpttype.data4[4],
                               gpttype.data4[5], gpttype.data4[6],
                               gpttype.data4[7]);
                }
              dev->disk->partition = p;
            }
          putchar (delim);
          grub_device_close (dev);
          continue;
        }
    }

 end:
  for (curdrive = drives_names; *curdrive; curdrive++)
    free (*curdrive);
  free (drives_names);
}
Beispiel #20
0
static void
grub_ofnet_findcards (void)
{
  auto int search_net_devices (struct grub_ieee1275_devalias *alias);

  int search_net_devices (struct grub_ieee1275_devalias *alias)
  {
    if (!grub_strcmp (alias->type, "network"))
      {
	struct grub_ofnetcard_data *ofdata;
	struct grub_net_card *card;
	grub_ieee1275_phandle_t devhandle;
	grub_net_link_level_address_t lla;
	char *shortname;

	ofdata = grub_malloc (sizeof (struct grub_ofnetcard_data));
	if (!ofdata)
	  {
	    grub_print_error ();
	    return 1;
	  }
	card = grub_zalloc (sizeof (struct grub_net_card));
	if (!card)
	  {
	    grub_free (ofdata);
	    grub_print_error ();
	    return 1;
	  }

	ofdata->path = grub_strdup (alias->path);

	grub_ieee1275_finddevice (ofdata->path, &devhandle);

	if (grub_ieee1275_get_integer_property
	    (devhandle, "max-frame-size", &(ofdata->mtu),
	     sizeof (ofdata->mtu), 0))
	  {
	    ofdata->mtu = 1500;
	  }

	if (grub_ieee1275_get_property (devhandle, "mac-address",
					&(lla.mac), 6, 0)
	    && grub_ieee1275_get_property (devhandle, "local-mac-address",
					   &(lla.mac), 6, 0))
	  {
	    grub_error (GRUB_ERR_IO, "Couldn't retrieve mac address.");
	    grub_print_error ();
	    return 0;
	  }

	lla.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
	card->default_address = lla;

	card->driver = NULL;
	card->data = ofdata;
	card->flags = 0;
	shortname = find_alias (alias->path);
	card->name = grub_xasprintf ("ofnet_%s", shortname ? : alias->path);
	card->idle_poll_delay_ms = 1;
	grub_free (shortname);

	card->driver = &ofdriver;
	grub_net_card_register (card);
	return 0;
      }
    return 0;
  }

  /* Look at all nodes for devices of the type network.  */
  grub_ieee1275_devices_iterate (search_net_devices);
}
Beispiel #21
0
static grub_err_t
interactive (void)
{
  const char *ps1 = "lua> ";
  const char *ps2 = "lua>> ";
  const char *prompt = ps1;
  char *line;
  char *chunk = NULL;
  size_t len;
  size_t oldlen = 0;
  int r;

  grub_printf ("%s", N_ ("Welcome to lua, press the escape key to exit."));

  while ((line = grub_cmdline_get (prompt)) != NULL)
    {
      /* len = lenght of chunk + line + newline character */
      len = oldlen + grub_strlen (line) + 1;
      chunk = grub_realloc (chunk, len + 1);
      grub_strcpy (chunk + oldlen , line);
      chunk[len - 1] = '\n';
      chunk[len] = '\0';
      grub_free (line);

      r = luaL_loadbuffer (state, chunk, len, "stdin");
      if (!r)
	{
	  /* No error: Execute this chunk and prepare to read another */
	  r = lua_pcall (state, 0, 0, 0);
	  if (r)
	    {
	      handle_lua_error ("Lua");
	      grub_print_error ();
	    }

	  grub_free (chunk);
	  chunk = NULL;
	  len = 0;
	  prompt = ps1;
	}
      else if (incomplete (state, r))
	{
	  /* Chunk is incomplete, try reading another line */
	  prompt = ps2;
	}
      else if (r == LUA_ERRSYNTAX)
	{
	  handle_lua_error ("Lua");
	  grub_print_error ();

	  /* This chunk is garbage, try starting another one */
	  grub_free (chunk);
	  chunk = NULL;
	  len = 0;
	  prompt = ps1;
	}
      else
	{
	  /* Handle errors other than syntax errors (out of memory, etc.) */
	  grub_free (chunk);
	  handle_lua_error ("Lua parser failed");
	  return grub_errno;
	}

      oldlen = len;
    }

  grub_free (chunk);
  lua_gc (state, LUA_GCCOLLECT, 0);

  return grub_errno;
}
Beispiel #22
0
grub_err_t
grub_multiboot_make_mbi (grub_uint32_t *target)
{
  struct multiboot_info *mbi;
  struct multiboot_mod_list *modlist;
  unsigned i;
  struct module *cur;
  grub_size_t mmap_size;
  grub_uint8_t *ptrorig; 
  grub_addr_t ptrdest;

  grub_err_t err;
  grub_size_t bufsize;
  grub_relocator_chunk_t ch;

  bufsize = grub_multiboot_get_mbi_size ();

  err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
					  0x10000, 0xa0000 - bufsize,
					  bufsize, 4,
					  GRUB_RELOCATOR_PREFERENCE_NONE, 0);
  if (err)
    return err;
  ptrorig = get_virtual_current_address (ch);
  ptrdest = get_physical_target_address (ch);

  *target = ptrdest;

  mbi = (struct multiboot_info *) ptrorig;
  ptrorig += sizeof (*mbi);
  ptrdest += sizeof (*mbi);
  grub_memset (mbi, 0, sizeof (*mbi));

  grub_memcpy (ptrorig, cmdline, cmdline_size);
  mbi->flags |= MULTIBOOT_INFO_CMDLINE;
  mbi->cmdline = ptrdest;
  ptrorig += ALIGN_UP (cmdline_size, 4);
  ptrdest += ALIGN_UP (cmdline_size, 4);

  grub_memcpy (ptrorig, PACKAGE_STRING, sizeof(PACKAGE_STRING));
  mbi->flags |= MULTIBOOT_INFO_BOOT_LOADER_NAME;
  mbi->boot_loader_name = ptrdest;
  ptrorig += ALIGN_UP (sizeof(PACKAGE_STRING), 4);
  ptrdest += ALIGN_UP (sizeof(PACKAGE_STRING), 4);

#ifdef GRUB_MACHINE_PCBIOS
  {
    struct grub_apm_info info;
    if (grub_apm_get_info (&info))
      {
	struct multiboot_apm_info *mbinfo = (void *) ptrorig;

	mbinfo->cseg = info.cseg;
	mbinfo->offset = info.offset;
	mbinfo->cseg_16 = info.cseg_16;
	mbinfo->dseg = info.dseg;
	mbinfo->flags = info.flags;
	mbinfo->cseg_len = info.cseg_len;
	mbinfo->dseg_len = info.dseg_len;
	mbinfo->cseg_16_len = info.cseg_16_len;
	mbinfo->version = info.version;

	ptrorig += ALIGN_UP (sizeof (struct multiboot_apm_info), 4);
	ptrdest += ALIGN_UP (sizeof (struct multiboot_apm_info), 4);
      }
  }
#endif

  if (modcnt)
    {
      mbi->flags |= MULTIBOOT_INFO_MODS;
      mbi->mods_addr = ptrdest;
      mbi->mods_count = modcnt;
      modlist = (struct multiboot_mod_list *) ptrorig;
      ptrorig += modcnt * sizeof (struct multiboot_mod_list);
      ptrdest += modcnt * sizeof (struct multiboot_mod_list);

      for (i = 0, cur = modules; i < modcnt; i++, cur = cur->next)
	{
	  modlist[i].mod_start = cur->start;
	  modlist[i].mod_end = modlist[i].mod_start + cur->size;
	  modlist[i].cmdline = ptrdest;
	  grub_memcpy (ptrorig, cur->cmdline, cur->cmdline_size);
	  ptrorig += ALIGN_UP (cur->cmdline_size, 4);
	  ptrdest += ALIGN_UP (cur->cmdline_size, 4);
	}
    }
  else
    {
      mbi->mods_addr = 0;
      mbi->mods_count = 0;
    }

  mmap_size = grub_get_multiboot_mmap_count () 
    * sizeof (struct multiboot_mmap_entry);
  grub_fill_multiboot_mmap ((struct multiboot_mmap_entry *) ptrorig);
  mbi->mmap_length = mmap_size;
  mbi->mmap_addr = ptrdest;
  mbi->flags |= MULTIBOOT_INFO_MEM_MAP;
  ptrorig += mmap_size;
  ptrdest += mmap_size;

  /* Convert from bytes to kilobytes.  */
  mbi->mem_lower = grub_mmap_get_lower () / 1024;
  mbi->mem_upper = grub_mmap_get_upper () / 1024;
  mbi->flags |= MULTIBOOT_INFO_MEMORY;

  if (bootdev_set)
    {
      mbi->boot_device = bootdev;
      mbi->flags |= MULTIBOOT_INFO_BOOTDEV;
    }

  {
    struct grub_net_network_level_interface *net;
    FOR_NET_NETWORK_LEVEL_INTERFACES(net)
      if (net->dhcp_ack)
	{
	  grub_memcpy (ptrorig, net->dhcp_ack, net->dhcp_acklen);
	  mbi->drives_addr = ptrdest;
	  mbi->drives_length = net->dhcp_acklen;
	  ptrorig += net->dhcp_acklen;
	  ptrdest += net->dhcp_acklen;
	  break;
	}
  }

  if (elf_sec_num)
    {
      mbi->u.elf_sec.addr = ptrdest;
      grub_memcpy (ptrorig, elf_sections, elf_sec_entsize * elf_sec_num);
      mbi->u.elf_sec.num = elf_sec_num;
      mbi->u.elf_sec.size = elf_sec_entsize;
      mbi->u.elf_sec.shndx = elf_sec_shstrndx;

      mbi->flags |= MULTIBOOT_INFO_ELF_SHDR;

      ptrorig += elf_sec_entsize * elf_sec_num;
      ptrdest += elf_sec_entsize * elf_sec_num;
    }

  err = retrieve_video_parameters (mbi, ptrorig, ptrdest);
  if (err)
    {
      grub_print_error ();
      grub_errno = GRUB_ERR_NONE;
    }

  if ((mbi->flags & MULTIBOOT_INFO_FRAMEBUFFER_INFO)
      && mbi->framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED)
    {
      ptrorig += mbi->framebuffer_palette_num_colors
	* sizeof (struct multiboot_color);
      ptrdest += mbi->framebuffer_palette_num_colors
	* sizeof (struct multiboot_color);
    }

#if GRUB_MACHINE_HAS_VBE
  ptrorig += sizeof (struct grub_vbe_info_block);
  ptrdest += sizeof (struct grub_vbe_info_block);
  ptrorig += sizeof (struct grub_vbe_mode_info_block);
  ptrdest += sizeof (struct grub_vbe_mode_info_block);
#endif

#ifdef GRUB_MACHINE_EFI
  err = grub_efi_finish_boot_services (NULL, NULL, NULL, NULL, NULL);
  if (err)
    return err;
#endif

  return GRUB_ERR_NONE;
}
Beispiel #23
0
grub_err_t
grub_multiboot_make_mbi (grub_uint32_t *target)
{
  grub_properly_aligned_t *ptrorig;
  grub_properly_aligned_t *mbistart;
  grub_err_t err;
  grub_size_t bufsize;
  grub_relocator_chunk_t ch;

  bufsize = grub_multiboot_get_mbi_size ();

  COMPILE_TIME_ASSERT (MULTIBOOT_TAG_ALIGN % sizeof (grub_properly_aligned_t) == 0);

  err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
					  0, 0xffffffff - bufsize,
					  bufsize, MULTIBOOT_TAG_ALIGN,
					  GRUB_RELOCATOR_PREFERENCE_NONE, 1);
  if (err)
    return err;

  ptrorig = get_virtual_current_address (ch);
#if defined (__i386__) || defined (__x86_64__)
  *target = get_physical_target_address (ch);
#elif defined (__mips)
  *target = get_physical_target_address (ch) | 0x80000000;
#else
#error Please complete this
#endif

  mbistart = ptrorig;
  COMPILE_TIME_ASSERT ((2 * sizeof (grub_uint32_t))
		       % sizeof (grub_properly_aligned_t) == 0);
  COMPILE_TIME_ASSERT (MULTIBOOT_TAG_ALIGN
		       % sizeof (grub_properly_aligned_t) == 0);
  ptrorig += (2 * sizeof (grub_uint32_t)) / sizeof (grub_properly_aligned_t);

  {
    struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig;
    tag->type = MULTIBOOT_TAG_TYPE_CMDLINE;
    tag->size = sizeof (struct multiboot_tag_string) + cmdline_size; 
    grub_memcpy (tag->string, cmdline, cmdline_size);
    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
       / sizeof (grub_properly_aligned_t);
  }

  {
    struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig;
    tag->type = MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME;
    tag->size = sizeof (struct multiboot_tag_string) + sizeof (PACKAGE_STRING); 
    grub_memcpy (tag->string, PACKAGE_STRING, sizeof (PACKAGE_STRING));
    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
      / sizeof (grub_properly_aligned_t);
  }

#ifdef GRUB_MACHINE_PCBIOS
  {
    struct grub_apm_info info;
    if (grub_apm_get_info (&info))
      {
	struct multiboot_tag_apm *tag = (struct multiboot_tag_apm *) ptrorig;

	tag->type = MULTIBOOT_TAG_TYPE_APM;
	tag->size = sizeof (struct multiboot_tag_apm); 

	tag->cseg = info.cseg;
	tag->offset = info.offset;
	tag->cseg_16 = info.cseg_16;
	tag->dseg = info.dseg;
	tag->flags = info.flags;
	tag->cseg_len = info.cseg_len;
	tag->dseg_len = info.dseg_len;
	tag->cseg_16_len = info.cseg_16_len;
	tag->version = info.version;

	ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
	  / sizeof (grub_properly_aligned_t);
      }
  }
#endif

  {
    unsigned i;
    struct module *cur;

    for (i = 0, cur = modules; i < modcnt; i++, cur = cur->next)
      {
	struct multiboot_tag_module *tag
	  = (struct multiboot_tag_module *) ptrorig;
	tag->type = MULTIBOOT_TAG_TYPE_MODULE;
	tag->size = sizeof (struct multiboot_tag_module) + cur->cmdline_size;
	tag->mod_start = cur->start;
	tag->mod_end = tag->mod_start + cur->size;
	grub_memcpy (tag->cmdline, cur->cmdline, cur->cmdline_size);
	ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
	  / sizeof (grub_properly_aligned_t);
      }
  }

  {
    struct multiboot_tag_mmap *tag = (struct multiboot_tag_mmap *) ptrorig;
    grub_fill_multiboot_mmap (tag);
    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
      / sizeof (grub_properly_aligned_t);
  }

  {
    struct multiboot_tag_elf_sections *tag
      = (struct multiboot_tag_elf_sections *) ptrorig;
    tag->type = MULTIBOOT_TAG_TYPE_ELF_SECTIONS;
    tag->size = sizeof (struct multiboot_tag_elf_sections)
      + elf_sec_entsize * elf_sec_num;
    grub_memcpy (tag->sections, elf_sections, elf_sec_entsize * elf_sec_num);
    tag->num = elf_sec_num;
    tag->entsize = elf_sec_entsize;
    tag->shndx = elf_sec_shstrndx;
    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
      / sizeof (grub_properly_aligned_t);
  }

  {
    struct multiboot_tag_basic_meminfo *tag
      = (struct multiboot_tag_basic_meminfo *) ptrorig;
    tag->type = MULTIBOOT_TAG_TYPE_BASIC_MEMINFO;
    tag->size = sizeof (struct multiboot_tag_basic_meminfo); 

    /* Convert from bytes to kilobytes.  */
    tag->mem_lower = grub_mmap_get_lower () / 1024;
    tag->mem_upper = grub_mmap_get_upper () / 1024;
    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
       / sizeof (grub_properly_aligned_t);
  }

  {
    struct grub_net_network_level_interface *net;

    FOR_NET_NETWORK_LEVEL_INTERFACES(net)
      if (net->dhcp_ack)
	{
	  struct multiboot_tag_network *tag
	    = (struct multiboot_tag_network *) ptrorig;
	  tag->type = MULTIBOOT_TAG_TYPE_NETWORK;
	  tag->size = sizeof (struct multiboot_tag_network) + net->dhcp_acklen;
	  grub_memcpy (tag->dhcpack, net->dhcp_ack, net->dhcp_acklen);
	  ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
	    / sizeof (grub_properly_aligned_t);
	}
  }

  if (bootdev_set)
    {
      struct multiboot_tag_bootdev *tag
	= (struct multiboot_tag_bootdev *) ptrorig;
      tag->type = MULTIBOOT_TAG_TYPE_BOOTDEV;
      tag->size = sizeof (struct multiboot_tag_bootdev); 

      tag->biosdev = biosdev;
      tag->slice = slice;
      tag->part = part;
      ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
	/ sizeof (grub_properly_aligned_t);
    }

  {
    err = retrieve_video_parameters (&ptrorig);
    if (err)
      {
	grub_print_error ();
	grub_errno = GRUB_ERR_NONE;
      }
  }

#if defined (GRUB_MACHINE_EFI) && defined (__x86_64__)
  {
    struct multiboot_tag_efi64 *tag = (struct multiboot_tag_efi64 *) ptrorig;
    tag->type = MULTIBOOT_TAG_TYPE_EFI64;
    tag->size = sizeof (*tag);
    tag->pointer = (grub_addr_t) grub_efi_system_table;
    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
      / sizeof (grub_properly_aligned_t);
  }
#endif

#if defined (GRUB_MACHINE_EFI) && defined (__i386__)
  {
    struct multiboot_tag_efi32 *tag = (struct multiboot_tag_efi32 *) ptrorig;
    tag->type = MULTIBOOT_TAG_TYPE_EFI32;
    tag->size = sizeof (*tag);
    tag->pointer = (grub_addr_t) grub_efi_system_table;
    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
      / sizeof (grub_properly_aligned_t);
  }
#endif

#if GRUB_MACHINE_HAS_ACPI
  {
    struct multiboot_tag_old_acpi *tag = (struct multiboot_tag_old_acpi *)
      ptrorig;
    struct grub_acpi_rsdp_v10 *a = grub_acpi_get_rsdpv1 ();
    if (a)
      {
	tag->type = MULTIBOOT_TAG_TYPE_ACPI_OLD;
	tag->size = sizeof (*tag) + sizeof (*a);
	grub_memcpy (tag->rsdp, a, sizeof (*a));
	ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
	  / sizeof (grub_properly_aligned_t);
      }
  }

  {
    struct multiboot_tag_new_acpi *tag = (struct multiboot_tag_new_acpi *)
      ptrorig;
    struct grub_acpi_rsdp_v20 *a = grub_acpi_get_rsdpv2 ();
    if (a)
      {
	tag->type = MULTIBOOT_TAG_TYPE_ACPI_NEW;
	tag->size = sizeof (*tag) + a->length;
	grub_memcpy (tag->rsdp, a, a->length);
	ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
	  / sizeof (grub_properly_aligned_t);
      }
  }
#endif

#ifdef GRUB_MACHINE_EFI
  {
    struct multiboot_tag_efi_mmap *tag = (struct multiboot_tag_efi_mmap *) ptrorig;
    grub_efi_uintn_t efi_desc_size;
    grub_efi_uint32_t efi_desc_version;

    tag->type = MULTIBOOT_TAG_TYPE_EFI_MMAP;
    tag->size = sizeof (*tag) + efi_mmap_size;

    if (!keep_bs)
      err = grub_efi_finish_boot_services (&efi_mmap_size, tag->efi_mmap, NULL,
					   &efi_desc_size, &efi_desc_version);
    else
      {
	if (grub_efi_get_memory_map (&efi_mmap_size, (void *) tag->efi_mmap,
				     NULL,
				     &efi_desc_size, &efi_desc_version) <= 0)
	  err = grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
      }
    if (err)
      return err;
    tag->descr_size = efi_desc_size;
    tag->descr_vers = efi_desc_version;
    tag->size = sizeof (*tag) + efi_mmap_size;

    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
      / sizeof (grub_properly_aligned_t);
  }

  if (keep_bs)
    {
      struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig;
      tag->type = MULTIBOOT_TAG_TYPE_EFI_BS;
      tag->size = sizeof (struct multiboot_tag);
      ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
	/ sizeof (grub_properly_aligned_t);
    }
#endif

  {
    struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig;
    tag->type = MULTIBOOT_TAG_TYPE_END;
    tag->size = sizeof (struct multiboot_tag);
    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
      / sizeof (grub_properly_aligned_t);
  }

  ((grub_uint32_t *) mbistart)[0] = (char *) ptrorig - (char *) mbistart;
  ((grub_uint32_t *) mbistart)[1] = 0;

  return GRUB_ERR_NONE;
}
Beispiel #24
0
static grub_err_t
retrieve_video_parameters (grub_properly_aligned_t **ptrorig)
{
  grub_err_t err;
  struct grub_video_mode_info mode_info;
  void *framebuffer;
  grub_video_driver_id_t driv_id;
  struct grub_video_palette_data palette[256];
  struct multiboot_tag_framebuffer *tag
    = (struct multiboot_tag_framebuffer *) *ptrorig;

  err = grub_multiboot_set_video_mode ();
  if (err)
    {
      grub_print_error ();
      grub_errno = GRUB_ERR_NONE;
    }

  grub_video_get_palette (0, ARRAY_SIZE (palette), palette);

  driv_id = grub_video_get_driver_id ();
#if HAS_VGA_TEXT
  if (driv_id == GRUB_VIDEO_DRIVER_NONE)
    {
      struct grub_vbe_mode_info_block vbe_mode_info;
      grub_uint32_t vbe_mode;

#if defined (GRUB_MACHINE_PCBIOS)
      {
	grub_vbe_status_t status;
	void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
	status = grub_vbe_bios_get_mode (scratch);
	vbe_mode = *(grub_uint32_t *) scratch;
	if (status != GRUB_VBE_STATUS_OK)
	  return GRUB_ERR_NONE;
      }
#else
      vbe_mode = 3;
#endif

      /* get_mode_info isn't available for mode 3.  */
      if (vbe_mode == 3)
	{
	  grub_memset (&vbe_mode_info, 0,
		       sizeof (struct grub_vbe_mode_info_block));
	  vbe_mode_info.memory_model = GRUB_VBE_MEMORY_MODEL_TEXT;
	  vbe_mode_info.x_resolution = 80;
	  vbe_mode_info.y_resolution = 25;
	}
#if defined (GRUB_MACHINE_PCBIOS)
      else
	{
	  grub_vbe_status_t status;
	  void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
	  status = grub_vbe_bios_get_mode_info (vbe_mode, scratch);
	  if (status != GRUB_VBE_STATUS_OK)
	    return GRUB_ERR_NONE;
	  grub_memcpy (&vbe_mode_info, scratch,
		       sizeof (struct grub_vbe_mode_info_block));
	}
#endif

      if (vbe_mode_info.memory_model == GRUB_VBE_MEMORY_MODEL_TEXT)
	{
	  tag = (struct multiboot_tag_framebuffer *) *ptrorig;
	  tag->common.type = MULTIBOOT_TAG_TYPE_FRAMEBUFFER;
	  tag->common.size = 0;

	  tag->common.framebuffer_addr = 0xb8000;
	  
	  tag->common.framebuffer_pitch = 2 * vbe_mode_info.x_resolution;	
	  tag->common.framebuffer_width = vbe_mode_info.x_resolution;
	  tag->common.framebuffer_height = vbe_mode_info.y_resolution;

	  tag->common.framebuffer_bpp = 16;
	  
	  tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT;
	  tag->common.size = sizeof (tag->common);
	  tag->common.reserved = 0;
	  *ptrorig += ALIGN_UP (tag->common.size, MULTIBOOT_TAG_ALIGN)
	    / sizeof (grub_properly_aligned_t);
	}
      return GRUB_ERR_NONE;
    }
#else
  if (driv_id == GRUB_VIDEO_DRIVER_NONE)
    return GRUB_ERR_NONE;
#endif

#if GRUB_MACHINE_HAS_VBE
  {
    struct multiboot_tag_vbe *tag_vbe = (struct multiboot_tag_vbe *) *ptrorig;

    fill_vbe_tag (tag_vbe);

    *ptrorig += ALIGN_UP (tag_vbe->size, MULTIBOOT_TAG_ALIGN)
      / sizeof (grub_properly_aligned_t);
  }
#endif

  err = grub_video_get_info_and_fini (&mode_info, &framebuffer);
  if (err)
    return err;

  tag = (struct multiboot_tag_framebuffer *) *ptrorig;
  tag->common.type = MULTIBOOT_TAG_TYPE_FRAMEBUFFER;
  tag->common.size = 0;

  tag->common.framebuffer_addr = (grub_addr_t) framebuffer;
  tag->common.framebuffer_pitch = mode_info.pitch;

  tag->common.framebuffer_width = mode_info.width;
  tag->common.framebuffer_height = mode_info.height;

  tag->common.framebuffer_bpp = mode_info.bpp;

  tag->common.reserved = 0;
      
  if (mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR)
    {
      unsigned i;
      tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED;
      tag->framebuffer_palette_num_colors = mode_info.number_of_colors;
      if (tag->framebuffer_palette_num_colors > ARRAY_SIZE (palette))
	tag->framebuffer_palette_num_colors = ARRAY_SIZE (palette);
      tag->common.size = sizeof (struct multiboot_tag_framebuffer_common)
	+ sizeof (multiboot_uint16_t) + tag->framebuffer_palette_num_colors
	* sizeof (struct multiboot_color);
      for (i = 0; i < tag->framebuffer_palette_num_colors; i++)
	{
	  tag->framebuffer_palette[i].red = palette[i].r;
	  tag->framebuffer_palette[i].green = palette[i].g;
	  tag->framebuffer_palette[i].blue = palette[i].b;
	}
    }
  else
    {
      tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_RGB;
      tag->framebuffer_red_field_position = mode_info.red_field_pos;
      tag->framebuffer_red_mask_size = mode_info.red_mask_size;
      tag->framebuffer_green_field_position = mode_info.green_field_pos;
      tag->framebuffer_green_mask_size = mode_info.green_mask_size;
      tag->framebuffer_blue_field_position = mode_info.blue_field_pos;
      tag->framebuffer_blue_mask_size = mode_info.blue_mask_size;

      tag->common.size = sizeof (struct multiboot_tag_framebuffer_common) + 6;
    }
  *ptrorig += ALIGN_UP (tag->common.size, MULTIBOOT_TAG_ALIGN)
    / sizeof (grub_properly_aligned_t);

  return GRUB_ERR_NONE;
}
Beispiel #25
0
struct grub_net_network_level_interface *
grub_net_configure_by_dhcp_ack (const char *name,
				struct grub_net_card *card,
				grub_net_interface_flags_t flags,
				const struct grub_net_bootp_packet *bp,
				grub_size_t size,
				int is_def, char **device, char **path)
{
  grub_net_network_level_address_t addr;
  grub_net_link_level_address_t hwaddr;
  struct grub_net_network_level_interface *inter;
  int mask = -1;

  addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
  addr.ipv4 = bp->your_ip;

  if (device)
    *device = 0;
  if (path)
    *path = 0;

  grub_memcpy (hwaddr.mac, bp->mac_addr,
	       bp->hw_len < sizeof (hwaddr.mac) ? bp->hw_len
	       : sizeof (hwaddr.mac));
  hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;

  inter = grub_net_add_addr (name, card, &addr, &hwaddr, flags);
#if 0
  /* This is likely based on misunderstanding. gateway_ip refers to
     address of BOOTP relay and should not be used after BOOTP transaction
     is complete.
     See RFC1542, 3.4 Interpretation of the 'giaddr' field
   */
  if (bp->gateway_ip)
    {
      grub_net_network_level_netaddress_t target;
      grub_net_network_level_address_t gw;
      char *rname;
	  
      target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
      target.ipv4.base = bp->server_ip;
      target.ipv4.masksize = 32;
      gw.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
      gw.ipv4 = bp->gateway_ip;
      rname = grub_xasprintf ("%s:gw", name);
      if (rname)
	grub_net_add_route_gw (rname, target, gw);
      grub_free (rname);

      target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
      target.ipv4.base = bp->gateway_ip;
      target.ipv4.masksize = 32;
      grub_net_add_route (name, target, inter);
    }
#endif

  if (size > OFFSET_OF (boot_file, bp))
    grub_env_set_net_property (name, "boot_file", bp->boot_file,
                               sizeof (bp->boot_file));
  if (is_def)
    grub_net_default_server = 0;
  if (is_def && !grub_net_default_server && bp->server_ip)
    {
      grub_net_default_server = grub_xasprintf ("%d.%d.%d.%d",
						((grub_uint8_t *) &bp->server_ip)[0],
						((grub_uint8_t *) &bp->server_ip)[1],
						((grub_uint8_t *) &bp->server_ip)[2],
						((grub_uint8_t *) &bp->server_ip)[3]);
      grub_print_error ();
    }

  if (is_def)
    {
      grub_env_set ("net_default_interface", name);
      grub_env_export ("net_default_interface");
    }

  if (device && !*device && bp->server_ip)
    {
      *device = grub_xasprintf ("tftp,%d.%d.%d.%d",
				((grub_uint8_t *) &bp->server_ip)[0],
				((grub_uint8_t *) &bp->server_ip)[1],
				((grub_uint8_t *) &bp->server_ip)[2],
				((grub_uint8_t *) &bp->server_ip)[3]);
      grub_print_error ();
    }
  if (size > OFFSET_OF (server_name, bp)
      && bp->server_name[0])
    {
      grub_env_set_net_property (name, "dhcp_server_name", bp->server_name,
                                 sizeof (bp->server_name));
      if (is_def && !grub_net_default_server)
	{
	  grub_net_default_server = grub_strdup (bp->server_name);
	  grub_print_error ();
	}
      if (device && !*device)
	{
	  *device = grub_xasprintf ("tftp,%s", bp->server_name);
	  grub_print_error ();
	}
    }

  if (size > OFFSET_OF (boot_file, bp) && path)
    {
      *path = grub_strndup (bp->boot_file, sizeof (bp->boot_file));
      grub_print_error ();
      if (*path)
	{
	  char *slash;
	  slash = grub_strrchr (*path, '/');
	  if (slash)
	    *slash = 0;
	  else
	    **path = 0;
	}
    }
  if (size > OFFSET_OF (vendor, bp))
    parse_dhcp_vendor (name, &bp->vendor, size - OFFSET_OF (vendor, bp), &mask);
  grub_net_add_ipv4_local (inter, mask);
  
  inter->dhcp_ack = grub_malloc (size);
  if (inter->dhcp_ack)
    {
      grub_memcpy (inter->dhcp_ack, bp, size);
      inter->dhcp_acklen = size;
    }
  else
    grub_errno = GRUB_ERR_NONE;

  return inter;
}
Beispiel #26
0
static grub_err_t
grub_linux_boot (void)
{
  grub_err_t err = 0;
  const char *modevar;
  char *tmp;
  struct grub_relocator32_state state;
  void *real_mode_mem;
  struct grub_linux_boot_ctx ctx = {
    .real_mode_target = 0
  };
  grub_size_t mmap_size;
  grub_size_t cl_offset;

#ifdef GRUB_MACHINE_IEEE1275
  {
    const char *bootpath;
    grub_ssize_t len;

    bootpath = grub_env_get ("root");
    if (bootpath)
      grub_ieee1275_set_property (grub_ieee1275_chosen,
				  "bootpath", bootpath,
				  grub_strlen (bootpath) + 1,
				  &len);
    linux_params.ofw_signature = GRUB_LINUX_OFW_SIGNATURE;
    linux_params.ofw_num_items = 1;
    linux_params.ofw_cif_handler = (grub_uint32_t) grub_ieee1275_entry_fn;
    linux_params.ofw_idt = 0;
  }
#endif

  modevar = grub_env_get ("gfxpayload");

  /* Now all graphical modes are acceptable.
     May change in future if we have modes without framebuffer.  */
  if (modevar && *modevar != 0)
    {
      tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar);
      if (! tmp)
	return grub_errno;
#if ACCEPTS_PURE_TEXT
      err = grub_video_set_mode (tmp, 0, 0);
#else
      err = grub_video_set_mode (tmp, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
#endif
      grub_free (tmp);
    }
  else       /* We can't go back to text mode from coreboot fb.  */
#ifdef GRUB_MACHINE_COREBOOT
    if (grub_video_get_driver_id () == GRUB_VIDEO_DRIVER_COREBOOT)
      err = GRUB_ERR_NONE;
    else
#endif
      {
#if ACCEPTS_PURE_TEXT
	err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0, 0);
#else
	err = grub_video_set_mode (DEFAULT_VIDEO_MODE,
				 GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
#endif
      }

  if (err)
    {
      grub_print_error ();
      grub_puts_ (N_("Booting in blind mode"));
      grub_errno = GRUB_ERR_NONE;
    }

  if (grub_linux_setup_video (&linux_params))
    {
#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU)
      linux_params.have_vga = GRUB_VIDEO_LINUX_TYPE_TEXT;
      linux_params.video_mode = 0x3;
#else
      linux_params.have_vga = 0;
      linux_params.video_mode = 0;
      linux_params.video_width = 0;
      linux_params.video_height = 0;
#endif
    }


#ifndef GRUB_MACHINE_IEEE1275
  if (linux_params.have_vga == GRUB_VIDEO_LINUX_TYPE_TEXT)
#endif
    {
      grub_term_output_t term;
      int found = 0;
      FOR_ACTIVE_TERM_OUTPUTS(term)
	if (grub_strcmp (term->name, "vga_text") == 0
	    || grub_strcmp (term->name, "console") == 0
	    || grub_strcmp (term->name, "ofconsole") == 0)
	  {
	    struct grub_term_coordinate pos = grub_term_getxy (term);
	    linux_params.video_cursor_x = pos.x;
	    linux_params.video_cursor_y = pos.y;
	    linux_params.video_width = grub_term_width (term);
	    linux_params.video_height = grub_term_height (term);
	    found = 1;
	    break;
	  }
      if (!found)
	{
	  linux_params.video_cursor_x = 0;
	  linux_params.video_cursor_y = 0;
	  linux_params.video_width = 80;
	  linux_params.video_height = 25;
	}
    }

  mmap_size = find_mmap_size ();
  /* Make sure that each size is aligned to a page boundary.  */
  cl_offset = ALIGN_UP (mmap_size + sizeof (linux_params), 4096);
  if (cl_offset < ((grub_size_t) linux_params.setup_sects << GRUB_DISK_SECTOR_BITS))
    cl_offset = ALIGN_UP ((grub_size_t) (linux_params.setup_sects
					 << GRUB_DISK_SECTOR_BITS), 4096);
  ctx.real_size = ALIGN_UP (cl_offset + maximal_cmdline_size, 4096);

#ifdef GRUB_MACHINE_EFI
  efi_mmap_size = find_efi_mmap_size ();
  if (efi_mmap_size == 0)
    return grub_errno;
#endif

  grub_dprintf ("linux", "real_size = %x, mmap_size = %x\n",
		(unsigned) ctx.real_size, (unsigned) mmap_size);

#ifdef GRUB_MACHINE_EFI
  grub_efi_mmap_iterate (grub_linux_boot_mmap_find, &ctx, 1);
  if (! ctx.real_mode_target)
    grub_efi_mmap_iterate (grub_linux_boot_mmap_find, &ctx, 0);
#else
  grub_mmap_iterate (grub_linux_boot_mmap_find, &ctx);
#endif
  grub_dprintf ("linux", "real_mode_target = %lx, real_size = %x, efi_mmap_size = %x\n",
                (unsigned long) ctx.real_mode_target,
		(unsigned) ctx.real_size,
		(unsigned) efi_mmap_size);

  if (! ctx.real_mode_target)
    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages");

  {
    grub_relocator_chunk_t ch;
    err = grub_relocator_alloc_chunk_addr (relocator, &ch,
					   ctx.real_mode_target,
					   (ctx.real_size + efi_mmap_size));
    if (err)
     return err;
    real_mode_mem = get_virtual_current_address (ch);
  }
  efi_mmap_buf = (grub_uint8_t *) real_mode_mem + ctx.real_size;

  grub_dprintf ("linux", "real_mode_mem = %p\n",
                real_mode_mem);

  ctx.params = real_mode_mem;

  *ctx.params = linux_params;
  ctx.params->cmd_line_ptr = ctx.real_mode_target + cl_offset;
  grub_memcpy ((char *) ctx.params + cl_offset, linux_cmdline,
	       maximal_cmdline_size);

  grub_dprintf ("linux", "code32_start = %x\n",
		(unsigned) ctx.params->code32_start);

  ctx.e820_num = 0;
  if (grub_mmap_iterate (grub_linux_boot_mmap_fill, &ctx))
    return grub_errno;
  ctx.params->mmap_size = ctx.e820_num;

#ifdef GRUB_MACHINE_EFI
  {
    grub_efi_uintn_t efi_desc_size;
    grub_size_t efi_mmap_target;
    grub_efi_uint32_t efi_desc_version;
    err = grub_efi_finish_boot_services (&efi_mmap_size, efi_mmap_buf, NULL,
					 &efi_desc_size, &efi_desc_version);
    if (err)
      return err;
    
    /* Note that no boot services are available from here.  */
    efi_mmap_target = ctx.real_mode_target 
      + ((grub_uint8_t *) efi_mmap_buf - (grub_uint8_t *) real_mode_mem);
    /* Pass EFI parameters.  */
    if (grub_le_to_cpu16 (ctx.params->version) >= 0x0208)
      {
	ctx.params->v0208.efi_mem_desc_size = efi_desc_size;
	ctx.params->v0208.efi_mem_desc_version = efi_desc_version;
	ctx.params->v0208.efi_mmap = efi_mmap_target;
	ctx.params->v0208.efi_mmap_size = efi_mmap_size;

#ifdef __x86_64__
	ctx.params->v0208.efi_mmap_hi = (efi_mmap_target >> 32);
#endif
      }
    else if (grub_le_to_cpu16 (ctx.params->version) >= 0x0206)
Beispiel #27
0
static grub_err_t
grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
		     int argc, char **args_in)
{
  char *uuid_root = 0, *uuid_prefix, *prefdev = 0;
  const char *prefix = 0;
  const char *path_prefix = 0;
  int mods_loaded = 0;
  grub_dl_t *mods;
  const char **args;
  int i;

  if (argc == 0)
    {
      argc = ARRAY_SIZE (modnames_def);
      args = modnames_def;
    }
  else
    args = (const char **) args_in;

  prefix = grub_env_get ("prefix");

  if (! prefix)
    return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix");

  if (prefix)
    path_prefix = (prefix[0] == '(') ? grub_strchr (prefix, ')') : NULL;
  if (path_prefix)
    path_prefix++;
  else
    path_prefix = prefix;

  mods = grub_malloc (argc * sizeof (mods[0]));
  if (!mods)
    return grub_errno;

  if (get_uuid (NULL, &uuid_root, 0))
    return grub_errno;

  prefdev = grub_file_get_device_name (prefix);
  if (grub_errno)
    {
      grub_print_error ();
      prefdev = 0;
    }

  if (get_uuid (prefdev, &uuid_prefix, 0))
    {
      grub_free (uuid_root);
      return grub_errno;
    }

  grub_dprintf ("nativedisk", "uuid_prefix = %s, uuid_root = %s\n",
		uuid_prefix, uuid_root);

  for (mods_loaded = 0; mods_loaded < argc; mods_loaded++)
    {
      char *filename;
      grub_dl_t mod;
      grub_file_t file = NULL;
      grub_ssize_t size;
      void *core = 0;

      mod = grub_dl_get (args[mods_loaded]);
      if (mod)
	{
	  mods[mods_loaded] = 0;
	  continue;
	}

      filename = grub_xasprintf ("%s/" GRUB_TARGET_CPU "-" GRUB_PLATFORM "/%s.mod",
				 prefix, args[mods_loaded]);
      if (! filename)
	goto fail;

      file = grub_file_open (filename);
      grub_free (filename);
      if (! file)
	goto fail;

      size = grub_file_size (file);
      core = grub_malloc (size);
      if (! core)
	{
	  grub_file_close (file);
	  goto fail;
	}

      if (grub_file_read (file, core, size) != (grub_ssize_t) size)
	{
	  grub_file_close (file);
	  grub_free (core);
	  goto fail;
	}

      grub_file_close (file);

      mods[mods_loaded] = grub_dl_load_core_noinit (core, size);
      if (! mods[mods_loaded])
	goto fail;
    }

  for (i = 0; i < argc; i++)
    if (mods[i])
      grub_dl_init (mods[i]);

  if (uuid_prefix || uuid_root)
    {
      struct search_ctx ctx;
      grub_fs_autoload_hook_t saved_autoload;

      /* No need to autoload FS since obviously we already have the necessary fs modules.  */
      saved_autoload = grub_fs_autoload_hook;
      grub_fs_autoload_hook = 0;

      ctx.root_uuid = uuid_root;
      ctx.prefix_uuid = uuid_prefix;
      ctx.prefix_path = path_prefix;
      ctx.prefix_found = !uuid_prefix;
      ctx.root_found = !uuid_root;

      /* FIXME: try to guess the correct values.  */
      grub_device_iterate (iterate_device, &ctx);

      grub_fs_autoload_hook = saved_autoload;
    }
  grub_free (uuid_root);
  grub_free (uuid_prefix);

  return GRUB_ERR_NONE;

 fail:
  grub_free (uuid_root);
  grub_free (uuid_prefix);

  for (i = 0; i < mods_loaded; i++)
    if (mods[i])
      {
	mods[i]->fini = 0;
	grub_dl_unload (mods[i]);
      }
  return grub_errno;
}
Beispiel #28
0
static grub_err_t
retrieve_video_parameters (struct multiboot_info *mbi,
			   grub_uint8_t *ptrorig, grub_uint32_t ptrdest)
{
  grub_err_t err;
  struct grub_video_mode_info mode_info;
  void *framebuffer;
  grub_video_driver_id_t driv_id;
  struct grub_video_palette_data palette[256];

  err = grub_multiboot_set_video_mode ();
  if (err)
    {
      grub_print_error ();
      grub_errno = GRUB_ERR_NONE;
    }

  grub_video_get_palette (0, ARRAY_SIZE (palette), palette);

  driv_id = grub_video_get_driver_id ();
  if (driv_id == GRUB_VIDEO_DRIVER_NONE)
    return GRUB_ERR_NONE;

  err = grub_video_get_info_and_fini (&mode_info, &framebuffer);
  if (err)
    return err;

  mbi->framebuffer_addr = (grub_addr_t) framebuffer;
  mbi->framebuffer_pitch = mode_info.pitch;

  mbi->framebuffer_width = mode_info.width;
  mbi->framebuffer_height = mode_info.height;

  mbi->framebuffer_bpp = mode_info.bpp;

  if (mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR)
    {
      struct multiboot_color *mb_palette;
      unsigned i;
      mbi->framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED;
      mbi->framebuffer_palette_addr = ptrdest;
      mbi->framebuffer_palette_num_colors = mode_info.number_of_colors;
      if (mbi->framebuffer_palette_num_colors > ARRAY_SIZE (palette))
	mbi->framebuffer_palette_num_colors = ARRAY_SIZE (palette);
      mb_palette = (struct multiboot_color *) ptrorig;
      for (i = 0; i < mbi->framebuffer_palette_num_colors; i++)
	{
	  mb_palette[i].red = palette[i].r;
	  mb_palette[i].green = palette[i].g;
	  mb_palette[i].blue = palette[i].b;
	}
      ptrorig += mbi->framebuffer_palette_num_colors
	* sizeof (struct multiboot_color);
      ptrdest += mbi->framebuffer_palette_num_colors
	* sizeof (struct multiboot_color);
    }
  else
    {
      mbi->framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_RGB;
      mbi->framebuffer_red_field_position = mode_info.green_field_pos;
      mbi->framebuffer_red_mask_size = mode_info.green_mask_size;
      mbi->framebuffer_green_field_position = mode_info.green_field_pos;
      mbi->framebuffer_green_mask_size = mode_info.green_mask_size;
      mbi->framebuffer_blue_field_position = mode_info.blue_field_pos;
      mbi->framebuffer_blue_mask_size = mode_info.blue_mask_size;
    }

  mbi->flags |= MULTIBOOT_INFO_FRAMEBUFFER_INFO;

  return GRUB_ERR_NONE;
}
Beispiel #29
0
grub_err_t
grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
			 grub_size_t bufsize)
{
  grub_uint8_t *ptrorig = (grub_uint8_t *) orig + buf_off;
  grub_uint32_t ptrdest = dest + buf_off;
  struct multiboot_info *mbi;
  struct multiboot_mod_list *modlist;
  unsigned i;
  struct module *cur;
  grub_size_t mmap_size;
  grub_err_t err;

  if (bufsize < grub_multiboot_get_mbi_size ())
    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "mbi buffer is too small");

  mbi = (struct multiboot_info *) ptrorig;
  ptrorig += sizeof (*mbi);
  ptrdest += sizeof (*mbi);
  grub_memset (mbi, 0, sizeof (*mbi));

  grub_memcpy (ptrorig, cmdline, cmdline_size);
  mbi->flags |= MULTIBOOT_INFO_CMDLINE;
  mbi->cmdline = ptrdest;
  ptrorig += ALIGN_UP (cmdline_size, 4);
  ptrdest += ALIGN_UP (cmdline_size, 4);

  grub_memcpy (ptrorig, PACKAGE_STRING, sizeof(PACKAGE_STRING));
  mbi->flags |= MULTIBOOT_INFO_BOOT_LOADER_NAME;
  mbi->boot_loader_name = ptrdest;
  ptrorig += ALIGN_UP (sizeof(PACKAGE_STRING), 4);
  ptrdest += ALIGN_UP (sizeof(PACKAGE_STRING), 4);

  if (modcnt)
    {
      mbi->flags |= MULTIBOOT_INFO_MODS;
      mbi->mods_addr = ptrdest;
      mbi->mods_count = modcnt;
      modlist = (struct multiboot_mod_list *) ptrorig;
      ptrorig += modcnt * sizeof (struct multiboot_mod_list);
      ptrdest += modcnt * sizeof (struct multiboot_mod_list);

      for (i = 0, cur = modules; i < modcnt; i++, cur = cur->next)
	{
	  modlist[i].mod_start = cur->start;
	  modlist[i].mod_end = modlist[i].mod_start + cur->size;
	  modlist[i].cmdline = ptrdest;
	  grub_memcpy (ptrorig, cur->cmdline, cur->cmdline_size);
	  ptrorig += ALIGN_UP (cur->cmdline_size, 4);
	  ptrdest += ALIGN_UP (cur->cmdline_size, 4);
	}
    }
  else
    {
      mbi->mods_addr = 0;
      mbi->mods_count = 0;
    }

  mmap_size = grub_get_multiboot_mmap_count ()
    * sizeof (struct multiboot_mmap_entry);
  grub_fill_multiboot_mmap ((struct multiboot_mmap_entry *) ptrorig);
  mbi->mmap_length = mmap_size;
  mbi->mmap_addr = ptrdest;
  mbi->flags |= MULTIBOOT_INFO_MEM_MAP;
  ptrorig += mmap_size;
  ptrdest += mmap_size;

  /* Convert from bytes to kilobytes.  */
  mbi->mem_lower = grub_mmap_get_lower () / 1024;
  mbi->mem_upper = grub_mmap_get_upper () / 1024;
  mbi->flags |= MULTIBOOT_INFO_MEMORY;

  if (bootdev_set)
    {
      mbi->boot_device = bootdev;
      mbi->flags |= MULTIBOOT_INFO_BOOTDEV;
    }

  err = retrieve_video_parameters (mbi, ptrorig, ptrdest);
  if (err)
    {
      grub_print_error ();
      grub_errno = GRUB_ERR_NONE;
    }

  return GRUB_ERR_NONE;
}
Beispiel #30
0
/* Run a menu entry.  */
static void
grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
{
  grub_err_t err = GRUB_ERR_NONE;
  int errs_before;
  grub_menu_t menu = NULL;
  char *optr, *buf, *oldchosen = NULL, *olddefault = NULL;
  const char *ptr, *chosen, *def;
  grub_size_t sz = 0;

  if (entry->restricted)
    err = grub_auth_check_authentication (entry->users);

  if (err)
    {
      grub_print_error ();
      grub_errno = GRUB_ERR_NONE;
      return;
    }

  errs_before = grub_err_printed_errors;

  chosen = grub_env_get ("chosen");
  def = grub_env_get ("default");

  if (entry->submenu)
    {
      grub_env_context_open ();
      menu = grub_zalloc (sizeof (*menu));
      if (! menu)
	return;
      grub_env_set_menu (menu);
      if (auto_boot)
	grub_env_set ("timeout", "0");
    }

  for (ptr = entry->id; *ptr; ptr++)
    sz += (*ptr == '>') ? 2 : 1;
  if (chosen)
    {
      oldchosen = grub_strdup (chosen);
      if (!oldchosen)
	grub_print_error ();
    }
  if (def)
    {
      olddefault = grub_strdup (def);
      if (!olddefault)
	grub_print_error ();
    }
  sz++;
  if (chosen)
    sz += grub_strlen (chosen);
  sz++;
  buf = grub_malloc (sz);
  if (!buf)
    grub_print_error ();
  else
    {
      optr = buf;
      if (chosen)
	{
	  optr = grub_stpcpy (optr, chosen);
	  *optr++ = '>';
	}
      for (ptr = entry->id; *ptr; ptr++)
	{
	  if (*ptr == '>')
	    *optr++ = '>';
	  *optr++ = *ptr;
	}
      *optr = 0;
      grub_env_set ("chosen", buf);
      grub_env_export ("chosen");
      grub_free (buf);
    }

  for (ptr = def; ptr && *ptr; ptr++)
    {
      if (ptr[0] == '>' && ptr[1] == '>')
	{
	  ptr++;
	  continue;
	}
      if (ptr[0] == '>')
	break;
    }

  if (ptr && ptr[0] && ptr[1])
    grub_env_set ("default", ptr + 1);
  else
    grub_env_unset ("default");

  grub_script_execute_sourcecode (entry->sourcecode, entry->argc, entry->args);

  if (errs_before != grub_err_printed_errors)
    grub_wait_after_message ();

  if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
    /* Implicit execution of boot, only if something is loaded.  */
    grub_command_execute ("boot", 0, 0);

  if (entry->submenu)
    {
      if (menu && menu->size)
	{
	  grub_show_menu (menu, 1, auto_boot);
	  grub_normal_free_menu (menu);
	}
      grub_env_context_close ();
    }
  if (oldchosen)
    grub_env_set ("chosen", oldchosen);
  else
    grub_env_unset ("chosen");
  if (olddefault)
    grub_env_set ("default", olddefault);
  else
    grub_env_unset ("default");
  grub_env_unset ("timeout");
}