]> Git Repo - J-u-boot.git/blob - lib/efi_loader/efi_bootmgr.c
7da3139f9177e76dc7944bfdc69120335c0222d1
[J-u-boot.git] / lib / efi_loader / efi_bootmgr.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  *  EFI boot manager
4  *
5  *  Copyright (c) 2017 Rob Clark
6  */
7
8 #define LOG_CATEGORY LOGC_EFI
9
10 #include <blk.h>
11 #include <blkmap.h>
12 #include <charset.h>
13 #include <dm.h>
14 #include <log.h>
15 #include <malloc.h>
16 #include <net.h>
17 #include <efi_default_filename.h>
18 #include <efi_loader.h>
19 #include <efi_variable.h>
20 #include <asm/unaligned.h>
21
22 static const struct efi_boot_services *bs;
23 static const struct efi_runtime_services *rs;
24
25 /**
26  * struct uridp_context - uri device path resource
27  *
28  * @image_size:         image size
29  * @image_addr:         image address
30  * @loaded_dp:          pointer to loaded device path
31  * @ramdisk_blk_dev:    pointer to the ramdisk blk device
32  * @mem_handle:         efi_handle to the loaded PE-COFF image
33  */
34 struct uridp_context {
35         ulong image_size;
36         ulong image_addr;
37         struct efi_device_path *loaded_dp;
38         struct udevice *ramdisk_blk_dev;
39         efi_handle_t mem_handle;
40 };
41
42 const efi_guid_t efi_guid_bootmenu_auto_generated =
43                 EFICONFIG_AUTO_GENERATED_ENTRY_GUID;
44
45 /*
46  * bootmgr implements the logic of trying to find a payload to boot
47  * based on the BootOrder + BootXXXX variables, and then loading it.
48  *
49  * TODO detecting a special key held (f9?) and displaying a boot menu
50  * like you would get on a PC would be clever.
51  *
52  * TODO if we had a way to write and persist variables after the OS
53  * has started, we'd also want to check OsIndications to see if we
54  * should do normal or recovery boot.
55  */
56
57 /**
58  * expand_media_path() - expand a device path for default file name
59  * @device_path:        device path to check against
60  *
61  * If @device_path is a media or disk partition which houses a file
62  * system, this function returns a full device path which contains
63  * an architecture-specific default file name for removable media.
64  *
65  * Return:      a newly allocated device path
66  */
67 static
68 struct efi_device_path *expand_media_path(struct efi_device_path *device_path)
69 {
70         struct efi_device_path *rem, *full_path;
71         efi_handle_t handle;
72
73         if (!device_path)
74                 return NULL;
75
76         /*
77          * If device_path is a (removable) media or partition which provides
78          * simple file system protocol, append a default file name to support
79          * booting from removable media.
80          */
81         handle = efi_dp_find_obj(device_path,
82                                  &efi_simple_file_system_protocol_guid, &rem);
83         if (handle) {
84                 if (rem->type == DEVICE_PATH_TYPE_END) {
85                         full_path = efi_dp_from_file(device_path,
86                                                      "/EFI/BOOT/" BOOTEFI_NAME);
87                 } else {
88                         full_path = efi_dp_dup(device_path);
89                 }
90         } else {
91                 full_path = efi_dp_dup(device_path);
92         }
93
94         return full_path;
95 }
96
97 /**
98  * try_load_from_file_path() - try to load a file
99  *
100  * Given a file media path iterate through a list of handles and try to
101  * to load the file from each of them until the first success.
102  *
103  * @fs_handles: array of handles with the simple file protocol
104  * @num:        number of handles in fs_handles
105  * @fp:         file path to open
106  * @handle:     on return pointer to handle for loaded image
107  * @removable:  if true only consider removable media, else only non-removable
108  */
109 static efi_status_t try_load_from_file_path(efi_handle_t *fs_handles,
110                                             efi_uintn_t num,
111                                             struct efi_device_path *fp,
112                                             efi_handle_t *handle,
113                                             bool removable)
114 {
115         struct efi_handler *handler;
116         struct efi_device_path *dp;
117         int i;
118         efi_status_t ret;
119
120         for (i = 0; i < num; i++) {
121                 if (removable != efi_disk_is_removable(fs_handles[i]))
122                         continue;
123
124                 ret = efi_search_protocol(fs_handles[i], &efi_guid_device_path,
125                                           &handler);
126                 if (ret != EFI_SUCCESS)
127                         continue;
128
129                 dp = handler->protocol_interface;
130                 if (!dp)
131                         continue;
132
133                 dp = efi_dp_concat(dp, fp, false);
134                 if (!dp)
135                         continue;
136
137                 ret = EFI_CALL(efi_load_image(true, efi_root, dp, NULL, 0,
138                                               handle));
139                 efi_free_pool(dp);
140                 if (ret == EFI_SUCCESS)
141                         return ret;
142         }
143
144         return EFI_NOT_FOUND;
145 }
146
147 /**
148  * try_load_from_short_path
149  * @fp:         file path
150  * @handle:     pointer to handle for newly installed image
151  *
152  * Enumerate all the devices which support file system operations,
153  * prepend its media device path to the file path, @fp, and
154  * try to load the file.
155  * This function should be called when handling a short-form path
156  * which is starting with a file device path.
157  *
158  * Return:      status code
159  */
160 static efi_status_t try_load_from_short_path(struct efi_device_path *fp,
161                                              efi_handle_t *handle)
162 {
163         efi_handle_t *fs_handles;
164         efi_uintn_t num;
165         efi_status_t ret;
166
167         ret = EFI_CALL(efi_locate_handle_buffer(
168                                         BY_PROTOCOL,
169                                         &efi_simple_file_system_protocol_guid,
170                                         NULL,
171                                         &num, &fs_handles));
172         if (ret != EFI_SUCCESS)
173                 return ret;
174         if (!num)
175                 return EFI_NOT_FOUND;
176
177         /* removable media first */
178         ret = try_load_from_file_path(fs_handles, num, fp, handle, true);
179         if (ret == EFI_SUCCESS)
180                 goto out;
181
182         /* fixed media */
183         ret = try_load_from_file_path(fs_handles, num, fp, handle, false);
184         if (ret == EFI_SUCCESS)
185                 goto out;
186
187 out:
188         return ret;
189 }
190
191 /**
192  * mount_image() - mount the image with blkmap
193  *
194  * @lo_label:   u16 label string of load option
195  * @addr:       image address
196  * @size:       image size
197  * Return:      pointer to the UCLASS_BLK udevice, NULL if failed
198  */
199 static struct udevice *mount_image(u16 *lo_label, ulong addr, ulong size)
200 {
201         int err;
202         struct blkmap *bm;
203         struct udevice *bm_dev;
204         char *label = NULL, *p;
205
206         label = efi_alloc(utf16_utf8_strlen(lo_label) + 1);
207         if (!label)
208                 return NULL;
209
210         p = label;
211         utf16_utf8_strcpy(&p, lo_label);
212         err = blkmap_create_ramdisk(label, addr, size, &bm_dev);
213         if (err) {
214                 efi_free_pool(label);
215                 return NULL;
216         }
217         bm = dev_get_plat(bm_dev);
218
219         efi_free_pool(label);
220
221         return bm->blk;
222 }
223
224 /**
225  * search_default_file() - search default file
226  *
227  * @dev:        pointer to the UCLASS_BLK or UCLASS_PARTITION udevice
228  * @loaded_dp:  pointer to default file device path
229  * Return:      status code
230  */
231 static efi_status_t search_default_file(struct udevice *dev,
232                                         struct efi_device_path **loaded_dp)
233 {
234         efi_status_t ret;
235         efi_handle_t handle;
236         u16 *default_file_name = NULL;
237         struct efi_file_handle *root, *f;
238         struct efi_device_path *dp = NULL, *fp = NULL;
239         struct efi_simple_file_system_protocol *file_system;
240         struct efi_device_path *device_path, *full_path = NULL;
241
242         if (dev_tag_get_ptr(dev, DM_TAG_EFI, (void **)&handle)) {
243                 log_warning("DM_TAG_EFI not found\n");
244                 return EFI_INVALID_PARAMETER;
245         }
246
247         ret = EFI_CALL(bs->open_protocol(handle, &efi_guid_device_path,
248                                          (void **)&device_path, efi_root, NULL,
249                                          EFI_OPEN_PROTOCOL_GET_PROTOCOL));
250         if (ret != EFI_SUCCESS)
251                 return ret;
252
253         ret = EFI_CALL(bs->open_protocol(handle, &efi_simple_file_system_protocol_guid,
254                                          (void **)&file_system, efi_root, NULL,
255                                          EFI_OPEN_PROTOCOL_GET_PROTOCOL));
256         if (ret != EFI_SUCCESS)
257                 return ret;
258
259         ret = EFI_CALL(file_system->open_volume(file_system, &root));
260         if (ret != EFI_SUCCESS)
261                 return ret;
262
263         full_path = expand_media_path(device_path);
264         ret = efi_dp_split_file_path(full_path, &dp, &fp);
265         if (ret != EFI_SUCCESS)
266                 goto err;
267
268         default_file_name = efi_dp_str(fp);
269         efi_free_pool(dp);
270         efi_free_pool(fp);
271         if (!default_file_name) {
272                 ret = EFI_OUT_OF_RESOURCES;
273                 goto err;
274         }
275
276         ret = EFI_CALL(root->open(root, &f, default_file_name,
277                                   EFI_FILE_MODE_READ, 0));
278         efi_free_pool(default_file_name);
279         if (ret != EFI_SUCCESS)
280                 goto err;
281
282         EFI_CALL(f->close(f));
283         EFI_CALL(root->close(root));
284
285         *loaded_dp = full_path;
286
287         return EFI_SUCCESS;
288
289 err:
290         EFI_CALL(root->close(root));
291         efi_free_pool(full_path);
292
293         return ret;
294 }
295
296 /**
297  * fill_default_file_path() - get fallback boot device path for block device
298  *
299  * Provide the device path to the fallback UEFI boot file, e.g.
300  * EFI/BOOT/BOOTAA64.EFI if that file exists on the block device @blk.
301  *
302  * @blk:        pointer to the UCLASS_BLK udevice
303  * @dp:         pointer to store the fallback boot device path
304  * Return:      status code
305  */
306 static efi_status_t fill_default_file_path(struct udevice *blk,
307                                            struct efi_device_path **dp)
308 {
309         efi_status_t ret;
310         struct udevice *partition;
311
312         /* image that has no partition table but a file system */
313         ret = search_default_file(blk, dp);
314         if (ret == EFI_SUCCESS)
315                 return ret;
316
317         /* try the partitions */
318         device_foreach_child(partition, blk) {
319                 enum uclass_id id;
320
321                 id = device_get_uclass_id(partition);
322                 if (id != UCLASS_PARTITION)
323                         continue;
324
325                 ret = search_default_file(partition, dp);
326                 if (ret == EFI_SUCCESS)
327                         return ret;
328         }
329
330         return EFI_NOT_FOUND;
331 }
332
333 /**
334  * prepare_loaded_image() - prepare ramdisk for downloaded image
335  *
336  * @label:      label of load option
337  * @addr:       image address
338  * @size:       image size
339  * @dp:         pointer to default file device path
340  * @blk:        pointer to created blk udevice
341  * Return:      status code
342  */
343 static efi_status_t prepare_loaded_image(u16 *label, ulong addr, ulong size,
344                                          struct efi_device_path **dp,
345                                          struct udevice **blk)
346 {
347         efi_status_t ret;
348         struct udevice *ramdisk_blk;
349
350         ramdisk_blk = mount_image(label, addr, size);
351         if (!ramdisk_blk)
352                 return EFI_LOAD_ERROR;
353
354         ret = fill_default_file_path(ramdisk_blk, dp);
355         if (ret != EFI_SUCCESS) {
356                 log_info("Cannot boot from downloaded image\n");
357                 goto err;
358         }
359
360         /*
361          * TODO: expose the ramdisk to OS.
362          * Need to pass the ramdisk information by the architecture-specific
363          * methods such as 'pmem' device-tree node.
364          */
365         ret = efi_add_memory_map(addr, size, EFI_RESERVED_MEMORY_TYPE);
366         if (ret != EFI_SUCCESS) {
367                 log_err("Memory reservation failed\n");
368                 goto err;
369         }
370
371         *blk = ramdisk_blk;
372
373         return EFI_SUCCESS;
374
375 err:
376         if (blkmap_destroy(ramdisk_blk->parent))
377                 log_err("Destroying blkmap failed\n");
378
379         return ret;
380 }
381
382 /**
383  * efi_bootmgr_release_uridp_resource() - cleanup uri device path resource
384  *
385  * @ctx:        event context
386  * Return:      status code
387  */
388 efi_status_t efi_bootmgr_release_uridp_resource(struct uridp_context *ctx)
389 {
390         efi_status_t ret = EFI_SUCCESS;
391
392         if (!ctx)
393                 return ret;
394
395         /* cleanup for iso or img image */
396         if (ctx->ramdisk_blk_dev) {
397                 ret = efi_add_memory_map(ctx->image_addr, ctx->image_size,
398                                          EFI_CONVENTIONAL_MEMORY);
399                 if (ret != EFI_SUCCESS)
400                         log_err("Reclaiming memory failed\n");
401
402                 if (blkmap_destroy(ctx->ramdisk_blk_dev->parent)) {
403                         log_err("Destroying blkmap failed\n");
404                         ret = EFI_DEVICE_ERROR;
405                 }
406         }
407
408         /* cleanup for PE-COFF image */
409         if (ctx->mem_handle) {
410                 ret = efi_uninstall_multiple_protocol_interfaces(
411                         ctx->mem_handle, &efi_guid_device_path, ctx->loaded_dp,
412                         NULL);
413                 if (ret != EFI_SUCCESS)
414                         log_err("Uninstall device_path protocol failed\n");
415         }
416
417         efi_free_pool(ctx->loaded_dp);
418         free(ctx);
419
420         return ret;
421 }
422
423 /**
424  * efi_bootmgr_image_return_notify() - return to efibootmgr callback
425  *
426  * @event:      the event for which this notification function is registered
427  * @context:    event context
428  */
429 static void EFIAPI efi_bootmgr_image_return_notify(struct efi_event *event,
430                                                    void *context)
431 {
432         efi_status_t ret;
433
434         EFI_ENTRY("%p, %p", event, context);
435         ret = efi_bootmgr_release_uridp_resource(context);
436         EFI_EXIT(ret);
437 }
438
439 /**
440  * try_load_from_uri_path() - Handle the URI device path
441  *
442  * @uridp:      uri device path
443  * @lo_label:   label of load option
444  * @handle:     pointer to handle for newly installed image
445  * Return:      status code
446  */
447 static efi_status_t try_load_from_uri_path(struct efi_device_path_uri *uridp,
448                                            u16 *lo_label,
449                                            efi_handle_t *handle)
450 {
451         char *s;
452         int err;
453         int uri_len;
454         efi_status_t ret;
455         void *source_buffer;
456         efi_uintn_t source_size;
457         struct uridp_context *ctx;
458         struct udevice *blk = NULL;
459         struct efi_event *event = NULL;
460         efi_handle_t mem_handle = NULL;
461         struct efi_device_path *loaded_dp;
462         static ulong image_size, image_addr;
463
464         ctx = calloc(1, sizeof(struct uridp_context));
465         if (!ctx)
466                 return EFI_OUT_OF_RESOURCES;
467
468         s = env_get("loadaddr");
469         if (!s) {
470                 log_err("Error: loadaddr is not set\n");
471                 ret = EFI_INVALID_PARAMETER;
472                 goto err;
473         }
474
475         image_addr = hextoul(s, NULL);
476         err = wget_with_dns(image_addr, uridp->uri);
477         if (err < 0) {
478                 ret = EFI_INVALID_PARAMETER;
479                 goto err;
480         }
481
482         image_size = env_get_hex("filesize", 0);
483         if (!image_size) {
484                 ret = EFI_INVALID_PARAMETER;
485                 goto err;
486         }
487
488         /*
489          * If the file extension is ".iso" or ".img", mount it and try to load
490          * the default file.
491          * If the file is PE-COFF image, load the downloaded file.
492          */
493         uri_len = strlen(uridp->uri);
494         if (!strncmp(&uridp->uri[uri_len - 4], ".iso", 4) ||
495             !strncmp(&uridp->uri[uri_len - 4], ".img", 4)) {
496                 ret = prepare_loaded_image(lo_label, image_addr, image_size,
497                                            &loaded_dp, &blk);
498                 if (ret != EFI_SUCCESS)
499                         goto err;
500
501                 source_buffer = NULL;
502                 source_size = 0;
503         } else if (efi_check_pe((void *)image_addr, image_size, NULL) == EFI_SUCCESS) {
504                 /*
505                  * loaded_dp must exist until efi application returns,
506                  * will be freed in return_to_efibootmgr event callback.
507                  */
508                 loaded_dp = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
509                                             (uintptr_t)image_addr, image_size);
510                 ret = efi_install_multiple_protocol_interfaces(
511                         &mem_handle, &efi_guid_device_path, loaded_dp, NULL);
512                 if (ret != EFI_SUCCESS)
513                         goto err;
514
515                 source_buffer = (void *)image_addr;
516                 source_size = image_size;
517         } else {
518                 log_err("Error: file type is not supported\n");
519                 ret = EFI_UNSUPPORTED;
520                 goto err;
521         }
522
523         ctx->image_size = image_size;
524         ctx->image_addr = image_addr;
525         ctx->loaded_dp = loaded_dp;
526         ctx->ramdisk_blk_dev = blk;
527         ctx->mem_handle = mem_handle;
528
529         ret = EFI_CALL(efi_load_image(false, efi_root, loaded_dp, source_buffer,
530                                       source_size, handle));
531         if (ret != EFI_SUCCESS)
532                 goto err;
533
534         /* create event for cleanup when the image returns or error occurs */
535         ret = efi_create_event(EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
536                                efi_bootmgr_image_return_notify, ctx,
537                                &efi_guid_event_group_return_to_efibootmgr,
538                                &event);
539         if (ret != EFI_SUCCESS) {
540                 log_err("Creating event failed\n");
541                 goto err;
542         }
543
544         return ret;
545
546 err:
547         efi_bootmgr_release_uridp_resource(ctx);
548
549         return ret;
550 }
551
552 /**
553  * try_load_from_media() - load file from media
554  *
555  * @file_path:          file path
556  * @handle_img:         on return handle for the newly installed image
557  *
558  * If @file_path contains a file name, load the file.
559  * If @file_path does not have a file name, search the architecture-specific
560  * fallback boot file and load it.
561  * TODO: If the FilePathList[0] device does not support
562  * EFI_SIMPLE_FILE_SYSTEM_PROTOCOL but supports EFI_BLOCK_IO_PROTOCOL,
563  * call EFI_BOOT_SERVICES.ConnectController()
564  * TODO: FilePathList[0] device supports the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
565  * not based on EFI_BLOCK_IO_PROTOCOL
566  *
567  * Return:      status code
568  */
569 static efi_status_t try_load_from_media(struct efi_device_path *file_path,
570                                         efi_handle_t *handle_img)
571 {
572         efi_handle_t handle_blkdev;
573         efi_status_t ret = EFI_SUCCESS;
574         struct efi_device_path *rem, *dp = NULL;
575         struct efi_device_path *final_dp = file_path;
576
577         handle_blkdev = efi_dp_find_obj(file_path, &efi_block_io_guid, &rem);
578         if (handle_blkdev) {
579                 if (rem->type == DEVICE_PATH_TYPE_END) {
580                         /* no file name present, try default file */
581                         ret = fill_default_file_path(handle_blkdev->dev, &dp);
582                         if (ret != EFI_SUCCESS)
583                                 return ret;
584
585                         final_dp = dp;
586                 }
587         }
588
589         ret = EFI_CALL(efi_load_image(true, efi_root, final_dp, NULL, 0, handle_img));
590
591         efi_free_pool(dp);
592
593         return ret;
594 }
595
596 /**
597  * try_load_entry() - try to load image for boot option
598  *
599  * Attempt to load load-option number 'n', returning device_path and file_path
600  * if successful. This checks that the EFI_LOAD_OPTION is active (enabled)
601  * and that the specified file to boot exists.
602  *
603  * @n:                  number of the boot option, e.g. 0x0a13 for Boot0A13
604  * @handle:             on return handle for the newly installed image
605  * @load_options:       load options set on the loaded image protocol
606  * Return:              status code
607  */
608 static efi_status_t try_load_entry(u16 n, efi_handle_t *handle,
609                                    void **load_options)
610 {
611         struct efi_load_option lo;
612         u16 varname[9];
613         void *load_option;
614         efi_uintn_t size;
615         efi_status_t ret;
616         u32 attributes;
617
618         *handle = NULL;
619         *load_options = NULL;
620
621         efi_create_indexed_name(varname, sizeof(varname), "Boot", n);
622         load_option = efi_get_var(varname, &efi_global_variable_guid, &size);
623         if (!load_option)
624                 return EFI_LOAD_ERROR;
625
626         ret = efi_deserialize_load_option(&lo, load_option, &size);
627         if (ret != EFI_SUCCESS) {
628                 log_warning("Invalid load option for %ls\n", varname);
629                 goto error;
630         }
631
632         if (!(lo.attributes & LOAD_OPTION_ACTIVE)) {
633                 ret = EFI_LOAD_ERROR;
634                 goto error;
635         }
636
637         log_debug("trying to load \"%ls\" from %pD\n", lo.label, lo.file_path);
638
639         if (EFI_DP_TYPE(lo.file_path, MEDIA_DEVICE, FILE_PATH)) {
640                 /* file_path doesn't contain a device path */
641                 ret = try_load_from_short_path(lo.file_path, handle);
642         } else if (EFI_DP_TYPE(lo.file_path, MESSAGING_DEVICE, MSG_URI)) {
643                 if (IS_ENABLED(CONFIG_EFI_HTTP_BOOT))
644                         ret = try_load_from_uri_path(
645                                 (struct efi_device_path_uri *)lo.file_path,
646                                 lo.label, handle);
647                 else
648                         ret = EFI_LOAD_ERROR;
649         } else {
650                 ret = try_load_from_media(lo.file_path, handle);
651         }
652         if (ret != EFI_SUCCESS) {
653                 log_warning("Loading %ls '%ls' failed\n",
654                             varname, lo.label);
655                 goto error;
656         }
657
658         attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS |
659                      EFI_VARIABLE_RUNTIME_ACCESS;
660         ret = efi_set_variable_int(u"BootCurrent", &efi_global_variable_guid,
661                                    attributes, sizeof(n), &n, false);
662         if (ret != EFI_SUCCESS)
663                 goto error;
664
665         /* try to register load file2 for initrd's */
666         if (IS_ENABLED(CONFIG_EFI_LOAD_FILE2_INITRD)) {
667                 ret = efi_initrd_register();
668                 if (ret != EFI_SUCCESS)
669                         goto error;
670         }
671
672         log_info("Booting: %ls\n", lo.label);
673
674         /* Ignore the optional data in auto-generated boot options */
675         if (size >= sizeof(efi_guid_t) &&
676             !guidcmp(lo.optional_data, &efi_guid_bootmenu_auto_generated))
677                 size = 0;
678
679         /* Set optional data in loaded file protocol */
680         if (size) {
681                 *load_options = malloc(size);
682                 if (!*load_options) {
683                         ret = EFI_OUT_OF_RESOURCES;
684                         goto error;
685                 }
686                 memcpy(*load_options, lo.optional_data, size);
687                 ret = efi_set_load_options(*handle, size, *load_options);
688                 if (ret != EFI_SUCCESS)
689                         free(load_options);
690         }
691
692 error:
693         if (ret != EFI_SUCCESS && *handle &&
694             EFI_CALL(efi_unload_image(*handle)) != EFI_SUCCESS)
695                 log_err("Unloading image failed\n");
696
697         free(load_option);
698
699         return ret;
700 }
701
702 /**
703  * efi_bootmgr_load() - try to load from BootNext or BootOrder
704  *
705  * Attempt to load from BootNext or in the order specified by BootOrder
706  * EFI variable, the available load-options, finding and returning
707  * the first one that can be loaded successfully.
708  *
709  * @handle:             on return handle for the newly installed image
710  * @load_options:       load options set on the loaded image protocol
711  * Return:              status code
712  */
713 efi_status_t efi_bootmgr_load(efi_handle_t *handle, void **load_options)
714 {
715         u16 bootnext, *bootorder;
716         efi_uintn_t size;
717         int i, num;
718         efi_status_t ret;
719
720         bs = systab.boottime;
721         rs = systab.runtime;
722
723         /* BootNext */
724         size = sizeof(bootnext);
725         ret = efi_get_variable_int(u"BootNext",
726                                    &efi_global_variable_guid,
727                                    NULL, &size, &bootnext, NULL);
728         if (ret == EFI_SUCCESS || ret == EFI_BUFFER_TOO_SMALL) {
729                 /* BootNext does exist here */
730                 if (ret == EFI_BUFFER_TOO_SMALL || size != sizeof(u16))
731                         log_err("BootNext must be 16-bit integer\n");
732
733                 /* delete BootNext */
734                 ret = efi_set_variable_int(u"BootNext",
735                                            &efi_global_variable_guid,
736                                            0, 0, NULL, false);
737
738                 /* load BootNext */
739                 if (ret == EFI_SUCCESS) {
740                         if (size == sizeof(u16)) {
741                                 ret = try_load_entry(bootnext, handle,
742                                                      load_options);
743                                 if (ret == EFI_SUCCESS)
744                                         return ret;
745                                 log_warning(
746                                         "Loading from BootNext failed, falling back to BootOrder\n");
747                         }
748                 } else {
749                         log_err("Deleting BootNext failed\n");
750                 }
751         }
752
753         /* BootOrder */
754         bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size);
755         if (!bootorder) {
756                 log_info("BootOrder not defined\n");
757                 ret = EFI_NOT_FOUND;
758                 goto error;
759         }
760
761         num = size / sizeof(uint16_t);
762         for (i = 0; i < num; i++) {
763                 log_debug("trying to load Boot%04X\n", bootorder[i]);
764                 ret = try_load_entry(bootorder[i], handle, load_options);
765                 if (ret == EFI_SUCCESS)
766                         break;
767         }
768
769         free(bootorder);
770
771 error:
772         return ret;
773 }
774
775 /**
776  * efi_bootmgr_enumerate_boot_options() - enumerate the possible bootable media
777  *
778  * @opt:                pointer to the media boot option structure
779  * @index:              index of the opt array to store the boot option
780  * @handles:            pointer to block device handles
781  * @count:              On entry number of handles to block devices.
782  *                      On exit number of boot options.
783  * @removable:          flag to parse removable only
784  * Return:              status code
785  */
786 static efi_status_t
787 efi_bootmgr_enumerate_boot_options(struct eficonfig_media_boot_option *opt,
788                                    efi_uintn_t index, efi_handle_t *handles,
789                                    efi_uintn_t *count, bool removable)
790 {
791         u32 i, num = index;
792         struct efi_handler *handler;
793         efi_status_t ret = EFI_SUCCESS;
794
795         for (i = 0; i < *count; i++) {
796                 u16 *p;
797                 u16 dev_name[BOOTMENU_DEVICE_NAME_MAX];
798                 char *optional_data;
799                 struct efi_load_option lo;
800                 char buf[BOOTMENU_DEVICE_NAME_MAX];
801                 struct efi_device_path *device_path;
802                 struct efi_device_path *short_dp;
803                 struct efi_block_io *blkio;
804
805                 ret = efi_search_protocol(handles[i], &efi_block_io_guid, &handler);
806                 blkio = handler->protocol_interface;
807
808                 if (blkio->media->logical_partition)
809                         continue;
810
811                 if (removable != (blkio->media->removable_media != 0))
812                         continue;
813
814                 ret = efi_search_protocol(handles[i], &efi_guid_device_path, &handler);
815                 if (ret != EFI_SUCCESS)
816                         continue;
817                 ret = efi_protocol_open(handler, (void **)&device_path,
818                                         efi_root, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
819                 if (ret != EFI_SUCCESS)
820                         continue;
821
822                 ret = efi_disk_get_device_name(handles[i], buf, BOOTMENU_DEVICE_NAME_MAX);
823                 if (ret != EFI_SUCCESS)
824                         continue;
825
826                 p = dev_name;
827                 utf8_utf16_strncpy(&p, buf, strlen(buf));
828
829                 /* prefer to short form device path */
830                 short_dp = efi_dp_shorten(device_path);
831                 if (short_dp)
832                         device_path = short_dp;
833
834                 lo.label = dev_name;
835                 lo.attributes = LOAD_OPTION_ACTIVE;
836                 lo.file_path = device_path;
837                 lo.file_path_length = efi_dp_size(device_path) + sizeof(END);
838                 /*
839                  * Set the dedicated guid to optional_data, it is used to identify
840                  * the boot option that automatically generated by the bootmenu.
841                  * efi_serialize_load_option() expects optional_data is null-terminated
842                  * utf8 string, so set the "1234567" string to allocate enough space
843                  * to store guid, instead of realloc the load_option.
844                  */
845                 lo.optional_data = "1234567";
846                 opt[num].size = efi_serialize_load_option(&lo, (u8 **)&opt[num].lo);
847                 if (!opt[num].size) {
848                         ret = EFI_OUT_OF_RESOURCES;
849                         goto out;
850                 }
851                 /* set the guid */
852                 optional_data = (char *)opt[num].lo + (opt[num].size - u16_strsize(u"1234567"));
853                 memcpy(optional_data, &efi_guid_bootmenu_auto_generated, sizeof(efi_guid_t));
854                 num++;
855
856                 if (num >= *count)
857                         break;
858         }
859
860 out:
861         *count = num;
862
863         return ret;
864 }
865
866 /**
867  * efi_bootmgr_delete_invalid_boot_option() - delete non-existing boot option
868  *
869  * @opt:                pointer to the media boot option structure
870  * @count:              number of media boot option structure
871  * Return:              status code
872  */
873 static efi_status_t efi_bootmgr_delete_invalid_boot_option(struct eficonfig_media_boot_option *opt,
874                                                            efi_status_t count)
875 {
876         efi_uintn_t size;
877         void *load_option;
878         u32 i, list_size = 0;
879         struct efi_load_option lo;
880         u16 *var_name16 = NULL;
881         u16 varname[] = u"Boot####";
882         efi_status_t ret = EFI_SUCCESS;
883         u16 *delete_index_list = NULL, *p;
884         efi_uintn_t buf_size;
885
886         buf_size = 128;
887         var_name16 = malloc(buf_size);
888         if (!var_name16)
889                 return EFI_OUT_OF_RESOURCES;
890
891         var_name16[0] = 0;
892         for (;;) {
893                 int index;
894                 efi_guid_t guid;
895                 efi_uintn_t tmp;
896
897                 ret = efi_next_variable_name(&buf_size, &var_name16, &guid);
898                 if (ret == EFI_NOT_FOUND) {
899                         /*
900                          * EFI_NOT_FOUND indicates we retrieved all EFI variables.
901                          * This should be treated as success.
902                          */
903                         ret = EFI_SUCCESS;
904                         break;
905                 }
906
907                 if (ret != EFI_SUCCESS)
908                         goto out;
909
910                 if (!efi_varname_is_load_option(var_name16, &index))
911                         continue;
912
913                 efi_create_indexed_name(varname, sizeof(varname), "Boot", index);
914                 load_option = efi_get_var(varname, &efi_global_variable_guid, &size);
915                 if (!load_option)
916                         continue;
917
918                 tmp = size;
919                 ret = efi_deserialize_load_option(&lo, load_option, &size);
920                 if (ret != EFI_SUCCESS)
921                         goto next;
922
923                 if (size >= sizeof(efi_guid_bootmenu_auto_generated) &&
924                     !guidcmp(lo.optional_data, &efi_guid_bootmenu_auto_generated)) {
925                         for (i = 0; i < count; i++) {
926                                 if (opt[i].size == tmp &&
927                                     memcmp(opt[i].lo, load_option, tmp) == 0) {
928                                         opt[i].exist = true;
929                                         break;
930                                 }
931                         }
932
933                         /*
934                          * The entire list of variables must be retrieved by
935                          * efi_get_next_variable_name_int() before deleting the invalid
936                          * boot option, just save the index here.
937                          */
938                         if (i == count) {
939                                 p = realloc(delete_index_list, sizeof(u32) *
940                                             (list_size + 1));
941                                 if (!p) {
942                                         ret = EFI_OUT_OF_RESOURCES;
943                                         goto out;
944                                 }
945                                 delete_index_list = p;
946                                 delete_index_list[list_size++] = index;
947                         }
948                 }
949 next:
950                 free(load_option);
951         }
952
953         /* delete all invalid boot options */
954         for (i = 0; i < list_size; i++) {
955                 ret = efi_bootmgr_delete_boot_option(delete_index_list[i]);
956                 if (ret != EFI_SUCCESS)
957                         goto out;
958         }
959
960 out:
961         free(var_name16);
962         free(delete_index_list);
963
964         return ret;
965 }
966
967 /**
968  * efi_bootmgr_get_unused_bootoption() - get unused "Boot####" index
969  *
970  * @buf:        pointer to the buffer to store boot option variable name
971  * @buf_size:   buffer size
972  * @index:      pointer to store the index in the BootOrder variable
973  * Return:      status code
974  */
975 efi_status_t efi_bootmgr_get_unused_bootoption(u16 *buf, efi_uintn_t buf_size,
976                                                unsigned int *index)
977 {
978         u32 i;
979         efi_status_t ret;
980         efi_uintn_t size;
981
982         if (buf_size < u16_strsize(u"Boot####"))
983                 return EFI_BUFFER_TOO_SMALL;
984
985         for (i = 0; i <= 0xFFFF; i++) {
986                 size = 0;
987                 efi_create_indexed_name(buf, buf_size, "Boot", i);
988                 ret = efi_get_variable_int(buf, &efi_global_variable_guid,
989                                            NULL, &size, NULL, NULL);
990                 if (ret == EFI_BUFFER_TOO_SMALL)
991                         continue;
992                 else
993                         break;
994         }
995
996         if (i > 0xFFFF)
997                 return EFI_OUT_OF_RESOURCES;
998
999         *index = i;
1000
1001         return EFI_SUCCESS;
1002 }
1003
1004 /**
1005  * efi_bootmgr_append_bootorder() - append new boot option in BootOrder variable
1006  *
1007  * @index:      "Boot####" index to append to BootOrder variable
1008  * Return:      status code
1009  */
1010 efi_status_t efi_bootmgr_append_bootorder(u16 index)
1011 {
1012         u16 *bootorder;
1013         efi_status_t ret;
1014         u16 *new_bootorder = NULL;
1015         efi_uintn_t last, size, new_size;
1016
1017         /* append new boot option */
1018         bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size);
1019         last = size / sizeof(u16);
1020         new_size = size + sizeof(u16);
1021         new_bootorder = calloc(1, new_size);
1022         if (!new_bootorder) {
1023                 ret = EFI_OUT_OF_RESOURCES;
1024                 goto out;
1025         }
1026         memcpy(new_bootorder, bootorder, size);
1027         new_bootorder[last] = index;
1028
1029         ret = efi_set_variable_int(u"BootOrder", &efi_global_variable_guid,
1030                                    EFI_VARIABLE_NON_VOLATILE |
1031                                    EFI_VARIABLE_BOOTSERVICE_ACCESS |
1032                                    EFI_VARIABLE_RUNTIME_ACCESS,
1033                                    new_size, new_bootorder, false);
1034         if (ret != EFI_SUCCESS)
1035                 goto out;
1036
1037 out:
1038         free(bootorder);
1039         free(new_bootorder);
1040
1041         return ret;
1042 }
1043
1044 /**
1045  * efi_bootmgr_delete_boot_option() - delete selected boot option
1046  *
1047  * @boot_index: boot option index to delete
1048  * Return:      status code
1049  */
1050 efi_status_t efi_bootmgr_delete_boot_option(u16 boot_index)
1051 {
1052         u16 *bootorder;
1053         u16 varname[9];
1054         efi_status_t ret;
1055         unsigned int index;
1056         efi_uintn_t num, size;
1057
1058         efi_create_indexed_name(varname, sizeof(varname),
1059                                 "Boot", boot_index);
1060         ret = efi_set_variable_int(varname, &efi_global_variable_guid,
1061                                    0, 0, NULL, false);
1062         if (ret != EFI_SUCCESS) {
1063                 log_err("delete boot option(%ls) failed\n", varname);
1064                 return ret;
1065         }
1066
1067         /* update BootOrder if necessary */
1068         bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size);
1069         if (!bootorder)
1070                 return EFI_SUCCESS;
1071
1072         num = size / sizeof(u16);
1073         if (!efi_search_bootorder(bootorder, num, boot_index, &index))
1074                 return EFI_SUCCESS;
1075
1076         memmove(&bootorder[index], &bootorder[index + 1],
1077                 (num - index - 1) * sizeof(u16));
1078         size -= sizeof(u16);
1079         ret = efi_set_variable_int(u"BootOrder", &efi_global_variable_guid,
1080                                    EFI_VARIABLE_NON_VOLATILE |
1081                                    EFI_VARIABLE_BOOTSERVICE_ACCESS |
1082                                    EFI_VARIABLE_RUNTIME_ACCESS,
1083                                    size, bootorder, false);
1084
1085         return ret;
1086 }
1087
1088 /**
1089  * efi_bootmgr_update_media_device_boot_option() - generate the media device boot option
1090  *
1091  * This function enumerates all BlockIo devices and add the boot option for it.
1092  * This function also provide the BOOT#### variable maintenance for
1093  * the media device entries.
1094  * - Automatically create the BOOT#### variable for the newly detected device,
1095  * this BOOT#### variable is distinguished by the special GUID
1096  * stored in the EFI_LOAD_OPTION.optional_data
1097  * - If the device is not attached to the system, the associated BOOT#### variable
1098  * is automatically deleted.
1099  *
1100  * Return:      status code
1101  */
1102 efi_status_t efi_bootmgr_update_media_device_boot_option(void)
1103 {
1104         u32 i;
1105         efi_status_t ret;
1106         efi_uintn_t count, num, total;
1107         efi_handle_t *handles = NULL;
1108         struct eficonfig_media_boot_option *opt = NULL;
1109
1110         ret = efi_locate_handle_buffer_int(BY_PROTOCOL,
1111                                            &efi_block_io_guid,
1112                                            NULL, &count,
1113                                            (efi_handle_t **)&handles);
1114         if (ret != EFI_SUCCESS)
1115                 goto out;
1116
1117         opt = calloc(count, sizeof(struct eficonfig_media_boot_option));
1118         if (!opt) {
1119                 ret = EFI_OUT_OF_RESOURCES;
1120                 goto out;
1121         }
1122
1123         /* parse removable block io followed by fixed block io */
1124         num = count;
1125         ret = efi_bootmgr_enumerate_boot_options(opt, 0, handles, &num, true);
1126         if (ret != EFI_SUCCESS)
1127                 goto out;
1128
1129         total = num;
1130         num = count;
1131         ret = efi_bootmgr_enumerate_boot_options(opt, total, handles, &num, false);
1132         if (ret != EFI_SUCCESS)
1133                 goto out;
1134
1135         total = num;
1136
1137         /*
1138          * System hardware configuration may vary depending on the user setup.
1139          * The boot option is automatically added by the bootmenu.
1140          * If the device is not attached to the system, the boot option needs
1141          * to be deleted.
1142          */
1143         ret = efi_bootmgr_delete_invalid_boot_option(opt, total);
1144         if (ret != EFI_SUCCESS)
1145                 goto out;
1146
1147         /* add non-existent boot option */
1148         for (i = 0; i < total; i++) {
1149                 u32 boot_index;
1150                 u16 var_name[9];
1151
1152                 if (!opt[i].exist) {
1153                         ret = efi_bootmgr_get_unused_bootoption(var_name, sizeof(var_name),
1154                                                                 &boot_index);
1155                         if (ret != EFI_SUCCESS)
1156                                 goto out;
1157
1158                         ret = efi_set_variable_int(var_name, &efi_global_variable_guid,
1159                                                    EFI_VARIABLE_NON_VOLATILE |
1160                                                    EFI_VARIABLE_BOOTSERVICE_ACCESS |
1161                                                    EFI_VARIABLE_RUNTIME_ACCESS,
1162                                                    opt[i].size, opt[i].lo, false);
1163                         if (ret != EFI_SUCCESS)
1164                                 goto out;
1165
1166                         ret = efi_bootmgr_append_bootorder(boot_index);
1167                         if (ret != EFI_SUCCESS) {
1168                                 efi_set_variable_int(var_name, &efi_global_variable_guid,
1169                                                      0, 0, NULL, false);
1170                                 goto out;
1171                         }
1172                 }
1173         }
1174
1175 out:
1176         if (opt) {
1177                 for (i = 0; i < total; i++)
1178                         free(opt[i].lo);
1179         }
1180         free(opt);
1181         efi_free_pool(handles);
1182
1183         if (ret == EFI_NOT_FOUND)
1184                 return EFI_SUCCESS;
1185         return ret;
1186 }
1187
1188 /**
1189  * efi_bootmgr_run() - execute EFI boot manager
1190  * @fdt:        Flat device tree
1191  *
1192  * Invoke EFI boot manager and execute a binary depending on
1193  * boot options. If @fdt is not NULL, it will be passed to
1194  * the executed binary.
1195  *
1196  * Return:      status code
1197  */
1198 efi_status_t efi_bootmgr_run(void *fdt)
1199 {
1200         efi_handle_t handle;
1201         void *load_options;
1202         efi_status_t ret;
1203
1204         /* Initialize EFI drivers */
1205         ret = efi_init_obj_list();
1206         if (ret != EFI_SUCCESS) {
1207                 log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n",
1208                         ret & ~EFI_ERROR_MASK);
1209                 return CMD_RET_FAILURE;
1210         }
1211
1212         ret = efi_bootmgr_load(&handle, &load_options);
1213         if (ret != EFI_SUCCESS) {
1214                 log_notice("EFI boot manager: Cannot load any image\n");
1215                 return ret;
1216         }
1217
1218         ret = efi_install_fdt(fdt);
1219         if (ret != EFI_SUCCESS) {
1220                 if (EFI_CALL(efi_unload_image(handle)) == EFI_SUCCESS)
1221                         free(load_options);
1222                 else
1223                         log_err("Unloading image failed\n");
1224
1225                 return ret;
1226         }
1227
1228         return do_bootefi_exec(handle, load_options);
1229 }
This page took 0.087563 seconds and 2 git commands to generate.