static int iterate_rec (const char *prefix, const struct grub_arc_component *parent, int (*hook) (const char *name, const struct grub_arc_component *comp), int alt_names) { const struct grub_arc_component *comp; FOR_ARC_CHILDREN(comp, parent) { char *name; const char *cname = NULL; if (comp->type < ARRAY_SIZE (type_names)) cname = type_names[comp->type]; if (!cname) cname = "unknown"; if (alt_names) name = grub_xasprintf ("%s/%s%lu", prefix, cname, comp->key); else name = grub_xasprintf ("%s%s(%lu)", prefix, cname, comp->key); if (!name) return 1; if (hook (name, comp)) { grub_free (name); return 1; } if (iterate_rec ((parent ? name : prefix), comp, hook, alt_names)) { grub_free (name); return 1; } grub_free (name); }
/* Convert a device name from IEEE1275 syntax to GRUB syntax. */ char * grub_ieee1275_encode_devname (const char *path) { char *device = grub_ieee1275_get_devname (path); char *partition = grub_ieee1275_parse_args (path, GRUB_PARSE_PARTITION); char *encoding; if (partition && partition[0]) { unsigned int partno = grub_strtoul (partition, 0, 0); if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS)) /* GRUB partition 1 is OF partition 0. */ partno++; encoding = grub_xasprintf ("(%s,%d)", device, partno); } else encoding = grub_xasprintf ("(%s)", device); grub_free (partition); grub_free (device); return encoding; }
grub_err_t grub_multiboot_set_console (int console_type, int accepted_consoles, int width, int height, int depth, int console_req) { console_required = console_req; if (!(accepted_consoles & (GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER | (GRUB_MACHINE_HAS_VGA_TEXT ? GRUB_MULTIBOOT_CONSOLE_EGA_TEXT : 0)))) { if (console_required) return grub_error (GRUB_ERR_BAD_OS, "OS requires a console but none is available"); grub_puts_ (N_("WARNING: no console will be available to OS")); accepts_video = 0; accepts_ega_text = 0; return GRUB_ERR_NONE; } if (console_type == GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER) { char *buf; if (depth && width && height) buf = grub_xasprintf ("%dx%dx%d,%dx%d,auto", width, height, depth, width, height); else if (width && height) buf = grub_xasprintf ("%dx%d,auto", width, height); else buf = grub_strdup ("auto"); if (!buf) return grub_errno; grub_env_set ("gfxpayload", buf); grub_free (buf); } else { #if GRUB_MACHINE_HAS_VGA_TEXT grub_env_set ("gfxpayload", "text"); #else /* Always use video if no VGA text is available. */ grub_env_set ("gfxpayload", "auto"); #endif } accepts_video = !!(accepted_consoles & GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER); accepts_ega_text = !!(accepted_consoles & GRUB_MULTIBOOT_CONSOLE_EGA_TEXT); return GRUB_ERR_NONE; }
/* Helper for grub_device_iterate. */ static int iterate_partition (grub_disk_t disk, const grub_partition_t partition, void *data) { struct grub_device_iterate_ctx *ctx = data; struct part_ent *p; char *part_name; p = grub_malloc (sizeof (*p)); if (!p) { return 1; } part_name = grub_partition_get_name (partition); if (!part_name) { grub_free (p); return 1; } p->name = grub_xasprintf ("%s,%s", disk->name, part_name); grub_free (part_name); if (!p->name) { grub_free (p); return 1; } p->next = ctx->ents; ctx->ents = p; return 0; }
/* Initialize the screen. */ void grub_normal_init_page (struct grub_term_output *term) { int msg_len; int posx; const char *msg = _("GNU GRUB version %s"); char *msg_formatted; grub_uint32_t *unicode_msg; grub_uint32_t *last_position; grub_term_cls (term); msg_formatted = grub_xasprintf (msg, PACKAGE_VERSION); if (!msg_formatted) return; msg_len = grub_utf8_to_ucs4_alloc (msg_formatted, &unicode_msg, &last_position); grub_free (msg_formatted); if (msg_len < 0) { return; } posx = grub_getstringwidth (unicode_msg, last_position, term); posx = (grub_term_width (term) - posx) / 2; grub_term_gotoxy (term, posx, 1); grub_print_ucs4 (unicode_msg, last_position, 0, 0, term); grub_putcode ('\n', term); grub_putcode ('\n', term); grub_free (unicode_msg); }
grub_err_t grub_multiboot_set_video_mode (void) { grub_err_t err; const char *modevar; #if GRUB_MACHINE_HAS_VGA_TEXT if (accepts_video) #endif { modevar = grub_env_get ("gfxpayload"); if (! modevar || *modevar == 0) err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0, 0); else { char *tmp; tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar); if (! tmp) return grub_errno; err = grub_video_set_mode (tmp, 0, 0); grub_free (tmp); } } #if GRUB_MACHINE_HAS_VGA_TEXT else err = grub_video_set_mode ("text", 0, 0); #endif return err; }
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; }
static int iterate_partition (grub_disk_t disk, const grub_partition_t partition, void *closure) { struct grub_device_iterate_closure *c = closure; char *partition_name; struct part_ent *p; partition_name = grub_partition_get_name (partition); if (! partition_name) return 1; p = grub_malloc (sizeof (*p)); if (!p) { grub_free (partition_name); return 1; } p->name = grub_xasprintf ("%s,%s", disk->name, partition_name); if (!p->name) { grub_free (partition_name); grub_free (p); return 1; } grub_free (partition_name); p->next = c->ents; c->ents = p; return 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; } } }
static grub_err_t grub_ext2_uuid (grub_device_t device, char **uuid) { struct grub_ext2_data *data; grub_disk_t disk = device->disk; grub_dl_ref (my_mod); data = grub_ext2_mount (disk); if (data) { *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x", grub_be_to_cpu16 (data->sblock.uuid[0]), grub_be_to_cpu16 (data->sblock.uuid[1]), grub_be_to_cpu16 (data->sblock.uuid[2]), grub_be_to_cpu16 (data->sblock.uuid[3]), grub_be_to_cpu16 (data->sblock.uuid[4]), grub_be_to_cpu16 (data->sblock.uuid[5]), grub_be_to_cpu16 (data->sblock.uuid[6]), grub_be_to_cpu16 (data->sblock.uuid[7])); } else *uuid = NULL; grub_dl_unref (my_mod); grub_free (data); return grub_errno; }
/* Helper for match_devices. */ static int match_devices_iter (const char *name, void *data) { struct match_devices_ctx *ctx = data; char **t; char *buffer; /* skip partitions if asked to. */ if (ctx->noparts && grub_strchr (name, ',')) return 0; buffer = grub_xasprintf ("(%s)", name); if (! buffer) return 1; grub_dprintf ("expand", "matching: %s\n", buffer); if (regexec (ctx->regexp, buffer, 0, 0, 0)) { grub_dprintf ("expand", "not matched\n"); grub_free (buffer); return 0; } t = grub_realloc (ctx->devs, sizeof (char*) * (ctx->ndev + 2)); if (! t) { grub_free (buffer); return 1; } ctx->devs = t; ctx->devs[ctx->ndev++] = buffer; ctx->devs[ctx->ndev] = 0; return 0; }
void grub_machine_set_prefix (void) { #ifndef __i386__ char bootpath[64]; /* XXX check length */ char *filename; char *prefix; #endif if (grub_prefix[0]) { grub_env_set ("prefix", grub_prefix); /* Prefix is hardcoded in the core image. */ return; } #ifdef __i386__ grub_env_set ("prefix", "(sd,1)/"); #else if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", &bootpath, sizeof (bootpath), 0)) { /* Should never happen. */ grub_printf ("/chosen/bootpath property missing!\n"); grub_env_set ("prefix", ""); return; } /* Transform an OF device path to a GRUB path. */ prefix = grub_ieee1275_encode_devname (bootpath); filename = grub_ieee1275_get_filename (bootpath); if (filename) { char *newprefix; char *lastslash = grub_strrchr (filename, '\\'); /* Truncate at last directory. */ if (lastslash) { *lastslash = '\0'; grub_translate_ieee1275_path (filename); newprefix = grub_xasprintf ("%s%s", prefix, filename); if (newprefix) { grub_free (prefix); prefix = newprefix; } } } grub_env_set ("prefix", prefix); grub_free (filename); grub_free (prefix); #endif }
void grub_efi_set_prefix (void) { grub_efi_loaded_image_t *image = NULL; char *device = NULL; char *path = NULL; { char *pptr = NULL; if (grub_prefix[0] == '(') { pptr = grub_strrchr (grub_prefix, ')'); if (pptr) { device = grub_strndup (grub_prefix + 1, pptr - grub_prefix - 1); pptr++; } } if (!pptr) pptr = grub_prefix; if (pptr[0]) path = grub_strdup (pptr); } if (!device || !path) image = grub_efi_get_loaded_image (grub_efi_image_handle); if (image && !device) device = grub_efidisk_get_device_name (image->device_handle); if (image && !path) { char *p; path = grub_efi_get_filename (image->file_path); /* Get the directory. */ p = grub_strrchr (path, '/'); if (p) *p = '\0'; } if (device && path) { char *prefix; prefix = grub_xasprintf ("(%s)%s", device, path); if (prefix) { grub_env_set ("prefix", prefix); grub_free (prefix); } } grub_free (device); grub_free (path); }
void grub_machine_get_bootlocation (char **device, char **path) { *device = root_dev; #ifdef BHYVE *path = grub_xasprintf ("%s/%s", dir, grub_cfg); #else *path = dir; #endif }
static void grub_gettext_init_ext (const char *lang) { char *mo_file; char *locale_dir; locale_dir = grub_env_get ("locale_dir"); if (locale_dir == NULL) { grub_dprintf ("gettext", "locale_dir variable is not set up.\n"); return; } fd_mo = NULL; /* mo_file e.g.: /boot/grub/locale/ca.mo */ mo_file = grub_xasprintf ("%s/%s.mo", locale_dir, lang); if (!mo_file) return; fd_mo = grub_mofile_open (mo_file); /* Will try adding .gz as well. */ if (fd_mo == NULL) { grub_free (mo_file); mo_file = grub_xasprintf ("%s.gz", mo_file); if (!mo_file) return; fd_mo = grub_mofile_open (mo_file); } if (fd_mo) { grub_gettext_offsetoriginal = grub_gettext_get_info (GETTEXT_OFFSET_ORIGINAL); grub_gettext_max = grub_gettext_get_info (GETTEXT_NUMBER_OF_STRINGS); grub_gettext_original = grub_gettext; grub_gettext = grub_gettext_translate; } }
char * grub_gpt_guid_to_str (grub_gpt_guid_t *guid) { return grub_xasprintf ("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", grub_le_to_cpu32 (guid->data1), grub_le_to_cpu16 (guid->data2), grub_le_to_cpu16 (guid->data3), guid->data4[0], guid->data4[1], guid->data4[2], guid->data4[3], guid->data4[4], guid->data4[5], guid->data4[6], guid->data4[7]); }
/* Returning grub_file_t would be more natural, but grub_mofile_open assigns to fd_mo anyway ... */ static grub_err_t grub_mofile_open_lang (struct grub_gettext_context *ctx, const char *part1, const char *part2, const char *locale) { char *mo_file; grub_err_t err; /* mo_file e.g.: /boot/grub/locale/ca.mo */ mo_file = grub_xasprintf ("%s%s/%s.mo", part1, part2, locale); if (!mo_file) return grub_errno; err = grub_mofile_open (ctx, mo_file); grub_free (mo_file); /* Will try adding .gz as well. */ if (err) { grub_errno = GRUB_ERR_NONE; mo_file = grub_xasprintf ("%s%s/%s.mo.gz", part1, part2, locale); if (!mo_file) return grub_errno; err = grub_mofile_open (ctx, mo_file); grub_free (mo_file); } /* Will try adding .gmo as well. */ if (err) { grub_errno = GRUB_ERR_NONE; mo_file = grub_xasprintf ("%s%s/%s.gmo", part1, part2, locale); if (!mo_file) return grub_errno; err = grub_mofile_open (ctx, mo_file); grub_free (mo_file); } return err; }
static int grub_scsi_iterate (int (*hook) (const char *name)) { grub_scsi_dev_t p; auto int scsi_iterate (int bus, int luns); int scsi_iterate (int bus, int luns) { int i; /* In case of a single LUN, just return `usbX'. */ if (luns == 1) { char *sname; int ret; sname = grub_xasprintf ("%s%d", p->name, bus); if (!sname) return 1; ret = hook (sname); grub_free (sname); return ret; } /* In case of multiple LUNs, every LUN will get a prefix to distinguish it. */ for (i = 0; i < luns; i++) { char *sname; int ret; sname = grub_xasprintf ("%s%d%c", p->name, bus, 'a' + i); if (!sname) return 1; ret = hook (sname); grub_free (sname); if (ret) return 1; } return 0; }
grub_autolist_t grub_autolist_load (const char *name) { grub_autolist_t result = 0; const char *prefix; prefix = grub_env_get ("prefix"); if (prefix) { char *filename; filename = grub_xasprintf ("%s/%s", prefix, name); if (filename) { grub_file_t file; file = grub_file_open (filename); if (file) { char *buf = NULL; for (;; grub_free (buf)) { char *p; buf = grub_getline (file); if (! buf) break; if (! grub_isgraph (buf[0])) continue; p = grub_strchr (buf, ':'); if (! p) continue; *p = '\0'; while (*++p == ' ') ; insert_item (&result, buf, p); } grub_file_close (file); } grub_free (filename); } } return result; }
char * grub_util_get_devmapper_grub_dev (const char *os_dev) { char *uuid, *optr; char *grub_dev; uuid = get_dm_uuid (os_dev); if (!uuid) return NULL; if (strncmp (uuid, "LVM-", sizeof ("LVM-") - 1) == 0) { unsigned i; int dashes[] = { 0, 6, 10, 14, 18, 22, 26, 32, 38, 42, 46, 50, 54, 58}; grub_dev = xmalloc (grub_strlen (uuid) + 40); optr = grub_stpcpy (grub_dev, "lvmid/"); for (i = 0; i < ARRAY_SIZE (dashes) - 1; i++) { memcpy (optr, uuid + sizeof ("LVM-") - 1 + dashes[i], dashes[i+1] - dashes[i]); optr += dashes[i+1] - dashes[i]; *optr++ = '-'; } optr = stpcpy (optr, uuid + sizeof ("LVM-") - 1 + dashes[i]); *optr = '\0'; grub_dev[sizeof("lvmid/xxxxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxxxx") - 1] = '/'; free (uuid); return grub_dev; } if (strncmp (uuid, "CRYPT-LUKS1-", sizeof ("CRYPT-LUKS1-") - 1) == 0) { char *dash; dash = grub_strchr (uuid + sizeof ("CRYPT-LUKS1-") - 1, '-'); if (dash) *dash = 0; grub_dev = grub_xasprintf ("cryptouuid/%s", uuid + sizeof ("CRYPT-LUKS1-") - 1); grub_free (uuid); return grub_dev; } grub_free (uuid); return NULL; }
/* Register a memory in a memory map under name PREFIXSUFFIX and increment SUFFIX. */ static grub_err_t grub_xnu_register_memory (char *prefix, int *suffix, void *addr, grub_size_t size) { struct grub_xnu_devtree_key *chosen; struct grub_xnu_devtree_key *memorymap; struct grub_xnu_devtree_key *driverkey; struct grub_xnu_extdesc *extdesc; if (! grub_xnu_heap_size) return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded"); chosen = grub_xnu_create_key (&grub_xnu_devtree_root, "chosen"); if (! chosen) return grub_errno; memorymap = grub_xnu_create_key (&(chosen->first_child), "memory-map"); if (! memorymap) return grub_errno; driverkey = (struct grub_xnu_devtree_key *) grub_malloc (sizeof (*driverkey)); if (! driverkey) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't register memory"); if (suffix) { driverkey->name = grub_xasprintf ("%s%d", prefix, (*suffix)++); if (!driverkey->name) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't register memory"); } else driverkey->name = grub_strdup (prefix); if (! driverkey->name) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't register extension"); driverkey->datasize = sizeof (*extdesc); driverkey->next = memorymap->first_child; memorymap->first_child = driverkey; driverkey->data = extdesc = (struct grub_xnu_extdesc *) grub_malloc (sizeof (*extdesc)); if (! driverkey->data) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't register extension"); extdesc->addr = grub_xnu_heap_will_be_at + ((grub_uint8_t *) addr - (grub_uint8_t *) grub_xnu_heap_start); extdesc->size = (grub_uint32_t) size; return GRUB_ERR_NONE; }
void grub_machine_set_prefix (void) { if (grub_prefix[0] != '(') { char bootpath[IEEE1275_MAX_PATH_LEN]; char *prefix, *path, *colon; grub_ssize_t actual; if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", &bootpath, sizeof (bootpath), &actual)) { /* Should never happen. */ grub_printf ("/chosen/bootpath property missing!\n"); grub_env_set ("prefix", ""); return; } /* Transform an OF device path to a GRUB path. */ colon = grub_strchr (bootpath, ':'); if (colon) { char *part = colon + 1; /* Consistently provide numbered partitions to GRUB. OpenBOOT traditionally uses alphabetical partition specifiers. */ if (part[0] >= 'a' && part[0] <= 'z') part[0] = '1' + (part[0] - 'a'); } prefix = grub_ieee1275_encode_devname (bootpath); path = grub_xasprintf("%s%s", prefix, grub_prefix); grub_strcpy (grub_prefix, path); grub_free (path); grub_free (prefix); } grub_env_set ("prefix", grub_prefix); }
/* Helper for FUNC_NAME. */ static int part_hook (grub_disk_t disk, const grub_partition_t partition, void *data) { struct search_ctx *ctx = data; char *partition_name, *devname; int ret; partition_name = grub_partition_get_name (partition); if (! partition_name) return 1; devname = grub_xasprintf ("%s,%s", disk->name, partition_name); grub_free (partition_name); if (!devname) return 1; ret = iterate_device (devname, ctx); grub_free (devname); return ret; }
void grub_efi_set_prefix (void) { grub_efi_loaded_image_t *image; image = grub_efi_get_loaded_image (grub_efi_image_handle); if (image) { char *device; char *file; char *prefix; device = grub_efidisk_get_device_name (image->device_handle); file = grub_efi_get_filename (image->file_path); if (file) { char *p; /* Get the directory. */ p = grub_strrchr (file, '/'); if (p) *p = '\0'; } prefix = grub_xasprintf ("(%s)%s", (device) ? device : "net0", (file) ? file : ""); if (prefix) { grub_env_set ("prefix", prefix); grub_free (prefix); } grub_free (device); grub_free (file); } }
/* Read the file crypto.lst for auto-loading. */ void read_crypto_list (const char *prefix) { char *filename; grub_file_t file; char *buf = NULL; if (!prefix) { grub_errno = GRUB_ERR_NONE; return; } filename = grub_xasprintf ("%s/" GRUB_TARGET_CPU "-" GRUB_PLATFORM "/crypto.lst", prefix); if (!filename) { grub_errno = GRUB_ERR_NONE; return; } file = grub_file_open (filename); grub_free (filename); if (!file) { grub_errno = GRUB_ERR_NONE; return; } /* Override previous crypto.lst. */ grub_crypto_spec_free (); for (;; grub_free (buf)) { char *p, *name; struct load_spec *cur; buf = grub_file_getline (file); if (! buf) break; name = buf; while (grub_isspace (name[0])) name++; p = grub_strchr (name, ':'); if (! p) continue; *p = '\0'; p++; while (*p == ' ' || *p == '\t') p++; cur = grub_malloc (sizeof (*cur)); if (!cur) { grub_errno = GRUB_ERR_NONE; continue; } cur->name = grub_strdup (name); if (! name) { grub_errno = GRUB_ERR_NONE; grub_free (cur); continue; } cur->modname = grub_strdup (p); if (! cur->modname) { grub_errno = GRUB_ERR_NONE; grub_free (cur); grub_free (cur->name); continue; } cur->next = crypto_specs; crypto_specs = cur; } grub_file_close (file); grub_errno = GRUB_ERR_NONE; grub_crypto_autoload_hook = grub_crypto_autoload; }
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; }
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)
/* Helper for grub_ls_list_files. */ static int print_files_long (const char *filename, const struct grub_dirhook_info *info, void *data) { struct grub_ls_list_files_ctx *ctx = data; if ((! ctx->all) && (filename[0] == '.')) return 0; if (! info->dir) { grub_file_t file; char *pathname; if (ctx->dirname[grub_strlen (ctx->dirname) - 1] == '/') pathname = grub_xasprintf ("%s%s", ctx->dirname, filename); else pathname = grub_xasprintf ("%s/%s", ctx->dirname, filename); if (!pathname) return 1; /* XXX: For ext2fs symlinks are detected as files while they should be reported as directories. */ grub_file_filter_disable_compression (); file = grub_file_open (pathname); if (! file) { grub_errno = 0; grub_free (pathname); return 0; } if (! ctx->human) grub_printf ("%-12llu", (unsigned long long) file->size); else { grub_uint64_t fsize = file->size * 100ULL; grub_uint64_t fsz = file->size; int units = 0; char buf[20]; while (fsz / 1024) { fsize = (fsize + 512) / 1024; fsz /= 1024; units++; } if (units) { grub_uint64_t whole, fraction; whole = grub_divmod64 (fsize, 100, &fraction); grub_snprintf (buf, sizeof (buf), "%" PRIuGRUB_UINT64_T ".%02" PRIuGRUB_UINT64_T "%c", whole, fraction, grub_human_sizes[units]); grub_printf ("%-12s", buf); } else grub_printf ("%-12llu", (unsigned long long) file->size); } grub_file_close (file); grub_free (pathname); } else grub_printf ("%-12s", _("DIR")); if (info->mtimeset) { struct grub_datetime datetime; grub_unixtime2datetime (info->mtime, &datetime); if (ctx->human) grub_printf (" %d-%02d-%02d %02d:%02d:%02d %-11s ", datetime.year, datetime.month, datetime.day, datetime.hour, datetime.minute, datetime.second, grub_get_weekday_name (&datetime)); else grub_printf (" %04d%02d%02d%02d%02d%02d ", datetime.year, datetime.month, datetime.day, datetime.hour, datetime.minute, datetime.second); } grub_printf ("%s%s\n", filename, info->dir ? "/" : ""); return 0; }
char * grub_legacy_parse (const char *buf, char **entryname, char **suffix) { const char *ptr; const char *cmdname; unsigned i, cmdnum; char *args[ARRAY_SIZE (legacy_commands[0].argt)]; *suffix = NULL; for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++); if (!*ptr || *ptr == '#') { char *ret; int len = grub_strlen (buf); ret = grub_malloc (len + 2); grub_memcpy (ret, buf, len); if (len && ret[len - 1] == '\n') ret[len] = 0; else { ret[len] = '\n'; ret[len + 1] = 0; } return ret; } cmdname = ptr; for (ptr = buf; *ptr && !grub_isspace (*ptr) && *ptr != '='; ptr++); for (cmdnum = 0; cmdnum < ARRAY_SIZE (legacy_commands); cmdnum++) if (grub_strncmp (legacy_commands[cmdnum].name, cmdname, ptr - cmdname) == 0 && legacy_commands[cmdnum].name[ptr - cmdname] == 0 && (!(*entryname != NULL && (legacy_commands[cmdnum].flags & FLAG_NO_MENUENTRY))) && (!(*entryname == NULL && (legacy_commands[cmdnum].flags & FLAG_MENUENTRY_ONLY)))) break; if (cmdnum == ARRAY_SIZE (legacy_commands)) return grub_xasprintf ("# Unsupported legacy command: %s\n", buf); for (; grub_isspace (*ptr) || *ptr == '='; ptr++); if (legacy_commands[cmdnum].flags & FLAG_TITLE) { const char *ptr2; ptr2 = ptr + grub_strlen (ptr); while (ptr2 > ptr && grub_isspace (*(ptr2 - 1))) ptr2--; *entryname = grub_strndup (ptr, ptr2 - ptr); return NULL; } if (legacy_commands[cmdnum].flags & FLAG_TERMINAL) { int dumb = 0, lines = 24; #ifdef TODO int no_echo = 0, no_edit = 0; #endif int hercules = 0; int console = 0, serial = 0, graphics = 0; /* Big enough for any possible resulting command. */ char outbuf[512] = ""; char *outptr; while (*ptr) { /* "[--timeout=SECS] [--silent]" " [console] [serial] [hercules]"*/ if (grub_memcmp (ptr, "--dumb", sizeof ("--dumb") - 1) == 0) dumb = 1; #ifdef TODO if (grub_memcmp (ptr, "--no-echo", sizeof ("--no-echo") - 1) == 0) no_echo = 1; if (grub_memcmp (ptr, "--no-edit", sizeof ("--no-edit") - 1) == 0) no_edit = 1; #endif if (grub_memcmp (ptr, "--lines=", sizeof ("--lines=") - 1) == 0) { lines = grub_strtoul (ptr + sizeof ("--lines=") - 1, 0, 0); if (grub_errno) { lines = 24; grub_errno = GRUB_ERR_NONE; } } if (grub_memcmp (ptr, "console", sizeof ("console") - 1) == 0) console = 1; if (grub_memcmp (ptr, "serial", sizeof ("serial") - 1) == 0) serial = 1; if (grub_memcmp (ptr, "hercules", sizeof ("hercules") - 1) == 0) hercules = 1; if (grub_memcmp (ptr, "graphics", sizeof ("graphics") - 1) == 0) graphics = 1; while (*ptr && !grub_isspace (*ptr)) ptr++; while (*ptr && grub_isspace (*ptr)) ptr++; } if (!console && !serial && !hercules && !graphics) return grub_strdup ("terminal_input; terminal_output; terminfo\n"); outptr = outbuf; if (graphics) outptr = grub_stpcpy (outptr, "insmod all_video; "); outptr = grub_stpcpy (outptr, "terminal_input "); if (serial) outptr = grub_stpcpy (outptr, "serial "); if (console || hercules || graphics) outptr = grub_stpcpy (outptr, "console "); outptr = grub_stpcpy (outptr, "; terminal_output "); if (serial) outptr = grub_stpcpy (outptr, "serial "); if (console) outptr = grub_stpcpy (outptr, "console "); if (hercules) outptr = grub_stpcpy (outptr, "mda_text "); if (graphics) outptr = grub_stpcpy (outptr, "gfxterm "); outptr = grub_stpcpy (outptr, "; "); *outptr = '\0'; if (serial) { grub_snprintf (outptr, outbuf + sizeof (outbuf) - outptr, "terminfo serial -g 80x%d %s; ", lines, dumb ? "dumb" : "vt100"); outptr += grub_strlen (outptr); } grub_strcpy (outptr, "\n"); return grub_strdup (outbuf); } grub_memset (args, 0, sizeof (args)); { int hold_arg = 0; const char *curarg = NULL; for (i = 0; i < legacy_commands[cmdnum].argc; i++) { grub_size_t curarglen; if (hold_arg) { ptr = curarg; hold_arg = 0; } for (; grub_isspace (*ptr); ptr++); curarg = ptr; if (!*curarg) break; for (; *ptr && !grub_isspace (*ptr); ptr++); if (i != legacy_commands[cmdnum].argc - 1 || (legacy_commands[cmdnum].flags & FLAG_IGNORE_REST)) curarglen = ptr - curarg; else { curarglen = grub_strlen (curarg); while (curarglen > 0 && grub_isspace (curarg[curarglen - 1])) curarglen--; } if (*ptr) ptr++; switch (legacy_commands[cmdnum].argt[i]) { case TYPE_FILE_NO_CONSUME: hold_arg = 1; case TYPE_PARTITION: case TYPE_FILE: args[i] = adjust_file (curarg, curarglen); break; case TYPE_REST_VERBATIM: { char *outptr, *outptr0; int overhead = 3; ptr = curarg; while (*ptr) { for (; *ptr && grub_isspace (*ptr); ptr++); for (; *ptr && !grub_isspace (*ptr); ptr++) if (*ptr == '\'') overhead += 3; if (*ptr) ptr++; overhead += 3; } outptr0 = args[i] = grub_malloc (overhead + (ptr - curarg)); if (!outptr0) return NULL; ptr = curarg; outptr = outptr0; while (*ptr) { for (; *ptr && grub_isspace (*ptr); ptr++); if (outptr != outptr0) *outptr++ = ' '; *outptr++ = '\''; for (; *ptr && !grub_isspace (*ptr); ptr++) { if (*ptr == '\'') { *outptr++ = '\''; *outptr++ = '\\'; *outptr++ = '\''; *outptr++ = '\''; } else *outptr++ = *ptr; } *outptr++ = '\''; if (*ptr) ptr++; } *outptr++ = 0; } break; case TYPE_VERBATIM: args[i] = grub_legacy_escape (curarg, curarglen); break; case TYPE_WITH_CONFIGFILE_OPTION: case TYPE_FORCE_OPTION: case TYPE_NOAPM_OPTION: case TYPE_TYPE_OR_NOMEM_OPTION: case TYPE_OPTION: if (is_option (legacy_commands[cmdnum].argt[i], curarg, curarglen)) { args[i] = grub_strndup (curarg, curarglen); break; } args[i] = grub_strdup (""); hold_arg = 1; break; case TYPE_INT: { const char *brk; int base = 10; brk = curarg; if (brk[0] == '0' && brk[1] == 'x') { base = 16; brk += 2; } else if (brk[0] == '0') base = 8; for (; *brk && brk < curarg + curarglen; brk++) { if (base == 8 && (*brk == '8' || *brk == '9')) break; if (grub_isdigit (*brk)) continue; if (base != 16) break; if (!(*brk >= 'a' && *brk <= 'f') && !(*brk >= 'A' && *brk <= 'F')) break; } if (brk == curarg) args[i] = grub_strdup ("0"); else args[i] = grub_strndup (curarg, brk - curarg); } break; case TYPE_VBE_MODE: { unsigned mod; struct grub_vesa_mode_table_entry *modedesc; mod = grub_strtoul (curarg, 0, 0); if (grub_errno) { mod = 0; grub_errno = GRUB_ERR_NONE; } if (mod < GRUB_VESA_MODE_TABLE_START || mod > GRUB_VESA_MODE_TABLE_END) { args[i] = grub_strdup ("auto"); break; } modedesc = &grub_vesa_mode_table[mod - GRUB_VESA_MODE_TABLE_START]; if (!modedesc->width) { args[i] = grub_strdup ("auto"); break; } args[i] = grub_xasprintf ("%ux%ux%u", modedesc->width, modedesc->height, modedesc->depth); break; } case TYPE_BOOL: if (curarglen == 2 && curarg[0] == 'o' && curarg[1] == 'n') args[i] = grub_strdup ("1"); else args[i] = grub_strdup ("0"); break; } } } while (legacy_commands[cmdnum].argc > 0 && args[legacy_commands[cmdnum].argc - 1] == NULL && (legacy_commands[cmdnum].flags & FLAG_FALLBACK_AVAILABLE) && args[legacy_commands[cmdnum + 1].argc] == NULL) cmdnum++; for (; i < legacy_commands[cmdnum].argc; i++) switch (legacy_commands[cmdnum].argt[i]) { case TYPE_FILE_NO_CONSUME: case TYPE_PARTITION: case TYPE_FILE: case TYPE_REST_VERBATIM: case TYPE_VERBATIM: case TYPE_WITH_CONFIGFILE_OPTION: case TYPE_FORCE_OPTION: case TYPE_NOAPM_OPTION: case TYPE_TYPE_OR_NOMEM_OPTION: case TYPE_OPTION: args[i] = grub_strdup (""); break; case TYPE_BOOL: case TYPE_INT: args[i] = grub_strdup ("0"); break; case TYPE_VBE_MODE: args[i] = grub_strdup ("auto"); break; } if (legacy_commands[cmdnum].flags & FLAG_COLOR_INVERT) { char *corig = args[legacy_commands[cmdnum].argc - 1]; char *slash = grub_strchr (corig, '/'); char *invert; grub_size_t len; len = grub_strlen (corig); if (!slash) { grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid color specification `%s'"), args[0]); return NULL; } invert = grub_malloc (len + 1); if (!invert) return NULL; grub_memcpy (invert, slash + 1, len - (slash - corig) - 1); invert[len - (slash - args[0]) - 1] = '/'; grub_memcpy (invert + len - (slash - corig), corig, slash - corig); invert[len] = 0; args[legacy_commands[cmdnum].argc] = invert; } if (legacy_commands[cmdnum].suffix) { *suffix = grub_xasprintf (legacy_commands[cmdnum].suffix, args[legacy_commands[cmdnum].suffixarg]); if (*suffix) return NULL; } { char *ret = grub_xasprintf (legacy_commands[cmdnum].map, args[0], args[1], args[2], args[3]); grub_free (args[0]); grub_free (args[1]); grub_free (args[2]); grub_free (args[3]); return ret; } }
/* Read the file fs.lst for auto-loading. */ void read_fs_list (const char *prefix) { if (prefix) { char *filename; filename = grub_xasprintf ("%s/fs.lst", prefix); if (filename) { grub_file_t file; grub_fs_autoload_hook_t tmp_autoload_hook; /* This rules out the possibility that read_fs_list() is invoked recursively when we call grub_file_open() below. */ tmp_autoload_hook = grub_fs_autoload_hook; grub_fs_autoload_hook = NULL; file = grub_file_open (filename); if (file) { /* Override previous fs.lst. */ while (fs_module_list) { grub_named_list_t tmp; tmp = fs_module_list->next; grub_free (fs_module_list); fs_module_list = tmp; } while (1) { char *buf; char *p; char *q; grub_named_list_t fs_mod; buf = grub_getline (file); if (! buf) break; p = buf; q = buf + grub_strlen (buf) - 1; /* Ignore space. */ while (grub_isspace (*p)) p++; while (p < q && grub_isspace (*q)) *q-- = '\0'; /* If the line is empty, skip it. */ if (p >= q) continue; fs_mod = grub_malloc (sizeof (*fs_mod)); if (! fs_mod) continue; fs_mod->name = grub_strdup (p); if (! fs_mod->name) { grub_free (fs_mod); continue; } fs_mod->next = fs_module_list; fs_module_list = fs_mod; } grub_file_close (file); grub_fs_autoload_hook = tmp_autoload_hook; } grub_free (filename); } } /* Ignore errors. */ grub_errno = GRUB_ERR_NONE; /* Set the hook. */ grub_fs_autoload_hook = autoload_fs_module; }