From patchwork Fri Mar 8 01:29:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1053308 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="TDM5j93t"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 44FqdR2wFzz9s7h for ; Fri, 8 Mar 2019 12:28:27 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id E913CC21DDC; Fri, 8 Mar 2019 01:28:20 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RCVD_IN_DNSWL_NONE, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 0129AC21DD4; Fri, 8 Mar 2019 01:28:18 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 2B3EEC21E29; Fri, 8 Mar 2019 01:28:10 +0000 (UTC) Received: from mail-yw1-f65.google.com (mail-yw1-f65.google.com [209.85.161.65]) by lists.denx.de (Postfix) with ESMTPS id 51ADBC21E1A for ; Fri, 8 Mar 2019 01:28:06 +0000 (UTC) Received: by mail-yw1-f65.google.com with SMTP id k14so15056530ywe.4 for ; Thu, 07 Mar 2019 17:28:06 -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=r8KkW1V+sEYRvnvk0LhWzdWuwgjq+v3rc6ZaHd9CWeQ=; b=TDM5j93t6g5SSYiqRZ2S1YvVcZVcJsX4jajxwsLkcWywkTt9ARE2VEA3vClNQsndNe 4wW1HYzVWzhFJ2IK67Oa+PXgbbhmT3dEhnaIh6oQ4pM0D/10XxbxXSvUndpWV00I4Ob3 hVlh8GFNTh43UHPI44jeY9ai5wQWfq5itx02FoX2CKFfLhZrA5NeM11IF/RnCV12pAch ixM21SDVddv2f4eLJMyZa+7zawsRRD0peQMgv/kJ5itamGj/O6q8xHZtgWDU0j16fujH tkpSCTEZjhYdvhuJT934fKo8J5TfRrYeKHi/y31WbrXi3K2R32cCtbeYbIxFeymg/sIH xrtg== 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=r8KkW1V+sEYRvnvk0LhWzdWuwgjq+v3rc6ZaHd9CWeQ=; b=USQ/vfrUUbZDcgyGsSbN4iwAQzV9rzE22pAin7fDV+aiexanD94ntaZV0gaUCTYDoF Iv1rX/xQRtdJXUcP2ok55VORMvsxUA6C06Kt3+234NYzvi4uaTdisJ5pZSfNUAhu59Fx UQG9hF1y8p09jbGZu2FwH6g7wUA8Z4e6qMjEAZRf5Y4+k1GjtBRquozBzqFd6A3WNele RyeeZ13j64pIO5dC96kT6yxMKlTtfgjCURpeR3jsbX6aQqIdIGYzAQafi1Up+ws5Tt8H Gzw97Iw2kIWp668hxaUkXEOx5+YOycJE8llfP1La64L2kR/XX6DRguOgRxV9q9/7YVgY sPRQ== X-Gm-Message-State: APjAAAVPuzNRpoWZigZ/qII+fOooPhprer71ibZia2BzP5L5gKfeWMw2 r0JQNdydVS8Vr2X0cFwtStWPWQ== X-Google-Smtp-Source: APXvYqzVQcfJsjJhlVxktrXRjO/Z5ylVnzMccKWsQS5G3XkTnOIXupycfPhvReLYT3t0/gVHBEzQjw== X-Received: by 2002:a81:110d:: with SMTP id 13mr12895899ywr.343.1552008485318; Thu, 07 Mar 2019 17:28:05 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id q190sm2090850ywd.6.2019.03.07.17.28.04 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Mar 2019 17:28:04 -0800 (PST) From: AKASHI Takahiro To: xypron.glpk@gmx.de, agraf@csgraf.de Date: Fri, 8 Mar 2019 10:29:30 +0900 Message-Id: <20190308012930.29191-2-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190308012930.29191-1-takahiro.akashi@linaro.org> References: <20190308012930.29191-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 Cc: u-boot@lists.denx.de Subject: [U-Boot] [PATCH v3 1/1] efi_loader: bootmgr: support BootNext and BootCurrent variable behavior X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" See UEFI v2.7, section 3.1.2 for details of the specification. With efidebug command, you can run any EFI boot option as follows: => efi boot add 1 SHELL ... => efi boot add 2 HELLO ... => efi boot order 1 2 => efi bootmgr (starting SHELL ...) => efi boot next 2 => efi bootmgr (starting HELLO ...) => env print -e BootCurrent: {boot,run}(blob) 00000000: 02 00 .. BootOrder: {boot,run}(blob) 00000000: 01 00 02 00 .... Signed-off-by: AKASHI Takahiro --- lib/efi_loader/efi_bootmgr.c | 54 +++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index 417016102b48..64fc4449446b 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -141,6 +141,7 @@ static void *try_load_entry(uint16_t n, struct efi_device_path **device_path, efi_deserialize_load_option(&lo, load_option); if (lo.attributes & LOAD_OPTION_ACTIVE) { + u32 attributes; efi_status_t ret; debug("%s: trying to load \"%ls\" from %pD\n", @@ -151,6 +152,16 @@ static void *try_load_entry(uint16_t n, struct efi_device_path **device_path, if (ret != EFI_SUCCESS) goto error; + attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS; + size = sizeof(n); + ret = EFI_CALL(efi_set_variable( + L"BootCurrent", + (efi_guid_t *)&efi_global_variable_guid, + attributes, size, &n)); + if (ret != EFI_SUCCESS) + goto error; + printf("Booting: %ls\n", lo.label); efi_dp_split_file_path(lo.file_path, device_path, file_path); } @@ -162,21 +173,56 @@ error: } /* - * Attempt to load, in the order specified by BootOrder EFI variable, the - * available load-options, finding and returning the first one that can - * be loaded successfully. + * Attempt to load from BootNext or in the order specified by BootOrder + * EFI variable, the available load-options, finding and returning + * the first one that can be loaded successfully. */ void *efi_bootmgr_load(struct efi_device_path **device_path, struct efi_device_path **file_path) { - uint16_t *bootorder; + u16 bootnext, *bootorder; efi_uintn_t size; void *image = NULL; int i, num; + efi_status_t ret; bs = systab.boottime; rs = systab.runtime; + /* BootNext */ + bootnext = 0; + size = sizeof(bootnext); + ret = EFI_CALL(efi_get_variable(L"BootNext", + (efi_guid_t *)&efi_global_variable_guid, + NULL, &size, &bootnext)); + if (ret == EFI_SUCCESS) { + /* delete BootNext */ + ret = EFI_CALL(efi_set_variable( + L"BootNext", + (efi_guid_t *)&efi_global_variable_guid, + 0, 0, &bootnext)); + if (ret == EFI_SUCCESS) { + image = try_load_entry(bootnext, + device_path, file_path); + if (image) + return image; + } else { + printf("BootNext note deleted\n"); + } + } else if (ret != EFI_NOT_FOUND) { + if (ret == EFI_BUFFER_TOO_SMALL) + printf("BootNext must be 16-bit integer\n"); + + /* delete BootNext */ + ret = EFI_CALL(efi_set_variable( + L"BootNext", + (efi_guid_t *)&efi_global_variable_guid, + 0, 0, &bootnext)); + if (ret != EFI_SUCCESS) + printf("BootNext note deleted\n"); + } + + /* BootOrder */ bootorder = get_var(L"BootOrder", &efi_global_variable_guid, &size); if (!bootorder) { printf("BootOrder not defined\n");