rc = sscanf(optarg, "%u", &num);
if (rc == 1) opts.edd_version = num;
else {
- fprintf (stderr,"invalid numeric value %s\n",optarg);
+ fprintf (stderr,"invalid numeric value %s\n",
+ optarg);
+ exit(1);
+ }
+ if (num != 0 && num != 1 && num != 3) {
+ fprintf (stderr, "invalid EDD version %d\n",
+ num);
exit(1);
}
break;
rc = sscanf(optarg, "%x", &num);
if (rc == 1) opts.edd10_devicenum = num;
else {
- fprintf (stderr,"invalid hex value %s\n",optarg);
+ fprintf (stderr,"invalid hex value %s\n",
+ optarg);
exit(1);
}
break;
}
#endif
+static int
+get_edd_version(void)
+{
+ efi_guid_t guid = BLKX_UNKNOWN_GUID;
+ uint8_t *data = NULL;
+ size_t data_size = 0;
+ uint32_t attributes;
+ efidp_header *path;
+ int rc = 0;
+
+ /* Allow global user option override */
+
+ switch (opts.edd_version)
+ {
+ case 0: /* No EDD information */
+ return 0;
+ case 1: /* EDD 1.0 */
+ return 1;
+ case 3: /* EDD 3.0 */
+ return 3;
+ default:
+ break;
+ }
+
+ rc = efi_get_variable(guid, "blk0", &data, &data_size, &attributes);
+ if (rc < 0)
+ return rc;
+
+ path = (efidp_header *)data;
+ if (path->type == 2 && path->subtype == 1)
+ return 3;
+ return 1;
+}
+
+
/**
* make_linux_load_option()
* @data - load option returned
goto err;
} else {
#endif
- needed = efi_generate_file_device_path(NULL, 0, opts.loader,
- EFIBOOT_ABBREV_HD);
+ /* there's really no telling if this is even the right disk,
+ * but... I also never see blk0 exported to runtime on any
+ * hardware, so it probably only happens on some old itanium
+ * box from the beginning of time anyway. */
+ uint32_t options = EFIBOOT_ABBREV_HD;
+ int edd = get_edd_version();
+
+ switch (edd) {
+ case 1:
+ options = EFIBOOT_ABBREV_EDD10;
+ break;
+ case 3:
+ options = EFIBOOT_ABBREV_NONE;
+ break;
+ }
+
+ needed = efi_generate_file_device_path_from_esp(NULL, 0,
+ opts.disk, opts.part,
+ opts.loader, options,
+ opts.edd10_devicenum);
if (needed < 0)
return -1;
dp = malloc(needed);
if (dp == NULL)
return -1;
- needed = efi_generate_file_device_path((uint8_t *)dp,
- needed,
- opts.loader,
- EFIBOOT_ABBREV_HD);
+ needed = efi_generate_file_device_path_from_esp(
+ (uint8_t *)dp, needed,
+ opts.disk, opts.part,
+ opts.loader, options,
+ opts.edd10_devicenum);
if (needed < 0) {
free(dp);
return -1;