* [PATCH 1/7] efi: improve malloc pool allocation
2015-07-16 8:43 [PATCH 0/7] EFI updates Michael Olbrich
@ 2015-07-16 8:43 ` Michael Olbrich
2015-07-16 8:43 ` [PATCH 2/7] efi: refactor & improve application loading code Michael Olbrich
` (5 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Michael Olbrich @ 2015-07-16 8:43 UTC (permalink / raw)
To: barebox; +Cc: Michael Olbrich
Use allocate_pages() instead of allocate_pool(). With allocate_pages() we
can specify the address. This way, any address passed to the kernel will
never exceed the lower 32 bit.
If possible, try to allocate a larger pool.
Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
---
arch/efi/efi/efi.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/arch/efi/efi/efi.c b/arch/efi/efi/efi.c
index d351775a2868..c05d183c02fa 100644
--- a/arch/efi/efi/efi.c
+++ b/arch/efi/efi/efi.c
@@ -310,7 +310,8 @@ device_initcall(efi_init);
*/
efi_status_t efi_main(efi_handle_t image, efi_system_table_t *sys_table)
{
- void *mem;
+ efi_physical_addr_t mem;
+ size_t memsize;
efi_status_t efiret;
#ifdef DEBUG
@@ -332,8 +333,21 @@ efi_status_t efi_main(efi_handle_t image, efi_system_table_t *sys_table)
fixup_tables();
- BS->allocate_pool(efi_loaded_image->image_data_type, SZ_16M, &mem);
- mem_malloc_init(mem, mem + SZ_16M);
+ mem = 0x3fffffff;
+ for (memsize = SZ_256M; memsize >= SZ_8M; memsize /= 2) {
+ efiret = BS->allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
+ EFI_LOADER_DATA,
+ memsize/PAGE_SIZE, &mem);
+ if (!EFI_ERROR(efiret))
+ break;
+ if (efiret != EFI_OUT_OF_RESOURCES)
+ panic("failed to allocate malloc pool: %s\n",
+ efi_strerror(efiret));
+ }
+ if (EFI_ERROR(efiret))
+ panic("failed to allocate malloc pool: %s\n",
+ efi_strerror(efiret));
+ mem_malloc_init((void *)mem, (void *)mem + memsize);
efi_clocksource_init();
--
2.1.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 2/7] efi: refactor & improve application loading code
2015-07-16 8:43 [PATCH 0/7] EFI updates Michael Olbrich
2015-07-16 8:43 ` [PATCH 1/7] efi: improve malloc pool allocation Michael Olbrich
@ 2015-07-16 8:43 ` Michael Olbrich
2015-07-16 8:43 ` [PATCH 3/7] efi: add support for initrd loading Michael Olbrich
` (4 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Michael Olbrich @ 2015-07-16 8:43 UTC (permalink / raw)
To: barebox; +Cc: Michael Olbrich
Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
---
checkpatch.pl complains about the header change here. My change matches the
surrounding declarations, so I left it like this.
arch/efi/efi/efi-image.c | 57 ++++++++++++++++++++++++++++++++++++++----------
include/efi.h | 2 +-
2 files changed, 46 insertions(+), 13 deletions(-)
diff --git a/arch/efi/efi/efi-image.c b/arch/efi/efi/efi-image.c
index f7bda8dfcb2a..a36a38147657 100644
--- a/arch/efi/efi/efi-image.c
+++ b/arch/efi/efi/efi-image.c
@@ -37,14 +37,13 @@
#include <mach/efi.h>
#include <mach/efi-device.h>
-static int efi_execute_image(const char *file)
+int efi_load_image(const char *file, efi_loaded_image_t **loaded_image,
+ efi_handle_t *h)
{
void *exe;
size_t size;
efi_handle_t handle;
- efi_status_t efiret;
- const char *options;
- efi_loaded_image_t *loaded_image;
+ efi_status_t efiret = EFI_SUCCESS;
exe = read_file(file, &size);
if (!exe)
@@ -54,25 +53,59 @@ static int efi_execute_image(const char *file)
&handle);
if (EFI_ERROR(efiret)) {
pr_err("failed to LoadImage: %s\n", efi_strerror(efiret));
- return -efi_errno(efiret);;
+ goto out;
};
efiret = BS->open_protocol(handle, &efi_loaded_image_protocol_guid,
- (void **)&loaded_image,
+ (void **)loaded_image,
efi_parent_image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
- if (EFI_ERROR(efiret))
- return -efi_errno(efiret);
+ if (EFI_ERROR(efiret)) {
+ pr_err("failed to OpenProtocol: %s\n", efi_strerror(efiret));
+ BS->unload_image(handle);
+ goto out;
+ }
- options = linux_bootargs_get();
- loaded_image->load_options = strdup_char_to_wchar(options);
- loaded_image->load_options_size = (strlen(options) + 1) * sizeof(wchar_t);
+ *h = handle;
+out:
+ memset(exe, 0, size);
+ free(exe);
+ return -efi_errno(efiret);
+}
+
+static int efi_execute_image(const char *file)
+{
+ efi_handle_t handle;
+ efi_loaded_image_t *loaded_image;
+ efi_status_t efiret;
+ struct linux_kernel_header *image_header;
+ const char *options;
+ int ret;
+
+ ret = efi_load_image(file, &loaded_image, &handle);
+ if (ret)
+ return ret;
+
+ image_header = (struct linux_kernel_header *)loaded_image->image_base;
+ if (image_header->boot_flag == 0xAA55 &&
+ image_header->header == 0x53726448) {
+ pr_debug("Linux kernel detected. Adding bootargs.");
+ options = linux_bootargs_get();
+ pr_err("add linux options '%s'\n", options);
+ loaded_image->load_options = strdup_char_to_wchar(options);
+ loaded_image->load_options_size =
+ (strlen(options) + 1) * sizeof(wchar_t);
+ }
efiret = BS->start_image(handle, NULL, NULL);
+ if (EFI_ERROR(efiret))
+ pr_err("failed to StartImage: %s\n", efi_strerror(efiret));
+
+ BS->unload_image(handle);
efi_connect_all();
efi_register_devices();
- return 0;
+ return -efi_errno(efiret);
}
static int do_bootm_efi(struct image_data *data)
diff --git a/include/efi.h b/include/efi.h
index 9b4f16bd9f54..e79a407bc2c8 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -211,7 +211,7 @@ typedef struct {
unsigned long *exitdata_size, s16 **exitdata);
efi_status_t(EFIAPI *exit)(efi_handle_t handle, efi_status_t exit_status,
unsigned long exitdata_size, s16 *exitdata);
- void *unload_image;
+ efi_status_t (EFIAPI *unload_image)(efi_handle_t handle);
efi_status_t (EFIAPI *exit_boot_services)(efi_handle_t, unsigned long);
void *get_next_monotonic_count;
efi_status_t (EFIAPI *stall)(unsigned long usecs);
--
2.1.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 3/7] efi: add support for initrd loading
2015-07-16 8:43 [PATCH 0/7] EFI updates Michael Olbrich
2015-07-16 8:43 ` [PATCH 1/7] efi: improve malloc pool allocation Michael Olbrich
2015-07-16 8:43 ` [PATCH 2/7] efi: refactor & improve application loading code Michael Olbrich
@ 2015-07-16 8:43 ` Michael Olbrich
2015-07-16 8:43 ` [PATCH 4/7] efi: add helper to get the GPT partition UUID for a device Michael Olbrich
` (3 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Michael Olbrich @ 2015-07-16 8:43 UTC (permalink / raw)
To: barebox; +Cc: Michael Olbrich
The kernel EFI code can load the initrd from a path. However, that only
works if the initrd is in the EFI boot partition. With these changes, any
initrd accessible by barebox can be used.
Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
---
arch/efi/efi/efi-image.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 135 insertions(+), 1 deletion(-)
diff --git a/arch/efi/efi/efi-image.c b/arch/efi/efi/efi-image.c
index a36a38147657..f41322744bbc 100644
--- a/arch/efi/efi/efi-image.c
+++ b/arch/efi/efi/efi-image.c
@@ -37,6 +37,55 @@
#include <mach/efi.h>
#include <mach/efi-device.h>
+struct linux_kernel_header {
+ /* first sector of the image */
+ uint8_t code1[0x0020];
+ uint16_t cl_magic; /**< Magic number 0xA33F */
+ uint16_t cl_offset; /**< The offset of command line */
+ uint8_t code2[0x01F1 - 0x0020 - 2 - 2];
+ uint8_t setup_sects; /**< The size of the setup in sectors */
+ uint16_t root_flags; /**< If the root is mounted readonly */
+ uint16_t syssize; /**< obsolete */
+ uint16_t swap_dev; /**< obsolete */
+ uint16_t ram_size; /**< obsolete */
+ uint16_t vid_mode; /**< Video mode control */
+ uint16_t root_dev; /**< Default root device number */
+ uint16_t boot_flag; /**< 0xAA55 magic number */
+
+ /* second sector of the image */
+ uint16_t jump; /**< Jump instruction (this is code!) */
+ uint32_t header; /**< Magic signature "HdrS" */
+ uint16_t version; /**< Boot protocol version supported */
+ uint32_t realmode_swtch; /**< Boot loader hook */
+ uint16_t start_sys; /**< The load-low segment (obsolete) */
+ uint16_t kernel_version; /**< Points to kernel version string */
+ uint8_t type_of_loader; /**< Boot loader identifier */
+ uint8_t loadflags; /**< Boot protocol option flags */
+ uint16_t setup_move_size; /**< Move to high memory size */
+ uint32_t code32_start; /**< Boot loader hook */
+ uint32_t ramdisk_image; /**< initrd load address */
+ uint32_t ramdisk_size; /**< initrd size */
+ uint32_t bootsect_kludge; /**< obsolete */
+ uint16_t heap_end_ptr; /**< Free memory after setup end */
+ uint8_t ext_loader_ver; /**< boot loader's extension of the version number */
+ uint8_t ext_loader_type; /**< boot loader's extension of its type */
+ uint32_t cmd_line_ptr; /**< Points to the kernel command line */
+ uint32_t initrd_addr_max; /**< Highest address for initrd */
+ uint32_t kernel_alignment; /**< Alignment unit required by the kernel */
+ uint8_t relocatable_kernel; /** */
+ uint8_t min_alignment; /** */
+ uint16_t xloadflags; /** */
+ uint32_t cmdline_size; /** */
+ uint32_t hardware_subarch; /** */
+ uint64_t hardware_subarch_data; /** */
+ uint32_t payload_offset; /** */
+ uint32_t payload_length; /** */
+ uint64_t setup_data; /** */
+ uint64_t pref_address; /** */
+ uint32_t init_size; /** */
+ uint32_t handover_offset; /** */
+} __attribute__ ((packed));
+
int efi_load_image(const char *file, efi_loaded_image_t **loaded_image,
efi_handle_t *h)
{
@@ -108,9 +157,94 @@ static int efi_execute_image(const char *file)
return -efi_errno(efiret);
}
+#ifdef __x86_64__
+typedef void(*handover_fn)(void *image, efi_system_table_t *table,
+ struct linux_kernel_header *header);
+
+static inline void linux_efi_handover(efi_handle_t handle,
+ struct linux_kernel_header *header)
+{
+ handover_fn handover;
+
+ asm volatile ("cli");
+ handover = (handover_fn)((long)header->code32_start + 512 +
+ header->handover_offset);
+ handover(handle, efi_sys_table, header);
+}
+#else
+typedef void(*handover_fn)(VOID *image, EFI_SYSTEM_TABLE *table,
+ struct SetupHeader *setup) __attribute__((regparm(0)));
+
+static inline void linux_efi_handover(efi_handle_t handle,
+ struct linux_kernel_header *header)
+{
+ handover_fn handover;
+
+ handover = (handover_fn)((long)header->code32_start +
+ header->handover_offset);
+ handover(handle, efi_sys_table, header);
+}
+#endif
+
static int do_bootm_efi(struct image_data *data)
{
- return efi_execute_image(data->os_file);
+ void *tmp;
+ void *initrd;
+ size_t size;
+ efi_handle_t handle;
+ int ret;
+ const char *options;
+ efi_loaded_image_t *loaded_image;
+ struct linux_kernel_header *image_header, *boot_header;
+
+ ret = efi_load_image(data->os_file, &loaded_image, &handle);
+ if (ret)
+ return ret;
+
+ image_header = (struct linux_kernel_header *)loaded_image->image_base;
+
+ if (image_header->boot_flag != 0xAA55 ||
+ image_header->header != 0x53726448 ||
+ image_header->version < 0x20b ||
+ !image_header->relocatable_kernel) {
+ pr_err("Not a valid kernel image!\n");
+ BS->unload_image(handle);
+ return -EINVAL;
+ }
+
+ boot_header = xmalloc(0x4000);
+ memset(boot_header, 0, 0x4000);
+ memcpy(boot_header, image_header, sizeof(*image_header));
+
+ boot_header->type_of_loader = 0xff;
+
+ if (data->initrd_file) {
+ tmp = read_file(data->initrd_file, &size);
+ initrd = memalign(PAGE_SIZE, PAGE_ALIGN(size));
+ memcpy(initrd, tmp, size);
+ memset(initrd + size, 0, PAGE_ALIGN(size) - size);
+ free(tmp);
+ boot_header->ramdisk_image = (uint64_t)initrd;
+ boot_header->ramdisk_size = PAGE_ALIGN(size);
+ }
+
+ options = linux_bootargs_get();
+ boot_header->cmd_line_ptr = (uint64_t)options;
+ boot_header->cmdline_size = strlen(options);
+
+ boot_header->code32_start = (uint64_t)loaded_image->image_base +
+ (image_header->setup_sects+1) * 512;
+
+ if (bootm_verbose(data)) {
+ printf("\nStarting kernel at 0x%p", loaded_image->image_base);
+ if (data->initrd_file)
+ printf(", initrd at 0x%08x",
+ boot_header->ramdisk_image);
+ printf("...\n");
+ }
+ linux_efi_handover(handle, boot_header);
+
+ return 0;
}
static struct image_handler efi_handle_tr = {
--
2.1.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 4/7] efi: add helper to get the GPT partition UUID for a device
2015-07-16 8:43 [PATCH 0/7] EFI updates Michael Olbrich
` (2 preceding siblings ...)
2015-07-16 8:43 ` [PATCH 3/7] efi: add support for initrd loading Michael Olbrich
@ 2015-07-16 8:43 ` Michael Olbrich
2015-07-16 9:34 ` Marc Kleine-Budde
2015-07-16 8:43 ` [PATCH 5/7] efi: export device_path_from_handle() Michael Olbrich
` (2 subsequent siblings)
6 siblings, 1 reply; 13+ messages in thread
From: Michael Olbrich @ 2015-07-16 8:43 UTC (permalink / raw)
To: barebox; +Cc: Michael Olbrich
Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
---
common/efi-devicepath.c | 31 +++++++++++++++++++++++++++++++
include/efi.h | 1 +
2 files changed, 32 insertions(+)
diff --git a/common/efi-devicepath.c b/common/efi-devicepath.c
index a53c6d2e8b9b..fdb86afc8eca 100644
--- a/common/efi-devicepath.c
+++ b/common/efi-devicepath.c
@@ -1383,3 +1383,34 @@ u8 device_path_to_type(struct efi_device_path *dev_path)
return device_path_type(dev_path);
}
+
+char *device_path_to_partuuid(struct efi_device_path *dev_path)
+{
+ struct efi_device_path *dev_path_node;
+ struct harddrive_device_path *hd;
+ char *str = NULL;;
+
+ dev_path = unpack_device_path(dev_path);
+
+ for (dev_path_node = dev_path; !is_device_path_end(dev_path_node);
+ dev_path_node = next_device_path_node(dev_path_node)) {
+
+ if (device_path_type(dev_path_node) != MEDIA_DEVICE_PATH)
+ continue;
+
+ if (dev_path_node->sub_type != MEDIA_HARDDRIVE_DP)
+ continue;
+
+ hd = (struct harddrive_device_path *)dev_path_node;
+
+ if (hd->signature_type != SIGNATURE_TYPE_GUID)
+ continue;
+
+ str = malloc(sizeof("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")+1);
+ sprintf(str, "%pU)", (efi_guid_t *)&(hd->signature[0]));
+ break;
+ }
+
+ return str;
+}
+
diff --git a/include/efi.h b/include/efi.h
index e79a407bc2c8..b6ee42b3fd49 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -624,6 +624,7 @@ static inline int efi_compare_guid(efi_guid_t *a, efi_guid_t *b)
char *device_path_to_str(struct efi_device_path *dev_path);
u8 device_path_to_type(struct efi_device_path *dev_path);
+char *device_path_to_partuuid(struct efi_device_path *dev_path);
const char *efi_guid_string(efi_guid_t *g);
--
2.1.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 4/7] efi: add helper to get the GPT partition UUID for a device
2015-07-16 8:43 ` [PATCH 4/7] efi: add helper to get the GPT partition UUID for a device Michael Olbrich
@ 2015-07-16 9:34 ` Marc Kleine-Budde
2015-07-16 9:43 ` Michael Olbrich
0 siblings, 1 reply; 13+ messages in thread
From: Marc Kleine-Budde @ 2015-07-16 9:34 UTC (permalink / raw)
To: Michael Olbrich, barebox
[-- Attachment #1.1: Type: text/plain, Size: 1697 bytes --]
On 07/16/2015 10:43 AM, Michael Olbrich wrote:
> Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
> ---
> common/efi-devicepath.c | 31 +++++++++++++++++++++++++++++++
> include/efi.h | 1 +
> 2 files changed, 32 insertions(+)
>
> diff --git a/common/efi-devicepath.c b/common/efi-devicepath.c
> index a53c6d2e8b9b..fdb86afc8eca 100644
> --- a/common/efi-devicepath.c
> +++ b/common/efi-devicepath.c
> @@ -1383,3 +1383,34 @@ u8 device_path_to_type(struct efi_device_path *dev_path)
>
> return device_path_type(dev_path);
> }
> +
> +char *device_path_to_partuuid(struct efi_device_path *dev_path)
> +{
> + struct efi_device_path *dev_path_node;
> + struct harddrive_device_path *hd;
> + char *str = NULL;;
> +
> + dev_path = unpack_device_path(dev_path);
> +
> + for (dev_path_node = dev_path; !is_device_path_end(dev_path_node);
> + dev_path_node = next_device_path_node(dev_path_node)) {
> +
> + if (device_path_type(dev_path_node) != MEDIA_DEVICE_PATH)
> + continue;
> +
> + if (dev_path_node->sub_type != MEDIA_HARDDRIVE_DP)
> + continue;
> +
> + hd = (struct harddrive_device_path *)dev_path_node;
> +
> + if (hd->signature_type != SIGNATURE_TYPE_GUID)
> + continue;
> +
> + str = malloc(sizeof("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")+1);
> + sprintf(str, "%pU)", (efi_guid_t *)&(hd->signature[0]));
> + break;
asprintf()?
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 455 bytes --]
[-- Attachment #2: Type: text/plain, Size: 149 bytes --]
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 4/7] efi: add helper to get the GPT partition UUID for a device
2015-07-16 9:34 ` Marc Kleine-Budde
@ 2015-07-16 9:43 ` Michael Olbrich
0 siblings, 0 replies; 13+ messages in thread
From: Michael Olbrich @ 2015-07-16 9:43 UTC (permalink / raw)
To: barebox
On Thu, Jul 16, 2015 at 11:34:25AM +0200, Marc Kleine-Budde wrote:
> On 07/16/2015 10:43 AM, Michael Olbrich wrote:
> > Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
> > ---
> > common/efi-devicepath.c | 31 +++++++++++++++++++++++++++++++
> > include/efi.h | 1 +
> > 2 files changed, 32 insertions(+)
> >
> > diff --git a/common/efi-devicepath.c b/common/efi-devicepath.c
> > index a53c6d2e8b9b..fdb86afc8eca 100644
> > --- a/common/efi-devicepath.c
> > +++ b/common/efi-devicepath.c
> > @@ -1383,3 +1383,34 @@ u8 device_path_to_type(struct efi_device_path *dev_path)
> >
> > return device_path_type(dev_path);
> > }
> > +
> > +char *device_path_to_partuuid(struct efi_device_path *dev_path)
> > +{
> > + struct efi_device_path *dev_path_node;
> > + struct harddrive_device_path *hd;
> > + char *str = NULL;;
> > +
> > + dev_path = unpack_device_path(dev_path);
> > +
> > + for (dev_path_node = dev_path; !is_device_path_end(dev_path_node);
> > + dev_path_node = next_device_path_node(dev_path_node)) {
> > +
> > + if (device_path_type(dev_path_node) != MEDIA_DEVICE_PATH)
> > + continue;
> > +
> > + if (dev_path_node->sub_type != MEDIA_HARDDRIVE_DP)
> > + continue;
> > +
> > + hd = (struct harddrive_device_path *)dev_path_node;
> > +
> > + if (hd->signature_type != SIGNATURE_TYPE_GUID)
> > + continue;
> > +
> > + str = malloc(sizeof("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")+1);
> > + sprintf(str, "%pU)", (efi_guid_t *)&(hd->signature[0]));
> > + break;
> asprintf()?
Good idea. And I need to add a OOM check.
Michael
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 5/7] efi: export device_path_from_handle()
2015-07-16 8:43 [PATCH 0/7] EFI updates Michael Olbrich
` (3 preceding siblings ...)
2015-07-16 8:43 ` [PATCH 4/7] efi: add helper to get the GPT partition UUID for a device Michael Olbrich
@ 2015-07-16 8:43 ` Michael Olbrich
2015-07-16 8:43 ` [PATCH 6/7] efi: add helper functions to write EFI variables Michael Olbrich
2015-07-16 8:43 ` [PATCH 7/7] efi: write volatile EFI variables used by systemd Michael Olbrich
6 siblings, 0 replies; 13+ messages in thread
From: Michael Olbrich @ 2015-07-16 8:43 UTC (permalink / raw)
To: barebox; +Cc: Michael Olbrich
Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
---
include/efi.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/efi.h b/include/efi.h
index b6ee42b3fd49..830e0457dd1c 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -622,6 +622,7 @@ static inline int efi_compare_guid(efi_guid_t *a, efi_guid_t *b)
return memcmp(a, b, sizeof(efi_guid_t));
}
+struct efi_device_path *device_path_from_handle(efi_handle_t Handle);
char *device_path_to_str(struct efi_device_path *dev_path);
u8 device_path_to_type(struct efi_device_path *dev_path);
char *device_path_to_partuuid(struct efi_device_path *dev_path);
--
2.1.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 6/7] efi: add helper functions to write EFI variables
2015-07-16 8:43 [PATCH 0/7] EFI updates Michael Olbrich
` (4 preceding siblings ...)
2015-07-16 8:43 ` [PATCH 5/7] efi: export device_path_from_handle() Michael Olbrich
@ 2015-07-16 8:43 ` Michael Olbrich
2015-07-16 8:43 ` [PATCH 7/7] efi: write volatile EFI variables used by systemd Michael Olbrich
6 siblings, 0 replies; 13+ messages in thread
From: Michael Olbrich @ 2015-07-16 8:43 UTC (permalink / raw)
To: barebox; +Cc: Michael Olbrich
Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
---
arch/efi/efi/efi.c | 27 +++++++++++++++++++++++++++
arch/efi/include/mach/efi.h | 4 ++++
2 files changed, 31 insertions(+)
diff --git a/arch/efi/efi/efi.c b/arch/efi/efi/efi.c
index c05d183c02fa..b0e98f95b02b 100644
--- a/arch/efi/efi/efi.c
+++ b/arch/efi/efi/efi.c
@@ -83,6 +83,33 @@ out:
return buf;
}
+int efi_set_variable(char *name, efi_guid_t *vendor, uint32_t attributes,
+ void *buf, unsigned long size)
+{
+ efi_status_t efiret = EFI_SUCCESS;
+ s16 *name16 = strdup_char_to_wchar(name);
+
+ efiret = RT->set_variable(name16, vendor, attributes, size, buf);
+
+ free(name16);
+
+ return -efi_errno(efiret);
+}
+
+int efi_set_variable_usec(char *name, efi_guid_t *vendor, uint64_t usec)
+{
+ char buf[20];
+ wchar_t buf16[40];
+
+ snprintf(buf, sizeof(buf), "%lld", usec);
+ strcpy_char_to_wchar(buf16, buf);
+
+ return efi_set_variable(name, vendor,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS, buf16,
+ (strlen(buf)+1) * sizeof(wchar_t));
+}
+
struct efi_boot {
u32 attributes;
u16 file_path_len;
diff --git a/arch/efi/include/mach/efi.h b/arch/efi/include/mach/efi.h
index 1e9782a136c2..2b25cf1868ad 100644
--- a/arch/efi/include/mach/efi.h
+++ b/arch/efi/include/mach/efi.h
@@ -21,4 +21,8 @@ static inline void *efi_get_global_var(char *name, int *var_size)
return efi_get_variable(name, &efi_global_variable_guid, var_size);
}
+int efi_set_variable(char *name, efi_guid_t *vendor, uint32_t attributes,
+ void *buf, unsigned long size);
+int efi_set_variable_usec(char *name, efi_guid_t *vendor, uint64_t usec);
+
#endif /* __MACH_EFI_H */
--
2.1.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 7/7] efi: write volatile EFI variables used by systemd
2015-07-16 8:43 [PATCH 0/7] EFI updates Michael Olbrich
` (5 preceding siblings ...)
2015-07-16 8:43 ` [PATCH 6/7] efi: add helper functions to write EFI variables Michael Olbrich
@ 2015-07-16 8:43 ` Michael Olbrich
2015-07-16 20:08 ` Sascha Hauer
6 siblings, 1 reply; 13+ messages in thread
From: Michael Olbrich @ 2015-07-16 8:43 UTC (permalink / raw)
To: barebox; +Cc: Michael Olbrich
LoaderTimeInitUSec and LoaderTimeExecUSec are used e.g. in systemd-analyze
to calculate the time spent in the firmare and barebox.
LoaderDevicePartUUID is used to mount the EFI partition to /boot.
Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
---
arch/efi/efi/efi-image.c | 5 +++++
arch/efi/efi/efi.c | 14 ++++++++++++++
common/efi-guid.c | 1 +
include/efi.h | 5 +++++
4 files changed, 25 insertions(+)
diff --git a/arch/efi/efi/efi-image.c b/arch/efi/efi/efi-image.c
index f41322744bbc..89b712baab1f 100644
--- a/arch/efi/efi/efi-image.c
+++ b/arch/efi/efi/efi-image.c
@@ -17,6 +17,7 @@
*
*/
+#include <clock.h>
#include <common.h>
#include <linux/sizes.h>
#include <memory.h>
@@ -242,6 +243,10 @@ static int do_bootm_efi(struct image_data *data)
boot_header->ramdisk_image);
printf("...\n");
}
+
+ efi_set_variable_usec("LoaderTimeExecUSec", &efi_systemd_vendor_guid,
+ get_time_ns()/1000);
+
linux_efi_handover(handle, boot_header);
return 0;
diff --git a/arch/efi/efi/efi.c b/arch/efi/efi/efi.c
index b0e98f95b02b..a665a546be90 100644
--- a/arch/efi/efi/efi.c
+++ b/arch/efi/efi/efi.c
@@ -340,6 +340,7 @@ efi_status_t efi_main(efi_handle_t image, efi_system_table_t *sys_table)
efi_physical_addr_t mem;
size_t memsize;
efi_status_t efiret;
+ char *uuid;
#ifdef DEBUG
sys_table->con_out->output_string(sys_table->con_out, L"barebox\n");
@@ -377,6 +378,19 @@ efi_status_t efi_main(efi_handle_t image, efi_system_table_t *sys_table)
mem_malloc_init((void *)mem, (void *)mem + memsize);
efi_clocksource_init();
+ efi_set_variable_usec("LoaderTimeInitUSec", &efi_systemd_vendor_guid,
+ get_time_ns()/1000);
+
+ uuid = device_path_to_partuuid(device_path_from_handle(
+ efi_loaded_image->device_handle));
+ if (uuid) {
+ wchar_t *uuid16 = strdup_char_to_wchar(uuid);
+ efi_set_variable("LoaderDevicePartUUID",
+ &efi_systemd_vendor_guid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ uuid16, (strlen(uuid)+1) * sizeof(wchar_t));
+ }
start_barebox();
diff --git a/common/efi-guid.c b/common/efi-guid.c
index f6b040410522..f4ff7feadfe4 100644
--- a/common/efi-guid.c
+++ b/common/efi-guid.c
@@ -9,6 +9,7 @@ efi_guid_t efi_unknown_device_guid = EFI_UNKNOWN_DEVICE_GUID;
efi_guid_t efi_null_guid = EFI_NULL_GUID;
efi_guid_t efi_global_variable_guid = EFI_GLOBAL_VARIABLE_GUID;
efi_guid_t efi_block_io_protocol_guid = EFI_BLOCK_IO_PROTOCOL_GUID;
+efi_guid_t efi_systemd_vendor_guid = EFI_SYSTEMD_VENDOR_GUID;
#define EFI_GUID_STRING(guid, short, long) do { \
if (!efi_guidcmp(guid, *g)) \
diff --git a/include/efi.h b/include/efi.h
index 830e0457dd1c..5b0de119fb74 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -473,6 +473,10 @@ extern efi_runtime_services_t *RT;
#define EFI_BAREBOX_VENDOR_GUID \
EFI_GUID(0x5b91f69c, 0x8b88, 0x4a2b, 0x92, 0x69, 0x5f, 0x1d, 0x80, 0x2b, 0x51, 0x75)
+/* for systemd */
+#define EFI_SYSTEMD_VENDOR_GUID \
+ EFI_GUID(0x4a67b082, 0x0a4c, 0x41cf, 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f)
+
extern efi_guid_t efi_file_info_id;
extern efi_guid_t efi_simple_file_system_protocol_guid;
extern efi_guid_t efi_device_path_protocol_guid;
@@ -481,6 +485,7 @@ extern efi_guid_t efi_unknown_device_guid;
extern efi_guid_t efi_null_guid;
extern efi_guid_t efi_global_variable_guid;
extern efi_guid_t efi_block_io_protocol_guid;
+extern efi_guid_t efi_systemd_vendor_guid;
#define EFI_SYSTEM_TABLE_SIGNATURE ((u64)0x5453595320494249ULL)
--
2.1.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 7/7] efi: write volatile EFI variables used by systemd
2015-07-16 8:43 ` [PATCH 7/7] efi: write volatile EFI variables used by systemd Michael Olbrich
@ 2015-07-16 20:08 ` Sascha Hauer
2015-07-17 7:05 ` Michael Olbrich
0 siblings, 1 reply; 13+ messages in thread
From: Sascha Hauer @ 2015-07-16 20:08 UTC (permalink / raw)
To: Michael Olbrich; +Cc: barebox
On Thu, Jul 16, 2015 at 10:43:56AM +0200, Michael Olbrich wrote:
> LoaderTimeInitUSec and LoaderTimeExecUSec are used e.g. in systemd-analyze
> to calculate the time spent in the firmare and barebox.
>
> LoaderDevicePartUUID is used to mount the EFI partition to /boot.
>
> Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
> ---
> arch/efi/efi/efi-image.c | 5 +++++
> arch/efi/efi/efi.c | 14 ++++++++++++++
> common/efi-guid.c | 1 +
> include/efi.h | 5 +++++
> 4 files changed, 25 insertions(+)
>
> diff --git a/arch/efi/efi/efi-image.c b/arch/efi/efi/efi-image.c
> index f41322744bbc..89b712baab1f 100644
> --- a/arch/efi/efi/efi-image.c
> +++ b/arch/efi/efi/efi-image.c
> @@ -17,6 +17,7 @@
> *
> */
>
> +#include <clock.h>
> #include <common.h>
> #include <linux/sizes.h>
> #include <memory.h>
> @@ -242,6 +243,10 @@ static int do_bootm_efi(struct image_data *data)
> boot_header->ramdisk_image);
> printf("...\n");
> }
> +
> + efi_set_variable_usec("LoaderTimeExecUSec", &efi_systemd_vendor_guid,
> + get_time_ns()/1000);
> +
> linux_efi_handover(handle, boot_header);
>
> return 0;
> diff --git a/arch/efi/efi/efi.c b/arch/efi/efi/efi.c
> index b0e98f95b02b..a665a546be90 100644
> --- a/arch/efi/efi/efi.c
> +++ b/arch/efi/efi/efi.c
> @@ -340,6 +340,7 @@ efi_status_t efi_main(efi_handle_t image, efi_system_table_t *sys_table)
> efi_physical_addr_t mem;
> size_t memsize;
> efi_status_t efiret;
> + char *uuid;
>
> #ifdef DEBUG
> sys_table->con_out->output_string(sys_table->con_out, L"barebox\n");
> @@ -377,6 +378,19 @@ efi_status_t efi_main(efi_handle_t image, efi_system_table_t *sys_table)
> mem_malloc_init((void *)mem, (void *)mem + memsize);
>
> efi_clocksource_init();
> + efi_set_variable_usec("LoaderTimeInitUSec", &efi_systemd_vendor_guid,
> + get_time_ns()/1000);
> +
> + uuid = device_path_to_partuuid(device_path_from_handle(
> + efi_loaded_image->device_handle));
> + if (uuid) {
> + wchar_t *uuid16 = strdup_char_to_wchar(uuid);
> + efi_set_variable("LoaderDevicePartUUID",
> + &efi_systemd_vendor_guid,
> + EFI_VARIABLE_BOOTSERVICE_ACCESS |
> + EFI_VARIABLE_RUNTIME_ACCESS,
> + uuid16, (strlen(uuid)+1) * sizeof(wchar_t));
> + }
Shouldn't you free uuid here?
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 7/7] efi: write volatile EFI variables used by systemd
2015-07-16 20:08 ` Sascha Hauer
@ 2015-07-17 7:05 ` Michael Olbrich
2015-07-17 7:19 ` Sascha Hauer
0 siblings, 1 reply; 13+ messages in thread
From: Michael Olbrich @ 2015-07-17 7:05 UTC (permalink / raw)
To: barebox
On Thu, Jul 16, 2015 at 10:08:48PM +0200, Sascha Hauer wrote:
> On Thu, Jul 16, 2015 at 10:43:56AM +0200, Michael Olbrich wrote:
> > LoaderTimeInitUSec and LoaderTimeExecUSec are used e.g. in systemd-analyze
> > to calculate the time spent in the firmare and barebox.
> >
> > LoaderDevicePartUUID is used to mount the EFI partition to /boot.
> >
> > Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
> > ---
> > arch/efi/efi/efi-image.c | 5 +++++
> > arch/efi/efi/efi.c | 14 ++++++++++++++
> > common/efi-guid.c | 1 +
> > include/efi.h | 5 +++++
> > 4 files changed, 25 insertions(+)
> >
> > diff --git a/arch/efi/efi/efi-image.c b/arch/efi/efi/efi-image.c
> > index f41322744bbc..89b712baab1f 100644
> > --- a/arch/efi/efi/efi-image.c
> > +++ b/arch/efi/efi/efi-image.c
> > @@ -17,6 +17,7 @@
> > *
> > */
> >
> > +#include <clock.h>
> > #include <common.h>
> > #include <linux/sizes.h>
> > #include <memory.h>
> > @@ -242,6 +243,10 @@ static int do_bootm_efi(struct image_data *data)
> > boot_header->ramdisk_image);
> > printf("...\n");
> > }
> > +
> > + efi_set_variable_usec("LoaderTimeExecUSec", &efi_systemd_vendor_guid,
> > + get_time_ns()/1000);
> > +
> > linux_efi_handover(handle, boot_header);
> >
> > return 0;
> > diff --git a/arch/efi/efi/efi.c b/arch/efi/efi/efi.c
> > index b0e98f95b02b..a665a546be90 100644
> > --- a/arch/efi/efi/efi.c
> > +++ b/arch/efi/efi/efi.c
> > @@ -340,6 +340,7 @@ efi_status_t efi_main(efi_handle_t image, efi_system_table_t *sys_table)
> > efi_physical_addr_t mem;
> > size_t memsize;
> > efi_status_t efiret;
> > + char *uuid;
> >
> > #ifdef DEBUG
> > sys_table->con_out->output_string(sys_table->con_out, L"barebox\n");
> > @@ -377,6 +378,19 @@ efi_status_t efi_main(efi_handle_t image, efi_system_table_t *sys_table)
> > mem_malloc_init((void *)mem, (void *)mem + memsize);
> >
> > efi_clocksource_init();
> > + efi_set_variable_usec("LoaderTimeInitUSec", &efi_systemd_vendor_guid,
> > + get_time_ns()/1000);
> > +
> > + uuid = device_path_to_partuuid(device_path_from_handle(
> > + efi_loaded_image->device_handle));
> > + if (uuid) {
> > + wchar_t *uuid16 = strdup_char_to_wchar(uuid);
> > + efi_set_variable("LoaderDevicePartUUID",
> > + &efi_systemd_vendor_guid,
> > + EFI_VARIABLE_BOOTSERVICE_ACCESS |
> > + EFI_VARIABLE_RUNTIME_ACCESS,
> > + uuid16, (strlen(uuid)+1) * sizeof(wchar_t));
> > + }
>
> Shouldn't you free uuid here?
Yes, and uuid16.
Hmmm, what's the policy for OOM checks for string functions? None of the
existing calls of strdup_char_to_wchar() check for NULL. And I didn't find
any checks for asprintf() either.
Michael
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 7/7] efi: write volatile EFI variables used by systemd
2015-07-17 7:05 ` Michael Olbrich
@ 2015-07-17 7:19 ` Sascha Hauer
0 siblings, 0 replies; 13+ messages in thread
From: Sascha Hauer @ 2015-07-17 7:19 UTC (permalink / raw)
To: barebox
On Fri, Jul 17, 2015 at 09:05:40AM +0200, Michael Olbrich wrote:
> On Thu, Jul 16, 2015 at 10:08:48PM +0200, Sascha Hauer wrote:
> > On Thu, Jul 16, 2015 at 10:43:56AM +0200, Michael Olbrich wrote:
> > > LoaderTimeInitUSec and LoaderTimeExecUSec are used e.g. in systemd-analyze
> > > to calculate the time spent in the firmare and barebox.
> > >
> > > LoaderDevicePartUUID is used to mount the EFI partition to /boot.
> > >
> > > Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
> > > ---
> > > arch/efi/efi/efi-image.c | 5 +++++
> > > arch/efi/efi/efi.c | 14 ++++++++++++++
> > > common/efi-guid.c | 1 +
> > > include/efi.h | 5 +++++
> > > 4 files changed, 25 insertions(+)
> > >
> > > diff --git a/arch/efi/efi/efi-image.c b/arch/efi/efi/efi-image.c
> > > index f41322744bbc..89b712baab1f 100644
> > > --- a/arch/efi/efi/efi-image.c
> > > +++ b/arch/efi/efi/efi-image.c
> > > @@ -17,6 +17,7 @@
> > > *
> > > */
> > >
> > > +#include <clock.h>
> > > #include <common.h>
> > > #include <linux/sizes.h>
> > > #include <memory.h>
> > > @@ -242,6 +243,10 @@ static int do_bootm_efi(struct image_data *data)
> > > boot_header->ramdisk_image);
> > > printf("...\n");
> > > }
> > > +
> > > + efi_set_variable_usec("LoaderTimeExecUSec", &efi_systemd_vendor_guid,
> > > + get_time_ns()/1000);
> > > +
> > > linux_efi_handover(handle, boot_header);
> > >
> > > return 0;
> > > diff --git a/arch/efi/efi/efi.c b/arch/efi/efi/efi.c
> > > index b0e98f95b02b..a665a546be90 100644
> > > --- a/arch/efi/efi/efi.c
> > > +++ b/arch/efi/efi/efi.c
> > > @@ -340,6 +340,7 @@ efi_status_t efi_main(efi_handle_t image, efi_system_table_t *sys_table)
> > > efi_physical_addr_t mem;
> > > size_t memsize;
> > > efi_status_t efiret;
> > > + char *uuid;
> > >
> > > #ifdef DEBUG
> > > sys_table->con_out->output_string(sys_table->con_out, L"barebox\n");
> > > @@ -377,6 +378,19 @@ efi_status_t efi_main(efi_handle_t image, efi_system_table_t *sys_table)
> > > mem_malloc_init((void *)mem, (void *)mem + memsize);
> > >
> > > efi_clocksource_init();
> > > + efi_set_variable_usec("LoaderTimeInitUSec", &efi_systemd_vendor_guid,
> > > + get_time_ns()/1000);
> > > +
> > > + uuid = device_path_to_partuuid(device_path_from_handle(
> > > + efi_loaded_image->device_handle));
> > > + if (uuid) {
> > > + wchar_t *uuid16 = strdup_char_to_wchar(uuid);
> > > + efi_set_variable("LoaderDevicePartUUID",
> > > + &efi_systemd_vendor_guid,
> > > + EFI_VARIABLE_BOOTSERVICE_ACCESS |
> > > + EFI_VARIABLE_RUNTIME_ACCESS,
> > > + uuid16, (strlen(uuid)+1) * sizeof(wchar_t));
> > > + }
> >
> > Shouldn't you free uuid here?
>
> Yes, and uuid16.
>
> Hmmm, what's the policy for OOM checks for string functions? None of the
> existing calls of strdup_char_to_wchar() check for NULL. And I didn't find
> any checks for asprintf() either.
Introducing xasprintf and using it throughout the tree is on my mental
todo list for some time now. I think You can skip the error check, or,
even better, introduce xasprintf ;)
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 13+ messages in thread