From patchwork Wed Dec 30 15:07:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilias Apalodimas X-Patchwork-Id: 355274 Delivered-To: patch@linaro.org Received: by 2002:a02:85a7:0:0:0:0:0 with SMTP id d36csp11403674jai; Wed, 30 Dec 2020 07:08:26 -0800 (PST) X-Google-Smtp-Source: ABdhPJxzxJNt03hqOXKGYMQLv3LlmsnjaxtK86OLvrgdsnXYNYWQQVPhZMFYuYx/1sv6/iVtFV/1 X-Received: by 2002:aa7:cb16:: with SMTP id s22mr52388400edt.53.1609340906029; Wed, 30 Dec 2020 07:08:26 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1609340906; cv=none; d=google.com; s=arc-20160816; b=AaH1Q0ddOJCB5UILDIHCNatoVYpNtu9wDh96P7B/nVUbHNim8fHWjDsqc5NJApX4n5 EiYIPFMDmdSvLSh93jidytDG57OuszTdEtZYJmpUygH2A6ICMVr1PgGVCybmnMk2geL2 x+6hSO3E1DeL9HxSq+1FcKmDq26pu1VzpA+ZpFmvEpnowU4fIOkTElIzDqQ9EyTO67ne nriJprUDv9bzGxn1UQ4ErZA3G1SbyuaCRgHcL4DdplHHT/qulsO2787W6mn0M7H1+i02 3s00DpPAP/D8HB6D7sXWS29OVoP6208Gm1eqDGHbRiP+i/1Jv5Lyw3ARPgyXXNLkFUs5 aGxA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=I0jzps4L2oZBIthJ7ddQ0geOL1wWUE/nbLZWhXu6c7c=; b=DWzG0IVsjpS8n/nL4Ut7NQWy7lpsQw8wd2mn8wWUZjyf/kjgZQ0IlNgn8wUHktERX/ jp56oC/V6NVkWXRrkj5zFRpiz3Jbkk09Z9XL3HDCsylAYBCGdMF+tv6j6T2keUG6Oh5V o7x6ogWxcGfe6TjxYpBrigR0S3zmUCfCe0VDiS1R8p4C/4Xa+7EU4QhitPjjgh9S9479 2fHRJH67Haic5oIsr9VI0P3gbIkt3CKQdgxM8q31oB6xs7ZQnNbwnPBTvMRZ2wmQWXQY QTMS6w7wqlaFmJ8BCGvAshbVbp6yRvHbqjat7xa9CcLQykUXFYwAMXXB27YvAgHCGd2Q hi5A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=lJEwYNNW; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id v1si23328003edf.22.2020.12.30.07.08.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 30 Dec 2020 07:08:26 -0800 (PST) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=lJEwYNNW; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id ACCE482607; Wed, 30 Dec 2020 16:07:58 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="lJEwYNNW"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id C6D568260A; Wed, 30 Dec 2020 16:07:41 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com [IPv6:2a00:1450:4864:20::436]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 0850C825AE for ; Wed, 30 Dec 2020 16:07:38 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=ilias.apalodimas@linaro.org Received: by mail-wr1-x436.google.com with SMTP id d13so17649715wrc.13 for ; Wed, 30 Dec 2020 07:07:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=I0jzps4L2oZBIthJ7ddQ0geOL1wWUE/nbLZWhXu6c7c=; b=lJEwYNNWIK+bkZlcWAiTqp7sS1bu3XNsWT6u6Ml/D69CkPWmL+cyvrc/Qt1EHMuJTL XXKveJtcM14CWTRroW+J5LIrfkC6hCG5mupEpTY00nc7MoqxEWSQ9WR2xT/BxdTheaRJ Y+YuYG6bw1ZD+tDDBoCcJhceX2zs0bCBWojbFdRCTJR3v6I3QlEetFTQfVTDL2R8vaqz +e+xXkCCp3LNzkQZzmDhuam0pZLWo0B4TJy8cdQaUNOg+VSwCo8MZ6Cat2f+zjxsb0i/ kFlfKx3eH0LQwt2/UIBaxvpkCZmG3252arZ16MC7x0LmuDXdOkhd/Ohw8fQv5hkUufuz 82OQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=I0jzps4L2oZBIthJ7ddQ0geOL1wWUE/nbLZWhXu6c7c=; b=athZFRxJHUaYmTGkNgcnevtfslYj1ZUvhTTLnXJ0XIuY+tue+YJ1/Y0wuM8ePX3nXF JOLv2MXRP+jU+PQwbfc/tZfNfCvMnNGyHDtw0NWTBACGA4ibdHPZBxCwCsG7R/BAWrYi walEE9S8Lz1ozw+rzUdAGDqB/d9JFHa7xzPsdu3e6t6DZhQ8f+txqLccFWmyPXnvp94m 1HA9wRYmCCJYd8KnmJZIvQTSx7mvFODv8uPFo+cYtkYVzkx6AxMlUQxiaUVgZ/xB31Tm w7XPQwSFEk2wolijIEF4OLgJCmezkXlSFwJxv+mws91f6iqzlak8X9ieQl21bt4kGc03 a6cw== X-Gm-Message-State: AOAM533ZSEUhzEt2Z+Q+uNLz6xZFv3wlOMne2/ukDES6VqPF1IKVwTrj 0XluOUnGxRrwm9mezQdztbuGCA== X-Received: by 2002:adf:a551:: with SMTP id j17mr60093330wrb.217.1609340857638; Wed, 30 Dec 2020 07:07:37 -0800 (PST) Received: from localhost.localdomain (athedsl-4484548.home.otenet.gr. [94.71.57.204]) by smtp.gmail.com with ESMTPSA id k10sm62062721wrq.38.2020.12.30.07.07.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 30 Dec 2020 07:07:37 -0800 (PST) From: Ilias Apalodimas To: xypron.glpk@gmx.de Cc: takahiro.akashi@linaro.org, ard.biesheuvel@arm.com, Ilias Apalodimas , Alexander Graf , u-boot@lists.denx.de Subject: [PATCH 4/8 v2] efi_loader: Introduce helper functions for EFI Date: Wed, 30 Dec 2020 17:07:16 +0200 Message-Id: <20201230150722.154663-5-ilias.apalodimas@linaro.org> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20201230150722.154663-1-ilias.apalodimas@linaro.org> References: <20201230150722.154663-1-ilias.apalodimas@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.3 at phobos.denx.de X-Virus-Status: Clean A following patch introduces a different logic for loading initrd's based on the EFI_LOAD_FILE2_PROTOCOL. Since similar logic can be applied in the future for other system files (i.e DTBs), let's add some helper functions which will retrieve and parse file paths stored in EFI variables. Signed-off-by: Ilias Apalodimas --- include/efi_helper.h | 28 ++++++ lib/efi_loader/efi_helper.c | 180 ++++++++++++++++++++++++++++++++++++ 2 files changed, 208 insertions(+) create mode 100644 include/efi_helper.h create mode 100644 lib/efi_loader/efi_helper.c -- 2.30.0 diff --git a/include/efi_helper.h b/include/efi_helper.h new file mode 100644 index 000000000000..5d3a43364619 --- /dev/null +++ b/include/efi_helper.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2020, Linaro Limited + */ + +#if !defined _EFI_HELPER_H_ +#define _EFI_HELPER_H + +#include +#include + +/* + * @dev: device string i.e 'mmc' + * @part: partition string i.e '0:2' + * @filename: name of the file + */ +struct load_file_info { + char dev[32]; + char part[16]; + char filename[256]; +}; + +loff_t get_file_size(const struct load_file_info *file_loc, + efi_status_t *status); +efi_status_t efi_get_fp_from_var(const char *name, struct load_file_info *loc); +void *get_var_efi(u16 *name, const efi_guid_t *vendor, efi_uintn_t *size); + +#endif diff --git a/lib/efi_loader/efi_helper.c b/lib/efi_loader/efi_helper.c new file mode 100644 index 000000000000..e5919343a5cc --- /dev/null +++ b/lib/efi_loader/efi_helper.c @@ -0,0 +1,180 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2020, Linaro Limited + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * get_file_size() - retrieve the size of initramfs, set efi status on error + * + * @dev: device to read from, e.g. "mmc" + * @part: device partition, e.g. "0:1" + * @file: name of file + * @status: EFI exit code in case of failure + * + * Return: size of file + */ +loff_t get_file_size(const struct load_file_info *info, efi_status_t *status) +{ + loff_t sz = 0; + int ret; + + ret = fs_set_blk_dev(info->dev, info->part, FS_TYPE_ANY); + if (ret) { + *status = EFI_NO_MEDIA; + goto out; + } + + ret = fs_size(info->filename, &sz); + if (ret) { + sz = 0; + *status = EFI_NOT_FOUND; + goto out; + } + +out: + return sz; +} + +/* + * string_to_load_args() - Fill in a struct load_file_info with the file info + * parsed from an EFI variable + * + * @args: value of the EFI variable i.e "mmc 0 initrd" + * @info: struct to fill in with file specific info + * + * Return: Status code + */ +static efi_status_t string_to_load_args(char *args, struct load_file_info *info) +{ + efi_status_t status = EFI_SUCCESS; + char *p; + + /* + * expect a string with three space separated parts: + * - block device type, e.g. "mmc" + * - device and partition identifier, e.g. "0:1" + * - file path on the block device, e.g. "/boot/initrd.cpio.gz" + */ + p = strsep(&args, " "); + if (!p) { + status = EFI_NO_MEDIA; + goto out; + } + strncpy(info->dev, p, sizeof(info->dev)); + info->dev[sizeof(info->dev) - 1] = 0; + + p = strsep(&args, " "); + if (!p) { + status = EFI_NO_MEDIA; + goto out; + } + strncpy(info->part, p, sizeof(info->part)); + info->part[sizeof(info->part) - 1] = 0; + + p = strsep(&args, " "); + if (!p) { + status = EFI_NOT_FOUND; + goto out; + } + strncpy(info->filename, p, sizeof(info->filename)); + info->filename[sizeof(info->filename) - 1] = 0; + +out: + return status; +} + +/** + * get_var_efi() - read value of an EFI variable + * + * @name: variable name + * @start: vendor GUID + * @size: size of allocated buffer + * + * Return: buffer with variable data or NULL + */ +void *get_var_efi(u16 *name, const efi_guid_t *vendor, efi_uintn_t *size) +{ + efi_status_t ret; + void *buf = NULL; + + *size = 0; + ret = efi_get_variable_int(name, vendor, NULL, size, buf, NULL); + if (ret == EFI_BUFFER_TOO_SMALL) { + buf = malloc(*size); + ret = efi_get_variable_int(name, vendor, NULL, size, buf, NULL); + } + + if (ret != EFI_SUCCESS) { + free(buf); + *size = 0; + return NULL; + } + + return buf; +} + +/** + * efi_get_fp_from_var() - Retrieve a file path from an EFI variable + * + * @name: variable name + * @info: struct to fill in with file specific info + */ +efi_status_t efi_get_fp_from_var(const char *name, struct load_file_info *info) +{ + efi_uintn_t boot_cur_size; + void *var_value = NULL; + efi_uintn_t size; + efi_status_t ret; + u16 boot_cur; + u16 var_name[16]; + u16 *pos; + + memset(info, 0, sizeof(*info)); + + boot_cur_size = sizeof(boot_cur); + ret = efi_get_variable_int(L"BootCurrent", + &efi_global_variable_guid, NULL, + &boot_cur_size, &boot_cur, NULL); + if (ret != EFI_SUCCESS) + goto out; + + pos = efi_create_indexed_name(var_name, sizeof(var_name), name, + boot_cur); + if (!pos) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + var_value = get_var_efi(var_name, &efi_global_variable_guid, &size); + if (!var_value) { + ret = EFI_NOT_FOUND; + goto out; + } + + ret = string_to_load_args(var_value, info); + if (ret != EFI_SUCCESS) + goto out; + + if (fs_set_blk_dev(info->dev, info->part, FS_TYPE_ANY)) { + ret = EFI_NO_MEDIA; + goto out; + } + + if (!fs_exists(info->filename)) { + ret = EFI_NOT_FOUND; + goto out; + } + +out: + free(var_value); + return ret; +}