From patchwork Wed Mar 20 00:07:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1058774 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="Uu6wc9gy"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 44P9GH05ZLz9sN4 for ; Wed, 20 Mar 2019 11:07:18 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id A2AFAC21FF6; Wed, 20 Mar 2019 00:07:13 +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=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 4DCCBC22019; Wed, 20 Mar 2019 00:07:11 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 787BDC22006; Wed, 20 Mar 2019 00:07:03 +0000 (UTC) Received: from mail-yw1-f66.google.com (mail-yw1-f66.google.com [209.85.161.66]) by lists.denx.de (Postfix) with ESMTPS id E6927C21FD3 for ; Wed, 20 Mar 2019 00:06:59 +0000 (UTC) Received: by mail-yw1-f66.google.com with SMTP id v127so565383ywe.13 for ; Tue, 19 Mar 2019 17:06:59 -0700 (PDT) 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=/gdWXSysQ/o5Fe7PHZzBezz1ZQQbsolx6G8s4yGkeYE=; b=Uu6wc9gyhHluxcqtfsgkj5WSI1EzFVFKMTii6NUtbPRv+LyJu89vkGqibKDImbtG3U J9nkWWKswiOhEA+iXM5phO5H2fpW7HWP6fHyg7IKJ9wsOJ3yTEx9oikA/oWte3FYh5+H n2lyAh55aqh2NWJbi9PuUSdmMFC/JBxHlMzDlvFFQAXD7Vg0P30MlLX9bNCfYD+yJkno 2gE3Rl4nJtwQMQleyC8qy5oT/E4ah3I1Ld8ZyxQmfY4c4fh9T96GgIIdrNN9hOkpTGKL 9g+RT0iQAPMc0PpZebYT1qpI6khRM1jyYp5PucnFjQYbVF3CaJg3cXKpvgRn5TWkgeTy ySDw== 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=/gdWXSysQ/o5Fe7PHZzBezz1ZQQbsolx6G8s4yGkeYE=; b=QgfpBAHc9T97Yx5LLUVCbBH7MZKgTUqoejUOFhDmYqwp62aGjhCNKGXmU1mmagpjf4 0EB8USYG7H9T0MYEwthtD6OMROb4tkV39MCtwbtZvArZsadaSZAdpUxT4e7cXlF4FqWj SIEbcm+T1Wr8tddA6dvVkuO5D7f+tTo4q26quWK8qq/l+HJf/+UMkmv/uD7PR0QxYYZK lPBZezFB3UJguScYE/AD0dXXjlNa3okYA8Ig9gToiC0bXkWffuYcHCEpu/rIxSuDhSEX xQ+htjQL8rNHOY96PBKa90obRR1rdqXGWEfCXUwqOHAApgUQdy2DeOlZ74oQsgLK+Sz3 8Smw== X-Gm-Message-State: APjAAAUnlfvqqGAzLFFTqNJPAlItAMCMBUmPdx4v1TzZzD5wMOqSRtOv E+XQJKKhq1WjnVTj+u62HDejSMkDjx0= X-Google-Smtp-Source: APXvYqzRHpKTiaeeSelI2UqQF687KLJ6EnMmqb/5yd4rZ68eyBLshdm7HO1OmM168anMUJJkUK/Rsw== X-Received: by 2002:a25:b82:: with SMTP id 124mr4683406ybl.63.1553040418889; Tue, 19 Mar 2019 17:06:58 -0700 (PDT) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id l143sm219298ywc.50.2019.03.19.17.06.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Mar 2019 17:06:58 -0700 (PDT) From: AKASHI Takahiro To: xypron.glpk@gmx.de, agraf@csgraf.de Date: Wed, 20 Mar 2019 09:07:55 +0900 Message-Id: <20190320000755.27049-2-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190320000755.27049-1-takahiro.akashi@linaro.org> References: <20190320000755.27049-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 Cc: u-boot@lists.denx.de Subject: [U-Boot] [PATCH v4 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 Reviewed-by: Heinrich Schuchardt --- lib/efi_loader/efi_bootmgr.c | 51 +++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index 417016102b48..4fccadc5483d 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,53 @@ 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 || ret == EFI_BUFFER_TOO_SMALL) { + /* BootNext does exist here */ + if (ret == EFI_BUFFER_TOO_SMALL || size != sizeof(u16)) + 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)); + + /* load BootNext */ + if (ret == EFI_SUCCESS) { + if (size == sizeof(u16)) { + image = try_load_entry(bootnext, device_path, + file_path); + if (image) + return image; + } + } else { + printf("Deleting BootNext failed\n"); + } + } + + /* BootOrder */ bootorder = get_var(L"BootOrder", &efi_global_variable_guid, &size); if (!bootorder) { printf("BootOrder not defined\n");