From patchwork Tue Mar 8 14:07:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 549287 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:6713:0:0:0:0 with SMTP id u19csp2655870mag; Tue, 8 Mar 2022 06:08:26 -0800 (PST) X-Google-Smtp-Source: ABdhPJyEaW/jieiWgFwhfuH2J6r7KRiOviQypUTXQrXaTB5bdcc/mV22kzakw4EPfkqln8rf7Qaf X-Received: by 2002:aa7:cb96:0:b0:413:8d05:ebc with SMTP id r22-20020aa7cb96000000b004138d050ebcmr16415167edt.81.1646748506385; Tue, 08 Mar 2022 06:08:26 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1646748506; cv=none; d=google.com; s=arc-20160816; b=VJFH4w/LDCMBxepK0AHVuuzMHeR+2iKWwSRBiyW5VRLRQNqbcJ0Ntw1OmWOySoZyQv uiHqZVFPFjeYZECu20d6RlAVp2rBel6fnRxnMIFhpRVil2sYlCJhMMrInBxUG4t4twVg S68vfzFXVaEyjBl8bW24NpMB/pHC2yY2L5BCTncD6YTcPVYayQUbbY+OXyDaNh2CVNyH /+T7P6oV8TDgKASN7CaN1o/vPgiiW/RR8dK8ZX5gW+TZOjLlikym43g35eIacq/QWNNG CMGgTJR7b9onHpWpajLmNuk+HmbPr+M+auNyHNOycrIj+Rd79F9013SA3H2NnNgo2GKA gygw== 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:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=NOqB4EvPzx6IMS7gf4xl1Q/t9oYdiZChLezc7ijSKh8=; b=R3pzSNs7W1YyHJ6pjZbPnkE/c51Gt+p7dqj6L23yJ1uLlWOxVorrlpa3cAmBDQ1TGK VwR1Xs+v7l+IXU/v5elD4YrC9jRYRY2qij6mB3xt0dwaULIUiz0wtMxiAsPlLKMqBH++ Z5uGh3yBkKxzhTe2nE2YdJhKjDQGVj/MXrwlfSMnsvTuIrhNjb/NAPbrMM9ep8Qevier xToOEzSNkXm1Z+r01F5Wd874zA0etp7nfheTyQtLIj8pJ/OShPXTdnw6G/uyv9oTeLz+ 9JioW45GzDR0TFRWpdKc91JHLT9KuP5FSrsSxnxHr02oZfXNxJYuLNuXE6sO8WKTSmFO 99Og== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ny0eSSJb; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 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. [85.214.62.61]) by mx.google.com with ESMTPS id w16-20020a1709061f1000b006d1240c3431si10001381ejj.896.2022.03.08.06.08.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Mar 2022 06:08:26 -0800 (PST) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ny0eSSJb; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 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 7E6FE83932; Tue, 8 Mar 2022 15:08:12 +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="ny0eSSJb"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 2C81783932; Tue, 8 Mar 2022 15:08:01 +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.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pl1-x632.google.com (mail-pl1-x632.google.com [IPv6:2607:f8b0:4864:20::632]) (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 C31EE83927 for ; Tue, 8 Mar 2022 15:07:55 +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=masahisa.kojima@linaro.org Received: by mail-pl1-x632.google.com with SMTP id s18so3926804plp.1 for ; Tue, 08 Mar 2022 06:07:55 -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; bh=NOqB4EvPzx6IMS7gf4xl1Q/t9oYdiZChLezc7ijSKh8=; b=ny0eSSJbHyprq4oMsZo6OSK/uP3lS85oW8S+5JPuCNw4Af4wiiUopiexLIJekCOT+h PBr1TPJRCT1kTUvLTCiNsmMk8TRkCtM1R8eTInB14kaSbj5R22t2cM/N5uUVBmdQ5Jzy ZeZhnJHGVcL/9AIZJKXJwPXMyYFeXQfP6Z0ON8ryaiFlQEDXOmLUBDdlm4uIOCcI4AyZ de1pmBwHSxJhzRLlIKtT14gl09LORUd+B5Nl7KjpNd9lD219gbp+5ovh6rjMRW1Q1BAX KdQwbDWwOH2sHU1CsqrLff+QkUzIxCPJV/0Pd3ADE53namW3V27vCnczbbVADMDTUZgs ByEA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=NOqB4EvPzx6IMS7gf4xl1Q/t9oYdiZChLezc7ijSKh8=; b=oKHZYupRz5+Pw8RNEpw7TCtkt5CPwqlmFdcantIiuAWMgkJMJo3UflG4xvzWWHLMYD nuALE8Jslgc0K9c0B6smm8jevxtILh4o7hAvi592gpv311WBG1avywHPgKkNu5RD3+ha +uD2cZH5ieqgomD9QKDYDitDfawRG+eQZ/wXA28Z7NzrpK+H7eqKk/vieYEZbrQgGTI+ 6QH/F3L+kNZ1LRuD0m/ZofJRS1JkYZkKZZmR4YMkGkYrP/mSNdm5+iAVWv/TmeRVBAp7 FV/BCz6IfaynP/dstmJJyOsKQzx3gUMvhhhhcjTF9BnQ6nceMp/5ccugKYL+ssrQwnwA CEvw== X-Gm-Message-State: AOAM532RNp96TjQ1IF6iL2wQ+XFJ57BDv1VjSUgep+RWmw89s9/A71AG +HMhvAmmBFZyVSKIQBkcuom6jw8LWpQMuA== X-Received: by 2002:a17:902:8605:b0:151:b6a2:8a1 with SMTP id f5-20020a170902860500b00151b6a208a1mr18144071plo.64.1646748474159; Tue, 08 Mar 2022 06:07:54 -0800 (PST) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id k62-20020a17090a4cc400b001bf0d92e1c7sm3142989pjh.41.2022.03.08.06.07.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Mar 2022 06:07:53 -0800 (PST) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Francois Ozog , Mark Kettenis , Masahisa Kojima Subject: [RFC PATCH v3 1/2] efi_loader: introduce "bootefi bootindex" command Date: Tue, 8 Mar 2022 23:07:44 +0900 Message-Id: <20220308140745.26180-2-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220308140745.26180-1-masahisa.kojima@linaro.org> References: <20220308140745.26180-1-masahisa.kojima@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 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.103.5 at phobos.denx.de X-Virus-Status: Clean This commit introduces the new command "bootefi bootindex". With this command, user can select which "Boot####" option to load and execute. Signed-off-by: Masahisa Kojima --- Changes in v3: - newly created cmd/bootefi.c | 42 ++++++++++++++++++++++++++++++++++++ include/efi_loader.h | 1 + lib/efi_loader/efi_bootmgr.c | 7 +++--- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 46eebd5ee2..df86438fec 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -416,6 +416,30 @@ static int do_efibootmgr(void) return CMD_RET_SUCCESS; } +/** + * do_efibootindex() - load and execute the specified Boot#### option + * + * Return: status code + */ +static int do_efibootindex(u16 boot_index) +{ + efi_handle_t handle; + efi_status_t ret; + void *load_options; + + ret = efi_try_load_entry(boot_index, &handle, &load_options); + if (ret != EFI_SUCCESS) { + log_notice("EFI boot manager: failed to load Boot%04X\n", boot_index); + return CMD_RET_FAILURE; + } + + ret = do_bootefi_exec(handle, load_options); + + if (ret != EFI_SUCCESS) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +} /** * do_bootefi_image() - execute EFI binary * @@ -654,6 +678,22 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_FAILURE; } + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) { + if (!strcmp(argv[1], "bootindex")) { + char *endp; + int boot_index; + + if (argc < 3) + return CMD_RET_USAGE; + + boot_index = (int)hextoul(argv[2], &endp); + if (*endp != '\0' || boot_index > 0xffff) + return CMD_RET_USAGE; + + return do_efibootindex((u16)boot_index); + } + } + if (argc > 2) { uintptr_t fdt_addr; @@ -702,6 +742,8 @@ static char bootefi_help_text[] = "\n" " If specified, the device tree located at gets\n" " exposed as EFI configuration table.\n" + "bootefi bootindex \n" + " - load and boot EFI payload based on the specified BootXXXX variable.\n" #endif ; #endif diff --git a/include/efi_loader.h b/include/efi_loader.h index 80a5f1ec01..e5972f5fee 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -861,6 +861,7 @@ efi_status_t efi_set_load_options(efi_handle_t handle, efi_uintn_t load_options_size, void *load_options); efi_status_t efi_bootmgr_load(efi_handle_t *handle, void **load_options); +efi_status_t efi_try_load_entry(u16 n, efi_handle_t *handle, void **load_options); /** * struct efi_image_regions - A list of memory regions diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index 8c04ecbdc8..a3060b5c62 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -42,8 +42,7 @@ static const struct efi_runtime_services *rs; * @load_options: load options set on the loaded image protocol * Return: status code */ -static efi_status_t try_load_entry(u16 n, efi_handle_t *handle, - void **load_options) +efi_status_t efi_try_load_entry(u16 n, efi_handle_t *handle, void **load_options) { struct efi_load_option lo; u16 varname[] = u"Boot0000"; @@ -165,7 +164,7 @@ efi_status_t efi_bootmgr_load(efi_handle_t *handle, void **load_options) /* load BootNext */ if (ret == EFI_SUCCESS) { if (size == sizeof(u16)) { - ret = try_load_entry(bootnext, handle, + ret = efi_try_load_entry(bootnext, handle, load_options); if (ret == EFI_SUCCESS) return ret; @@ -189,7 +188,7 @@ efi_status_t efi_bootmgr_load(efi_handle_t *handle, void **load_options) for (i = 0; i < num; i++) { log_debug("%s trying to load Boot%04X\n", __func__, bootorder[i]); - ret = try_load_entry(bootorder[i], handle, load_options); + ret = efi_try_load_entry(bootorder[i], handle, load_options); if (ret == EFI_SUCCESS) break; } From patchwork Tue Mar 8 14:07:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 549288 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:6713:0:0:0:0 with SMTP id u19csp2656092mag; Tue, 8 Mar 2022 06:08:39 -0800 (PST) X-Google-Smtp-Source: ABdhPJzSEefwRXlb1BmyP0lOOMErAY+7fzG272839/5vrhKJBuzAd+yocgvdW7u8E8efHvWpbep2 X-Received: by 2002:a17:907:3e22:b0:6da:83fd:418 with SMTP id hp34-20020a1709073e2200b006da83fd0418mr13648854ejc.321.1646748518968; Tue, 08 Mar 2022 06:08:38 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1646748518; cv=none; d=google.com; s=arc-20160816; b=owVP+mKhilrviP4ouJESnO8/CIh9QFU10Nz++wPT39qaTfBvgyMH7wFzWP/iHzupuQ yS1/FvWXC9il8WQVLW9kl49m6ip4PYBuzI5jH1RcwlYpPuKJyNSI2vKLYG6tX07RHU9L WplBXNpCKFrYYaL/qfwefsEZ/eT+ir25i7w0brjEsoWGNtXwN3ZfKO3L96m6t9OsYRU6 68MCndSVpClSGPPTol0eZ6SxmkUCiqDwYWFpe4/tPkaEDxLnL4QGpd5zrLeC0cGyURKZ dNNiVAs2AAXBQaZYp6LfJZazVES2K3zo1tWBMOVAZ+63mnKIHnENIM96nH8oWmd1VM0y XXSw== 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=FeterVYany2pC8QVjP8gnF1/h1e87YyyrEj8rCADLlA=; b=LiKq/mqRUCEQvQbNQuYvBbUIIQHEXfN/zwSswN/JJCyGX25tafxLjv4gHrXvh5G5XR 7Jl44zynnNEIEH6EMFu/rGUCRdMfddkOai9YGUwqO9b6X/hxD5ifwG/2C0dpOWFap3Ye kjgOE0UtDz8UT/DTlM8moiM77m8wL/PuTBPIOR2ZiyJJcXXTiwQ39gQUAuCu4uh1HGU4 WPNawINuGFeKr4Ivan/Ymewo1raNqwLpv3g/fyNePyimhVB91FmYHZR7T+n3+ZZorkAP lKvNF6JMg/B7GwTFBK7E6anfcxEgGOcRBSvbPQcpT7Ks5EbdA9So6lYtO5lbon5twYp1 IMtA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=RVHyIvxa; 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 o4-20020a50fd84000000b0041599071e8asi10745723edt.24.2022.03.08.06.08.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Mar 2022 06:08:38 -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=RVHyIvxa; 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 61FEE83995; Tue, 8 Mar 2022 15:08:20 +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="RVHyIvxa"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id E0E2983977; Tue, 8 Mar 2022 15:08:09 +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.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pj1-x102b.google.com (mail-pj1-x102b.google.com [IPv6:2607:f8b0:4864:20::102b]) (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 68C52836A9 for ; Tue, 8 Mar 2022 15: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=masahisa.kojima@linaro.org Received: by mail-pj1-x102b.google.com with SMTP id mg21-20020a17090b371500b001bef9e4657cso2372685pjb.0 for ; Tue, 08 Mar 2022 06:07:58 -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=FeterVYany2pC8QVjP8gnF1/h1e87YyyrEj8rCADLlA=; b=RVHyIvxaeQUrt35LVF+ok48Ta/cbhd72mktXsTqMYtu+iGK/OfbqupYDOrVhN09Jaq 05r4cJwwqwlr7PSoA++0UlcoqcN4gEH48RvIIVVq9xrPZXctwQS0VADy2dWxQVl+vvgq yHOsdNGoqR0Ag1jig3KTlUzSQiMVTePZWv7f/KDzwCpl3XGCjHsu1YEq3mf5qqJPQY/k zC3I4pVlTYAnbVMfUCNznJTg/m4cw55EF/6Y/u6Uq9Utwzu57kHS6/+J0XJq3kS1CwbJ +DYyAvsA4bZjlGEqZtPyBZQ0/JqEDomFMLXb+nUV9QbJzt6pPD9b/WFMLeTjtVtOjEZq U/xg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=FeterVYany2pC8QVjP8gnF1/h1e87YyyrEj8rCADLlA=; b=ic52gOgdpSCYh3USVsUxw0MGFnKfczE86oY3WpshH/QPNRBZXlEHpQ+2VyEbWHrFSn uahN3jEdEqG6NhqtakK1H2Q3O1aEZrBxSSnae6+bYXqx3bmGn7BdxuUjR5pBJ9qi/4RO /4g2lXUXqh1x+Spa2TQn07fXX/05C5l3Y6Whu8xx7deoGmS9ViAERHJH4jU21BHY0Xov VrK9m2nXBooUlRo6qfMKc1lJ1dzmThWojAJnSCDe84bK5XODjon0BNOxDEEhKPVl/S+b Knl8n8H9ddqFznByurs4Rio9FSqe27VHqbK6xDcNnC6ZduDEWDKF27zetMJhsNK2XXf8 koAg== X-Gm-Message-State: AOAM530hQE+MkCTEEEvqjYtbOzqzO/hMIVA7jqE4Ve0RbwjOfNmx6/tN 0VJuvAOeDRZwgDVowv4/SRhfk2tfIbMIFQ== X-Received: by 2002:a17:90a:dc18:b0:1bf:50c7:a4fa with SMTP id i24-20020a17090adc1800b001bf50c7a4famr4768636pjv.187.1646748476785; Tue, 08 Mar 2022 06:07:56 -0800 (PST) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id k62-20020a17090a4cc400b001bf0d92e1c7sm3142989pjh.41.2022.03.08.06.07.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Mar 2022 06:07:56 -0800 (PST) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Francois Ozog , Mark Kettenis , Masahisa Kojima Subject: [RFC PATCH v3 2/2] bootmenu: add UEFI and disto_boot entries Date: Tue, 8 Mar 2022 23:07:45 +0900 Message-Id: <20220308140745.26180-3-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220308140745.26180-1-masahisa.kojima@linaro.org> References: <20220308140745.26180-1-masahisa.kojima@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 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.103.5 at phobos.denx.de X-Virus-Status: Clean This commit adds the UEFI related menu entries and distro_boot entries into the bootmenu. For UEFI, user can select which UEFI "Boot####" option to execute, call UEFI bootmgr and UEFI boot variable maintenance menu. UEFI bootmgr entry is required to correctly handle "BootNext" variable. For distro_boot, user can select the boot device included in "boot_targets" u-boot environment variable. The menu example is as follows. *** U-Boot Boot Menu *** Boot 1. kernel (bootmenu_0) Boot 2. kernel (bootmenu_1) Reset board (bootmenu_2) debian (BOOT0000) ubuntu (BOOT0001) UEFI Boot Manager usb0 scsi0 virtio0 dhcp UEFI Boot Manager Maintenance U-Boot console Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit Signed-off-by: Masahisa Kojima --- Changes in v3: - newly created cmd/bootmenu.c | 268 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 259 insertions(+), 9 deletions(-) diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index 409ef9a848..a8dc50dcaa 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -3,9 +3,12 @@ * (C) Copyright 2011-2013 Pali Rohár */ +#include #include #include #include +#include +#include #include #include #include @@ -24,11 +27,20 @@ */ #define MAX_ENV_SIZE (9 + 2 + 1) +enum boot_type { + BOOT_TYPE_NONE = 0, + BOOT_TYPE_BOOTMENU, + BOOT_TYPE_UEFI, + BOOT_TYPE_DISTRO_BOOT, +}; + struct bootmenu_entry { unsigned short int num; /* unique number 0 .. MAX_COUNT */ char key[3]; /* key identifier of number */ - char *title; /* title of entry */ + u16 *title; /* title of entry */ char *command; /* hush command of entry */ + enum boot_type type; + u16 bootorder; struct bootmenu_data *menu; /* this bootmenu */ struct bootmenu_entry *next; /* next menu entry (num+1) */ }; @@ -75,7 +87,12 @@ static void bootmenu_print_entry(void *data) if (reverse) puts(ANSI_COLOR_REVERSE); - puts(entry->title); + if (entry->type == BOOT_TYPE_BOOTMENU) + printf("%ls (bootmenu_%d)", entry->title, entry->bootorder); + else if (entry->type == BOOT_TYPE_UEFI) + printf("%ls (BOOT%04X)", entry->title, entry->bootorder); + else + printf("%ls", entry->title); if (reverse) puts(ANSI_COLOR_RESET); @@ -87,6 +104,10 @@ static void bootmenu_autoboot_loop(struct bootmenu_data *menu, int i, c; if (menu->delay > 0) { + /* flush input */ + while (tstc()) + getchar(); + printf(ANSI_CURSOR_POSITION, menu->count + 5, 1); printf(" Hit any key to stop autoboot: %2d ", menu->delay); } @@ -300,6 +321,8 @@ static struct bootmenu_data *bootmenu_create(int delay) menu->active = (int)simple_strtol(default_str, NULL, 10); while ((option = bootmenu_getoption(i))) { + u16 *buf; + sep = strchr(option, '='); if (!sep) { printf("Invalid bootmenu entry: %s\n", option); @@ -311,13 +334,13 @@ static struct bootmenu_data *bootmenu_create(int delay) goto cleanup; len = sep-option; - entry->title = malloc(len + 1); + buf = calloc(1, (len + 1) * sizeof(u16)); + entry->title = buf; if (!entry->title) { free(entry); goto cleanup; } - memcpy(entry->title, option, len); - entry->title[len] = 0; + utf8_utf16_strncpy(&buf, option, len); len = strlen(sep + 1); entry->command = malloc(len + 1); @@ -333,6 +356,190 @@ static struct bootmenu_data *bootmenu_create(int delay) entry->num = i; entry->menu = menu; + entry->type = BOOT_TYPE_BOOTMENU; + entry->bootorder = i; + entry->next = NULL; + + if (!iter) + menu->first = entry; + else + iter->next = entry; + + iter = entry; + ++i; + + if (i == MAX_COUNT - 1) + break; + } + +{ + u16 *bootorder; + efi_status_t ret; + unsigned short j; + efi_uintn_t num, size; + void *load_option; + struct efi_load_option lo; + u16 varname[] = u"Boot####"; + + /* Initialize EFI drivers */ + ret = efi_init_obj_list(); + if (ret != EFI_SUCCESS) { + log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n", + ret & ~EFI_ERROR_MASK); + goto cleanup; + } + + bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size); + if (!bootorder) + goto bootmgr; + + num = size / sizeof(u16); + for (j = 0; j < num; j++) { + entry = malloc(sizeof(struct bootmenu_entry)); + if (!entry) + goto cleanup; + + efi_create_indexed_name(varname, sizeof(varname), + "Boot", bootorder[j]); + load_option = efi_get_var(varname, &efi_global_variable_guid, &size); + if (!load_option) + continue; + + ret = efi_deserialize_load_option(&lo, load_option, &size); + if (ret != EFI_SUCCESS) { + log_warning("Invalid load option for %ls\n", varname); + free(load_option); + continue; + } + + if (lo.attributes & LOAD_OPTION_ACTIVE) { + char *command; + int command_size; + + entry->title = u16_strdup(lo.label); + if (!entry->title) { + free(load_option); + free(entry); + goto cleanup; + } + command_size = strlen("bootefi bootindex XXXX") + 1; + command = calloc(1, command_size); + if (!command) { + free(entry->title); + free(load_option); + free(entry); + goto cleanup; + } + snprintf(command, command_size, "bootefi bootindex %X", bootorder[j]); + entry->command = command; + sprintf(entry->key, "%d", i); + entry->num = i; + entry->menu = menu; + entry->type = BOOT_TYPE_UEFI; + entry->bootorder = bootorder[j]; + entry->next = NULL; + + if (!iter) + menu->first = entry; + else + iter->next = entry; + + iter = entry; + ++i; + } + + if (i == MAX_COUNT - 1) + break; + } + free(bootorder); +} + +bootmgr: + /* Add UEFI Boot Manager entry if available */ + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) { + if (i <= MAX_COUNT - 1) { + entry = malloc(sizeof(struct bootmenu_entry)); + if (!entry) + goto cleanup; + + entry->title = u16_strdup(u"UEFI Boot Manager"); + if (!entry->title) { + free(entry); + goto cleanup; + } + + entry->command = strdup("bootefi bootmgr"); + if (!entry->command) { + free(entry->title); + free(entry); + goto cleanup; + } + + sprintf(entry->key, "%d", i); + + entry->num = i; + entry->menu = menu; + entry->type = BOOT_TYPE_NONE; + entry->next = NULL; + + if (!iter) + menu->first = entry; + else + iter->next = entry; + + iter = entry; + ++i; + } + } + +{ + char *p; + char *token; + char *boot_targets; + int len; + + /* list the distro boot "boot_targets" */ + boot_targets = env_get("boot_targets"); + if (!boot_targets) + goto exit_boot_targets; + + len = strlen(boot_targets); + p = calloc(1, len + 1); + strncpy(p, boot_targets, len); + + token = strtok(p, " "); + + do { + u16 *buf; + char *command; + int command_size; + + entry = malloc(sizeof(struct bootmenu_entry)); + if (!entry) + goto cleanup; + + len = strlen(token); + buf = calloc(1, (len + 1) * sizeof(u16)); + entry->title = buf; + if (!entry->title) { + free(entry); + goto cleanup; + } + utf8_utf16_strncpy(&buf, token,len); + sprintf(entry->key, "%d", i); + entry->num = i; + entry->menu = menu; + + command_size = strlen("run bootcmd_") + len + 1; + command = calloc(1, command_size); + if (!command) { + free(entry->title); + free(entry); + goto cleanup; + } + snprintf(command, command_size, "run bootcmd_%s", token); + entry->command = command; + entry->type = BOOT_TYPE_DISTRO_BOOT; entry->next = NULL; if (!iter) @@ -345,6 +552,48 @@ static struct bootmenu_data *bootmenu_create(int delay) if (i == MAX_COUNT - 1) break; + + token = strtok(NULL, " "); + } while (token); + + free(p); +} + +exit_boot_targets: + + /* Add UEFI Boot Manager Maintenance entry */ + if (i <= MAX_COUNT - 1) { + entry = malloc(sizeof(struct bootmenu_entry)); + if (!entry) + goto cleanup; + + entry->title = u16_strdup(u"UEFI Boot Manager Maintenance"); + if (!entry->title) { + free(entry); + goto cleanup; + } + + entry->command = strdup("echo TODO: Not implemented"); + if (!entry->command) { + free(entry->title); + free(entry); + goto cleanup; + } + + sprintf(entry->key, "%d", i); + + entry->num = i; + entry->menu = menu; + entry->type = BOOT_TYPE_NONE; + entry->next = NULL; + + if (!iter) + menu->first = entry; + else + iter->next = entry; + + iter = entry; + ++i; } /* Add U-Boot console entry at the end */ @@ -353,7 +602,7 @@ static struct bootmenu_data *bootmenu_create(int delay) if (!entry) goto cleanup; - entry->title = strdup("U-Boot console"); + entry->title = u16_strdup(u"U-Boot console"); if (!entry->title) { free(entry); goto cleanup; @@ -370,6 +619,7 @@ static struct bootmenu_data *bootmenu_create(int delay) entry->num = i; entry->menu = menu; + entry->type = BOOT_TYPE_NONE; entry->next = NULL; if (!iter) @@ -427,7 +677,7 @@ static void bootmenu_show(int delay) { int init = 0; void *choice = NULL; - char *title = NULL; + u16 *title = NULL; char *command = NULL; struct menu *menu; struct bootmenu_data *bootmenu; @@ -478,7 +728,7 @@ static void bootmenu_show(int delay) if (menu_get_choice(menu, &choice)) { iter = choice; - title = strdup(iter->title); + title = u16_strdup(iter->title); command = strdup(iter->command); } @@ -493,7 +743,7 @@ cleanup: } if (title && command) { - debug("Starting entry '%s'\n", title); + debug("Starting entry '%ls'\n", title); free(title); run_command(command, 0); free(command);