Commit 8c3df0bf2e530c6e6f592f5144ef4f456c9e0260
Committed by
Tom Rini
1 parent
4a12a97c14
Exists in
v2017.01-smarct4x
and in
29 other branches
efi_loader: Add el torito support
When loading an el torito image, uEFI exposes said image as a raw block device to the payload. Let's do the same by creating new block devices with added offsets for the respective el torito partitions. Signed-off-by: Alexander Graf <agraf@suse.de>
Showing 2 changed files with 49 additions and 0 deletions Side-by-side Diff
cmd/bootefi.c
... | ... | @@ -194,12 +194,26 @@ |
194 | 194 | |
195 | 195 | void efi_set_bootdev(const char *dev, const char *devnr) |
196 | 196 | { |
197 | + __maybe_unused struct blk_desc *desc; | |
197 | 198 | char devname[16] = { 0 }; /* dp->str is u16[16] long */ |
198 | 199 | char *colon; |
199 | 200 | |
200 | 201 | /* Assemble the condensed device name we use in efi_disk.c */ |
201 | 202 | snprintf(devname, sizeof(devname), "%s%s", dev, devnr); |
202 | 203 | colon = strchr(devname, ':'); |
204 | + | |
205 | +#ifdef CONFIG_ISO_PARTITION | |
206 | + /* For ISOs we create partition block devices */ | |
207 | + desc = blk_get_dev(dev, simple_strtol(devnr, NULL, 10)); | |
208 | + if (desc && (desc->type != DEV_TYPE_UNKNOWN) && | |
209 | + (desc->part_type == PART_TYPE_ISO)) { | |
210 | + if (!colon) | |
211 | + snprintf(devname, sizeof(devname), "%s%s:1", dev, | |
212 | + devnr); | |
213 | + colon = NULL; | |
214 | + } | |
215 | +#endif | |
216 | + | |
203 | 217 | if (colon) |
204 | 218 | *colon = '\0'; |
205 | 219 |
lib/efi_loader/efi_disk.c
... | ... | @@ -27,6 +27,8 @@ |
27 | 27 | struct efi_block_io_media media; |
28 | 28 | /* EFI device path to this block device */ |
29 | 29 | struct efi_device_path_file_path *dp; |
30 | + /* Offset into disk for simple partitions */ | |
31 | + lbaint_t offset; | |
30 | 32 | }; |
31 | 33 | |
32 | 34 | static efi_status_t efi_disk_open_block(void *handle, efi_guid_t *protocol, |
... | ... | @@ -81,6 +83,7 @@ |
81 | 83 | return EFI_EXIT(EFI_DEVICE_ERROR); |
82 | 84 | blksz = desc->blksz; |
83 | 85 | blocks = buffer_size / blksz; |
86 | + lba += diskobj->offset; | |
84 | 87 | |
85 | 88 | #ifdef DEBUG_EFI |
86 | 89 | printf("EFI: %s:%d blocks=%x lba=%"PRIx64" blksz=%x dir=%d\n", __func__, |
... | ... | @@ -159,6 +162,7 @@ |
159 | 162 | diskobj->ops = block_io_disk_template; |
160 | 163 | diskobj->ifname = cur_drvr->name; |
161 | 164 | diskobj->dev_index = dev_index; |
165 | + diskobj->offset = offset; | |
162 | 166 | |
163 | 167 | /* Fill in EFI IO Media info (for read/write callbacks) */ |
164 | 168 | diskobj->media.removable_media = desc->removable; |
... | ... | @@ -184,6 +188,31 @@ |
184 | 188 | list_add_tail(&diskobj->parent.link, &efi_obj_list); |
185 | 189 | } |
186 | 190 | |
191 | +static int efi_disk_create_eltorito(struct blk_desc *desc, | |
192 | + const struct block_drvr *cur_drvr, | |
193 | + int diskid) | |
194 | +{ | |
195 | + int disks = 0; | |
196 | +#ifdef CONFIG_ISO_PARTITION | |
197 | + char devname[16] = { 0 }; /* dp->str is u16[16] long */ | |
198 | + disk_partition_t info; | |
199 | + int part = 1; | |
200 | + | |
201 | + if (desc->part_type != PART_TYPE_ISO) | |
202 | + return 0; | |
203 | + | |
204 | + while (!part_get_info(desc, part, &info)) { | |
205 | + snprintf(devname, sizeof(devname), "%s%d:%d", cur_drvr->name, | |
206 | + diskid, part); | |
207 | + efi_disk_add_dev(devname, cur_drvr, desc, diskid, info.start); | |
208 | + part++; | |
209 | + disks++; | |
210 | + } | |
211 | +#endif | |
212 | + | |
213 | + return disks; | |
214 | +} | |
215 | + | |
187 | 216 | /* |
188 | 217 | * U-Boot doesn't have a list of all online disk devices. So when running our |
189 | 218 | * EFI payload, we scan through all of the potentially available ones and |
... | ... | @@ -214,6 +243,12 @@ |
214 | 243 | cur_drvr->name, i); |
215 | 244 | efi_disk_add_dev(devname, cur_drvr, desc, i, 0); |
216 | 245 | disks++; |
246 | + | |
247 | + /* | |
248 | + * El Torito images show up as block devices | |
249 | + * in an EFI world, so let's create them here | |
250 | + */ | |
251 | + disks += efi_disk_create_eltorito(desc, cur_drvr, i); | |
217 | 252 | } |
218 | 253 | } |
219 | 254 | printf("Found %d disks\n", disks); |