From patchwork Thu Apr 28 08:09:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 567126 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:6886:0:0:0:0 with SMTP id m6csp5232216map; Thu, 28 Apr 2022 01:11:02 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwW8hu8Cv44QMqcklgjbM/ioI8lVQGR92062++9pGppyxZP+OzxFTYvIQn8BjrrenKYKYwn X-Received: by 2002:a17:907:3f86:b0:6df:ad43:583 with SMTP id hr6-20020a1709073f8600b006dfad430583mr31554271ejc.535.1651133462119; Thu, 28 Apr 2022 01:11:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1651133462; cv=none; d=google.com; s=arc-20160816; b=ixY2eFcQytbrDz74wJY0Apu6c/w+Ag1ymMYOt06uZuQNugsRHJIf7wZrJF67Bm+6p3 dc3mM/Obk87KZID3qjiHzm9Vt5aNl54hhs1bdGk85nSra2FBLenCLS5cQbd9I6o8VESs BHVqXcQeEgi4dpiqs6kFtGLRIP6wpGxZAdInU1CB7HeiyB6JILM/34m0bQPCmc4tbrlq nFlfv9dJ/OHwThRqfG2B/ws8lQe++E7o4SdrX9wktZzXz5cllt1NRMIZ+Ha83ZeYs/ro SABiuNaeB9ByBUtvQaIM4Wu0AXoYEXHQPfe5sEA8JnmJiPogJPXCs/JaTFv+Gq0DZDZX Dg0A== 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=B6ZTRPfwFqK5oz2mCyJUqTqHSpVyXj5iJbffRrIjLy8=; b=0L/9j22I0mVnL1HeCg8ZrFm5Y1ISLGwrrO8v/9+wu7OUuMKNmCWGUpCmv2enCFcvS9 9JD/9EEbcNJU1bF0ITy+wPdn/e/L8DAOmv4aFMXYSRVoxE496HWf3R8BMh9UTN4fv5/H rh65DLYXLd36s2Hwg+UcoHvnFkSdj2aA0GYV0G6ZbzQHReQeRDlsjuefREV4LXQKtgPb DjrCzvhbLt4CxqpYSpBNqfMDfCK2PWFGXHzQiXCsuTjNVqKjTUnKVeG0ZGI2CDTUsw8K NOctspSiuF16OVrf67IX1FyKp/zMRFdyNCtB5z4vtaV6IoqHrZYH6aOXq+eHfTPFkKjP HhIA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="gZ7Cy/cD"; 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 g1-20020a1709061e0100b006e83fe14ac1si3325735ejj.554.2022.04.28.01.11.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:11:02 -0700 (PDT) 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="gZ7Cy/cD"; 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 B19DA807E1; Thu, 28 Apr 2022 10:10:52 +0200 (CEST) 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="gZ7Cy/cD"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 4567780818; Thu, 28 Apr 2022 10:10:44 +0200 (CEST) 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 autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pj1-x1034.google.com (mail-pj1-x1034.google.com [IPv6:2607:f8b0:4864:20::1034]) (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 A0CAF80818 for ; Thu, 28 Apr 2022 10:10:40 +0200 (CEST) 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-x1034.google.com with SMTP id cu23-20020a17090afa9700b001d98d8e53b7so5571900pjb.0 for ; Thu, 28 Apr 2022 01:10:40 -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; bh=B6ZTRPfwFqK5oz2mCyJUqTqHSpVyXj5iJbffRrIjLy8=; b=gZ7Cy/cD+4Us9BdZYp2LIoO7Srr8/s54D/2DAVZFMSZsMtc5QHzQzhhjlfV6DXic59 PiNowowOWd1m+P2YPPa/Lz2fEgKmGi+FvlSjdOZTvaD7rrldxm7KLXYl8Wa6Er4uk7Fo olfNT/FMuXdE0fWlX2oa+YwJGot4Wbtv51z6gmdFf7VOsFF8ykGBylAgeLwDRjkm6f9n 6ex3EIbTI4SpgIlLmsbuRTYUNRxcscN461BFxFWTIxuwe4pHOOjDzeaNfHTg1SdcGC2M 6ZJYw9pYQlpzRsYD8wlUinG/rDOE8Anc0lgvZQklDVXIRs6BCUHrMuxYtHbUyB2F/Er1 1GEg== 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=B6ZTRPfwFqK5oz2mCyJUqTqHSpVyXj5iJbffRrIjLy8=; b=j0gbs1kAsrzLPARkCQx+nhgUYQJCPk1E0dvTyEMOHv+1/eIdEQuZwbYLHP4ntqnps2 SOebIqd+Q8urQ2kphUzkF1WWIe58OPdRBaHfFOnQKJThJzDZBsYHsf7AqA6+yoG+lkVi pXaDPFAG4lIq92DPgvIG1DfUwdZPLpxSORRnFsAxgL7SHET4EovhlYPFdH2uFMcHoHgA 4Xw3EVhFW2xAczOFzEsSrFrd9MFAs7+/VTvew9r7jqqWVdP8aobXMWUVy8VKZbmYtb/Z 3A7X2chqkNjTTUa16SFeW0bvVTfLDFoPU4UAT1P+gak7e1+4NmNyzcCxX6onEwS4w3VJ UDjQ== X-Gm-Message-State: AOAM532nwPHiOz83LLuGKoOw9odpoX4/M7FxUlJgNonezSwKp0UokOxL PoK4UciMCkENwCS8042Vmmr3umUkU/Gr3A== X-Received: by 2002:a17:90a:94c2:b0:1d9:3fbd:bbe1 with SMTP id j2-20020a17090a94c200b001d93fbdbbe1mr28248074pjw.59.1651133438546; Thu, 28 Apr 2022 01:10:38 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id b15-20020a17090a7acf00b001cd4989ff5fsm5684259pjl.38.2022.04.28.01.10.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:10:38 -0700 (PDT) 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: [PATCH v5 01/17] lib/charset: add u16_strlcat() function Date: Thu, 28 Apr 2022 17:09:34 +0900 Message-Id: <20220428080950.23509-2-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220428080950.23509-1-masahisa.kojima@linaro.org> References: <20220428080950.23509-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 Provide u16 string version of strlcat(). Signed-off-by: Masahisa Kojima --- Changes in v5: - change 3rd argument from size to count, it indicates the maximum u16 string count that dest buffer can have. Other u16_strXXX functions in U-Boot use string count, not the buffer size. u16_strlcat() should follow. - update function comment to clealy describe the behavior - use strlen() instead of strnlen(), to correctly handle the case if the count is smaller than or equal to initial dest count Changes in v4: - add blank line above the return statement Changes in v2: - implement u16_strlcat(with the destination buffer size in argument) instead of u16_strcat include/charset.h | 17 +++++++++++++++++ lib/charset.c | 22 ++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/include/charset.h b/include/charset.h index 38908e08f0..ae356ad9a5 100644 --- a/include/charset.h +++ b/include/charset.h @@ -261,6 +261,23 @@ u16 *u16_strcpy(u16 *dest, const u16 *src); */ u16 *u16_strdup(const void *src); +/** + * u16_strlcat() - Append a length-limited, %NUL-terminated string to another + * + * Append the src string to the dest string, overwriting the terminating + * null word at the end of dest, and then adds a terminating null word. + * + * @dest: destination buffer (must include the trailing 0x0000) + * @src: source buffer (must include the trailing 0x0000) + * @count: maximum number of code points that dest buffer can have, + * including the trailing 0x0000 + * Return: total count of the created u16 string + * u16_strlen(src) + min(count, u16_strlen(initial dest)), + * does not include trailing 0x0000. + * If return value >= count, truncation occurred. + */ +size_t u16_strlcat(u16 *dest, const u16 *src, size_t size); + /** * utf16_to_utf8() - Convert an utf16 string to utf8 * diff --git a/lib/charset.c b/lib/charset.c index de201cf3b9..f295dfc11a 100644 --- a/lib/charset.c +++ b/lib/charset.c @@ -416,6 +416,28 @@ u16 *u16_strdup(const void *src) return new; } +size_t u16_strlcat(u16 *dest, const u16 *src, size_t count) +{ + size_t destlen, srclen, ret; + + destlen = u16_strlen(dest); + srclen = u16_strlen(src); + ret = min(count, destlen) + srclen; /* does not include trailing 0x0000 */ + + if (destlen >= count) + return ret; + + dest += destlen; + count -= destlen; + if (srclen >= count) + srclen = count - 1 /* for trailing 0x0000 */; + + memcpy(dest, src, srclen * sizeof(u16)); + dest[srclen] = u'\0'; + + return ret; +} + /* Convert UTF-16 to UTF-8. */ uint8_t *utf16_to_utf8(uint8_t *dest, const uint16_t *src, size_t size) { From patchwork Thu Apr 28 08:09:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 567127 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:6886:0:0:0:0 with SMTP id m6csp5232382map; Thu, 28 Apr 2022 01:11:15 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyip2BYq/Hsa/6Meue1NN85kSgGfcHfwQglDZamwGzcsx0Z6nfnYZPeFpWUw2h/qz++ea7c X-Received: by 2002:a17:907:9506:b0:6da:b4cd:515b with SMTP id ew6-20020a170907950600b006dab4cd515bmr30550490ejc.602.1651133474880; Thu, 28 Apr 2022 01:11:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1651133474; cv=none; d=google.com; s=arc-20160816; b=sRhxU5DMQR+2EzPLnk/9G01l+nG/23XZ7QzA/3JI5TwoUWWfreImlD/KUDNwdyWY1K 5CKSsnIMzKhRcN/gXUpSUSbeSzm5r4IuwouGbwP2R5dt0wwhFy8I7/OeqLSLESgDwW86 Yni4ywEL8e2yUZvx6sIdB3a9xrEf5r6sjrjXe02xAXGn1UOOrFLLNmVadfUqluqwkabZ XcY2JfrqJ3ySa7gl3yuaRCRrWkCeXUJ7F69Y0Ipcbe2L+7+butn04WlL6rpp5yxan6U0 u0FXxe5Z1DGARKsB3SyEgHI4858UY18p/j/vcwB8weYeMP1IBq+uR/UUNPb3RBcHG5dK /eRg== 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=wC/Gl1W6f0ZbbBUR2Z7bJBsjJ0RSAlgY+u7HPwH7vS4=; b=b35iOdRlztQUHuvmyL2E0xvidWA3Z061Zv0F39rZ/X0S6Sr3ErpSTtryP/sf5w2j8N /CrBZ+iTkdpcQWCDkqe4L2AeefnRbZ0qH4NbJgjLXm7Oax9n+RUMs9ktHeRBETg/mBd8 2weESv/7P7B71dIJoP8gh3bAVC7Np7zZNDnF9ZtDGyT1S+vyk0pRl4DKRtHWZn4bYlpf /sqf27NK60sZHGUwj3uVIgn8GFjFF1KZkBaGZq7O6x71Z+SJpGhXWarqu1XSDTHid3tn TsYpzC5U4s9cXTeUKDvhydkA3UfXI0mfB98vLRUIc/Bda5NwZt057a65PfWBAFI74uiE RPDA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=T2S8kx0g; 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 s15-20020a50d48f000000b0042610f5f98asi3535305edi.376.2022.04.28.01.11.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:11:14 -0700 (PDT) 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=T2S8kx0g; 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 9FD7783108; Thu, 28 Apr 2022 10:10:55 +0200 (CEST) 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="T2S8kx0g"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id BEC3583108; Thu, 28 Apr 2022 10:10:46 +0200 (CEST) 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 autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pg1-x534.google.com (mail-pg1-x534.google.com [IPv6:2607:f8b0:4864:20::534]) (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 ED949802EF for ; Thu, 28 Apr 2022 10:10:42 +0200 (CEST) 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-pg1-x534.google.com with SMTP id g3so3391405pgg.3 for ; Thu, 28 Apr 2022 01:10:42 -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=wC/Gl1W6f0ZbbBUR2Z7bJBsjJ0RSAlgY+u7HPwH7vS4=; b=T2S8kx0gVexVptEaiRVF/ew+kT+/M9kR01coUFV2/uBWtwj7qQs9BSpR7RP+Dif7g+ j4QWZZLSq5arOduma/LkCLAJsSCnXTW6WcK/vGaqt16ifecoZCxvvg3LiQj8dIhHQ2+l +K0iuVtOlrxC8+ciAVEbZpKmEiuFJjMPQWmLxakIgpZ+oAxhEMi4Ab2/CcGAV5IXGMwm tew7SDxBHh8Hq1R6RGyMKikJtIGaT81d0E9jhrXgerItAFvWMGXUkEnoKvvJAdfrcVW+ aPxtKcWCIbsNgjNv00ToDR59n+/ac6zjo3FP7RSews3ctGvL/jui5MDG0J0v+PO+s+Qs 1fYQ== 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=wC/Gl1W6f0ZbbBUR2Z7bJBsjJ0RSAlgY+u7HPwH7vS4=; b=QSXvQ5giMEFNMZY67R3FNN1XfXHx1fgRx06J/6Mreg8L7+E2fRlREL/KrTCoiKGz0C QS0f2QSo34sZKomnHiLrwctpaiy7j5Raf7zu20jKE46HX++fKOtjIR9P6yLgUN0Q4cbf mduMaAs7NM/cx+C3omQyZ/XT3dzU1i+GerqE0LWU0CHJflf2SLSGGctQvoLiX98k0VPA hWIem0k1tAe5fJtg0PoLVZ2v514QPgvu4YyZuCjeEkHv9NdruEYSkQH+WU+9iDU9MYsr aUPjFDcbKbK6JGbPbgnjU3vkAj7YZOK7VWTyj51RIFFgaGL0DXuEIow+Sr6v2/MoO2oT oeDg== X-Gm-Message-State: AOAM532s2QSZVKmpIO4T5HnqlUBQO1le9QUo3SxJGVwiY1V9cHL3vV9h d8D3ZnhVI+XFtLfu2nSDf2qbdc0RNuD8xA== X-Received: by 2002:a05:6a00:c94:b0:50d:9044:429b with SMTP id a20-20020a056a000c9400b0050d9044429bmr3839768pfv.47.1651133441184; Thu, 28 Apr 2022 01:10:41 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id b15-20020a17090a7acf00b001cd4989ff5fsm5684259pjl.38.2022.04.28.01.10.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:10:40 -0700 (PDT) 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: [PATCH v5 02/17] test: unit test for u16_strlcat() Date: Thu, 28 Apr 2022 17:09:35 +0900 Message-Id: <20220428080950.23509-3-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220428080950.23509-1-masahisa.kojima@linaro.org> References: <20220428080950.23509-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 Provide a unit test for function u16_strlcat(). Signed-off-by: Masahisa Kojima --- Changes in v5: - u16_strlcat() 3rd agument update from buffer size to maximum string count - increase buffer size for test - change u16 string for the test, the letters in the test are different each other - buffer to be used for the test is filled with non-zero value except for the last two bytes - add test cases Newly created in v2 test/unicode_ut.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/test/unicode_ut.c b/test/unicode_ut.c index f2f63d5367..81c9549ba5 100644 --- a/test/unicode_ut.c +++ b/test/unicode_ut.c @@ -758,6 +758,56 @@ static int unicode_test_efi_create_indexed_name(struct unit_test_state *uts) UNICODE_TEST(unicode_test_efi_create_indexed_name); #endif +static int unicode_test_u16_strlcat(struct unit_test_state *uts) +{ + u16 buf[40]; + u16 dest[] = {0x3053, 0x3093, 0x306b, 0x3061, 0x306f, 0}; /* u"こんにちは" */ + u16 src[] = {0x03B1, 0x2172, 0x6F5C, 0x8247, 0}; /* u"αⅲ潜艇" */ + u16 concat_str[] = {0x3053, 0x3093, 0x306b, 0x3061, 0x306f, + 0x03B1, 0x2172, 0x6F5C, 0x8247, 0}; + u16 null_src = u'\0'; + size_t ret, expected; + int i; + + /* dest and src are empty string */ + memset(buf, 0, sizeof(buf)); + ret = u16_strlcat(buf, &null_src, sizeof(buf)); + ut_asserteq(0, ret); + + /* dest is empty string */ + memset(buf, 0, sizeof(buf)); + ret = u16_strlcat(buf, src, sizeof(buf)); + ut_asserteq(4, ret); + ut_assert(!unicode_test_u16_strcmp(buf, src, 40)); + + /* src is empty string */ + memset(buf, 0xCD, (sizeof(buf) - sizeof(u16))); + buf[39] = 0; + memcpy(buf, dest, sizeof(dest)); + ret = u16_strlcat(buf, &null_src, sizeof(buf)); + ut_asserteq(5, ret); + ut_assert(!unicode_test_u16_strcmp(buf, dest, 40)); + + for (i = 0; i <= 40; i++) { + memset(buf, 0xCD, (sizeof(buf) - sizeof(u16))); + buf[39] = 0; + memcpy(buf, dest, sizeof(dest)); + expected = min(i, 5 /* u16_strlen(dest) */) + 4 /* u16_strlen(src) */; + ret = u16_strlcat(buf, src, i); + ut_asserteq(expected, ret); + if (i <= 6) { + ut_assert(!unicode_test_u16_strcmp(buf, dest, 40)); + } else if (i < 10) { + ut_assert(!unicode_test_u16_strcmp(buf, concat_str, i - 1)); + } else { + ut_assert(!unicode_test_u16_strcmp(buf, concat_str, 40)); + } + } + + return 0; +} +UNICODE_TEST(unicode_test_u16_strlcat); + int do_ut_unicode(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { struct unit_test *tests = UNIT_TEST_SUITE_START(unicode_test); From patchwork Thu Apr 28 08:09:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 567129 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:6886:0:0:0:0 with SMTP id m6csp5232635map; Thu, 28 Apr 2022 01:11:41 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyzWDcl5HAelbRtRLbiRO/jChDEWTyWiD1eB5/dEGrrl28XNue+SukJwUMq+YOR9Jhvwi7k X-Received: by 2002:a17:907:86a4:b0:6f3:ac7f:e9a2 with SMTP id qa36-20020a17090786a400b006f3ac7fe9a2mr12885521ejc.317.1651133500869; Thu, 28 Apr 2022 01:11:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1651133500; cv=none; d=google.com; s=arc-20160816; b=xIf6AnJjvTgb9g7Orz7wMunzzzSRCUr3GV7Y9gVyChr79r8ITeFKrkG3O7ToBkQtwL IveHG308/dh4PP4ZTpSk0v7jiFNuTAdCPNzw1Nue7O8SouGRBmE7aRoA8FvvBQvow4ES eoLiiDhdcD/BZ0jx/RSE6Dy0R0WEfnW8Z/pKPurB6MceBDF1GJ4FMbRFcZ4JowzgcTld dCYHQh5UOJyZd/dWYxh5oiSFX7V4IgFyDYZyVgd7fXosxg6aolyY4pd2pqKi/7EjdlW0 MOWeo61rye4w3+Cx28DIWq7PfpHAhAerKHpd6Uc4hsegMDZmvtVFlxHIgfWQwa8i6gV/ N9SQ== 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=TvFMYVvCihxIbsCZUiFnET6ZrMQ6iJOCvVE3fpXk/QE=; b=JCgvebnhgjfqJWAqmU7L6ld/4Sp5BJGzMWobZGNvzd6bObOu9xbCsCYW8HDvoZXFTh qDfS28y9AmiD58/nmcAWMuXdHsfCfY4uur4MGS2cb3W2ECB8A9aWlkOjWnKAe5tpd3Ul 67WP/Rq9LYoYEvkKkRM6VK/2RJ2yqTUq2YppKqSEyh7A7v+pfu5PiL1lwIOcpN3/QEn0 6KBbGP0z0fqJXsdmd9aelESTO5R9cvTzXFP1zp9f4vsE/7eU4vRX0q+YhiRfRoArdpa+ oDLWGoes8HH1dkX8nfgdLXDP8maKmGjrNrrmfVsnzfhDkFv3JpKNtvsFdDF4Yeb1cQvl 1QrQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=S7VFvGBz; 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 re19-20020a170906d8d300b006f3891ead87si3206383ejb.802.2022.04.28.01.11.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:11:40 -0700 (PDT) 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=S7VFvGBz; 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 B1EBF83EDA; Thu, 28 Apr 2022 10:11:21 +0200 (CEST) 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="S7VFvGBz"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 6AC7883ECA; Thu, 28 Apr 2022 10:10:55 +0200 (CEST) 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 autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pl1-x633.google.com (mail-pl1-x633.google.com [IPv6:2607:f8b0:4864:20::633]) (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 CC3F581A02 for ; Thu, 28 Apr 2022 10:10:50 +0200 (CEST) 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-x633.google.com with SMTP id b12so3696524plg.4 for ; Thu, 28 Apr 2022 01:10:50 -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; bh=TvFMYVvCihxIbsCZUiFnET6ZrMQ6iJOCvVE3fpXk/QE=; b=S7VFvGBzuQE0CSGAaRxEgxqtpRNLyuvowo80buWQczDg4p1Euk99BS0OYh70UcgzKQ 0/Q5hoXhci4yULFq/tJK55ROsf8W4uB0wAt2xzdGOMVLZPkiB41Z2mFjjfjar/YauKUo gGWE4jPOxePWp8JeNoUETAYH+meYUOhP/WelBSyhBJ1nYkAWBj9Dzmsrr/fQ9l2Jlcr+ I8fotqRM+wAoJ5nZgL5A8JJPK0RchMqZHl1arhT7l7KQ6Ba4rvzrMv2duG+p5pTxjYeO +o80iMeV9SiDD1xsAWApFlkH8J8oTSzfM6jd121kGWFniHZCddqaUCMrYqnjlzGt6Otr W75Q== 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=TvFMYVvCihxIbsCZUiFnET6ZrMQ6iJOCvVE3fpXk/QE=; b=HkIpXTjchSv//aO8jA41vr1w2YhGkmcJea8eByXnqIQN4oi2wGXC2zL0I02/Xt7N7S XIDbj6mPxCdMNKuYqNV5Jm/BHEwIglVDDqluXSCd9iWOikV2fLUgB6mWutWOMkgYjjqq sNPDDEmLYvPtV2NJcAO1w/yOTjhu0ir02/Y/O6iyhcuhdeSmlS9W8A3lfqR9iIqc7yxp pjYTsxoXGrID9yp5mDHnFYilJnzMASG8d5zTCsr7tyaQSxVpv4hqTizva/2BDX6pMJ8G T8sloLKEvh/gVs/3GNxnnxP0xKef9uRIqT+Jy9cdD6/9YwPmQUrIva8LFXKy9qUkCXjR 1o+A== X-Gm-Message-State: AOAM5314kHl/Fn9VTWPZCCRhxoNPojANXqOpT0+VlTx5IyPaDqs3/4+q QKcyqCv4w/FBupdVFAPCh9PzpePVuY+PHg== X-Received: by 2002:a17:90b:1803:b0:1d9:a23a:3f15 with SMTP id lw3-20020a17090b180300b001d9a23a3f15mr16710323pjb.11.1651133444096; Thu, 28 Apr 2022 01:10:44 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id b15-20020a17090a7acf00b001cd4989ff5fsm5684259pjl.38.2022.04.28.01.10.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:10:43 -0700 (PDT) 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: [PATCH v5 03/17] menu: always show the menu regardless of the number of entry Date: Thu, 28 Apr 2022 17:09:36 +0900 Message-Id: <20220428080950.23509-4-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220428080950.23509-1-masahisa.kojima@linaro.org> References: <20220428080950.23509-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 To make user aware of the menu entry selection, menu always appears regardless of the number of entry. Signed-off-by: Masahisa Kojima Reviewed-by: Heinrich Schuchardt --- No changes since v4 Newly created in v4 common/menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/menu.c b/common/menu.c index 5fb2ffbd06..b577d80b4f 100644 --- a/common/menu.c +++ b/common/menu.c @@ -271,7 +271,7 @@ int menu_get_choice(struct menu *m, void **choice) if (!m || !choice) return -EINVAL; - if (!m->prompt || m->item_cnt == 1) + if (!m->prompt) return menu_default_choice(m, choice); return menu_interactive_choice(m, choice); From patchwork Thu Apr 28 08:09:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 567128 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:6886:0:0:0:0 with SMTP id m6csp5232552map; Thu, 28 Apr 2022 01:11:33 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy9eSJjBhZG/0oJQGaKU5NGoGlDMq4ztxgJXUpt6UFoXmMK4+xtapqbwRLe3+ycawJCZpVF X-Received: by 2002:a17:907:94cd:b0:6f3:ce51:af98 with SMTP id dn13-20020a17090794cd00b006f3ce51af98mr5698136ejc.510.1651133493399; Thu, 28 Apr 2022 01:11:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1651133493; cv=none; d=google.com; s=arc-20160816; b=LFzZykcARI6umdKzFnIASZuFviRLLwEuJwfM48btvUQUom41bL2Yo7/IfN+oUV4aXN 1B5EwCxvBxzaZfCiK4w9rkVFzhspsp+4Iz2a6YqgmWFdfGeh7gy72/r5Trv/sb8noWaK /zaYxf9AHlhabNFDWW1GtaraLQm1vBh5FsUlwOUwGKJjPe7J6nQNsTPs4C0I9R91MvaZ yq/xKj96gE/vxVFUNHm9lEFAH+NrIuOHUYKUAC6q0viYETlcBnObRkyq3B8YAfIQDkDX dYu68Kcb0qeZ0xTN8vbE0JuSJdFi0HIEdLVHO+O01b8UTpmRqofTwUiqZwStl5EFIb6O w3GQ== 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=OWv4MTlDdTk2oATpKOKyZfwRbxZoAD1cLmsNm+lGX6Y=; b=hY0sk4/cEeAtqEU6HQHSmBJyoF7lDxl8kHeiKQd7rMqq+TjN/u7TdrnzqubXdkYgnK FFqBRH6XS/7RXfgLeTbJzNrCWREY8y0HVsHNDvo9efGhXm/X12hTIqlW9IVJ2UeCfHKp 76zFSNo6oZRfV5mzYDWAZ2VCfHuD9Xfxu9OQjgQ85wuk/ZfFochQM8ZIEzZmzbRaSc06 WqrUOUBm6696Q51CKLQTClIuqH6uVsLBpC3UKjzEObF74VhpAFGXFRS5R2QowENpZVo1 uYyWw/M2b6IOCvtvod6kGLw08Jnl4hHoB8q94faXct3gG73cs98ohBvvIqRb6fLoGxl8 dhHA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="liw/ljnn"; 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 i25-20020a170906115900b006e86c3056c2si3214830eja.33.2022.04.28.01.11.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:11:33 -0700 (PDT) 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="liw/ljnn"; 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 D77028393F; Thu, 28 Apr 2022 10:11:16 +0200 (CEST) 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="liw/ljnn"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id AA004802EF; Thu, 28 Apr 2022 10:10:52 +0200 (CEST) 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 autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pg1-x536.google.com (mail-pg1-x536.google.com [IPv6:2607:f8b0:4864:20::536]) (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 9C665802EF for ; Thu, 28 Apr 2022 10:10:48 +0200 (CEST) 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-pg1-x536.google.com with SMTP id z21so3393134pgj.1 for ; Thu, 28 Apr 2022 01:10:48 -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; bh=OWv4MTlDdTk2oATpKOKyZfwRbxZoAD1cLmsNm+lGX6Y=; b=liw/ljnnmet52AvXUNyc1xxGmzsFsAxW1Dj7Fnd7LggnNtR5qlUAeYlegCPw6KJEbX kblIO6oXTuYUZr9IE5XdBZXEGzUMO9WqLQXlJZ/1/cs5rRFeEy3yiY+VbMBmWV78vNfD e10v2BM5I7dEqXc75i1yxFgbmLe0FpTYR3ajXgsdV5HUeAMkPNjCuarpQdbLGj6VHtaa dK4GZA19I/glcg5ZnoV69NTI1zpdJzbinGIxStcJGETvF4a4YKltSjS+yg1f0zpI82iX 3mSKUygDRXV5oEhaA6HnJK7S08aIuSr+JJPXLFrvtrNiUaCovhuc2sD/Aw1ZdwGZBPNB OX4g== 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=OWv4MTlDdTk2oATpKOKyZfwRbxZoAD1cLmsNm+lGX6Y=; b=U7RoWOUYeYTB0h26yzMvWuGCCVferz3iYvvUKrvQP7dFSweFVFMVsLtGw/r9ceca5y h1HMEY3ux8sV1bd+IBj8Kck9E2rMtxH74id1bfJQuSfV6SqOhoT0EFCIFVJ3zzvTS3qN x3Jpk1UNQ14nMuwMsUPEgT0QZKQ7X+yzi5NBHj+tqBDykuIcC8r5moTkk/6sXJTrPMY7 664CblI7ufZZkMhlQeQVNRm9X5LSCorPExhoXgzTV15Cc9lB15Gn4ts4zblHtOH2bO2N +Mr2u5ypN7Hp+fBgyqZzLRr9VUD6Rhq5uxK5dISZWGSfxZkGjiaxH/u8z01AoHM0eH3/ HFZA== X-Gm-Message-State: AOAM531gdvPen2bJLraMt4qL6R77KV9XoGf+w/UL2DB2s9r4bP2I2LUT YOG2tYmFoySGi5ug7OxlZfT1uTq2ljfnPw== X-Received: by 2002:a63:2bc4:0:b0:3ab:1d76:64db with SMTP id r187-20020a632bc4000000b003ab1d7664dbmr18438212pgr.508.1651133446943; Thu, 28 Apr 2022 01:10:46 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id b15-20020a17090a7acf00b001cd4989ff5fsm5684259pjl.38.2022.04.28.01.10.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:10:46 -0700 (PDT) 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: [PATCH v5 04/17] menu: menu_get_choice() return -ENOENT if menu item is empty Date: Thu, 28 Apr 2022 17:09:37 +0900 Message-Id: <20220428080950.23509-5-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220428080950.23509-1-masahisa.kojima@linaro.org> References: <20220428080950.23509-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 menu_get_choice() needs to handle the case that menu item is empty. In this case, menu_get_choice() returns -ENOENT. Signed-off-by: Masahisa Kojima --- Newly created in v5 common/menu.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/menu.c b/common/menu.c index b577d80b4f..4118c6dc3c 100644 --- a/common/menu.c +++ b/common/menu.c @@ -271,6 +271,9 @@ int menu_get_choice(struct menu *m, void **choice) if (!m || !choice) return -EINVAL; + if (m->item_cnt == 0) + return -ENOENT; + if (!m->prompt) return menu_default_choice(m, choice); From patchwork Thu Apr 28 08:09:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 567130 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:6886:0:0:0:0 with SMTP id m6csp5232783map; Thu, 28 Apr 2022 01:11:59 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyWHRS9DIb03kkLNkYt0RCIWIkHUivVwHfeVYJKLN4BbYWYFKktgXYbZgoAAjNtk4kpNH7b X-Received: by 2002:a17:906:5006:b0:6ce:3762:c72e with SMTP id s6-20020a170906500600b006ce3762c72emr29827302ejj.30.1651133519346; Thu, 28 Apr 2022 01:11:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1651133519; cv=none; d=google.com; s=arc-20160816; b=l+4NT8Xp5ttwV1uNrC/aX3dKIqaQH9+4aioYql2/PC1D6WYkS+rG6l0bNfUjE7lgto LOhjS48NdONgV7sKQr500RTMJDgN+OvqV5bBcr85sGIV2rVFpK7lc+VUhrKkSADXpcvR eqVsQNkBbQ4BdEwSJ0zj3Yk5STurtaro2EjyYvBXKyH9CyvYcKS4/CcwjHO4nVL+O/m6 XXve+VnjD/pWBCpwnDpvD4dx1fS9rVyURPjv4aWY967vHlCKgItC4tcT30tvaq7oUoam 4ofoaXvo3DNdhD4VTH2aogGcRYrb+jnCMtAqtF6TGBLI9Qr3iOO12hnf+q2dLjo/U7K0 HFVQ== 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=rD6DTSGjbYlpKtq+SWtmijWsysS024y9Pdlgu6tWWtg=; b=cNZ7NYzSsKlT62YjL57NYSLVAK35o0Cal9EuNv6C0d9NEl92FshwWnkU5nOt3Yx8Tu S73SSIYuboVgH/rcyPITARGdCEnMvYWp8/uC+EsTJd35lkS/jwyqR0bF2MU744KOKA+5 Q5MlFrpiQqBGKG+BCM91OHZMrhQUFowzlS8Xqg3R1wkrqC7W+qq0On2W6VY/xE1WnJ+t 1V7POwQkfx4JmWNwskCzZGOsdtJ0v2zcVeFz1WR5XbFVmGvYXsQsT/6VCmHh//DmGx/E D81+9aXeStyy9Szp1As+zZBJnHAMARAt19sjy4tOawKc6OE07OzBc4b3UKNFAvme8YA5 iVaQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=RdE7DgyG; 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 hr13-20020a1709073f8d00b006e7f92842dbsi3907441ejc.355.2022.04.28.01.11.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:11:59 -0700 (PDT) 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=RdE7DgyG; 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 19D7383EE7; Thu, 28 Apr 2022 10:11:27 +0200 (CEST) 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="RdE7DgyG"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 90DFD83ED1; Thu, 28 Apr 2022 10:10:58 +0200 (CEST) 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 autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pf1-x435.google.com (mail-pf1-x435.google.com [IPv6:2607:f8b0:4864:20::435]) (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 21391834AD for ; Thu, 28 Apr 2022 10:10:51 +0200 (CEST) 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-pf1-x435.google.com with SMTP id j6so3592017pfe.13 for ; Thu, 28 Apr 2022 01:10:51 -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; bh=rD6DTSGjbYlpKtq+SWtmijWsysS024y9Pdlgu6tWWtg=; b=RdE7DgyGVJYOynPjMvJ/OpnQ9qYwtArblhlOLk4vWB1Tc2t1Ils+cjwStW/Psbw1Vp vPBqVBxeCQgH+SkKQoIxdpjtGPRrpKzQcXGNSzDOM4M38Sa2y860oVuiF8pxLKPy9te5 auNezcvfQhVh9adn9crVcBUOiM9RB9Pk5Sg2pgcUTtg684QslC9bwFdNfu2uGBxGJBa7 aaFclD8UI3v79T0/zTDbqI2KGHU39Oy3Jf6GHaQv6anRu1IZ1B1OVo7tV+55XkN+71nC T2rQhWvDIRLlFwBE4fBpT3S+FU6Qd/J0Som+oEDyf+l9U0oe4SLiQmXPsUHcifc4XHjH uz3g== 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=rD6DTSGjbYlpKtq+SWtmijWsysS024y9Pdlgu6tWWtg=; b=torZrivg4Sqa3aQ+6ZjINlSOH/txyC6co0bZm9uJaMWT4dn97xSPmlYhbCe/ZvfMXO NiitWs8p/u5ruR9hirJkAb8O2vnuGGxo23Nc1pH6nx5k6DwpBvOI70XqJJ3vewlSwWpg GThxoDLCEbtmZ2Fry+uxvJ9dfwEmjRZ3V08L1+/gONmwjuSgZsl8I0/KXiwhqcWZtpY2 3iUXneDkS18df/i8hQbciLo/okmBu5GGeKnREI+HouQmEszQzg69RU2T3mfvwLsZOuqo B96IaHdt6LPmdC+4nU4TR90JnTSs5WBm9Lbp/fFuGw4BKZg+b9ksvUmUvqSLpItBO6Kb m32g== X-Gm-Message-State: AOAM533yfV9h9ecJBT9yMYjKijwtS7NVWptGStAiXlqkXoraG4iZlRAv TPEGX8+4fHgtbpxJjIe9kliiHIKyFc0iWQ== X-Received: by 2002:a63:5a20:0:b0:3aa:2fd0:9e94 with SMTP id o32-20020a635a20000000b003aa2fd09e94mr27764642pgb.602.1651133449427; Thu, 28 Apr 2022 01:10:49 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id b15-20020a17090a7acf00b001cd4989ff5fsm5684259pjl.38.2022.04.28.01.10.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:10:49 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Francois Ozog , Mark Kettenis Subject: [PATCH v5 05/17] efi_loader: export efi_locate_device_handle() Date: Thu, 28 Apr 2022 17:09:38 +0900 Message-Id: <20220428080950.23509-6-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220428080950.23509-1-masahisa.kojima@linaro.org> References: <20220428080950.23509-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 From: AKASHI Takahiro This function will be used in the next commit where some behavior of EFI boot manager will be expanded. Signed-off-by: AKASHI Takahiro Reviewed-by: Ilias Apalodimas Reviewed-by: Heinrich Schuchardt Reviewed-by: Ilias Apalodimas --- No changes from original version include/efi_loader.h | 4 ++++ lib/efi_loader/efi_boottime.c | 7 +++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/efi_loader.h b/include/efi_loader.h index ba79a9afb4..effb43369d 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -595,6 +595,10 @@ efi_status_t efi_create_handle(efi_handle_t *handle); void efi_delete_handle(efi_handle_t obj); /* Call this to validate a handle and find the EFI object for it */ struct efi_object *efi_search_obj(const efi_handle_t handle); +/* Locate device_path handle */ +efi_status_t EFIAPI efi_locate_device_path(const efi_guid_t *protocol, + struct efi_device_path **device_path, + efi_handle_t *device); /* Load image */ efi_status_t EFIAPI efi_load_image(bool boot_policy, efi_handle_t parent_image, diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 5bcb8253ed..4da64b5d29 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -1799,10 +1799,9 @@ failure: * * Return: status code */ -static efi_status_t EFIAPI efi_locate_device_path( - const efi_guid_t *protocol, - struct efi_device_path **device_path, - efi_handle_t *device) +efi_status_t EFIAPI efi_locate_device_path(const efi_guid_t *protocol, + struct efi_device_path **device_path, + efi_handle_t *device) { struct efi_device_path *dp; size_t i; From patchwork Thu Apr 28 08:09:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 567131 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:6886:0:0:0:0 with SMTP id m6csp5232848map; Thu, 28 Apr 2022 01:12:07 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz4GjGnJ3REpEVYuz5H6tA6LrVnwBP9WZJg48x9n06dm1RtSPVZuW2qtvBXMa85a+l4OwB7 X-Received: by 2002:a17:907:7f13:b0:6f3:bfbb:2f9b with SMTP id qf19-20020a1709077f1300b006f3bfbb2f9bmr8375649ejc.101.1651133527069; Thu, 28 Apr 2022 01:12:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1651133527; cv=none; d=google.com; s=arc-20160816; b=RsuNuz/Zayanc9tqCZDQriOdIZmQAAP+7wp/H76USQ7delPCZxu7gQ2qXRfEOyvEHh aEw4SkHMcju11LdhDqHmLKx+gegUd0fY+ByUOrcfAa6DyUQ1/Fz2ZmKleL6FyOtdZ6PF VggAK+vrjxGraJTgTxPTuyBuacwpRkWI1jMahJ7q2V5Ya0rcxCqmNb0xUU4fubxH1rFP G0S6ujVvo3q8TXGWdmwDSUkVLyo8Wt0zVWjHB0ukvUKmt9/kYxcO4BBWKmmhcK8C0gAG A3HJl1NaTC04ypN4UYB8rG4XVHDbVpDSuFMU+k+6u7u6WjXshjw0ZdEaCDf2GdhcaL8d w1MQ== 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=HOOiTkHqbSMr7iKUGSNzxIwAONnXeJsOnOrhzB5sHvc=; b=YUoqpSLR2CS2ag9D5dcijQhZQmTPcdyu9Mswz9Jr/CHkB8ACIDPlFQWpEA4piFIyPs g50+np7orBMOXdqo9HQPbVqtiaq1t9l0h0HaO0WDfRDuJ+F+GaFjy20EMhRaDUCTlb9p oKBdj//C4d5NtKhQFU4gUgEKUktLvbPajmr8pnudHbXKXvQ8HCcQTGIkCBthrJTUZ4Y3 LxKqH7Vv+en2FzShrQYlV+jQ0cQ7AkQ72DLfe5CS5X/gf4Wjz2DoDS4d0i4K/tbHYKMB eY0g0MJw4gCiaUFX0o+L3AHzzIfx+nMkpbNVvApVaJGF00RuQkodhE0xuneOwxKDjvrh OhLw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="o1J/CtZy"; 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 oy12-20020a170907104c00b006df76385e39si2597720ejb.729.2022.04.28.01.12.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:12:07 -0700 (PDT) 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="o1J/CtZy"; 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 EBC1F83EF1; Thu, 28 Apr 2022 10:11:31 +0200 (CEST) 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="o1J/CtZy"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 46B8383B32; Thu, 28 Apr 2022 10:11:03 +0200 (CEST) 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 autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pj1-x1032.google.com (mail-pj1-x1032.google.com [IPv6:2607:f8b0:4864:20::1032]) (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 96E54802EF for ; Thu, 28 Apr 2022 10:10:54 +0200 (CEST) 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-x1032.google.com with SMTP id w17-20020a17090a529100b001db302efed6so2213140pjh.4 for ; Thu, 28 Apr 2022 01:10:54 -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; bh=HOOiTkHqbSMr7iKUGSNzxIwAONnXeJsOnOrhzB5sHvc=; b=o1J/CtZy+OQZM/xYxqzZCZli4ASIq7ViO3SccElDjxiX+EsehOlsnCYmw/rgyJFrca biQcCmcf6laeioiQq9FdX9EFzc0UfFqLUUVilsMh9kM+U+f6rTl3UA6+EPi42K6Sardh yXQQLkup2aqokfZg0Ch6VxEsFJf8QjcNPGi/bAv/GBu/CqVtSAzoBRjZDxxXOTrlANY4 smaOviVNc8xdobWWUfAKgiL58PQ0H9UrNN0wlccQVjgCIycPV8p05U1imY4Ml8Aco7N9 U0eoEN6ZnrRkgIjmpUfDKGgP90rOvlXt1+Rude6JNJ0SnI0+PHzYi/8nwDpCsyf1RVoJ d5uA== 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=HOOiTkHqbSMr7iKUGSNzxIwAONnXeJsOnOrhzB5sHvc=; b=dGnbdhXOzksjNfrYT+8i0pRHDx5hKM7CUP8gdUdQGofxmuMzOCOXlD+y4PWa0MI8d0 QaDU+1K0xi8FLmRLe16mL8sGi6g3nR9PiIKTVMwQiz02SiophwmIj6o1JfuT0aF9HlwK xmIFo2fSG4dIl/SpCZAeoDOrobzC1YyDuv12FWVqATJ1DQtVgx+x2l36yyrNmv8Gqcpu +LuB11DEoUt7NivJJxxC2j5lzwfCO8ChLGx4aEaq2I9tI8AEShtLPm0F3+hJP6yvrqf3 gmZ1KwnXr1JIL2/n6TE7Kcqc71SzIvbXgQjf2YdzaF3kPs5AEKHsaZ1FtHsfUeiVDEAu iOhw== X-Gm-Message-State: AOAM531ujQDw1jMybWoKvm/eh8OXim8YSmXQUlXIVwUxox+87Ul71WFZ FlIJnCDsCpK3XXN8sbHPuQszXVqe/z7Klw== X-Received: by 2002:a17:90b:1809:b0:1d9:c10f:7ed6 with SMTP id lw9-20020a17090b180900b001d9c10f7ed6mr12115625pjb.57.1651133452858; Thu, 28 Apr 2022 01:10:52 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id b15-20020a17090a7acf00b001cd4989ff5fsm5684259pjl.38.2022.04.28.01.10.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:10:52 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Francois Ozog , Mark Kettenis , Masahisa Kojima , Mark Kettenis , Peter Hoyes , Neil Armstrong , Andre Przywara Subject: [PATCH v5 06/17] efi_loader: bootmgr: add booting from removable media Date: Thu, 28 Apr 2022 17:09:39 +0900 Message-Id: <20220428080950.23509-7-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220428080950.23509-1-masahisa.kojima@linaro.org> References: <20220428080950.23509-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 From: AKASHI Takahiro Under the current implementation, booting from removable media using a architecture-specific default image name, say BOOTAA64.EFI, is supported only in distro_bootcmd script. See the commit 74522c898b35 ("efi_loader: Add distro boot script for removable media"). This is, however, half-baked implementation because 1) UEFI specification requires this feature to be implemented as part of Boot Manager's responsibility: 3 - Boot Manager 3.5.1 Boot via the Simple File Protocol When booting via the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, the FilePath will start with a device path that points to the device that implements the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL or the EFI_BLOCK_IO_PROTOCOL. The next part of the FilePath may point to the file name, including subdirectories, which contain the bootable image. If the file name is a null device path, the file name must be generated from the rules defined below. ... 3.5.1.1 Removable Media Boot Behavior To generate a file name when none is present in the FilePath, the firmware must append a default file name in the form \EFI\BOOT\BOOT{machine type short-name}.EFI ... 2) So (1) entails the hehavior that the user's preference of boot media order should be determined by Boot#### and BootOrder variables. With this patch, the semantics mentioned above is fully implemented. For example, if you want to boot the system from USB and SCSI in this order, * define Boot0001 which contains only a device path to the USB device (without any file path/name) * define Boot0002 which contains only a device path to the SCSI device, and * set BootOrder to Boot0001:Boot0002 To avoid build error for sandbox, default file name "BOOTSANDBOX.efi" is defined even if it is out of scope of UEFI specification. Signed-off-by: AKASHI Takahiro Signed-off-by: Masahisa Kojima --- Changes in v5: - add default file name definition for SANDBOX to avoid build error Changes from original version: - create new include file "efi_default_filename.h" to avoid conflict with config_distro_bootcmd.h - modify the target pointer of efi_free_pool(), expand_media_path() should only free the pointer allocated by efi_dp_from_file() function. include/config_distro_bootcmd.h | 14 +-------- include/efi_default_filename.h | 33 ++++++++++++++++++++++ lib/efi_loader/efi_bootmgr.c | 50 ++++++++++++++++++++++++++++++++- 3 files changed, 83 insertions(+), 14 deletions(-) create mode 100644 include/efi_default_filename.h diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h index c55023889c..6a3110f27b 100644 --- a/include/config_distro_bootcmd.h +++ b/include/config_distro_bootcmd.h @@ -91,19 +91,7 @@ #endif #ifdef CONFIG_EFI_LOADER -#if defined(CONFIG_ARM64) -#define BOOTEFI_NAME "bootaa64.efi" -#elif defined(CONFIG_ARM) -#define BOOTEFI_NAME "bootarm.efi" -#elif defined(CONFIG_X86_RUN_32BIT) -#define BOOTEFI_NAME "bootia32.efi" -#elif defined(CONFIG_X86_RUN_64BIT) -#define BOOTEFI_NAME "bootx64.efi" -#elif defined(CONFIG_ARCH_RV32I) -#define BOOTEFI_NAME "bootriscv32.efi" -#elif defined(CONFIG_ARCH_RV64I) -#define BOOTEFI_NAME "bootriscv64.efi" -#endif +#include #endif #ifdef BOOTEFI_NAME diff --git a/include/efi_default_filename.h b/include/efi_default_filename.h new file mode 100644 index 0000000000..cb2ef9e131 --- /dev/null +++ b/include/efi_default_filename.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Default boot file name when none is present in the FilePath. + * This is defined in the UEFI specification. + * + * Copyright (c) 2022, Linaro Limited + */ +#ifndef _EFI_DEFAULT_FILENAME_H +#define _EFI_DEFAULT_FILENAME_H + +#if defined(CONFIG_ARM64) +#define BOOTEFI_NAME "BOOTAA64.EFI" +#elif defined(CONFIG_ARM) +#define BOOTEFI_NAME "BOOTARM.EFI" +#elif defined(CONFIG_X86_64) +#define BOOTEFI_NAME "BOOTX64.EFI" +#elif defined(CONFIG_X86) +#define BOOTEFI_NAME "BOOTIA32.EFI" +#elif defined(CONFIG_ARCH_RV32I) +#define BOOTEFI_NAME "BOOTRISCV32.EFI" +#elif defined(CONFIG_ARCH_RV64I) +#define BOOTEFI_NAME "BOOTRISCV64.EFI" +#elif defined(CONFIG_SANDBOX) +/* + * SANDBOX is not defined in UEFI specification, but + * this definition avoids build failure for SANDBOX. + */ +#define BOOTEFI_NAME "BOOTSANDBOX.EFI" +#else +#error Unsupported UEFI architecture +#endif + +#endif diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index 8c04ecbdc8..22a4302aac 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,50 @@ static const struct efi_runtime_services *rs; * should do normal or recovery boot. */ +/** + * expand_media_path() - expand a device path for default file name + * @device_path: device path to check against + * + * If @device_path is a media or disk partition which houses a file + * system, this function returns a full device path which contains + * an architecture-specific default file name for removable media. + * + * Return: a newly allocated device path + */ +static +struct efi_device_path *expand_media_path(struct efi_device_path *device_path) +{ + struct efi_device_path *dp, *full_path; + efi_handle_t handle; + efi_status_t ret; + + if (!device_path) + return NULL; + + /* + * If device_path is a (removable) media or partition which provides + * simple file system protocol, append a default file name to support + * booting from removable media. + */ + dp = device_path; + ret = efi_locate_device_path(&efi_simple_file_system_protocol_guid, + &dp, &handle); + if (ret == EFI_SUCCESS) { + if (dp->type == DEVICE_PATH_TYPE_END) { + dp = efi_dp_from_file(NULL, 0, + "/EFI/BOOT/" BOOTEFI_NAME); + full_path = efi_dp_append(device_path, dp); + efi_free_pool(dp); + } else { + full_path = efi_dp_dup(device_path); + } + } else { + full_path = efi_dp_dup(device_path); + } + + return full_path; +} + /** * try_load_entry() - try to load image for boot option * @@ -68,13 +113,16 @@ static efi_status_t try_load_entry(u16 n, efi_handle_t *handle, } if (lo.attributes & LOAD_OPTION_ACTIVE) { + struct efi_device_path *file_path; u32 attributes; log_debug("%s: trying to load \"%ls\" from %pD\n", __func__, lo.label, lo.file_path); - ret = EFI_CALL(efi_load_image(true, efi_root, lo.file_path, + file_path = expand_media_path(lo.file_path); + ret = EFI_CALL(efi_load_image(true, efi_root, file_path, NULL, 0, handle)); + efi_free_pool(file_path); if (ret != EFI_SUCCESS) { log_warning("Loading %ls '%ls' failed\n", varname, lo.label); From patchwork Thu Apr 28 08:09:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 567132 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:6886:0:0:0:0 with SMTP id m6csp5232979map; Thu, 28 Apr 2022 01:12:19 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyty2uA1OXwqVDUFVShl0LSjupacY5HHeGyKll91yIBBYSXiPF5CgF1tc1uVYe1dCAAxLeX X-Received: by 2002:a05:6402:524e:b0:423:e919:8eb4 with SMTP id t14-20020a056402524e00b00423e9198eb4mr35061256edd.153.1651133539619; Thu, 28 Apr 2022 01:12:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1651133539; cv=none; d=google.com; s=arc-20160816; b=n+CGF5mFqETG4cDc0HP5RRhjsV9nWmkG8wrt906Xrc5/c1jJn2G5upjqwkDe+PWj/8 C8lVb//3o9aw54uK/DLHIFCpDZbxQlaj52shsBg/HI3jxJTOAyFPL+xfTwLqmaIAOyEk TxGclK/RkntxU/Y7bhq6inrRvf+RHDk1LC9jkoioiCOoNc4RpmF0muR31FdusD4KZQfm ib4v5wwXfXfQgDz+C5uRvJiEeSBrmTpuJOHvcQzlaid9tMd6z1bl/IQT0HEHgJ1LCK2b ZqbkGe9fUnYpqG93zt+qvlMDDGg7eX2nFrV+u68M14u0Q3c43u8APcJWfP1gY0FUbIoC 9vyg== 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=0d5XzgIT22LtcbfvaH5xwq+RVmN2SJ3ZzE3Sh0PRB00=; b=jUVhBr5+4PbeaCPsSLrY0EOGIjnlwbp4l62Z/7BkFLhcFxgS1DWPggLcITmjCdG2gv 3CRjSmQvECy68qD6Z5oXAsluFHQ0BvfOzhsSP6cIxaoT9ZXN6tn3kV01Wxq4eSIhJwSg Jn/kAtR46VTRqOyjvYIz3POS93hnQBqLpRbWwjv9NjCU4STiCNW9fLK/3e5PHaHdbvrp gk+1GBE77frdn6GtRGdgCsFxWzL507Gr88kiQmjjdJSGVYdG2VAGWe9Po2Ft4L6TK/5j 3gd/pPe9dv3paVS3a0vFafD9y9gqpOAAg3Ve8YbIYHicn5Hh5hJ2Y9ZupVUeQNqUn+Av trCQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="Xr/E8U1d"; 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 sd22-20020a170906ce3600b006e12386caa3si3180403ejb.748.2022.04.28.01.12.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:12:19 -0700 (PDT) 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="Xr/E8U1d"; 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 ED8D883ECB; Thu, 28 Apr 2022 10:11:35 +0200 (CEST) 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="Xr/E8U1d"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 168C283ED1; Thu, 28 Apr 2022 10:11:10 +0200 (CEST) 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 autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pl1-x633.google.com (mail-pl1-x633.google.com [IPv6:2607:f8b0:4864:20::633]) (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 46D4B8393F for ; Thu, 28 Apr 2022 10:10:57 +0200 (CEST) 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-x633.google.com with SMTP id b12so3696943plg.4 for ; Thu, 28 Apr 2022 01:10:57 -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; bh=0d5XzgIT22LtcbfvaH5xwq+RVmN2SJ3ZzE3Sh0PRB00=; b=Xr/E8U1dc4jPqfOpSeuTY8OdYZltpQZXodr/zyufV+Qon4ZP2Hrf4cDV8nRychZ23g j9tIu6Upw6UUQiidibwrLIheMNjx8g/WyEAiUZ6JyM73V1R6hdHFgn6GQZ34BkN57Btm 8MG6QuusHjkga81si3WsuokLjgr38IhyWsXrW+Q4NiXwCdW1ZQIUwoGRibXxRovcOoJk L16cYCQNmR+DrkmU0X3vG/9x9P27n+8BtDuyjpurPiawDFo/unpkCNp/8v+rDh+TPmdN Ht0qjsE5/KJHdMV4DiLyAB7ELI5num197B8SWd4NgFzapf5HToQOcS2lAcMtRoYe3EZW T9EQ== 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=0d5XzgIT22LtcbfvaH5xwq+RVmN2SJ3ZzE3Sh0PRB00=; b=wRTMjF4hhtl+kyYEcP+e5I5PuIBBC9J1W07yFdZUMkNtINKXxK4lPyEEmZFNBKDbNQ nFJSA92bhJI/UHpyn0SilGta8oH9GL+4KHB2+dzNUr6mLUHaUlmHdZWevuXxVZSi3Eyb 3/0pSG0AXVYyreelJGVsWURtqBGfKZXuPAJYK3H0hq0cqcDDck3CEmn3yFioVCJ3oTXg WJTzXotbcc1XrPcv4W/sHA3suI4X2QVrdyX3nAj8WFI7slVI6WfQrpOh9p1kBsS4AixW iQnainf7kKPQS1aN7J/jWT90ukmt3ZiF0SlHT1cD/xk2izBwDSb9RJeKQ4yjkZPd3yvq +qSg== X-Gm-Message-State: AOAM53305W3PB9RwQEGQTK/yV7Ymdeye7yP1jq9DFC7vxwuViXOjih5r WCmDSmpYBoKgBDXeI10mb0sonIT72Tkttg== X-Received: by 2002:a17:90a:8044:b0:1d9:7a6c:38dd with SMTP id e4-20020a17090a804400b001d97a6c38ddmr21791517pjw.156.1651133455653; Thu, 28 Apr 2022 01:10:55 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id b15-20020a17090a7acf00b001cd4989ff5fsm5684259pjl.38.2022.04.28.01.10.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:10:55 -0700 (PDT) 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: [PATCH v5 07/17] bootmenu: flush input buffer before waiting user key input Date: Thu, 28 Apr 2022 17:09:40 +0900 Message-Id: <20220428080950.23509-8-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220428080950.23509-1-masahisa.kojima@linaro.org> References: <20220428080950.23509-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 Before waiting user key input to stop autoboot, the input buffer must be flushed. Signed-off-by: Masahisa Kojima --- Change in v5: - newly created, split into separate patch cmd/bootmenu.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index d573487272..9a32a18b19 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -87,6 +87,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); } From patchwork Thu Apr 28 08:09:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 567133 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:6886:0:0:0:0 with SMTP id m6csp5233092map; Thu, 28 Apr 2022 01:12:32 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwI6nSgSdeVpMnEbnsBzTz/HtoUmeD29TkhTPsU8HlfggAjnSARZdwtmHhRyKCNDHHYrIQd X-Received: by 2002:a17:906:cb09:b0:6f3:87ca:1351 with SMTP id lk9-20020a170906cb0900b006f387ca1351mr21164251ejb.674.1651133551833; Thu, 28 Apr 2022 01:12:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1651133551; cv=none; d=google.com; s=arc-20160816; b=wGkogo9r0iHIcBAgBYF7acBQ6NW2GCk2j8ez+37Y8KaAfsVwGr5ZBRslDywmkeVGy8 eAERnZtIJhjF5p2j904qZgNNsk4dBV2zYlN6FiHQrUAbQhCpCk/0mHnvmqK0R2AElV4Z Lc5jYZAlug/v1WypdvGBzl54E2S1TtCc/QGPvakYsaTYfCaNGCFouPEbh7ASHEH+or1U aY3/iGwXYZPa92tmvgVMxxkepa2JKXQT9lc1JbabOuANC8fuby7drZgWh0f6GkcAOGx0 9xXaYPfgXBp1hnwJkVMpL4sDDdvE2XDoa70CfEs3A/T0o5kdISVWTZvurNWD41KVP8j8 TS/Q== 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=n4W36B8jOo8JDupeTyquxGIwlG2fL+m3SorYvvl2pzE=; b=0LdeJNuEDgd53kJ4X+tVyGFHBLjDUjjlB80rq0/C/DEQsZrqRG6HZIHV3tijr/n1aa D5xXQBTR2+/lQ/knXKt4ulXqzYgb2urNwS2Nn2lYCG3ktdG+KVbWTVeMXK05AGZ3+G3G o5WfDSDXjDye9VhHPXtvN8Rh5UDYSyXy4apMoZxjSC+5oXEdiY84W2VB4RQQaRaDhkxh yBTf/0FZah7GWf19t6mX4WwUofiZvB75EdhAq6KsUbTZFD+yu6dIgac0hPBZNQWBcQ4q xgTldgkLAVxsVgim6ikLcRdDGw9lAdHaETniWcujO72YxTgtlx47iDi5gfJDZYHZ+oJE qXsg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=OhCHj73p; 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 lz4-20020a170906fb0400b006e8a89825fesi3053319ejb.768.2022.04.28.01.12.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:12:31 -0700 (PDT) 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=OhCHj73p; 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 E29F083EDF; Thu, 28 Apr 2022 10:11:40 +0200 (CEST) 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="OhCHj73p"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 9D00B8393F; Thu, 28 Apr 2022 10:11:10 +0200 (CEST) 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 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 318B783565 for ; Thu, 28 Apr 2022 10:11:00 +0200 (CEST) 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 k4so3685962plk.7 for ; Thu, 28 Apr 2022 01:11:00 -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=n4W36B8jOo8JDupeTyquxGIwlG2fL+m3SorYvvl2pzE=; b=OhCHj73ppHQTHoS3OIOwF2+0NUMmlTwQ3uWdyrMcDExeVJWPJ/LWzyUTszzeAfFmxs tKwRpMTPaJSmc4uapr8HZ+uOmR0gic1RbULuqpNQwyRmSBFdCmaCV4C0XtQfTtwkTErX flOvUx8T0/O4SUnUAgG9KKdw9uFAy05PAPgBteNC/uklpgEN3PyRZ+8pU+BOzR/Bnf3P O0eYPi41ZUVBuBRqLRAKmyG2R8zr339Yp7WN1mUlR5zV41gbqLmaEKNhfHnFKJFmdioT 8IMUEO424M964pgL/N9gP60OO6IP6uSgA7YO88u1xCd0o453VfY5kg0QCgSzP8CaJvmm UHpg== 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=n4W36B8jOo8JDupeTyquxGIwlG2fL+m3SorYvvl2pzE=; b=JMeKm9pQzN0LxPdIHYqTCTAC02hudDlzenYrBA91pPp9D3JD5vA9g/v/vJbUPEkHDO avi6jjqHLpo4m2xcCpzLpiKOHU7FGe7FBzlXEVfH0l6CDtpAxfC3ifvnxS93TiFviSsw c7vs+rCS4usdkzfRWI5+F8yA//qd/H+egIt9OcBN8eZsPBZeDSuZ6NZILpNrfBch16rF JQ6xqt10dyTTxjhaADBqGJYMHNwYp2l0Ess/H2vi1vHs4lcJjkD+EcETS4UJVH0k9XXT 3UUZVEfwJTCwDvb/yQs4KOHiEP9mVRIUmm9RS+4pT9IEN9nHWHa6Se9A+zTBeqShGpHU 0oXA== X-Gm-Message-State: AOAM533499clcUlbMVL2MTLfWPzU0KgmvuIRWMdq6q23FicwX3DE375G /Im2+ls+MPDZ+HPAs22twaKnJq4G5l+8Xg== X-Received: by 2002:a17:902:820f:b0:158:c308:d4c5 with SMTP id x15-20020a170902820f00b00158c308d4c5mr32167147pln.155.1651133458423; Thu, 28 Apr 2022 01:10:58 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id b15-20020a17090a7acf00b001cd4989ff5fsm5684259pjl.38.2022.04.28.01.10.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:10:57 -0700 (PDT) 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: [PATCH v5 08/17] bootmenu: update bootmenu_entry structure Date: Thu, 28 Apr 2022 17:09:41 +0900 Message-Id: <20220428080950.23509-9-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220428080950.23509-1-masahisa.kojima@linaro.org> References: <20220428080950.23509-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 is a preparation for succeeding addition of uefi boot and distro boot menu entries into bootmenu. The bootmenu_entry title is updated to u16 string because uefi use u16 string. This commit also factors out the function to prepare the entries generated by "bootmenu_x" U-Boot environment variable. This commit also updates the bootmenu entry title. The entry derived from "bootmenu_x" U-Boot environment variable has the "bootmenu_xx" prefix as below. *** U-Boot Boot Menu *** bootmenu_00 : Boot 1. kernel bootmenu_01 : Boot 2. kernel bootmenu_02 : Reset board Signed-off-by: Masahisa Kojima --- Changes in v5: - split into the separate patch - add function description comment cmd/bootmenu.c | 110 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 78 insertions(+), 32 deletions(-) diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index 9a32a18b19..15ad621c9f 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -3,6 +3,7 @@ * (C) Copyright 2011-2013 Pali Rohár */ +#include #include #include #include @@ -24,11 +25,18 @@ */ #define MAX_ENV_SIZE (9 + 2 + 1) +enum boot_type { + BOOTMENU_TYPE_NONE = 0, + BOOTMENU_TYPE_BOOTMENU, +}; + 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; /* boot type of entry */ + u16 bootorder; /* order for each boot type */ struct bootmenu_data *menu; /* this bootmenu */ struct bootmenu_entry *next; /* next menu entry (num+1) */ }; @@ -75,7 +83,10 @@ static void bootmenu_print_entry(void *data) if (reverse) puts(ANSI_COLOR_REVERSE); - puts(entry->title); + if (entry->type == BOOTMENU_TYPE_BOOTMENU) + printf("bootmenu_%02d : %ls", entry->bootorder, entry->title); + else + printf("%ls", entry->title); if (reverse) puts(ANSI_COLOR_RESET); @@ -279,31 +290,32 @@ static void bootmenu_destroy(struct bootmenu_data *menu) free(menu); } -static struct bootmenu_data *bootmenu_create(int delay) +/** + * prepare_bootmenu_entry() - generate the bootmenu_xx entries + * + * This function read the "bootmenu_x" U-Boot environment variable + * and generate the bootmenu entries. + * + * @menu: pointer to the bootmenu structure + * @current: pointer to the last bootmenu entry list + * @index: pointer to the index of the last bootmenu entry, + * the number of bootmenu entry is added by this function + * Return: 1 on success, negative value on error + */ +static int prepare_bootmenu_entry(struct bootmenu_data *menu, + struct bootmenu_entry **current, + unsigned short int *index) { - unsigned short int i = 0; - const char *option; - struct bootmenu_data *menu; - struct bootmenu_entry *iter = NULL; - int len; char *sep; - char *default_str; - struct bootmenu_entry *entry; - - menu = malloc(sizeof(struct bootmenu_data)); - if (!menu) - return NULL; - - menu->delay = delay; - menu->active = 0; - menu->first = NULL; - - default_str = env_get("bootmenu_default"); - if (default_str) - menu->active = (int)simple_strtol(default_str, NULL, 10); + const char *option; + unsigned short int i = *index; + struct bootmenu_entry *entry = NULL; + struct bootmenu_entry *iter = *current; while ((option = bootmenu_getoption(i))) { + u16 *buf; + sep = strchr(option, '='); if (!sep) { printf("Invalid bootmenu entry: %s\n", option); @@ -312,23 +324,23 @@ static struct bootmenu_data *bootmenu_create(int delay) entry = malloc(sizeof(struct bootmenu_entry)); if (!entry) - goto cleanup; + return -ENOMEM; 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; + return -ENOMEM; } - memcpy(entry->title, option, len); - entry->title[len] = 0; + utf8_utf16_strncpy(&buf, option, len); len = strlen(sep + 1); entry->command = malloc(len + 1); if (!entry->command) { free(entry->title); free(entry); - goto cleanup; + return -ENOMEM; } memcpy(entry->command, sep + 1, len); entry->command[len] = 0; @@ -337,6 +349,8 @@ static struct bootmenu_data *bootmenu_create(int delay) entry->num = i; entry->menu = menu; + entry->type = BOOTMENU_TYPE_BOOTMENU; + entry->bootorder = i; entry->next = NULL; if (!iter) @@ -351,13 +365,44 @@ static struct bootmenu_data *bootmenu_create(int delay) break; } + *index = i; + *current = iter; + + return 1; +} + +static struct bootmenu_data *bootmenu_create(int delay) +{ + int ret; + unsigned short int i = 0; + struct bootmenu_data *menu; + struct bootmenu_entry *iter = NULL; + struct bootmenu_entry *entry; + char *default_str; + + menu = malloc(sizeof(struct bootmenu_data)); + if (!menu) + return NULL; + + menu->delay = delay; + menu->active = 0; + menu->first = NULL; + + default_str = env_get("bootmenu_default"); + if (default_str) + menu->active = (int)simple_strtol(default_str, NULL, 10); + + ret = prepare_bootmenu_entry(menu, &iter, &i); + if (ret < 0) + goto cleanup; + /* Add U-Boot console entry at the end */ if (i <= MAX_COUNT - 1) { entry = malloc(sizeof(struct bootmenu_entry)); 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; @@ -374,6 +419,7 @@ static struct bootmenu_data *bootmenu_create(int delay) entry->num = i; entry->menu = menu; + entry->type = BOOTMENU_TYPE_NONE; entry->next = NULL; if (!iter) @@ -431,7 +477,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; @@ -482,7 +528,7 @@ static void bootmenu_show(int delay) if (menu_get_choice(menu, &choice) == 1) { iter = choice; - title = strdup(iter->title); + title = u16_strdup(iter->title); command = strdup(iter->command); } @@ -497,7 +543,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); From patchwork Thu Apr 28 08:09:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 567136 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:6886:0:0:0:0 with SMTP id m6csp5233477map; Thu, 28 Apr 2022 01:13:11 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwH5AdwFTK0WZnudFR8diFQzZ0aEbgWjhLClk+v/a0hg1nEYnot9snn/w8TPbeZToUzXsdJ X-Received: by 2002:a17:907:d8d:b0:6df:b214:392a with SMTP id go13-20020a1709070d8d00b006dfb214392amr30776184ejc.669.1651133591004; Thu, 28 Apr 2022 01:13:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1651133590; cv=none; d=google.com; s=arc-20160816; b=Acn80u3xN6A05Tmk3XmA76C4pEJdAAPiUh3reY9a6mLRR81H8DHAe0PwoaKhR692sD wn+mKzd/8Gzt6vWbZRvEpDl0EQ57jywI+9y/fwGp/ND+BY1QTi0Q35FngQgah5dkvqeS /m6NyOROep1elRCrl+5oFdGYC9sLwfsfXUoUgtNrEFcJKULeE+dQWHT5xmxoDvjIg+T0 t/reO2YnPE0Lg831e7hGzAhsUO9drSgycT2lH+oK0Mps5X0xLRPyWpuRDEOJmPv/FePQ MLqOzOhXqprQ85afV+hrQWKFlXcrEX9mukNnJmuM3JZfVoBQlLo5eToQsYrdmutTumst C/CQ== 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=Xe69R6FDlBovFEuSAtFxJhquUkinf9gjFq4OL2sJCZs=; b=C5fo4rtnn6l0+Okc+4srIjUYEIu7D2iXaMk7k5++0DfxZjHJjHzzQKXPn+1xypfcL2 B4VmFM7j0QiwWAojqaRZZeapJ2B0Nm9oKXmCsNJgYr9WbJIt7sahcRGxpmpYJbappdXL S7v8PE+C2AqKW98IVxFSznOn+E5BGeFxS7sZwlCeZiwh7Di0WzrgS9nPrOzAvwtQ8jqY czoh7IJcBeAuWbS+y8UKSXiLFa/jHCkBmureeBfvI8PcDwxaHa/W1RCfr6dRC0nUeYvM zSETPREWywXpZD+GWOSpt92HxgpjZswR64iWY3W1qF19mhXnWXH0sPzGwmhsFVFMlTY0 T+Wg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=phKCLtJz; 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 gn40-20020a1709070d2800b006f3a2a7fd95si3420089ejc.636.2022.04.28.01.13.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:13:10 -0700 (PDT) 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=phKCLtJz; 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 94E5583EFB; Thu, 28 Apr 2022 10:11:52 +0200 (CEST) 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="phKCLtJz"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 50B5E81D4B; Thu, 28 Apr 2022 10:11:16 +0200 (CEST) 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 autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pg1-x52f.google.com (mail-pg1-x52f.google.com [IPv6:2607:f8b0:4864:20::52f]) (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 1A5F983E17 for ; Thu, 28 Apr 2022 10:11:03 +0200 (CEST) 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-pg1-x52f.google.com with SMTP id bg9so3373735pgb.9 for ; Thu, 28 Apr 2022 01:11:03 -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; bh=Xe69R6FDlBovFEuSAtFxJhquUkinf9gjFq4OL2sJCZs=; b=phKCLtJzIyp4LDl1UqWppGRYhOlMCPVlWQ+TG+hlEPrEYmINc7e9Had+aX1ximZrPo z2BXcTo7i7mRO01Ypah+q+hCi3u/5qoFYA9pa7b2SHF92CBlwVBoRaoOEDn1P2djfwzK AAKFjl8xcC8x8XZNUMvFGAsWhkAEL9lj22+fbumTyOY+habNeYZ8TtcdIhQah2b2/Pce 9Ec13a1mGKaRvrt3wLJEw1vYbaP9QgmNSfkfvNV35boGZMNPbKRbt3PXrE6MXCQrcpWY XIe1gA87G+NpYyHF9u4/2F1lfTh428xt27qUloS2Qfr8XlKZMztcCmBZ4cbwB2sg51Ug kKbA== 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=Xe69R6FDlBovFEuSAtFxJhquUkinf9gjFq4OL2sJCZs=; b=DxZALAXTSKEac2tO4fmHWrJ1VZaIiZUGpTYXXmw/HLZEYQYnQ+HcEdNXhdBMQfF5KM 7I0XAnvq1x9s140r6LcAGMx7zkaPwVbHzM2sZMldg/xEsjVm535kudx3epAUnUuMC+Sp vybcnTloZkXb/qfXWCt5PtOQIhJPhl9dxWArFrnGP4EjJj3b/SFoGgyPywvt/EmX4ilS rDWryPcUnSiO5u9YUZbqL8JQVq3CZj+ummDi2tDOUeyuV4T3uahOpnKPlg5d25i3kZ+W j41L6tYJD35pU51PiMQqQdJvRtWbsFtt+2MgQ43ZtjdfMQo4CC7jXvXT7IMXvI9URK4D 6Pqw== X-Gm-Message-State: AOAM533BC09+jN4e6UPQTDXq+XD3J4FsyWl4exBFA5L45RBHE+Y8rsBC 9K7jGv1+OMQ2xdf4yiQqnj6t5DpHZ+ApFg== X-Received: by 2002:a63:195f:0:b0:399:1f0e:a21d with SMTP id 31-20020a63195f000000b003991f0ea21dmr26823935pgz.393.1651133461177; Thu, 28 Apr 2022 01:11:01 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id b15-20020a17090a7acf00b001cd4989ff5fsm5684259pjl.38.2022.04.28.01.10.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:11:00 -0700 (PDT) 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: [PATCH v5 09/17] bootmenu: add UEFI boot entry into bootmenu Date: Thu, 28 Apr 2022 17:09:42 +0900 Message-Id: <20220428080950.23509-10-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220428080950.23509-1-masahisa.kojima@linaro.org> References: <20220428080950.23509-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 adds the UEFI related menu entries into the bootmenu. User can select which UEFI "Boot####" option to execute from bootmenu, then bootmenu sets the "BootNext" UEFI variable and invoke efi bootmgr. The efi bootmgr will handle the "BootNext" UEFI variable. If the "BootNext" UEFI variable is preset and efi bootmgr is enabled, bootmenu invokes efi bootmgr to handle "BootNext" as first priority. The UEFI boot entry has the "UEFI BOOTXXXX" prefix as below. *** U-Boot Boot Menu *** UEFI BOOT0000 : debian UEFI BOOT0001 : ubuntu Signed-off-by: Masahisa Kojima --- Changes in v5: - split into the separate patch - add function description comment - remove non-volatile attribute for BootNext variable to minimize the access to the non-volatile storage cmd/bootmenu.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 154 insertions(+), 1 deletion(-) diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index 15ad621c9f..da688e6213 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include #include #include @@ -28,6 +30,7 @@ enum boot_type { BOOTMENU_TYPE_NONE = 0, BOOTMENU_TYPE_BOOTMENU, + BOOTMENU_TYPE_UEFI_BOOT_OPTION, }; struct bootmenu_entry { @@ -85,6 +88,8 @@ static void bootmenu_print_entry(void *data) if (entry->type == BOOTMENU_TYPE_BOOTMENU) printf("bootmenu_%02d : %ls", entry->bootorder, entry->title); + else if (entry->type == BOOTMENU_TYPE_UEFI_BOOT_OPTION) + printf("UEFI BOOT%04X : %ls", entry->bootorder, entry->title); else printf("%ls", entry->title); @@ -371,6 +376,95 @@ static int prepare_bootmenu_entry(struct bootmenu_data *menu, return 1; } +/** + * prepare_uefi_bootorder_entry() - generate the uefi bootmenu entries + * + * This function read the "BootOrder" UEFI variable + * and generate the bootmenu entries in the order of "BootOrder". + * + * @menu: pointer to the bootmenu structure + * @current: pointer to the last bootmenu entry list + * @index: pointer to the index of the last bootmenu entry, + * the number of uefi entry is added by this function + * Return: 1 on success, negative value on error + */ +static int prepare_uefi_bootorder_entry(struct bootmenu_data *menu, + struct bootmenu_entry **current, + unsigned short int *index) +{ + 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####"; + unsigned short int i = *index; + struct bootmenu_entry *entry = NULL; + struct bootmenu_entry *iter = *current; + + bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size); + if (!bootorder) + return -ENOENT; + + num = size / sizeof(u16); + for (j = 0; j < num; j++) { + entry = malloc(sizeof(struct bootmenu_entry)); + if (!entry) + return -ENOMEM; + + 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); + free(entry); + continue; + } + + if (lo.attributes & LOAD_OPTION_ACTIVE) { + entry->title = u16_strdup(lo.label); + if (!entry->title) { + free(load_option); + free(entry); + free(bootorder); + return -ENOMEM; + } + entry->command = strdup("bootefi bootmgr"); + sprintf(entry->key, "%d", i); + entry->num = i; + entry->menu = menu; + entry->type = BOOTMENU_TYPE_UEFI_BOOT_OPTION; + entry->bootorder = bootorder[j]; + entry->next = NULL; + + if (!iter) + menu->first = entry; + else + iter->next = entry; + + iter = entry; + i++; + } + + free(load_option); + + if (i == MAX_COUNT - 1) + break; + } + + free(bootorder); + *index = i; + *current = iter; + + return 1; +} + static struct bootmenu_data *bootmenu_create(int delay) { int ret; @@ -396,6 +490,14 @@ static struct bootmenu_data *bootmenu_create(int delay) if (ret < 0) goto cleanup; + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) { + if (i < MAX_COUNT - 1) { + ret = prepare_uefi_bootorder_entry(menu, &iter, &i); + if (ret < 0 && ret != -ENOENT) + goto cleanup; + } + } + /* Add U-Boot console entry at the end */ if (i <= MAX_COUNT - 1) { entry = malloc(sizeof(struct bootmenu_entry)); @@ -473,6 +575,31 @@ static void menu_display_statusline(struct menu *m) puts(ANSI_CLEAR_LINE); } +static void handle_uefi_bootnext(void) +{ + u16 bootnext; + efi_status_t ret; + efi_uintn_t size; + + /* 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); + + return; + } + + /* If UEFI BootNext variable is set, boot the BootNext load option */ + size = sizeof(u16); + ret = efi_get_variable_int(u"BootNext", + &efi_global_variable_guid, + NULL, &size, &bootnext, NULL); + if (ret == EFI_SUCCESS) + /* BootNext does exist here, try to boot */ + run_command("bootefi bootmgr", 0); +} + static void bootmenu_show(int delay) { int init = 0; @@ -482,8 +609,12 @@ static void bootmenu_show(int delay) struct menu *menu; struct bootmenu_data *bootmenu; struct bootmenu_entry *iter; + efi_status_t efi_ret = EFI_SUCCESS; char *option, *sep; + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) + handle_uefi_bootnext(); + /* If delay is 0 do not create menu, just run first entry */ if (delay == 0) { option = bootmenu_getoption(0); @@ -532,6 +663,27 @@ static void bootmenu_show(int delay) command = strdup(iter->command); } + /* + * If the selected entry is UEFI BOOT####, set the BootNext variable. + * Then uefi bootmgr is invoked by the preset command in iter->command. + */ + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) { + if (iter->type == BOOTMENU_TYPE_UEFI_BOOT_OPTION) { + /* + * UEFI specification requires BootNext variable needs non-volatile + * attribute, but this BootNext is only used inside of U-Boot and + * removed by efi bootmgr once BootNext is processed. + * So this BootNext can be volatile. + */ + efi_ret = efi_set_variable_int(u"BootNext", &efi_global_variable_guid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(u16), &iter->bootorder, false); + if (efi_ret != EFI_SUCCESS) + goto cleanup; + } + } + cleanup: menu_destroy(menu); bootmenu_destroy(bootmenu); @@ -545,7 +697,8 @@ cleanup: if (title && command) { debug("Starting entry '%ls'\n", title); free(title); - run_command(command, 0); + if (efi_ret == EFI_SUCCESS) + run_command(command, 0); free(command); } From patchwork Thu Apr 28 08:09:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 567134 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:6886:0:0:0:0 with SMTP id m6csp5233237map; Thu, 28 Apr 2022 01:12:44 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzeypVj7VYpQwKtCSuWKLVtK8B37GjzhOD7v9rwPsl0PZ+iUmWuY4SxlwSCsXi34J3+XQuY X-Received: by 2002:a17:907:2d2a:b0:6f3:85a0:3987 with SMTP id gs42-20020a1709072d2a00b006f385a03987mr22187719ejc.383.1651133564544; Thu, 28 Apr 2022 01:12:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1651133564; cv=none; d=google.com; s=arc-20160816; b=DjUkKnvtQ8+q2paNWt/uLunebNUv6ykeEKF2DPbx1c4MCEmXnEnzQoVVVaeRyw/RBI QFQvaHT0KLmih9PDX5jCFCJRGl5z0LBgzufskRzOHnxRRwWaP2aCkGuu6duJrxelGxTQ qZa7HX8C88lnyoPCDpjfGq63toiF6ahi3dtagH0RI5ah5uLdBruLZNt0cGLB40PIn5vh ufiVp9c2PKHYsr9+CvRk+fzzDHNBRQMVX2X2QF+3icav0qSwihkrGtolVRGKjQwttmLE 9cIAcikgVIwGMAHlSXhuKQpKbhC++W+o8ELPke3RvLsGYsZFaaHbpJZ8h/7RppNH8/kc ktTQ== 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=0EQ3MOONx8H9Vnow2CgVj7ug336Cl++Am4tz+bMuhPg=; b=aAieVutWa5zk7LAszXtmd8e/N3sOgpdl+Ir6qhyNeDhPj1TDspGXwigY/43M5vmTip FIDCzO0e1a9DR5cvIJIe2e5WZ6bZZxSNOHKvy5uGZd2fSPV1IHsZOy39BBPN9in6rVFO ELWe1uW12jHel0+IfatuH9DEY3YdEk98KMmLyMaY3qJrhzyVOqNMktk8AIDe4hPKC6C8 AB6eqXcqT/unJfbbtBK2R3/aH/zdAISVhx7W/m+I+UqciInv/H6c93i8B5s/khR+6YBt eCcAK6jwJq6879A4b2qyA1XLoMuSYfNaVOTLnLF8ZlJic1ijaW9n2NohNU3ta97EsdlL GSfw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=GcP2topi; 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 j25-20020aa7de99000000b00425c2dd8b9asi3322772edv.296.2022.04.28.01.12.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:12:44 -0700 (PDT) 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=GcP2topi; 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 0822883EE6; Thu, 28 Apr 2022 10:11:44 +0200 (CEST) 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="GcP2topi"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id CBE2E834AD; Thu, 28 Apr 2022 10:11:11 +0200 (CEST) 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 autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pg1-x532.google.com (mail-pg1-x532.google.com [IPv6:2607:f8b0:4864:20::532]) (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 9F2DC834AD for ; Thu, 28 Apr 2022 10:11:05 +0200 (CEST) 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-pg1-x532.google.com with SMTP id 15so3387222pgf.4 for ; Thu, 28 Apr 2022 01:11:05 -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; bh=0EQ3MOONx8H9Vnow2CgVj7ug336Cl++Am4tz+bMuhPg=; b=GcP2topiwuxIQFkegS+heerL1pg3B3C3iSn7ZCgF5CIGj4i0S3yAVQ6LnQtAQ2wRQO 5JAsgCYfddyEJWsFbUX06LUdJfw0On4Hpz+4vDwDuxLQLQo0Pc954ZEja3RDiUENhnvH gNWE6uUS5VTVPFxJBDaneAolLY7gGp4yPK1wZeOn8OAcjmDB2Im+IXfHerN6a+Fh5Ap/ 8Dlnl/PG2kMH0h8RYxQwnbNNsoK9vjgdZpmrU51rpngO7eKIZ4+t8AOKCdl7sqxA2t0+ xj+osF7z1vsVehGOhMgzUX2KiTrdSL5HZmFcTu81L1LUpt9LysKGDAGNq89JRRqZMV3P aYFQ== 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=0EQ3MOONx8H9Vnow2CgVj7ug336Cl++Am4tz+bMuhPg=; b=XRoi9fhVCSJULkq+HKSobC8P8zd1gI7Nitr2YwdGf69SsPJgDH5jbp1KAqIFUzYGmG zmHtjfVUPC8B/ZhgHgFGUucCgz0JpcSS3x/BgCPhWtSvyQLKN3ipFytBFcI5xtpg6Ogj Qfwace9RzZ4PIx7MP/csZ8BO8ZivGaQJzGdZmnBST8Afxyh53w339vHQ4uTYZeoNytil vx/c04QQLCnhHvmi2PZT26U4T2bVcrL0ELT6kGMaVCFhgTJ6X9kiOvwTDYMK6FJco+6b EHGn7vVichi+N0GduSK3/2NCDyMfkrOriFBChVRp50np9a2KsclNYcjRgaxy3pRUiCx4 tbKg== X-Gm-Message-State: AOAM532Qset0LDJx6yXjiNgwP5+4Hzlox6rRLBz1URofTtkv9244DA7D PhlS9CkEfhgazH3CJjzY1turdPFgFIJBFQ== X-Received: by 2002:a65:4848:0:b0:39c:c393:688c with SMTP id i8-20020a654848000000b0039cc393688cmr26839228pgs.376.1651133463820; Thu, 28 Apr 2022 01:11:03 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id b15-20020a17090a7acf00b001cd4989ff5fsm5684259pjl.38.2022.04.28.01.11.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:11:03 -0700 (PDT) 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: [PATCH v5 10/17] bootmenu: add distro boot entry Date: Thu, 28 Apr 2022 17:09:43 +0900 Message-Id: <20220428080950.23509-11-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220428080950.23509-1-masahisa.kojima@linaro.org> References: <20220428080950.23509-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 adds the distro_boot entries into the bootmenu. The bootmenu read the "boot_targets" U-Boot environment variable and enumerate it. User can select the distro boot entry, then bootmenu executes "run bootcmd_xxx" command. The bootmenu also checks the existing block devices and network option("dhcp" and "pxe") availability, then filter out the "boot_targets" appeared in bootmenu. The bootmenu example is as follows, distro boot entry has the "distro_boot" prefix. *** U-Boot Boot Menu *** distro_boot : usb0 distro_boot : scsi0 distro_boot : virtio0 distro_boot : dhcp Signed-off-by: Masahisa Kojima --- Changes in v5: - split into the separate patch - add function description comment - handle the case boot_targets variable is empty - filter out the non-exist device entry cmd/bootmenu.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index da688e6213..afe42b8041 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -14,6 +15,7 @@ #include #include #include +#include #include #include @@ -31,6 +33,7 @@ enum boot_type { BOOTMENU_TYPE_NONE = 0, BOOTMENU_TYPE_BOOTMENU, BOOTMENU_TYPE_UEFI_BOOT_OPTION, + BOOTMENU_TYPE_DISTRO_BOOT, }; struct bootmenu_entry { @@ -90,6 +93,8 @@ static void bootmenu_print_entry(void *data) printf("bootmenu_%02d : %ls", entry->bootorder, entry->title); else if (entry->type == BOOTMENU_TYPE_UEFI_BOOT_OPTION) printf("UEFI BOOT%04X : %ls", entry->bootorder, entry->title); + else if (entry->type == BOOTMENU_TYPE_DISTRO_BOOT) + printf("distro_boot : %ls", entry->title); else printf("%ls", entry->title); @@ -465,6 +470,172 @@ static int prepare_uefi_bootorder_entry(struct bootmenu_data *menu, return 1; } +static int is_blk_device_available(char *token) +{ + struct driver *d = ll_entry_start(struct driver, driver); + const int n_ents = ll_entry_count(struct driver, driver); + struct driver *entry; + struct udevice *udev; + struct uclass *uc; + struct blk_desc *desc; + int ret, i; + const char *if_type_name; + + ret = uclass_get(UCLASS_BLK, &uc); + if (ret) + return -ENODEV; + + for (entry = d; entry < d + n_ents; entry++) { + if (entry->id != UCLASS_BLK) + continue; + i = 0; + uclass_foreach_dev(udev, uc) { + if (udev->driver != entry) + continue; + desc = dev_get_uclass_plat(udev); + if_type_name = blk_get_if_type_name(desc->if_type); + if (strncmp(token, if_type_name, strlen(if_type_name)) == 0) { + char *p; + int j, len; + int devnum = 0; + + p = token + strlen(if_type_name); + len = strlen(p); + if (!len) + continue; /* no device number */ + + for (j = 0; j < len; j++) { + if (!isdigit(*p)) { + /* invalid device number */ + devnum = INT_MAX; + break; + } + devnum = (devnum * 10) + (*p++ - '0'); + } + + if (devnum == INT_MAX) + continue; + + if (devnum == desc->devnum) + return 1; + } + } + } + + if (strncmp(token, "dhcp", strlen("dhcp")) == 0) { + if (IS_ENABLED(CONFIG_CMD_DHCP)) + return 1; + } + + if (strncmp(token, "pxe", strlen("pxe")) == 0) { + if (IS_ENABLED(CONFIG_CMD_PXE)) + return 1; + } + + return -ENODEV; +} + +/** + * prepare_distro_boot_entry() - generate the distro boot entries + * + * This function read the "boot_targets" U-Boot environment variable + * and generate the bootmenu entries. + * + * @menu: pointer to the bootmenu structure + * @current: pointer to the last bootmenu entry list + * @index: pointer to the index of the last bootmenu entry, + * the number of uefi entry is added by this function + * Return: 1 on success, negative value on error + */ +static int prepare_distro_boot_entry(struct bootmenu_data *menu, + struct bootmenu_entry **current, + unsigned short int *index) +{ + char *p; + int len; + char *token; + char *boot_targets; + unsigned short int i = *index; + struct bootmenu_entry *entry = NULL; + struct bootmenu_entry *iter = *current; + + /* list the distro boot "boot_targets" */ + boot_targets = env_get("boot_targets"); + if (!boot_targets) + return -ENOENT; + + len = strlen(boot_targets); + if (!len) + return -ENOENT; + + p = calloc(1, len + 1); + strlcpy(p, boot_targets, len); + + token = strtok(p, " "); + + do { + u16 *buf; + char *command; + int command_size; + + if (is_blk_device_available(token) != 1) { + token = strtok(NULL, " "); + continue; + } + + entry = malloc(sizeof(struct bootmenu_entry)); + if (!entry) { + free(p); + return -ENOMEM; + } + + len = strlen(token); + buf = calloc(1, (len + 1) * sizeof(u16)); + entry->title = buf; + if (!entry->title) { + free(entry); + free(p); + return -ENOMEM; + } + utf8_utf16_strncpy(&buf, token, len); + sprintf(entry->key, "%d", i); + entry->num = i; + entry->menu = menu; + + command_size = sizeof("run bootcmd_") + len; + command = calloc(1, command_size); + if (!command) { + free(entry->title); + free(entry); + free(p); + return -ENOMEM; + } + snprintf(command, command_size, "run bootcmd_%s", token); + entry->command = command; + entry->type = BOOTMENU_TYPE_DISTRO_BOOT; + entry->next = NULL; + + if (!iter) + menu->first = entry; + else + iter->next = entry; + + iter = entry; + i++; + + if (i == MAX_COUNT - 1) + break; + + token = strtok(NULL, " "); + } while (token); + + free(p); + *index = i; + *current = iter; + + return 1; +} + static struct bootmenu_data *bootmenu_create(int delay) { int ret; @@ -498,6 +669,12 @@ static struct bootmenu_data *bootmenu_create(int delay) } } + if (i < MAX_COUNT - 1) { + ret = prepare_distro_boot_entry(menu, &iter, &i); + if (ret < 0 && ret != -ENOENT) + goto cleanup; + } + /* Add U-Boot console entry at the end */ if (i <= MAX_COUNT - 1) { entry = malloc(sizeof(struct bootmenu_entry)); From patchwork Thu Apr 28 08:09: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: 567135 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:6886:0:0:0:0 with SMTP id m6csp5233363map; Thu, 28 Apr 2022 01:12:58 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwFxNEsyW2m7PQtzIUSwVsDisaEMReqympsKKizWAc/Bi5ZA1CF4cxLTDkQwew2h5Iyl3y0 X-Received: by 2002:a17:906:c114:b0:6f3:ad4c:c886 with SMTP id do20-20020a170906c11400b006f3ad4cc886mr13545227ejc.124.1651133578210; Thu, 28 Apr 2022 01:12:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1651133578; cv=none; d=google.com; s=arc-20160816; b=xqGFmuaz0QhU5xA7lvA4kNCMsa8YCEadg1KRHYFDDWh1PEHR5lToLq0o3j8InUeBuJ aAoJTaPl1b2T/Oa9ZrcEwrF0CIirMNepMhMr7o4cq6SmTdin3Tm/w0uIAxQu3Z8eiFUu OafKui9PGW3uGJfi9GgZzWatmV92pddoj7uIXdZO+kx99OAts04Ciq2v3u5IB7UN6QRT H7sSzbcEOGOcvgldsdqSS5VRyqnKcgyRY4QRLq5lwlvzMtRDl069Ma6bWjRd/+RDXrG9 20OisuFlob16bLPyjHl7T7/G0h/HjsD+pnlrtQf1MuBs3NBHu6EUtYDXMORn+mN/hDJT PhFg== 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=x6/5QQUKffmkn89OIbMNZWa+hTgla18bSqTlHz9+c/M=; b=HW63Wq5cHrceqFh6E+xAvPmIKfVjS+gTTf5HNUbKd3yBh0AGDS5M+LeNt8fyK5w7Ib 13pz5vA0/YHUu2IXYT5QwcOPCE4a+xdOeLnbz3KJt7kw60SSzZU5B2bZoQ4wZ+OFMRIL 0ui/FpjjYEq+Q7bqeAUfjJzDeffgEK5GzmfP1ctuJlzo+n/BZLmb9RKy5IHZJEybPtky BlsKYEJqXp64CRZVQPiPTvaXVxd2munuwiP+oKLbVgF0jaKUrw00BfHVg0wbcj4uj1gh ZEpnO9IIZmB2/YwUX14cAe06lihe3QTq/QIsK79NB1s6g3yjUtGS0wFO083Z95Oh7v4p ti1A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=NWEuT1kd; 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 i15-20020a17090639cf00b006f3a813732dsi3423014eje.605.2022.04.28.01.12.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:12:58 -0700 (PDT) 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=NWEuT1kd; 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 046C983EF7; Thu, 28 Apr 2022 10:11:48 +0200 (CEST) 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="NWEuT1kd"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id AC32E834AD; Thu, 28 Apr 2022 10:11:14 +0200 (CEST) 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 autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pj1-x1035.google.com (mail-pj1-x1035.google.com [IPv6:2607:f8b0:4864:20::1035]) (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 6978783ECB for ; Thu, 28 Apr 2022 10:11:09 +0200 (CEST) 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-x1035.google.com with SMTP id cu23-20020a17090afa9700b001d98d8e53b7so5572736pjb.0 for ; Thu, 28 Apr 2022 01:11:09 -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; bh=x6/5QQUKffmkn89OIbMNZWa+hTgla18bSqTlHz9+c/M=; b=NWEuT1kdZ77pK4Gxe5bmtw/DGl+OG4Z/6HP0W1vi7lhTgGbRKboqjJSXk9v8n3sRs7 o4guHjeVr7NmJUCIsX62UjAaNygGgdhwYVvMVGYVxWIIaHl1fGGQgXV0unX/EpR+aqll qUY2oKBfseoAvUjil2XXjp6bMqMxqhvvGc9xPouHi9lgwVQOigfe0hvB8TgteOk7ypmG 05bKf7eQ8XA2GU5D/lrmxlGwqTSc062nLxv3P4d36+gl8MNoqerqbHTo7C5gk/NJtkff rlOpCxVpBdog7CjMR+ndNlBFwpMdGd9eTBY/VzB5Fw6N50bveyr1qeGpgGnXysI9rhak a32Q== 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=x6/5QQUKffmkn89OIbMNZWa+hTgla18bSqTlHz9+c/M=; b=G1glI18yEFDnFjAr4W3LPR8dmjI2DdADX0pOlfHOSHCZ5q9OVQLqj8Bup9OL5sFsBg WoVGAah/qLJ0/HuX1CLPeoc1p30T0ajs1N7vh1lcbD2GfPRk6TeJhooOQJvP0DQ/vJYb OlMjfsOPiMjRj9TLOEcs1/lUulS4yoeBvVD8P/cJ1ezRBgZobKjBQGmQVygy6m9t9j4S 3xSeO3Y5UoHNQnH3UVaAnu8WKV1QlhWL2xxBa3Yd60sF0aSVfcPW2mXockNrIIoi49F3 Cv0F9efoxPhIodlaUGDQmOsaYQ2Mmy6FTucHo4De5ixHUbld0/LUx8+041LRaudoLgKU ENQw== X-Gm-Message-State: AOAM533tQYCA3knokLS7Zoc8/EWtGz2tytYrFA3wfgL5gGOjCUadku1z tYwwiPiGCnbyWzquawHwgAjBWRpOhQltPg== X-Received: by 2002:a17:90a:a090:b0:1cb:a443:f19c with SMTP id r16-20020a17090aa09000b001cba443f19cmr38058694pjp.135.1651133467613; Thu, 28 Apr 2022 01:11:07 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id b15-20020a17090a7acf00b001cd4989ff5fsm5684259pjl.38.2022.04.28.01.11.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:11:07 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Francois Ozog , Mark Kettenis , Masahisa Kojima , Michal Simek , Kory Maincent , Ovidiu Panait , Ashok Reddy Soma Subject: [PATCH v5 11/17] bootmenu: add Kconfig option not to enter U-Boot console Date: Thu, 28 Apr 2022 17:09:44 +0900 Message-Id: <20220428080950.23509-12-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220428080950.23509-1-masahisa.kojima@linaro.org> References: <20220428080950.23509-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 adds the Kconfig option to disable to enter the U-Boot console from bootmenu. If CMD_BOOTMENU_ENTER_UBOOT_CONSOLE is enabled, "U-Boot console" entry is appeared as the last entry in the bootmenu, then user can enter U-Boot console. If CMD_BOOTMENU_ENTER_UBOOT_CONSOLE is disabled, "Quit" entry is appeared as the last entry instead of "U-Boot console". When user chooses "Quit" from bootmenu, the following default commands are invoked. - "bootefi bootmgr" (if efi bootmgr is enabled) - "run bootcmd" If the both commands are executed and returns to the bootmenu, the bootmenu will appears again. Signed-off-by: Masahisa Kojima --- Changes in v5: - split into the separate patch - clear the console when user select "U-Boot console" - if the console is disabled, the last entry title is "Quit" cmd/Kconfig | 10 ++++++++ cmd/bootmenu.c | 69 ++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 68 insertions(+), 11 deletions(-) diff --git a/cmd/Kconfig b/cmd/Kconfig index 2b575a2b42..99a1435467 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -356,6 +356,16 @@ config CMD_BOOTMENU help Add an ANSI terminal boot menu command. +config CMD_BOOTMENU_ENTER_UBOOT_CONSOLE + bool "Allow Bootmenu to enter the U-Boot console" + depends on CMD_BOOTMENU + default n + help + Add an entry to enter U-Boot console in bootmenu. + If this option is disabled, user can not enter + the U-Boot console from bootmenu. It increases + the system security. + config CMD_ADTIMG bool "adtimg" help diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index afe42b8041..bfbb1b5248 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -29,6 +29,13 @@ */ #define MAX_ENV_SIZE (9 + 2 + 1) +enum bootmenu_ret { + BOOTMENU_RET_SUCCESS = 0, + BOOTMENU_RET_FAIL, + BOOTMENU_RET_QUIT, + BOOTMENU_RET_UPDATED, +}; + enum boot_type { BOOTMENU_TYPE_NONE = 0, BOOTMENU_TYPE_BOOTMENU, @@ -681,7 +688,12 @@ static struct bootmenu_data *bootmenu_create(int delay) if (!entry) goto cleanup; - entry->title = u16_strdup(u"U-Boot console"); + /* Add Quit entry if entering U-Boot console is disabled */ + if (IS_ENABLED(CONFIG_CMD_BOOTMENU_ENTER_UBOOT_CONSOLE)) + entry->title = u16_strdup(u"U-Boot console"); + else + entry->title = u16_strdup(u"Quit"); + if (!entry->title) { free(entry); goto cleanup; @@ -777,15 +789,17 @@ static void handle_uefi_bootnext(void) run_command("bootefi bootmgr", 0); } -static void bootmenu_show(int delay) +static enum bootmenu_ret bootmenu_show(int delay) { + int cmd_ret; int init = 0; void *choice = NULL; u16 *title = NULL; char *command = NULL; struct menu *menu; - struct bootmenu_data *bootmenu; struct bootmenu_entry *iter; + int ret = BOOTMENU_RET_SUCCESS; + struct bootmenu_data *bootmenu; efi_status_t efi_ret = EFI_SUCCESS; char *option, *sep; @@ -797,27 +811,27 @@ static void bootmenu_show(int delay) option = bootmenu_getoption(0); if (!option) { puts("bootmenu option 0 was not found\n"); - return; + return BOOTMENU_RET_FAIL; } sep = strchr(option, '='); if (!sep) { puts("bootmenu option 0 is invalid\n"); - return; + return BOOTMENU_RET_FAIL; } - run_command(sep+1, 0); - return; + cmd_ret = run_command(sep + 1, 0); + return (cmd_ret == CMD_RET_SUCCESS ? BOOTMENU_RET_SUCCESS : BOOTMENU_RET_FAIL); } bootmenu = bootmenu_create(delay); if (!bootmenu) - return; + return BOOTMENU_RET_FAIL; menu = menu_create(NULL, bootmenu->delay, 1, menu_display_statusline, bootmenu_print_entry, bootmenu_choice_entry, bootmenu); if (!menu) { bootmenu_destroy(bootmenu); - return; + return BOOTMENU_RET_FAIL; } for (iter = bootmenu->first; iter; iter = iter->next) { @@ -838,6 +852,14 @@ static void bootmenu_show(int delay) iter = choice; title = u16_strdup(iter->title); command = strdup(iter->command); + + /* last entry is U-Boot console or Quit */ + if (iter->num == iter->menu->count - 1) { + ret = BOOTMENU_RET_QUIT; + goto cleanup; + } + } else { + goto cleanup; } /* @@ -875,19 +897,44 @@ cleanup: debug("Starting entry '%ls'\n", title); free(title); if (efi_ret == EFI_SUCCESS) - run_command(command, 0); + cmd_ret = run_command(command, 0); free(command); } #ifdef CONFIG_POSTBOOTMENU run_command(CONFIG_POSTBOOTMENU, 0); #endif + + if (efi_ret != EFI_SUCCESS || cmd_ret != CMD_RET_SUCCESS) + ret = BOOTMENU_RET_FAIL; + + return ret; } #ifdef CONFIG_AUTOBOOT_MENU_SHOW int menu_show(int bootdelay) { - bootmenu_show(bootdelay); + int ret; + + while (1) { + ret = bootmenu_show(bootdelay); + bootdelay = -1; + if (ret == BOOTMENU_RET_UPDATED) + continue; + + if (!IS_ENABLED(CONFIG_CMD_BOOTMENU_ENTER_UBOOT_CONSOLE)) { + if (ret == BOOTMENU_RET_QUIT) { + /* default boot process */ + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) + run_command("bootefi bootmgr", 0); + + run_command("run bootcmd", 0); + } + } else { + break; + } + } + return -1; /* -1 - abort boot and run monitor code */ } #endif From patchwork Thu Apr 28 08:09:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 567137 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:6886:0:0:0:0 with SMTP id m6csp5233580map; Thu, 28 Apr 2022 01:13:22 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzbzneAyEUITj14Ixq5ba/RukEaWx/6EG/6Mjo5YyEidiv93V7AIRpUyUmExPw8g6O6MP0A X-Received: by 2002:a17:907:728c:b0:6e8:a052:4f03 with SMTP id dt12-20020a170907728c00b006e8a0524f03mr29619871ejc.344.1651133602587; Thu, 28 Apr 2022 01:13:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1651133602; cv=none; d=google.com; s=arc-20160816; b=xyvvhyXRtXkPMzrSz9zjuhZmYZq7p6V4et/CiF2wzHE5vBOawk7cwdiKTrRz/jYmNA JdGSHBgHH0MScgIQt68KYWIN3sEPVTzR5+P4hgHwuqMNP0NQcB2v5NJSqS3cTy66e8Oj 6tUV/58gwyykaV943wCcY+foayzt35ragULePD3Je0uUTWWPCQh4xzMqp68ZkVrmTzkr rlwmPC+JYriTHiRGJ6g5nM5jatmPjWBoiA4YJ6VYoZSM0oT9SGvfolrngVdj3E6spvjh DxLbMCg5GGAD30X9f+WDh4t04qd5D/rBHdPpYEEGiiqYze/4Rew1V7POG/jjZUMl6gHE PmEQ== 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=zBDapxkVgOA+Ow6v/YmlE9HXGz7la71K6woowRKURzI=; b=qsVzNHDKiL3bNZ7TVW/wCq54IRnNkIS/GExoyJua2+puG1drnNfBRXRSUK8QIR7um1 uPojQRpxB64XBTGQwEuiHDAVNN9hBISy2tlLIPoUkvC9LAmPG4ix3EZJHLqL7kdMf6Lg 3BlmzitsnUMyPujOCAGjJBdDKG9x4YSpG6YzpTORClokSUWXeAIKZNbayLUz+33YWSvS kmXXcLwErKXsO6mqMIKE5woscjay8S03hyxJWM6cr7bnC+C5g5EEh+tQ4gPm0S+HrNGo T6s4JYMD/4e0m2ezJ+iWFnqaVgVfnVJ3Wb/OhJwL+Q7z9/3FyjFIVWykIwVTSaiDKWGF wRNg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Z9yp3kJu; 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 i9-20020a508709000000b00423c3e6e1e0si3428042edb.567.2022.04.28.01.13.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:13:22 -0700 (PDT) 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=Z9yp3kJu; 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 38A0D81DB4; Thu, 28 Apr 2022 10:12:44 +0200 (CEST) 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="Z9yp3kJu"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id A2A8383EE2; Thu, 28 Apr 2022 10:11:25 +0200 (CEST) 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 autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pl1-x62a.google.com (mail-pl1-x62a.google.com [IPv6:2607:f8b0:4864:20::62a]) (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 656CA834AD for ; Thu, 28 Apr 2022 10:11:12 +0200 (CEST) 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-x62a.google.com with SMTP id b12so3697432plg.4 for ; Thu, 28 Apr 2022 01:11:12 -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; bh=zBDapxkVgOA+Ow6v/YmlE9HXGz7la71K6woowRKURzI=; b=Z9yp3kJu1fiIxqA4Pd37Zo/YF893cKd3OCHyUqikAQ6r8xlag00YmVphJR0pCM0aL1 C4kYkYpxL+ryGiLoygNVziQQjvADQJehWw+TW6KlbvwP+vmV+O5/8RcIdXTgh005hHd2 HyRyhSyUFxXBu7vlS06+DO+BGBGQwRohaJVbfpHoEqeNXYm+q6lSlOFvhHuEqWDTWR4w mESDp3msn0kYGylz64RQi6mrc5v/BG2X+PSMPVCOe0jlfkiorHzo9NQjNYK53Xz0euif iCh5F2oIFolZgtJpZpYnEO5NCx5XhCM8/bhuEo4b4LLSyOmMkOLUtBfgPBagFnGJnWTg sOzQ== 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=zBDapxkVgOA+Ow6v/YmlE9HXGz7la71K6woowRKURzI=; b=m9TgGhA5RTI9QKqAPx8xubDSxDMpAnAwGZcMhHc0PQqjofIbCkRv3+hIpPsn80OraI 5TZdItyzeDkMlbcmgW3moAWh1JYgdWL16rmvWkWyGwnAz4R4kWVpJG6EgvUKyUZ6pLCP f3tfhK41MkosEgPK9215fjgdGV7uD+X9VBEIvTIo3z90phDcz5How/eEjbOSwblq6ZAV OGd90KeeG0Y6IhUkgbi8xTrFsGdU0CxtngLcmXJ6myvYr81+pYF+BlKou+bcYUpsfla6 jWrh21ggJ4m+lzI+PzW5lqG7nRT5pP2J7wmSl+MOB171WMKO4It29TW0H6Axi5jWEtvW 8CdA== X-Gm-Message-State: AOAM532jbXDklHix3ufsbGhEnU1SS6+XwSqaEf0Ga3nbX97fzNdyrOTe b+qfK252yrcu3LRnrN2PtMHLP7TCtrS2Ng== X-Received: by 2002:a17:90b:1b4f:b0:1d2:a09e:1fc6 with SMTP id nv15-20020a17090b1b4f00b001d2a09e1fc6mr47907553pjb.147.1651133470625; Thu, 28 Apr 2022 01:11:10 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id b15-20020a17090a7acf00b001cd4989ff5fsm5684259pjl.38.2022.04.28.01.11.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:11:10 -0700 (PDT) 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: [PATCH v5 12/17] bootmenu: factor out the user input handling Date: Thu, 28 Apr 2022 17:09:45 +0900 Message-Id: <20220428080950.23509-13-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220428080950.23509-1-masahisa.kojima@linaro.org> References: <20220428080950.23509-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 moves the user input handling from cmd/bootmenu.c to common/menu.c to reuse it from other modules. Signed-off-by: Masahisa Kojima --- No change since v4 Newly created in v4. cmd/bootmenu.c | 149 ------------------------------------------------- common/menu.c | 137 +++++++++++++++++++++++++++++++++++++++++++++ include/menu.h | 20 +++++++ 3 files changed, 157 insertions(+), 149 deletions(-) diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index bfbb1b5248..eb23afdd41 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -54,21 +54,6 @@ struct bootmenu_entry { struct bootmenu_entry *next; /* next menu entry (num+1) */ }; -struct bootmenu_data { - int delay; /* delay for autoboot */ - int active; /* active menu entry */ - int count; /* total count of menu entries */ - struct bootmenu_entry *first; /* first menu entry */ -}; - -enum bootmenu_key { - KEY_NONE = 0, - KEY_UP, - KEY_DOWN, - KEY_SELECT, - KEY_QUIT, -}; - static char *bootmenu_getoption(unsigned short int n) { char name[MAX_ENV_SIZE]; @@ -109,140 +94,6 @@ static void bootmenu_print_entry(void *data) puts(ANSI_COLOR_RESET); } -static void bootmenu_autoboot_loop(struct bootmenu_data *menu, - enum bootmenu_key *key, int *esc) -{ - 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); - } - - while (menu->delay > 0) { - for (i = 0; i < 100; ++i) { - if (!tstc()) { - WATCHDOG_RESET(); - mdelay(10); - continue; - } - - menu->delay = -1; - c = getchar(); - - switch (c) { - case '\e': - *esc = 1; - *key = KEY_NONE; - break; - case '\r': - *key = KEY_SELECT; - break; - case 0x3: /* ^C */ - *key = KEY_QUIT; - break; - default: - *key = KEY_NONE; - break; - } - - break; - } - - if (menu->delay < 0) - break; - - --menu->delay; - printf("\b\b\b%2d ", menu->delay); - } - - printf(ANSI_CURSOR_POSITION, menu->count + 5, 1); - puts(ANSI_CLEAR_LINE); - - if (menu->delay == 0) - *key = KEY_SELECT; -} - -static void bootmenu_loop(struct bootmenu_data *menu, - enum bootmenu_key *key, int *esc) -{ - int c; - - if (*esc == 1) { - if (tstc()) { - c = getchar(); - } else { - WATCHDOG_RESET(); - mdelay(10); - if (tstc()) - c = getchar(); - else - c = '\e'; - } - } else { - while (!tstc()) { - WATCHDOG_RESET(); - mdelay(10); - } - c = getchar(); - } - - switch (*esc) { - case 0: - /* First char of ANSI escape sequence '\e' */ - if (c == '\e') { - *esc = 1; - *key = KEY_NONE; - } - break; - case 1: - /* Second char of ANSI '[' */ - if (c == '[') { - *esc = 2; - *key = KEY_NONE; - } else { - /* Alone ESC key was pressed */ - *key = KEY_QUIT; - *esc = (c == '\e') ? 1 : 0; - } - break; - case 2: - case 3: - /* Third char of ANSI (number '1') - optional */ - if (*esc == 2 && c == '1') { - *esc = 3; - *key = KEY_NONE; - break; - } - - *esc = 0; - - /* ANSI 'A' - key up was pressed */ - if (c == 'A') - *key = KEY_UP; - /* ANSI 'B' - key down was pressed */ - else if (c == 'B') - *key = KEY_DOWN; - /* other key was pressed */ - else - *key = KEY_NONE; - - break; - } - - /* enter key was pressed */ - if (c == '\r') - *key = KEY_SELECT; - - /* ^C was pressed */ - if (c == 0x3) - *key = KEY_QUIT; -} - static char *bootmenu_choice_entry(void *data) { struct bootmenu_data *menu = data; diff --git a/common/menu.c b/common/menu.c index 4118c6dc3c..53b026b52e 100644 --- a/common/menu.c +++ b/common/menu.c @@ -4,11 +4,14 @@ * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. */ +#include #include #include #include #include +#include #include +#include #include "menu.h" @@ -421,3 +424,137 @@ int menu_destroy(struct menu *m) return 1; } + +void bootmenu_autoboot_loop(struct bootmenu_data *menu, + enum bootmenu_key *key, int *esc) +{ + 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); + } + + while (menu->delay > 0) { + for (i = 0; i < 100; ++i) { + if (!tstc()) { + WATCHDOG_RESET(); + mdelay(10); + continue; + } + + menu->delay = -1; + c = getchar(); + + switch (c) { + case '\e': + *esc = 1; + *key = KEY_NONE; + break; + case '\r': + *key = KEY_SELECT; + break; + case 0x3: /* ^C */ + *key = KEY_QUIT; + break; + default: + *key = KEY_NONE; + break; + } + + break; + } + + if (menu->delay < 0) + break; + + --menu->delay; + printf("\b\b\b%2d ", menu->delay); + } + + printf(ANSI_CURSOR_POSITION, menu->count + 5, 1); + puts(ANSI_CLEAR_LINE); + + if (menu->delay == 0) + *key = KEY_SELECT; +} + +void bootmenu_loop(struct bootmenu_data *menu, + enum bootmenu_key *key, int *esc) +{ + int c; + + if (*esc == 1) { + if (tstc()) { + c = getchar(); + } else { + WATCHDOG_RESET(); + mdelay(10); + if (tstc()) + c = getchar(); + else + c = '\e'; + } + } else { + while (!tstc()) { + WATCHDOG_RESET(); + mdelay(10); + } + c = getchar(); + } + + switch (*esc) { + case 0: + /* First char of ANSI escape sequence '\e' */ + if (c == '\e') { + *esc = 1; + *key = KEY_NONE; + } + break; + case 1: + /* Second char of ANSI '[' */ + if (c == '[') { + *esc = 2; + *key = KEY_NONE; + } else { + /* Alone ESC key was pressed */ + *key = KEY_QUIT; + *esc = (c == '\e') ? 1 : 0; + } + break; + case 2: + case 3: + /* Third char of ANSI (number '1') - optional */ + if (*esc == 2 && c == '1') { + *esc = 3; + *key = KEY_NONE; + break; + } + + *esc = 0; + + /* ANSI 'A' - key up was pressed */ + if (c == 'A') + *key = KEY_UP; + /* ANSI 'B' - key down was pressed */ + else if (c == 'B') + *key = KEY_DOWN; + /* other key was pressed */ + else + *key = KEY_NONE; + + break; + } + + /* enter key was pressed */ + if (c == '\r') + *key = KEY_SELECT; + + /* ^C was pressed */ + if (c == 0x3) + *key = KEY_QUIT; +} diff --git a/include/menu.h b/include/menu.h index ad5859437e..e74616cae8 100644 --- a/include/menu.h +++ b/include/menu.h @@ -35,4 +35,24 @@ int menu_default_choice(struct menu *m, void **choice); */ int menu_show(int bootdelay); +struct bootmenu_data { + int delay; /* delay for autoboot */ + int active; /* active menu entry */ + int count; /* total count of menu entries */ + struct bootmenu_entry *first; /* first menu entry */ +}; + +enum bootmenu_key { + KEY_NONE = 0, + KEY_UP, + KEY_DOWN, + KEY_SELECT, + KEY_QUIT, +}; + +void bootmenu_autoboot_loop(struct bootmenu_data *menu, + enum bootmenu_key *key, int *esc); +void bootmenu_loop(struct bootmenu_data *menu, + enum bootmenu_key *key, int *esc); + #endif /* __MENU_H__ */ From patchwork Thu Apr 28 08:09:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 567139 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:6886:0:0:0:0 with SMTP id m6csp5233796map; Thu, 28 Apr 2022 01:13:48 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzLCe5JeS19HhVLj2fe67GVSvIKmmC2BmrJ53ggWE7Df+xPNlsmitI1aQ7uUXnA0S5Yop+V X-Received: by 2002:a05:6402:5189:b0:423:f342:e0ce with SMTP id q9-20020a056402518900b00423f342e0cemr34761513edd.120.1651133627950; Thu, 28 Apr 2022 01:13:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1651133627; cv=none; d=google.com; s=arc-20160816; b=xF7b9iuQ3j5SjHX5UFEKKQxEi3u3eiD8Gn16Racdj1Ss825MHIPj+tZJ2BTi0Jtoke 92bzTWsBeHKNjQ13KYHNm9gXxCtiLLd2hh+AtFubsZJjRj3DN55AMlTlPdEuZEfpq2Kp x6A+i7HYMjs95m+jrEFGjzAY1WJUzk5s9gg2otlneGy6t2YZ2XrymzXyetE6i59YKeti 3mZYov7W8D690P3OMsEjqAlO/fpLz2oEWIcUIQ57gI/MYZBtg6HmC44v01eavEIXulYa EqTL8BFRmNK2gMz9bgi00i0dNwv2us3eWS4vYRwQNKJKsi1rXLUCAYybdDsX42oJMoyh nV7w== 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=Suq2Lney715GAw3FGAYy+OBA+qoTKJwvlh6BwIPQtds=; b=lLSBw1VKvRXBE2OApUjM7zI/3x4grdFXSvMSV27PCy6WxVPN4npiH+asUGcJCKshYy iZ2dTGzHX894f9oLJKq4g+dDyojmH+O55D+KG2dFZwP552lIzVxhGN/uCUMcBsF8koVZ Y7uAvRR9CgY4zk/wodidrJfVLf7P9dptPkAD0RgO13ATrFfb2Y6u7dbAK2xRZ38xIZYs IOlnuYiMyq/QffIZHhc3K2QIAAMIWOgc8ZsCGVzIt8ZVbtEo7yXZFgK63ADsrtbDBmj8 ito89bnN152c7APrrlMdU1frrSlFpuYjVC0zJgXiQu3GkY6+EhcNl4tRTFXpH3ng4gBE 532A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="X91/u28q"; 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 dk16-20020a0564021d9000b00425f22cc019si3315221edb.210.2022.04.28.01.13.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:13:47 -0700 (PDT) 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="X91/u28q"; 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 391DA83F0F; Thu, 28 Apr 2022 10:12:51 +0200 (CEST) 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="X91/u28q"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 4F64683EEE; Thu, 28 Apr 2022 10:11:31 +0200 (CEST) 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 autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pf1-x42d.google.com (mail-pf1-x42d.google.com [IPv6:2607:f8b0:4864:20::42d]) (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 6DBF383565 for ; Thu, 28 Apr 2022 10:11:16 +0200 (CEST) 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-pf1-x42d.google.com with SMTP id y38so3624584pfa.6 for ; Thu, 28 Apr 2022 01:11:16 -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; bh=Suq2Lney715GAw3FGAYy+OBA+qoTKJwvlh6BwIPQtds=; b=X91/u28qt0mUkmet3eUgz0nSXO99ljVt6sP4IMPef9MDe/PuRvQe4AMyhgDWY5Zdb6 Htr3N5ka1jMlKpNgy31dA7UuU4+Aev917ci8Sa5XoMIjoH6HnwNWRP4oCrnBGQlDDRbE SK7rBA8FA+3nKSOr7eb2AiqpSGstY71k3wgnAKMhPcGo3BqeJnl+AzXrHn2ywutwvohy EYJhrK1Ai6KlbHaFWWz2n3posa7VEIQvNdwrvvIJjTTkinylQeBQekaItn2iI/5+KaAz qzYKM2msjw3hd4KGtUNOXatzPPE28yV3ja6ptd201Y0oIsx/tIaTFLkuKEmBfOmuTT0e SLsA== 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=Suq2Lney715GAw3FGAYy+OBA+qoTKJwvlh6BwIPQtds=; b=ijFCCDeMM0KdypV4vWjDeyWvb+FVSDd+sq2SJkXOge0kzwaPpIvHZ/8PnoLSpiB8oP pVOWrljTWizFOkKrH2sbsHjhLQZpyENUkBzg2ETUypc5B6QNRELnnQgYjVYaFheALJm8 jYlif3z+jD8jc6cWrfuCQgeeOm9/VsF67TdAmQ9uxsEm7B6pAOKxTQ/5ERZ6w8YwPsf/ eQulknI+Ebtu0WCe+Alz7CjfzUZsfjmFeR99stNsu0M6RYip0xnVZ51JUpfbGkt35XjJ HJO5QPtrpiyAv6I1FolocEKFQN7CfY5STIE6MH953aKWyIU6VlrXRbhF6H4lYzI0vinM eIkg== X-Gm-Message-State: AOAM530blnv1Ov0OVhqsfBLOFU8SaYQ8SXbNAIPhSgoZ7WVcIb6NFwLK ytO9hrXXjdYcciy0MPR02UIO7h5NXoy7Vw== X-Received: by 2002:a63:4862:0:b0:385:fb1d:fc54 with SMTP id x34-20020a634862000000b00385fb1dfc54mr27326876pgk.57.1651133473971; Thu, 28 Apr 2022 01:11:13 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id b15-20020a17090a7acf00b001cd4989ff5fsm5684259pjl.38.2022.04.28.01.11.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:11:13 -0700 (PDT) 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: [PATCH v5 13/17] efi_loader: menu-driven addition of UEFI boot option Date: Thu, 28 Apr 2022 17:09:46 +0900 Message-Id: <20220428080950.23509-14-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220428080950.23509-1-masahisa.kojima@linaro.org> References: <20220428080950.23509-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 supports the menu-driven UEFI boot option addition. User can select the block device volume having efi_simple_file_system_protocol and select the file corresponding to the Boot#### variable. Then user enter the label of the BOOT#### variable in utf8. Signed-off-by: Masahisa Kojima --- Changes in v5: - remove forward declarations - add const qualifier for menu items - fix the possible unaligned access for directory info access - split into three commit 1)add boot option 2) delete boot option 3)change boot order This commit is 1)add boot option. - fix file name buffer allocation size, it should be EFI_BOOTMENU_FILE_PATH_MAX * sizeof(u16) - fix wrong size checking for file selection Chanes in v4: - UEFI boot option maintenance menu is integrated into bootmenu - display the simplified volume name(e.g. usb0:1, nvme1:2) for the volume selection - instead of extending lib/efi_loader/efi_bootmgr.c, newly create lib/efi_loader/efi_bootmenu_maintenance.c and implement boot variable maintenance into it. Changes in RFC v3: not included in v3 series Changes in RFC v2: - enable utf8 user input for boot option name - create lib/efi_loader/efi_console.c::efi_console_get_u16_string() for utf8 user input handling - use u16_strlcat instead of u16_strcat - remove the EFI_CALLs, and newly create or expose the following xxx_int() functions. efi_locate_handle_buffer_int(), efi_open_volume_int(), efi_file_open_int(), efi_file_close_int(), efi_file_read_int() and efi_file_setpos_int(). Note that EFI_CALLs still exist for EFI_DEVICE_PATH_TO_TEXT_PROTOCOL and EFI_SIMPLE_TEXT_INPUT/OUTPUT_PROTOCOL - use efi_search_protocol() instead of calling locate_protocol() to get the device_path_to_text_protocol interface. - remove unnecessary puts(ANSI_CLEAR_LINE), this patch is still depends on puts(ANSI_CLEAR_CONSOLE) - skip SetVariable() if the bootorder is not changed cmd/bootmenu.c | 69 +- include/efi_loader.h | 37 + lib/efi_loader/Makefile | 1 + lib/efi_loader/efi_bootmenu_maintenance.c | 862 ++++++++++++++++++++++ lib/efi_loader/efi_boottime.c | 52 +- lib/efi_loader/efi_console.c | 81 ++ lib/efi_loader/efi_disk.c | 11 + lib/efi_loader/efi_file.c | 75 +- 8 files changed, 1133 insertions(+), 55 deletions(-) create mode 100644 lib/efi_loader/efi_bootmenu_maintenance.c diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index eb23afdd41..860cb83182 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -21,6 +21,8 @@ /* maximum bootmenu entries */ #define MAX_COUNT 99 +#define STATIC_ENTRY 2 +#define MAX_DYNAMIC_ENTRY (MAX_COUNT - STATIC_ENTRY) /* maximal size of bootmenu env * 9 = strlen("bootmenu_") @@ -41,10 +43,11 @@ enum boot_type { BOOTMENU_TYPE_BOOTMENU, BOOTMENU_TYPE_UEFI_BOOT_OPTION, BOOTMENU_TYPE_DISTRO_BOOT, + BOOTMENU_TYPE_UEFI_MAINTENANCE, }; struct bootmenu_entry { - unsigned short int num; /* unique number 0 .. MAX_COUNT */ + unsigned short int num; /* unique number 0 .. MAX_DYNAMIC_ENTRY */ char key[3]; /* key identifier of number */ u16 *title; /* title of entry */ char *command; /* hush command of entry */ @@ -58,7 +61,7 @@ static char *bootmenu_getoption(unsigned short int n) { char name[MAX_ENV_SIZE]; - if (n > MAX_COUNT) + if (n > MAX_DYNAMIC_ENTRY) return NULL; sprintf(name, "bootmenu_%d", n); @@ -229,7 +232,7 @@ static int prepare_bootmenu_entry(struct bootmenu_data *menu, iter = entry; ++i; - if (i == MAX_COUNT - 1) + if (i == MAX_DYNAMIC_ENTRY) break; } @@ -317,7 +320,7 @@ static int prepare_uefi_bootorder_entry(struct bootmenu_data *menu, free(load_option); - if (i == MAX_COUNT - 1) + if (i == MAX_DYNAMIC_ENTRY) break; } @@ -481,7 +484,7 @@ static int prepare_distro_boot_entry(struct bootmenu_data *menu, iter = entry; i++; - if (i == MAX_COUNT - 1) + if (i == MAX_DYNAMIC_ENTRY) break; token = strtok(NULL, " "); @@ -520,19 +523,56 @@ static struct bootmenu_data *bootmenu_create(int delay) goto cleanup; if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) { - if (i < MAX_COUNT - 1) { + if (i < MAX_DYNAMIC_ENTRY) { ret = prepare_uefi_bootorder_entry(menu, &iter, &i); if (ret < 0 && ret != -ENOENT) goto cleanup; } } - if (i < MAX_COUNT - 1) { + if (i < MAX_DYNAMIC_ENTRY) { ret = prepare_distro_boot_entry(menu, &iter, &i); if (ret < 0 && ret != -ENOENT) goto cleanup; } + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) { + /* Add UEFI Boot Manager Maintenance entry */ + if (i <= MAX_DYNAMIC_ENTRY) { + 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(""); + if (!entry->command) { + free(entry->title); + free(entry); + goto cleanup; + } + + sprintf(entry->key, "%d", i); + + entry->num = i; + entry->menu = menu; + entry->type = BOOTMENU_TYPE_UEFI_MAINTENANCE; + entry->next = NULL; + + if (!iter) + menu->first = entry; + else + iter->next = entry; + + iter = entry; + i++; + } + } + /* Add U-Boot console entry at the end */ if (i <= MAX_COUNT - 1) { entry = malloc(sizeof(struct bootmenu_entry)); @@ -704,6 +744,12 @@ static enum bootmenu_ret bootmenu_show(int delay) title = u16_strdup(iter->title); command = strdup(iter->command); + if (iter->type == BOOTMENU_TYPE_UEFI_MAINTENANCE) { + efi_bootmenu_show_maintenance_menu(); + ret = BOOTMENU_RET_UPDATED; + goto cleanup; + } + /* last entry is U-Boot console or Quit */ if (iter->num == iter->menu->count - 1) { ret = BOOTMENU_RET_QUIT; @@ -794,6 +840,7 @@ int do_bootmenu(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { char *delay_str = NULL; int delay = 10; + int ret; #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) delay = CONFIG_BOOTDELAY; @@ -808,7 +855,13 @@ int do_bootmenu(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) if (delay_str) delay = (int)simple_strtol(delay_str, NULL, 10); - bootmenu_show(delay); + while (1) { + ret = bootmenu_show(delay); + delay = -1; + if (ret != BOOTMENU_RET_UPDATED) + break; + } + return 0; } diff --git a/include/efi_loader.h b/include/efi_loader.h index effb43369d..533618341b 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -226,6 +226,9 @@ const char *__efi_nesting_dec(void); #define EFI_CACHELINE_SIZE 128 #endif +/* max bootmenu title size for volume selection */ +#define BOOTMENU_DEVICE_NAME_MAX 16 + /* Key identifying current memory map */ extern efi_uintn_t efi_memory_map_key; @@ -312,6 +315,9 @@ extern const efi_guid_t efi_guid_firmware_management_protocol; extern const efi_guid_t efi_esrt_guid; /* GUID of the SMBIOS table */ extern const efi_guid_t smbios_guid; +/*GUID of console */ +extern const efi_guid_t efi_guid_text_input_protocol; +extern const efi_guid_t efi_guid_text_output_protocol; extern char __efi_runtime_start[], __efi_runtime_stop[]; extern char __efi_runtime_rel_start[], __efi_runtime_rel_stop[]; @@ -871,6 +877,8 @@ efi_status_t efi_set_load_options(efi_handle_t handle, void *load_options); efi_status_t efi_bootmgr_load(efi_handle_t *handle, void **load_options); +efi_status_t efi_bootmenu_show_maintenance_menu(void); + /** * struct efi_image_regions - A list of memory regions * @@ -1042,4 +1050,33 @@ efi_status_t efi_esrt_populate(void); efi_status_t efi_load_capsule_drivers(void); efi_status_t platform_get_eventlog(struct udevice *dev, u64 *addr, u32 *sz); + +efi_status_t efi_locate_handle_buffer_int(enum efi_locate_search_type search_type, + const efi_guid_t *protocol, void *search_key, + efi_uintn_t *no_handles, efi_handle_t **buffer); + +efi_status_t efi_open_volume_int(struct efi_simple_file_system_protocol *this, + struct efi_file_handle **root); +efi_status_t efi_file_open_int(struct efi_file_handle *this, + struct efi_file_handle **new_handle, + u16 *file_name, u64 open_mode, + u64 attributes); +efi_status_t efi_file_close_int(struct efi_file_handle *file); +efi_status_t efi_file_read_int(struct efi_file_handle *this, + efi_uintn_t *buffer_size, void *buffer); +efi_status_t efi_file_setpos_int(struct efi_file_handle *file, u64 pos); + +typedef efi_status_t (*efi_console_filter_func)(struct efi_input_key *key); +efi_status_t efi_console_get_u16_string + (struct efi_simple_text_input_protocol *cin, + struct efi_simple_text_output_protocol *cout, + u16 *buf, efi_uintn_t count, efi_console_filter_func filer_func, + int row, int col); + +efi_status_t efi_bootmenu_get_unused_bootoption(u16 *buf, + efi_uintn_t buf_size, u32 *index); +efi_status_t efi_bootmenu_append_bootorder(u16 index); + +efi_status_t efi_disk_get_device_name(struct efi_block_io *this, char *buf, int size); + #endif /* _EFI_LOADER_H */ diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index aaaa25cefe..792eabe18a 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -77,6 +77,7 @@ obj-$(CONFIG_EFI_TCG2_PROTOCOL) += efi_tcg2.o obj-$(CONFIG_EFI_RISCV_BOOT_PROTOCOL) += efi_riscv.o obj-$(CONFIG_EFI_LOAD_FILE2_INITRD) += efi_load_initrd.o obj-$(CONFIG_EFI_SIGNATURE_SUPPORT) += efi_signature.o +obj-$(CONFIG_CMD_BOOTMENU) += efi_bootmenu_maintenance.o EFI_VAR_SEED_FILE := $(subst $\",,$(CONFIG_EFI_VAR_SEED_FILE)) $(obj)/efi_var_seed.o: $(srctree)/$(EFI_VAR_SEED_FILE) diff --git a/lib/efi_loader/efi_bootmenu_maintenance.c b/lib/efi_loader/efi_bootmenu_maintenance.c new file mode 100644 index 0000000000..77401a7829 --- /dev/null +++ b/lib/efi_loader/efi_bootmenu_maintenance.c @@ -0,0 +1,862 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Menu-driven UEFI Boot Variable maintenance + * + * Copyright (c) 2022 Masahisa Kojima, Linaro Limited + */ + +#define LOG_CATEGORY LOGC_EFI + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct efi_simple_text_input_protocol *cin; +static struct efi_simple_text_output_protocol *cout; + +#define EFI_BOOTMENU_ENTRY_NUM_MAX 99 +#define EFI_BOOTMENU_FILE_PATH_MAX 512 +#define EFI_BOOTMENU_FILE_PATH_BUF_SIZE (EFI_BOOTMENU_FILE_PATH_MAX * sizeof(u16)) +#define EFI_BOOTMENU_BOOT_NAME_MAX 32 +#define EFI_BOOT_ORDER_MAX_SIZE_IN_DECIMAL 6 + +typedef efi_status_t (*efi_bootmenu_entry_func)(void *data, bool *exit); + +/** + * struct efi_bootmenu_entry - menu entry structure + * + * @num: menu entry index + * @title: title of entry + * @key: unique key + * @bootmgr_menu: pointer to the menu structure + * @next: pointer to the next entry + * @func: callback function to be called when this entry is selected + * @data: data to be passed to the callback function + */ +struct efi_bootmenu_entry { + u32 num; + u16 *title; + char key[6]; + struct efi_bootmenu *bootmgr_menu; + struct efi_bootmenu_entry *next; + efi_bootmenu_entry_func func; + void *data; +}; + +/** + * struct efi_bootmenu - bootmgr menu structure + * + * @delay: delay for autoboot + * @active: active menu entry index + * @count: total count of menu entry + * @first: pointer to the first menu entry + */ +struct efi_bootmenu { + int delay; + int active; + int count; + struct efi_bootmenu_entry *first; +}; + +struct efi_bootmenu_item { + u16 *title; + efi_bootmenu_entry_func func; + void *data; +}; + +struct efi_bootmenu_boot_option { + struct efi_simple_file_system_protocol *current_volume; + struct efi_device_path *dp_volume; + u16 *current_path; + u16 *boot_name; + bool file_selected; +}; + +static const struct efi_device_path END = { + .type = DEVICE_PATH_TYPE_END, + .sub_type = DEVICE_PATH_SUB_TYPE_END, + .length = sizeof(END), +}; + +struct efi_bootmenu_volume_entry_data { + struct efi_bootmenu_boot_option *bo; + struct efi_simple_file_system_protocol *v; + struct efi_device_path *dp; +}; + +struct efi_bootmenu_file_entry_data { + struct efi_bootmenu_boot_option *bo; + bool is_directory; + u16 *file_name; +}; + +static void efi_bootmenu_print_entry(void *data) +{ + struct efi_bootmenu_entry *entry = data; + int reverse = (entry->bootmgr_menu->active == entry->num); + + /* TODO: support scroll or page for many entries */ + + /* + * Move cursor to line where the entry will be drown (entry->count) + * First 3 lines contain bootmgr menu header + one empty line + * For the last "Quit" entry, add one empty line + */ + if (entry->num == (entry->bootmgr_menu->count - 1)) + printf(ANSI_CURSOR_POSITION, entry->num + 5, 1); + else + printf(ANSI_CURSOR_POSITION, entry->num + 4, 1); + + puts(" "); + + if (reverse) + puts(ANSI_COLOR_REVERSE); + + printf("%ls", entry->title); + + if (reverse) + puts(ANSI_COLOR_RESET); +} + +static void efi_bootmenu_display_statusline(struct menu *m) +{ + struct efi_bootmenu_entry *entry; + struct efi_bootmenu *bootmgr_menu; + + if (menu_default_choice(m, (void *)&entry) < 0) + return; + + bootmgr_menu = entry->bootmgr_menu; + + printf(ANSI_CURSOR_POSITION, 1, 1); + puts(ANSI_CLEAR_LINE); + printf(ANSI_CURSOR_POSITION, 2, 1); + puts(" *** U-Boot EFI Boot Manager ***"); + puts(ANSI_CLEAR_LINE_TO_END); + printf(ANSI_CURSOR_POSITION, 3, 1); + puts(ANSI_CLEAR_LINE); + + /* First 3 lines are bootmgr_menu header + 2 empty lines between entries */ + printf(ANSI_CURSOR_POSITION, bootmgr_menu->count + 5, 1); + puts(ANSI_CLEAR_LINE); + printf(ANSI_CURSOR_POSITION, bootmgr_menu->count + 6, 1); + puts(" Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit"); + puts(ANSI_CLEAR_LINE_TO_END); + printf(ANSI_CURSOR_POSITION, bootmgr_menu->count + 7, 1); + puts(ANSI_CLEAR_LINE); +} + +static char *efi_bootmenu_choice_entry(void *data) +{ + int i; + int esc = 0; + struct efi_bootmenu_entry *iter; + enum bootmenu_key key = KEY_NONE; + struct efi_bootmenu *bootmgr_menu = data; + + while (1) { + if (bootmgr_menu->delay >= 0) { + /* Autoboot was not stopped */ + bootmenu_autoboot_loop((struct bootmenu_data *)bootmgr_menu, &key, &esc); + } else { + /* Some key was pressed, so autoboot was stopped */ + bootmenu_loop((struct bootmenu_data *)bootmgr_menu, &key, &esc); + } + + if (bootmgr_menu->delay == 0) + key = KEY_QUIT; + + switch (key) { + case KEY_UP: + if (bootmgr_menu->active > 0) + --bootmgr_menu->active; + /* no menu key selected, regenerate menu */ + return NULL; + case KEY_DOWN: + if (bootmgr_menu->active < bootmgr_menu->count - 1) + ++bootmgr_menu->active; + /* no menu key selected, regenerate menu */ + return NULL; + case KEY_SELECT: + iter = bootmgr_menu->first; + for (i = 0; i < bootmgr_menu->active; ++i) + iter = iter->next; + return iter->key; + case KEY_QUIT: + /* Quit by choosing the last entry */ + iter = bootmgr_menu->first; + while (iter->next) + iter = iter->next; + return iter->key; + default: + break; + } + } + + /* never happens */ + debug("bootmgr menu: this should not happen"); + return NULL; +} + +static void efi_bootmenu_destroy(struct efi_bootmenu *bootmgr_menu) +{ + struct efi_bootmenu_entry *next; + struct efi_bootmenu_entry *iter = bootmgr_menu->first; + + while (iter) { + next = iter->next; + free(iter); + iter = next; + } + free(bootmgr_menu); +} + +/** + * efi_bootmenu_process_common() - main handler for uefi bootmgr menu + * + * Construct the structures required to show the menu, then handle + * the user input intracting with u-boot menu functions. + * + * @items: pointer to the structure of each menu entry + * @count: the number of menu entry + * @delay: delay for autoboot/autoselect + * Return: status code + */ +static efi_status_t efi_bootmenu_process_common(const struct efi_bootmenu_item *items, + int count, int delay) +{ + u32 i; + bool exit = false; + efi_status_t ret; + struct menu *menu; + void *choice = NULL; + struct efi_bootmenu_entry *entry; + struct efi_bootmenu *bootmgr_menu; + struct efi_bootmenu_entry *iter = NULL; + + if (count > EFI_BOOTMENU_ENTRY_NUM_MAX) + return EFI_OUT_OF_RESOURCES; + + bootmgr_menu = calloc(1, sizeof(struct efi_bootmenu)); + if (!bootmgr_menu) + return EFI_OUT_OF_RESOURCES; + + bootmgr_menu->delay = delay; + bootmgr_menu->active = 0; + bootmgr_menu->first = NULL; + + for (i = 0; i < count; i++) { + entry = calloc(1, sizeof(struct efi_bootmenu_entry)); + if (!entry) { + ret = EFI_LOAD_ERROR; + goto out; + } + + entry->num = i; + entry->title = items->title; + snprintf(entry->key, sizeof(entry->key), "%04X", i); + entry->bootmgr_menu = bootmgr_menu; + entry->func = items->func; + entry->data = items->data; + entry->next = NULL; + + if (!iter) + bootmgr_menu->first = entry; + else + iter->next = entry; + + iter = entry; + items++; + } + bootmgr_menu->count = count; + + menu = menu_create(NULL, 0, 1, efi_bootmenu_display_statusline, + efi_bootmenu_print_entry, efi_bootmenu_choice_entry, + bootmgr_menu); + if (!menu) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + + for (entry = bootmgr_menu->first; entry; entry = entry->next) { + if (!menu_item_add(menu, entry->key, entry)) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + } + + menu_default_set(menu, bootmgr_menu->first->key); + + while (!exit) { + puts(ANSI_CURSOR_HIDE); + puts(ANSI_CLEAR_CONSOLE); + printf(ANSI_CURSOR_POSITION, 1, 1); + + if (menu_get_choice(menu, &choice)) { + entry = choice; + if (entry->func) + ret = entry->func(entry->data, &exit); + + /* last entry "Quit" is selected, exit this menu */ + if (entry->num == (entry->bootmgr_menu->count - 1)) { + ret = EFI_ABORTED; + break; + } + } + } + +out: + menu_destroy(menu); + efi_bootmenu_destroy(bootmgr_menu); + + puts(ANSI_CLEAR_CONSOLE); + printf(ANSI_CURSOR_POSITION, 1, 1); + puts(ANSI_CURSOR_SHOW); + + return ret; +} + +static efi_status_t efi_bootmenu_volume_selected(void *data, bool *exit) +{ + struct efi_bootmenu_volume_entry_data *info = data; + + *exit = true; + + if (info) { + info->bo->current_volume = info->v; + info->bo->dp_volume = info->dp; + } + + return EFI_SUCCESS; +} + +static efi_status_t efi_bootmenu_file_selected(void *data, bool *exit) +{ + struct efi_bootmenu_file_entry_data *info = data; + + *exit = true; + + if (!info) + return EFI_INVALID_PARAMETER; + + if (u16_strncmp(info->file_name, u".", 1) == 0 && + u16_strlen(info->file_name) == 1) { + /* stay current path */ + } else if (u16_strncmp(info->file_name, u"..", 2) == 0 && + u16_strlen(info->file_name) == 2) { + u32 i; + int len = u16_strlen(info->bo->current_path); + + for (i = len - 2; i > 0; i--) { + if (info->bo->current_path[i] == u'\\') + break; + } + + if (i == 0) + info->bo->current_path[0] = u'\0'; + else + info->bo->current_path[i + 1] = u'\0'; + } else { + size_t new_len; + + new_len = u16_strlen(info->bo->current_path) + + u16_strlen(info->file_name) + 1; + if (new_len > EFI_BOOTMENU_FILE_PATH_MAX) { + /* TODO: show error notification to user */ + log_err("file path is too long\n"); + return EFI_INVALID_PARAMETER; + } + u16_strlcat(info->bo->current_path, info->file_name, + EFI_BOOTMENU_FILE_PATH_MAX); + if (info->is_directory) { + /* + * Remainig buffer should have enough space to contain u"\\" and + * at least one character for file name + */ + if (new_len + 2 > EFI_BOOTMENU_FILE_PATH_MAX) { + log_err("directory path is too long\n"); + return EFI_INVALID_PARAMETER; + } + u16_strlcat(info->bo->current_path, u"\\", + EFI_BOOTMENU_FILE_PATH_MAX); + } else { + info->bo->file_selected = true; + } + } + return EFI_SUCCESS; +} + +static efi_status_t efi_bootmenu_select_volume(struct efi_bootmenu_boot_option *bo) +{ + u32 i; + efi_status_t ret; + efi_uintn_t count; + struct efi_handler *handler; + struct efi_device_path *device_path; + efi_handle_t *volume_handles = NULL; + struct efi_simple_file_system_protocol *v; + struct efi_bootmenu_item *menu_item, *iter; + + ret = efi_locate_handle_buffer_int(BY_PROTOCOL, &efi_simple_file_system_protocol_guid, + NULL, &count, (efi_handle_t **)&volume_handles); + if (ret != EFI_SUCCESS) + return ret; + + menu_item = calloc(count + 1, sizeof(struct efi_bootmenu_item)); + if (!menu_item) { + ret = EFI_OUT_OF_RESOURCES; + goto out1; + } + + iter = menu_item; + for (i = 0; i < count; i++) { + u16 *dev_name, *p; + struct efi_block_io *block_io; + char buf[BOOTMENU_DEVICE_NAME_MAX]; + struct efi_bootmenu_volume_entry_data *info; + + ret = efi_search_protocol(volume_handles[i], + &efi_simple_file_system_protocol_guid, &handler); + if (ret != EFI_SUCCESS) + continue; + ret = efi_protocol_open(handler, (void **)&v, efi_root, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) + continue; + + ret = efi_search_protocol(volume_handles[i], &efi_guid_device_path, &handler); + if (ret != EFI_SUCCESS) + continue; + ret = efi_protocol_open(handler, (void **)&device_path, + efi_root, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) + continue; + + ret = efi_search_protocol(volume_handles[i], &efi_block_io_guid, &handler); + if (ret != EFI_SUCCESS) + continue; + ret = efi_protocol_open(handler, (void **)&block_io, + efi_root, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) + continue; + + info = calloc(1, sizeof(struct efi_bootmenu_volume_entry_data)); + if (!info) { + ret = EFI_OUT_OF_RESOURCES; + goto out2; + } + + efi_disk_get_device_name(block_io, buf, BOOTMENU_DEVICE_NAME_MAX); + dev_name = calloc(1, (strlen(buf) + 1) * sizeof(u16)); + if (!dev_name) { + free(info); + ret = EFI_OUT_OF_RESOURCES; + goto out2; + } + p = dev_name; + utf8_utf16_strncpy(&p, buf, strlen(buf)); + + info->v = v; + info->dp = device_path; + info->bo = bo; + iter->title = dev_name; + iter->func = efi_bootmenu_volume_selected; + iter->data = info; + iter++; + } + + iter->title = u16_strdup(u"Quit"); + iter->func = NULL; + iter->data = NULL; + count += 1; + + ret = efi_bootmenu_process_common(menu_item, count, -1); + +out2: + iter = menu_item; + for (i = 0; i < count; i++) { + struct efi_bootmenu_volume_entry_data *p; + + p = (struct efi_bootmenu_volume_entry_data *)(iter->data); + free(iter->title); + free(p); + iter++; + } + + free(menu_item); + +out1: + efi_free_pool(volume_handles); + + return ret; +} + +static efi_status_t efi_bootmenu_select_file(struct efi_bootmenu_boot_option *bo, + struct efi_file_handle *root) +{ + u32 i; + struct efi_file_info *buf; + u32 count = 0; + efi_uintn_t len; + efi_status_t ret; + struct efi_file_handle *f; + struct efi_bootmenu_item *menu_item, *iter; + + buf = calloc(1, sizeof(struct efi_file_info) + EFI_BOOTMENU_FILE_PATH_BUF_SIZE); + if (!buf) + return EFI_OUT_OF_RESOURCES; + + while (!bo->file_selected) { + count = 0; + + ret = efi_file_open_int(root, &f, bo->current_path, EFI_FILE_MODE_READ, 0); + if (ret != EFI_SUCCESS) + return ret; + + /* calculate directory information total count */ + for (;;) { + len = sizeof(struct efi_file_info) + EFI_BOOTMENU_FILE_PATH_BUF_SIZE; + ret = efi_file_read_int(f, &len, buf); + if (ret != EFI_SUCCESS || len == 0) + break; + + count++; + } + + menu_item = calloc(count + 1, sizeof(struct efi_bootmenu_item)); + if (!menu_item) { + efi_file_close_int(f); + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + /* read directory and construct menu structure */ + efi_file_setpos_int(f, 0); + iter = menu_item; + for (i = 0; i < count; i++) { + u16 *name; + int name_len; + struct efi_bootmenu_file_entry_data *info; + + len = sizeof(struct efi_file_info) + EFI_BOOTMENU_FILE_PATH_BUF_SIZE; + ret = efi_file_read_int(f, &len, buf); + if (ret != EFI_SUCCESS || len == 0) + goto err; + + info = calloc(1, sizeof(struct efi_bootmenu_file_entry_data)); + if (!info) { + ret = EFI_OUT_OF_RESOURCES; + goto err; + } + + if (buf->attribute & EFI_FILE_DIRECTORY) { + /* append u'/' at the end of directory name */ + name_len = u16_strsize(buf->file_name) + sizeof(u16); + name = calloc(1, name_len); + if (!name) { + ret = EFI_OUT_OF_RESOURCES; + goto err; + } + u16_strcpy(name, buf->file_name); + name[u16_strlen(buf->file_name)] = u'/'; + + info->is_directory = true; + } else { + name_len = u16_strsize(buf->file_name); + name = calloc(1, name_len); + if (!name) { + ret = EFI_OUT_OF_RESOURCES; + goto err; + } + u16_strcpy(name, buf->file_name); + } + + info->file_name = u16_strdup(buf->file_name); + info->bo = bo; + iter->title = name; + iter->func = efi_bootmenu_file_selected; + iter->data = info; + iter++; + } + + /* add "Quit" entry */ + iter->title = u"Quit"; + iter->func = NULL; + iter->data = NULL; + count += 1; + + ret = efi_bootmenu_process_common(menu_item, count, -1); +err: + efi_file_close_int(f); + iter = menu_item; + for (i = 0; i < count - 1; i++, iter++) { + free(((struct efi_bootmenu_file_entry_data *)(iter->data))->file_name); + free(iter->title); + free(iter->data); + } + + free(menu_item); + + if (ret != EFI_SUCCESS) + break; + } + +out: + free(buf); + return ret; +} + +static efi_status_t efi_bootmenu_boot_add_enter_name(struct efi_bootmenu_boot_option *bo) +{ + efi_status_t ret; + + printf(ANSI_CURSOR_POSITION, 2, 1); + puts(" *** U-Boot EFI Boot Manager Menu ***"); + printf(ANSI_CURSOR_POSITION, 4, 1); + puts(" enter name:"); + + printf(ANSI_CURSOR_POSITION, 8, 1); + puts(" ENTER to complete, ESC/CTRL+C to quit"); + + ret = efi_console_get_u16_string(cin, cout, bo->boot_name, + EFI_BOOTMENU_BOOT_NAME_MAX, NULL, 4, 15); + + return ret; +} + +static efi_status_t efi_bootmenu_select_file_handler(struct efi_bootmenu_boot_option *bo) +{ + efi_status_t ret; + struct efi_file_handle *root; + + bo->file_selected = false; + + while (!bo->file_selected) { + bo->current_volume = NULL; + memset(bo->current_path, 0, sizeof(bo->current_path)); + + ret = efi_bootmenu_select_volume(bo); + if (ret != EFI_SUCCESS) + return ret; + + if (!bo->current_volume) + return EFI_INVALID_PARAMETER; + + ret = efi_open_volume_int(bo->current_volume, &root); + if (ret != EFI_SUCCESS) + return ret; + + ret = efi_bootmenu_select_file(bo, root); + if (ret != EFI_SUCCESS) + return ret; + } + + ret = efi_bootmenu_boot_add_enter_name(bo); + + return ret; +} + +efi_status_t efi_bootmenu_get_unused_bootoption(u16 *buf, + efi_uintn_t buf_size, u32 *index) +{ + u32 i; + efi_status_t ret; + efi_uintn_t size; + + if (buf_size < u16_strsize(u"Boot####")) + return EFI_BUFFER_TOO_SMALL; + + for (i = 0; i <= 0xFFFF; i++) { + size = 0; + efi_create_indexed_name(buf, buf_size, "Boot", i); + ret = efi_get_variable_int(buf, &efi_global_variable_guid, + NULL, &size, NULL, NULL); + if (ret == EFI_BUFFER_TOO_SMALL) + continue; + else + break; + } + + if (i > 0xFFFF) + return EFI_OUT_OF_RESOURCES; + + *index = i; + + return EFI_SUCCESS; +} + +static efi_status_t efi_bootmenu_set_boot_option(u16 *var_name, struct efi_device_path *dp, + u16 *label, char *optional_data) +{ + void *p = NULL; + efi_status_t ret; + efi_uintn_t size; + struct efi_load_option lo; + + lo.file_path = dp; + lo.file_path_length = efi_dp_size(dp) + sizeof(END); + lo.attributes = LOAD_OPTION_ACTIVE; + lo.optional_data = optional_data; + lo.label = label; + + size = efi_serialize_load_option(&lo, (u8 **)&p); + if (!size) + return EFI_INVALID_PARAMETER; + + ret = efi_set_variable_int(var_name, &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + size, p, false); + free(p); + + return ret; +} + +efi_status_t efi_bootmenu_append_bootorder(u16 index) +{ + u16 *bootorder; + efi_status_t ret; + u16 *new_bootorder = NULL; + efi_uintn_t last, size, new_size; + + /* append new boot option */ + bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size); + last = size / sizeof(u16); + new_size = size + sizeof(u16); + new_bootorder = calloc(1, new_size); + if (!new_bootorder) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + memcpy(new_bootorder, bootorder, size); + new_bootorder[last] = index; + + ret = efi_set_variable_int(u"BootOrder", &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + new_size, new_bootorder, false); + if (ret != EFI_SUCCESS) + goto out; + +out: + free(bootorder); + free(new_bootorder); + + return ret; +} + +static efi_status_t efi_bootmenu_process_add_boot_option(void *data, bool *exit) +{ + u32 index; + u16 var_name[9]; + char *buf = NULL; + efi_status_t ret; + char *iter = NULL; + efi_uintn_t dp_size, fp_size; + struct efi_bootmenu_boot_option bo; + struct efi_device_path_file_path *fp; + + ret = efi_bootmenu_get_unused_bootoption(var_name, sizeof(var_name), + &index); + if (ret != EFI_SUCCESS) + return ret; + + bo.current_path = calloc(1, EFI_BOOTMENU_FILE_PATH_BUF_SIZE); + if (!bo.current_path) + goto out; + + bo.boot_name = calloc(1, EFI_BOOTMENU_BOOT_NAME_MAX * sizeof(u16)); + if (!bo.boot_name) + goto out; + + ret = efi_bootmenu_select_file_handler(&bo); + if (ret != EFI_SUCCESS) + goto out; + + dp_size = efi_dp_size(bo.dp_volume); + fp_size = sizeof(struct efi_device_path) + + ((u16_strlen(bo.current_path) + 1) * sizeof(u16)); + buf = calloc(1, dp_size + fp_size + sizeof(END)); + if (!buf) + goto out; + + iter = buf; + memcpy(iter, bo.dp_volume, dp_size); + iter += dp_size; + + fp = (struct efi_device_path_file_path *)iter; + fp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE; + fp->dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH; + fp->dp.length = (u16)fp_size; + u16_strcpy(fp->str, bo.current_path); + iter += fp_size; + *((struct efi_device_path *)iter) = END; + + ret = efi_bootmenu_set_boot_option(var_name, (struct efi_device_path *)buf, + bo.boot_name, NULL); + if (ret != EFI_SUCCESS) + goto out; + + efi_bootmenu_append_bootorder((u16)index); + if (ret != EFI_SUCCESS) + goto out; + +out: + free(buf); + free(bo.boot_name); + free(bo.current_path); + + return ret; +} + +static efi_status_t efi_bootmenu_init(void) +{ + efi_status_t ret; + struct efi_handler *handler; + + ret = efi_search_protocol(efi_root, &efi_guid_text_input_protocol, &handler); + if (ret != EFI_SUCCESS) + return ret; + + ret = efi_protocol_open(handler, (void **)&cin, efi_root, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) + return ret; + + ret = efi_search_protocol(efi_root, &efi_guid_text_output_protocol, &handler); + if (ret != EFI_SUCCESS) + return ret; + + ret = efi_protocol_open(handler, (void **)&cout, efi_root, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) + return ret; + + return ret; +} + +static const struct efi_bootmenu_item maintenance_menu_items[] = { + {u"Add Boot Option", efi_bootmenu_process_add_boot_option}, + {u"Quit", NULL}, +}; + +efi_status_t efi_bootmenu_show_maintenance_menu(void) +{ + efi_status_t ret; + + ret = efi_bootmenu_init(); + if (ret != EFI_SUCCESS) + return ret; + + return efi_bootmenu_process_common(maintenance_menu_items, + ARRAY_SIZE(maintenance_menu_items), + -1); +} diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 4da64b5d29..1233418e77 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -2453,6 +2453,35 @@ static efi_status_t EFIAPI efi_protocols_per_handle( return EFI_EXIT(EFI_SUCCESS); } +efi_status_t efi_locate_handle_buffer_int(enum efi_locate_search_type search_type, + const efi_guid_t *protocol, void *search_key, + efi_uintn_t *no_handles, efi_handle_t **buffer) +{ + efi_status_t r; + efi_uintn_t buffer_size = 0; + + if (!no_handles || !buffer) { + r = EFI_INVALID_PARAMETER; + goto out; + } + *no_handles = 0; + *buffer = NULL; + r = efi_locate_handle(search_type, protocol, search_key, &buffer_size, + *buffer); + if (r != EFI_BUFFER_TOO_SMALL) + goto out; + r = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, buffer_size, + (void **)buffer); + if (r != EFI_SUCCESS) + goto out; + r = efi_locate_handle(search_type, protocol, search_key, &buffer_size, + *buffer); + if (r == EFI_SUCCESS) + *no_handles = buffer_size / sizeof(efi_handle_t); +out: + return r; +} + /** * efi_locate_handle_buffer() - locate handles implementing a protocol * @search_type: selection criterion @@ -2474,30 +2503,13 @@ efi_status_t EFIAPI efi_locate_handle_buffer( efi_uintn_t *no_handles, efi_handle_t **buffer) { efi_status_t r; - efi_uintn_t buffer_size = 0; EFI_ENTRY("%d, %pUs, %p, %p, %p", search_type, protocol, search_key, no_handles, buffer); - if (!no_handles || !buffer) { - r = EFI_INVALID_PARAMETER; - goto out; - } - *no_handles = 0; - *buffer = NULL; - r = efi_locate_handle(search_type, protocol, search_key, &buffer_size, - *buffer); - if (r != EFI_BUFFER_TOO_SMALL) - goto out; - r = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, buffer_size, - (void **)buffer); - if (r != EFI_SUCCESS) - goto out; - r = efi_locate_handle(search_type, protocol, search_key, &buffer_size, - *buffer); - if (r == EFI_SUCCESS) - *no_handles = buffer_size / sizeof(efi_handle_t); -out: + r = efi_locate_handle_buffer_int(search_type, protocol, search_key, + no_handles, buffer); + return EFI_EXIT(r); } diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c index ba68a15017..f5002e1c99 100644 --- a/lib/efi_loader/efi_console.c +++ b/lib/efi_loader/efi_console.c @@ -5,6 +5,7 @@ * Copyright (c) 2016 Alexander Graf */ +#include #include #include #include @@ -1312,3 +1313,83 @@ out_of_memory: printf("ERROR: Out of memory\n"); return r; } + +/** + * efi_console_get_u16_string() - get user input string + * + * @cin: protocol interface to EFI_SIMPLE_TEXT_INPUT_PROTOCOL + * @cout: protocol interface to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL + * @buf: buffer to store user input string in UTF16 + * @size: buffer size including NULL terminator + * @filter_func: callback to filter user input + * @row: row number to locate user input form + * @col: column number to locate user input form + * Return: status code + */ +efi_status_t efi_console_get_u16_string(struct efi_simple_text_input_protocol *cin, + struct efi_simple_text_output_protocol *cout, + u16 *buf, efi_uintn_t size, + efi_console_filter_func filter_func, + int row, int col) +{ + efi_status_t ret; + efi_uintn_t len = 0; + struct efi_input_key key; + + printf(ANSI_CURSOR_POSITION, row, col); + puts(ANSI_CLEAR_LINE_TO_END); + puts(ANSI_CURSOR_SHOW); + + ret = EFI_CALL(cin->reset(cin, false)); + if (ret != EFI_SUCCESS) + return ret; + + for (;;) { + do { + ret = EFI_CALL(cin->read_key_stroke(cin, &key)); + mdelay(10); + } while (ret == EFI_NOT_READY); + + if (key.unicode_char == u'\b') { + if (len > 0) + buf[--len] = u'\0'; + + printf(ANSI_CURSOR_POSITION, row, col); + ret = EFI_CALL(cout->output_string(cout, buf)); + if (ret != EFI_SUCCESS) + return ret; + + puts(ANSI_CLEAR_LINE_TO_END); + continue; + } else if (key.unicode_char == u'\r') { + if (len == 0) /* no user input */ + continue; + + buf[len] = u'\0'; + return EFI_SUCCESS; + } else if (key.unicode_char == 0x3 || key.scan_code == 23) { + return EFI_ABORTED; + } else if (key.unicode_char < 0x20) { + /* ignore control codes other than Ctrl+C, '\r' and '\b' */ + continue; + } else if (key.scan_code != 0) { + /* only accept single ESC press for cancel */ + continue; + } + + if (filter_func) { + if (filter_func(&key) != EFI_SUCCESS) + continue; + } + + if (len >= (size - 1)) + continue; + + buf[len] = key.unicode_char; + len++; + printf(ANSI_CURSOR_POSITION, row, col); + ret = EFI_CALL(cout->output_string(cout, buf)); + if (ret != EFI_SUCCESS) + return ret; + } +} diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index 8fb5b2363c..58736a8a5b 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -750,3 +750,14 @@ efi_status_t efi_disk_init(void) return EFI_SUCCESS; } + +efi_status_t efi_disk_get_device_name(struct efi_block_io *this, char *buf, int size) +{ + struct efi_disk_obj *diskobj; + + diskobj = container_of(this, struct efi_disk_obj, ops); + + snprintf(buf, size, "%s%d:%d", diskobj->ifname, diskobj->dev_index, diskobj->part); + + return EFI_SUCCESS; +} diff --git a/lib/efi_loader/efi_file.c b/lib/efi_loader/efi_file.c index 7a7077e6d0..c96a7f7ca3 100644 --- a/lib/efi_loader/efi_file.c +++ b/lib/efi_loader/efi_file.c @@ -246,10 +246,10 @@ error: return NULL; } -static efi_status_t efi_file_open_int(struct efi_file_handle *this, - struct efi_file_handle **new_handle, - u16 *file_name, u64 open_mode, - u64 attributes) +efi_status_t efi_file_open_int(struct efi_file_handle *this, + struct efi_file_handle **new_handle, + u16 *file_name, u64 open_mode, + u64 attributes) { struct file_handle *fh = to_fh(this); efi_status_t ret; @@ -369,11 +369,17 @@ static efi_status_t file_close(struct file_handle *fh) return EFI_SUCCESS; } -static efi_status_t EFIAPI efi_file_close(struct efi_file_handle *file) +efi_status_t efi_file_close_int(struct efi_file_handle *file) { struct file_handle *fh = to_fh(file); + + return file_close(fh); +} + +static efi_status_t EFIAPI efi_file_close(struct efi_file_handle *file) +{ EFI_ENTRY("%p", file); - return EFI_EXIT(file_close(fh)); + return EFI_EXIT(efi_file_close_int(file)); } static efi_status_t EFIAPI efi_file_delete(struct efi_file_handle *file) @@ -562,8 +568,8 @@ static efi_status_t dir_read(struct file_handle *fh, u64 *buffer_size, return EFI_SUCCESS; } -static efi_status_t efi_file_read_int(struct efi_file_handle *this, - efi_uintn_t *buffer_size, void *buffer) +efi_status_t efi_file_read_int(struct efi_file_handle *this, + efi_uintn_t *buffer_size, void *buffer) { struct file_handle *fh = to_fh(this); efi_status_t ret = EFI_SUCCESS; @@ -773,24 +779,11 @@ out: return EFI_EXIT(ret); } -/** - * efi_file_setpos() - set current position in file - * - * This function implements the SetPosition service of the EFI file protocol. - * See the UEFI spec for details. - * - * @file: file handle - * @pos: new file position - * Return: status code - */ -static efi_status_t EFIAPI efi_file_setpos(struct efi_file_handle *file, - u64 pos) +efi_status_t efi_file_setpos_int(struct efi_file_handle *file, u64 pos) { struct file_handle *fh = to_fh(file); efi_status_t ret = EFI_SUCCESS; - EFI_ENTRY("%p, %llu", file, pos); - if (fh->isdir) { if (pos != 0) { ret = EFI_UNSUPPORTED; @@ -812,6 +805,28 @@ static efi_status_t EFIAPI efi_file_setpos(struct efi_file_handle *file, fh->offset = pos; error: + return ret; +} + +/** + * efi_file_setpos() - set current position in file + * + * This function implements the SetPosition service of the EFI file protocol. + * See the UEFI spec for details. + * + * @file: file handle + * @pos: new file position + * Return: status code + */ +static efi_status_t EFIAPI efi_file_setpos(struct efi_file_handle *file, + u64 pos) +{ + efi_status_t ret = EFI_SUCCESS; + + EFI_ENTRY("%p, %llu", file, pos); + + ret = efi_file_setpos_int(file, pos); + return EFI_EXIT(ret); } @@ -1138,17 +1153,23 @@ struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp) return f; } +efi_status_t efi_open_volume_int(struct efi_simple_file_system_protocol *this, + struct efi_file_handle **root) +{ + struct file_system *fs = to_fs(this); + + *root = file_open(fs, NULL, NULL, 0, 0); + + return EFI_SUCCESS; +} + static efi_status_t EFIAPI efi_open_volume(struct efi_simple_file_system_protocol *this, struct efi_file_handle **root) { - struct file_system *fs = to_fs(this); - EFI_ENTRY("%p, %p", this, root); - *root = file_open(fs, NULL, NULL, 0, 0); - - return EFI_EXIT(EFI_SUCCESS); + return EFI_EXIT(efi_open_volume_int(this, root)); } struct efi_simple_file_system_protocol * From patchwork Thu Apr 28 08:09:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 567138 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:6886:0:0:0:0 with SMTP id m6csp5233678map; Thu, 28 Apr 2022 01:13:35 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwdTzcQWgpMHQAv2q3nUF131g293az3zBXu4MszQgbPdRHF7e6Z3BK52ukP3SUMj3Jl2LFx X-Received: by 2002:a17:907:3f24:b0:6f3:c2df:3432 with SMTP id hq36-20020a1709073f2400b006f3c2df3432mr7647619ejc.614.1651133615319; Thu, 28 Apr 2022 01:13:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1651133615; cv=none; d=google.com; s=arc-20160816; b=AVPr4z6KcpFUE54/b76trahRqwhE0zEFL3A4yYD8GpLiYoejum78zKkmxhqPtPwzN3 lbYTr0bpY/LQRiWNAbRSNXNEtCz6vSAWbcjtRQ+cr4yVaul42L0+v5nqsBZhQDlv0Ugf /2IqOeOD1pud8XYVCho9IXpnwBRh1H3TcXXBzVdGSKr7dljxEHKAY4bA2nz/VnHXJXPi iirJ/3T34kl8X4Olp6B+OFtHQWTtQENDOzSaY9tVuVJV312ST2FzqVYcvf3ve5Jqfwem kczOhSuCV8uTQMdTrM938vm/j2GWhcxDTz2Z3hlju97uT27fisWUdh3dSK0VhLUjdAhA zcfA== 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=lX31U9MXgpDF4WofAMeq6aQhG9iXZD3fdgc2+/bk0Lg=; b=iItGkS5US5cYaFwb6lEf155B2XTYLC/dHftS8wB9HjfVbBrCFj/LOoGUxsSXitNhUL X6SSeXkcogkW4WAA9YP61l5SNIRoqol2UjKl0SmHup/mS3Y+2ZadoF1wN0/TWbnlOhBY SmZTvFJbCTQtJQmpEN9YFu7HLbZ+sJzJsuDqN/qubXlWRgBPV/JURv1mYUrTfW44/42w 63/2wIugLdzVSUwy70RFpQ4UGbrgp3vp9GxKBg+Aqpj0tT2R32t9660i19dsDOApWC6K 3J70ctOQLcRC3d2s6TcVOzDLRgCQ9vVIUmlFUnLCmT64TE4xp7uucFQv1id5Ukn1axmY kCPA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=BA61FZDJ; 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 u11-20020aa7db8b000000b00424085b80c5si3286932edt.215.2022.04.28.01.13.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:13:35 -0700 (PDT) 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=BA61FZDJ; 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 0334983EE4; Thu, 28 Apr 2022 10:12:47 +0200 (CEST) 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="BA61FZDJ"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 2237A83565; Thu, 28 Apr 2022 10:11:32 +0200 (CEST) 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 autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pl1-x62e.google.com (mail-pl1-x62e.google.com [IPv6:2607:f8b0:4864:20::62e]) (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 2F32683DCA for ; Thu, 28 Apr 2022 10:11:18 +0200 (CEST) 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-x62e.google.com with SMTP id p6so3677426plf.9 for ; Thu, 28 Apr 2022 01:11:18 -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; bh=lX31U9MXgpDF4WofAMeq6aQhG9iXZD3fdgc2+/bk0Lg=; b=BA61FZDJ/CKRNRrY23WLeDN6CJySooO5kM3tw85lWnHnjwl/d+F5kNmumOOu86IfVX xLpjSekVN6BfUS/cynyg6r7JLg3+FEQ+EkxRKa1CCFLFQfE6UJLpuVZSrdkgfsKKuIbq 85fop11VKKYYJke7cf6VoqLJSxq6z1KtvZVNlpRqMWMy33dmjqtXJkoaGrT6suczFYYP 1HtbI/C5+YTmeCDTnbW8pwHSlOhHc4DZIE7vYjz1dhH30UfvjPnx9JM5M2MUv7UGt5m6 ciEO2oWZ+21oJWbfIC4R/SBLnqvwV1kIZiWhFF7eYGbu+BEZsFhYlFiIv65YDQCCbO8g asVA== 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=lX31U9MXgpDF4WofAMeq6aQhG9iXZD3fdgc2+/bk0Lg=; b=YBdwVy1cFFKS8XoCJF0OVarOP38A8Uxy6Hr8R8pn80PAjQGdlwiEIyRViUFyrZhflS cEOiF1+bbFumA0j+ExwcRuGxQaV92D+vhkPGsMOoiZ70s0OP7UtcoFDAAKrnPm5TMBWZ DSqZllSyXIPthS+m5Pthw+Tp+t0pVc9PVysClbis0d2t8qBjBk8SU5isDDBjDonHFY7d UzVaJdvXlznogfPvnSYMrPWO7oCC+9o/KYu2OGNSwFyhhcMX8pGJTARTrZMkAEh1bgn/ KSif2TpZwJ9cobNac/1QwBHBqd1hyD5HIUFSTiOOMhFiHyU18TMAb8jIxB2vp0b5Gc7y tE+w== X-Gm-Message-State: AOAM531gt3YsNmaMw187T6+Uxd8Z3jT+aobLkOJN/kgUJgIqQ/9ZEjy5 //mS1ZFZ85dJyiCLLMY3hgeJiL38f04GtA== X-Received: by 2002:a17:90a:4414:b0:1cd:4c16:e7eb with SMTP id s20-20020a17090a441400b001cd4c16e7ebmr48461955pjg.166.1651133476455; Thu, 28 Apr 2022 01:11:16 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id b15-20020a17090a7acf00b001cd4989ff5fsm5684259pjl.38.2022.04.28.01.11.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:11:16 -0700 (PDT) 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: [PATCH v5 14/17] efi_loader: menu-driven deletion of UEFI boot variable Date: Thu, 28 Apr 2022 17:09:47 +0900 Message-Id: <20220428080950.23509-15-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220428080950.23509-1-masahisa.kojima@linaro.org> References: <20220428080950.23509-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 adds the menu-driven deletion of UEFI boot variable. Signed-off-by: Masahisa Kojima --- Changes in v5: - split into the separate patch lib/efi_loader/efi_bootmenu_maintenance.c | 142 ++++++++++++++++++++++ 1 file changed, 142 insertions(+) diff --git a/lib/efi_loader/efi_bootmenu_maintenance.c b/lib/efi_loader/efi_bootmenu_maintenance.c index 77401a7829..26320a8b73 100644 --- a/lib/efi_loader/efi_bootmenu_maintenance.c +++ b/lib/efi_loader/efi_bootmenu_maintenance.c @@ -70,6 +70,12 @@ struct efi_bootmenu_item { void *data; }; +struct efi_bootmenu_boot_selection_data { + u16 bootorder_index; + void *load_option; + int *selected; +}; + struct efi_bootmenu_boot_option { struct efi_simple_file_system_protocol *current_volume; struct efi_device_path *dp_volume; @@ -322,6 +328,89 @@ out: return ret; } +static efi_status_t efi_bootmenu_process_boot_selected(void *data, bool *exit) +{ + struct efi_bootmenu_boot_selection_data *info = data; + + *exit = true; + + if (info) + *info->selected = info->bootorder_index; + + return EFI_SUCCESS; +} + +static efi_status_t efi_bootmenu_show_boot_selection(u16 *bootorder, efi_uintn_t count, + int *selected) +{ + u32 i; + efi_status_t ret; + efi_uintn_t size; + void *load_option; + struct efi_load_option lo; + u16 varname[] = u"Boot####"; + struct efi_bootmenu_item *menu_item, *iter; + + menu_item = calloc(count + 1, sizeof(struct efi_bootmenu_item)); + if (!menu_item) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + iter = menu_item; + for (i = 0; i < count; i++) { + efi_create_indexed_name(varname, sizeof(varname), + "Boot", bootorder[i]); + 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) { + struct efi_bootmenu_boot_selection_data *info; + + info = calloc(1, sizeof(struct efi_bootmenu_boot_selection_data)); + if (!info) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + info->bootorder_index = i; + info->load_option = load_option; + info->selected = selected; + iter->title = lo.label; + iter->func = efi_bootmenu_process_boot_selected; + iter->data = info; + iter++; + } + } + + /* add "Quit" entry */ + iter->title = u"Quit"; + iter->func = NULL; + iter->data = NULL; + count += 1; + + ret = efi_bootmenu_process_common(menu_item, count, -1); + +out: + iter = menu_item; + for (i = 0; i < count - 1; i++, iter++) { + free(((struct efi_bootmenu_boot_selection_data *)iter->data)->load_option); + free(iter->data); + } + + free(menu_item); + + return ret; +} + static efi_status_t efi_bootmenu_volume_selected(void *data, bool *exit) { struct efi_bootmenu_volume_entry_data *info = data; @@ -817,6 +906,58 @@ out: return ret; } +static efi_status_t delete_boot_option(u16 *bootorder, u16 index, efi_uintn_t size) +{ + u16 var_name[9]; + efi_status_t ret; + efi_uintn_t num; + + efi_create_indexed_name(var_name, sizeof(var_name), + "Boot", bootorder[index]); + ret = efi_set_variable_int(var_name, &efi_global_variable_guid, + 0, 0, NULL, false); + if (ret != EFI_SUCCESS) { + log_err("delete boot option(%ls) failed\n", var_name); + return ret; + } + + /* update BootOrder */ + num = size / sizeof(u16); + memmove(&bootorder[index], &bootorder[index + 1], + (num - index - 1) * sizeof(u16)); + size -= sizeof(u16); + ret = efi_set_variable_int(u"BootOrder", &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + size, bootorder, false); + + return ret; +} + +static efi_status_t efi_bootmenu_process_delete_boot_option(void *data, bool *exit) +{ + int selected; + u16 *bootorder; + efi_status_t ret; + efi_uintn_t num, size; + + bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size); + if (!bootorder) { + ret = EFI_NOT_FOUND; + return ret; + } + + num = size / sizeof(u16); + ret = efi_bootmenu_show_boot_selection(bootorder, num, &selected); + if (ret == EFI_SUCCESS) + ret = delete_boot_option(bootorder, selected, size); + + free(bootorder); + + return ret; +} + static efi_status_t efi_bootmenu_init(void) { efi_status_t ret; @@ -845,6 +986,7 @@ static efi_status_t efi_bootmenu_init(void) static const struct efi_bootmenu_item maintenance_menu_items[] = { {u"Add Boot Option", efi_bootmenu_process_add_boot_option}, + {u"Delete Boot Option", efi_bootmenu_process_delete_boot_option}, {u"Quit", NULL}, }; From patchwork Thu Apr 28 08:09:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 567141 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:6886:0:0:0:0 with SMTP id m6csp5234042map; Thu, 28 Apr 2022 01:14:14 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyLJYd6Q6pVZhyIyy1tJotoKj4N7yks9uEeDFCYxsnIkaIFmMWJ8buyxxqPcri9PosUm8P1 X-Received: by 2002:a05:6402:1850:b0:425:f2e2:2594 with SMTP id v16-20020a056402185000b00425f2e22594mr17561884edy.3.1651133654069; Thu, 28 Apr 2022 01:14:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1651133654; cv=none; d=google.com; s=arc-20160816; b=uzeA4jDgkul2cu5M8J0TKBHD1VTt3M+rz4AvQZaiIY7emlraJy5htJY2xNE4BBb5q8 cJgD6qfhfMf6UYzH1cs5YiI7MQA9xZm54QiaZ55GyMoxMGIkc4aSOZv6ZHWvP6pCZhcy M2WLYDjFeHbF7sZ1zF/EuBeLizG3hdoX+bku8RoDlpcTBPgNrCKSI1TmknkDtHtq3ui5 r57de9Gv9KEv20ke8dgYhQQXXTiva5sSFE9bBEnGA9NyQGayUtw+W6gbcb+IdN20UiVJ 6O4On/XCoy6f9UZEIMUaxtLBaugl+/Z3ggHfUFPQ4LsikRQ6UEaOiGWCqRieWKKVQAq5 4vTA== 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=iKVe0Cu41bsyIFo0sDuKev4Fa1eoKYlqHnpLTZDzMaA=; b=q4b/rfMWNGMjeINKCgcJqfOy4m8jUQCJ1CULRDJWmSmW89OiY9GmCo22nR1uHo9Mzu q4eW923AERZFNAyF6NogaySVgMq/XH5hOXSHdipeF2Fwuqpym0CJ2zt69mu2L5EhPcLp ZqVPW03R1mU7uebxq+ZZgQMj71oeBNe7sw41cZM+PpU6u3FGg9OiyD0dp4nyujn9DSls iAynwquPAf4Mr+CiZCDfYATgI+z/DXpM3T6NbGoPyDU8izWhNfHb02O+k6acudidvKa2 p9oSELJ49ZTeRARhCIGHO0ES2aBYkhtF6U89ZW2AfMJE2yYfySui65wOy8Y+ZXfdX+P2 PFow== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=kiCjO3dJ; 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 gf25-20020a170906e21900b006e48d161aaasi3277578ejb.213.2022.04.28.01.14.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:14:14 -0700 (PDT) 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=kiCjO3dJ; 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 07B5083F0A; Thu, 28 Apr 2022 10:12:59 +0200 (CEST) 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="kiCjO3dJ"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 5577483EDF; Thu, 28 Apr 2022 10:11:38 +0200 (CEST) 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 autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pl1-x62c.google.com (mail-pl1-x62c.google.com [IPv6:2607:f8b0:4864:20::62c]) (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 0CFEB83ED7 for ; Thu, 28 Apr 2022 10:11:21 +0200 (CEST) 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-x62c.google.com with SMTP id n18so3693989plg.5 for ; Thu, 28 Apr 2022 01:11:20 -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; bh=iKVe0Cu41bsyIFo0sDuKev4Fa1eoKYlqHnpLTZDzMaA=; b=kiCjO3dJ74DggUmxPuO3foZf6TGhSyaL+537pC9dyn2flqX8WyvkCW77L/nKy/XUbk Cjr+ZjuFvcBsnHVzQthFW7J8BF7k3Z3FofXkhFxZYYxJ5P0bJ1YCrmyWtKpMteajf9yx mB2Sn3rRZ68qun5Zs5wuLmrlVGx1gzgGzusUpz3DpwMGPtalutIyMQzqFupbXFFO74be x0R2qsLrWuP5J/PU8nMeVK3TxWepjMJVEVa9Fp4kaneqlibzNreIZ4dg7cUwyWcwyzLg NTWpZIWyutMT9bARvWtWqG947RGJNugW1QoV4NXgoY3YtKQwgBhJS0J2HFlYCKocmpt0 cUPA== 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=iKVe0Cu41bsyIFo0sDuKev4Fa1eoKYlqHnpLTZDzMaA=; b=nKM3ZWNRNhAgonq6zQv6X77hTh1n4F2/LclXBKMCVBEco4E6un1DmGg+zD21BgaRIz z4eFecBsM0EXChTvqiRW+JWCR6fl8VDuYjz4cd97SuC2fJG51zVHpgCN74YU3MdgmiIp 07xHtpX+VCalsEg0Kx9oBnNHoAYr5rPI3kJMQpsnsJvVua7Yrjv3rCEEq/joyqCq1GQn jQi+gzY5EFnN44KRMI1gnrOqNAYXXQfoQE4Cq/ot9jE8u5XttxFqEcoSyiPRrMz3TAIz qu5REnHCzpbwLFLxY5qpWH8PGC0auqnG1t+T0qJ4OA3e12+zPTjCyiJGxAGvPr1D7TJM nwmQ== X-Gm-Message-State: AOAM530adrMpsJKjhH6FFLafOipGbCWxtMkFsPF7iBYFN5jDR4ztKHnQ 4wylmGinBmVCkV9/x0pzNlRlXB61kYm3vQ== X-Received: by 2002:a17:90a:ab90:b0:1da:375f:2f44 with SMTP id n16-20020a17090aab9000b001da375f2f44mr8180160pjq.33.1651133479303; Thu, 28 Apr 2022 01:11:19 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id b15-20020a17090a7acf00b001cd4989ff5fsm5684259pjl.38.2022.04.28.01.11.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:11:18 -0700 (PDT) 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: [PATCH v5 15/17] efi_loader: menu-driven update of UEFI bootorder variable Date: Thu, 28 Apr 2022 17:09:48 +0900 Message-Id: <20220428080950.23509-16-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220428080950.23509-1-masahisa.kojima@linaro.org> References: <20220428080950.23509-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 adds the menu-driven update of UEFI bootorder variable. Signed-off-by: Masahisa Kojima --- Changes in v5: - split into the separate patch lib/efi_loader/efi_bootmenu_maintenance.c | 102 ++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/lib/efi_loader/efi_bootmenu_maintenance.c b/lib/efi_loader/efi_bootmenu_maintenance.c index 26320a8b73..8c3f94c695 100644 --- a/lib/efi_loader/efi_bootmenu_maintenance.c +++ b/lib/efi_loader/efi_bootmenu_maintenance.c @@ -719,6 +719,56 @@ static efi_status_t efi_bootmenu_boot_add_enter_name(struct efi_bootmenu_boot_op return ret; } +static efi_status_t allow_decimal(struct efi_input_key *key) +{ + if (u'0' <= key->unicode_char && key->unicode_char <= u'9') + return EFI_SUCCESS; + + return EFI_INVALID_PARAMETER; +} + +static efi_status_t efi_bootmenu_change_boot_order(int selected, int max, int *new) +{ + efi_status_t ret; + u16 new_order[EFI_BOOT_ORDER_MAX_SIZE_IN_DECIMAL] = {0}; + + printf(ANSI_CURSOR_POSITION, 2, 1); + puts(" *** U-Boot EFI Boot Manager Menu ***"); + printf(ANSI_CURSOR_POSITION, 4, 1); + printf(" current boot order : %d", selected); + + printf(ANSI_CURSOR_POSITION, 6, 1); + printf(" new boot order(0 - %4d): ", max); + + printf(ANSI_CURSOR_POSITION, 8, 1); + puts(" ENTER to complete, ESC/CTRL+C to quit"); + + printf(ANSI_CURSOR_POSITION, 6, 29); + puts(ANSI_CURSOR_SHOW); + + for (;;) { + memset(new_order, 0, sizeof(new_order)); + ret = efi_console_get_u16_string(cin, cout, new_order, 6, allow_decimal, 6, 29); + if (ret == EFI_SUCCESS) { + int i; + int val = 0; + + for (i = 0; + i < u16_strnlen(new_order, EFI_BOOT_ORDER_MAX_SIZE_IN_DECIMAL - 1); + i++) + val = (val * 10) + (new_order[i] - u'0'); + + if (val > max) + continue; + + *new = val; + return EFI_SUCCESS; + } else { + return ret; + } + } +} + static efi_status_t efi_bootmenu_select_file_handler(struct efi_bootmenu_boot_option *bo) { efi_status_t ret; @@ -958,6 +1008,57 @@ static efi_status_t efi_bootmenu_process_delete_boot_option(void *data, bool *ex return ret; } +static efi_status_t efi_bootmenu_process_change_boot_order(void *data, bool *exit) +{ + int selected; + int new_order; + efi_status_t ret; + efi_uintn_t num, size; + u16 *bootorder = NULL; + u16 *new_bootorder = NULL; + + bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size); + if (!bootorder) + return EFI_NOT_FOUND; + + num = size / sizeof(u16); + ret = efi_bootmenu_show_boot_selection(bootorder, num, &selected); + if (ret != EFI_SUCCESS) + goto out; + + ret = efi_bootmenu_change_boot_order(selected, num - 1, &new_order); + if (ret != EFI_SUCCESS) + goto out; + + new_bootorder = calloc(1, size); + if (!new_bootorder) + goto out; + + memcpy(new_bootorder, bootorder, size); + if (selected > new_order) { + new_bootorder[new_order] = bootorder[selected]; + memcpy(&new_bootorder[new_order + 1], &bootorder[new_order], + (selected - new_order) * sizeof(u16)); + } else if (selected < new_order) { + new_bootorder[new_order] = bootorder[selected]; + memcpy(&new_bootorder[selected], &bootorder[selected + 1], + (new_order - selected) * sizeof(u16)); + } else { + /* nothing to change */ + goto out; + } + ret = efi_set_variable_int(u"BootOrder", &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + size, new_bootorder, false); +out: + free(new_bootorder); + free(bootorder); + + return ret; +} + static efi_status_t efi_bootmenu_init(void) { efi_status_t ret; @@ -987,6 +1088,7 @@ static efi_status_t efi_bootmenu_init(void) static const struct efi_bootmenu_item maintenance_menu_items[] = { {u"Add Boot Option", efi_bootmenu_process_add_boot_option}, {u"Delete Boot Option", efi_bootmenu_process_delete_boot_option}, + {u"Change Boot Order", efi_bootmenu_process_change_boot_order}, {u"Quit", NULL}, }; From patchwork Thu Apr 28 08:09:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 567140 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:6886:0:0:0:0 with SMTP id m6csp5233969map; Thu, 28 Apr 2022 01:14:06 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxVIE9/94CwCPW399m/m/EIOBAWKmNdJPo12uujrVilOR0VFLadoYlrXPV3sDVg4VTErwr8 X-Received: by 2002:a50:f69c:0:b0:425:c96a:5c09 with SMTP id d28-20020a50f69c000000b00425c96a5c09mr29247770edn.256.1651133646452; Thu, 28 Apr 2022 01:14:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1651133646; cv=none; d=google.com; s=arc-20160816; b=y7hdvn1VWBCliqm8FqZcFC5BStURLzZHryz0bYLw7ETdrBl8XOZycfrWbRLzEs+01l EB/UZWVDhyJ7zpaO37SotrW+blcaP7TaiUvLRsU9ZC+bO3HYMHZ9YDuvjzUtH+HBmm8L 38fAb2oSmG7Hmo4zBLqjuG8ShBs9WySKZwHKJd/AXnGpfuBANWH1pXU1qwI1mQRZHAG/ cvJ4SKj4naPk4b+azaKPpE5WF0OWrQGBD5HOPqUOsMySGO6Qc1OP8+be40Dd6cs2pZVC PUxo5arRbRiII8fy2KaM5Ab3e7ntTp+AYwzrf9h2zQSZOeEbe0KFIQMDrf0oaqD7UJiy tR/w== 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=pWxQ99sUASXABUsqKS5sp+tF6e1iyMlVSlL0Ow7hKQc=; b=RW466IoIOSamOTdFX8SVZYtUVNlyMiejeuK0q5od/7oLJf/qMFz+LY4NOrRIx3L9Zt tDaKfJ+He2hm+KGwHOD2zgvAmjnQtJZC/T9qYE2jEGzs/ezPOtP7hGFy8B0lBUR0D1Ix OpPfKNK5rhgEK/gBzAPurSPhm/hM0r+ImvaZHGDoRov++5wkxwacplAN2QaZvHfHb5Ir SfDmCkHJv3e7Y2bCD1upHtk3s3wn0KuHCsdFlxgXYSt2Mz6o6JpfWRmB2BcHws5UhuNK B7Fy46S4tPn6U4TiTRbAVCt02ck7wxz3xFTMTTO7KQVXArPC/9G0NrNUERri9mOukoH6 D0PA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Utiguflj; 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 bc25-20020a056402205900b00425be73e318si3406539edb.347.2022.04.28.01.14.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:14:06 -0700 (PDT) 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=Utiguflj; 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 08D4D83F05; Thu, 28 Apr 2022 10:12:56 +0200 (CEST) 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="Utiguflj"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 7431681D4B; Thu, 28 Apr 2022 10:11:34 +0200 (CEST) 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 autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pg1-x536.google.com (mail-pg1-x536.google.com [IPv6:2607:f8b0:4864:20::536]) (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 09C6383EDF for ; Thu, 28 Apr 2022 10:11:24 +0200 (CEST) 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-pg1-x536.google.com with SMTP id t13so3376470pgn.8 for ; Thu, 28 Apr 2022 01:11:23 -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; bh=pWxQ99sUASXABUsqKS5sp+tF6e1iyMlVSlL0Ow7hKQc=; b=UtigufljGbSsdiEQBy5oBw92D5xdneuX6ndi0esyCWn9CrGfXrSRkjAm40/3NhvQhH LRiPjcKseOtEukNLl0GhzIEVMYV8ixYo5AFukQG/OBZY5+qkkb4+I83UoQyqWyc0lA+J IwD/KWFvaAKNmeZHzSV+8YEFViUPkxeZ7d1b2SBUD9NoudOycW3I/cJlbAmA/lrzoZyk FTcYWuWkO6MYIwxDKbyOr1TPi59eXX4w+b606kzq0ZEQG+oHywtw0AH4XYyTRpq7cADs 5g1kqEh6sJcI8D2+5r5wzyvNPJZyXWc7Ub8gRvyLMJhmw/VUheWiIPqbhWWlUqVXFw6r Z3gQ== 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=pWxQ99sUASXABUsqKS5sp+tF6e1iyMlVSlL0Ow7hKQc=; b=hHohv3cZsGPNzaK8VA/VsdLLhsssWKhkcJX0psDZRgzFTSqE5o6vROv66kPhAzK3p7 LnZ0vZ5HwWTrUfIEYkDIIt74tWsr1+ToWoA6EFQuPuUA3eVi6MRbc46vzu2Z9Ss65Iwn gXnQQNp+owoB6hHnL+T5wXM13ghZValT8rOz6o7J8fEWbZowgW5rycaWOvsFlcDih0rk pxp0vDU8ODzLO8W+yW+6ijkK7dXXVdvuEdkHFP+f9kH9Oq8fN2ja8QZDo80N8txjb+Da qe0Z8fVGY2w2ZfxoafXUbCuxg4tdF5YMIY5dAmipaAGnFPvTBKo4j/Pu5YUmextGjCkg ZLSQ== X-Gm-Message-State: AOAM532Kv382Y80caIetU3Squ9K4rWSKVUngec5Q/beegKLo7aWuGK34 B0v4eMzRvmaXOw4iLEm7sdYyLKYe4oVTwQ== X-Received: by 2002:a63:8c1a:0:b0:3ab:35b8:bb02 with SMTP id m26-20020a638c1a000000b003ab35b8bb02mr16773677pgd.546.1651133482173; Thu, 28 Apr 2022 01:11:22 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id b15-20020a17090a7acf00b001cd4989ff5fsm5684259pjl.38.2022.04.28.01.11.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:11:21 -0700 (PDT) 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: [PATCH v5 16/17] bootmenu: add removable media entries Date: Thu, 28 Apr 2022 17:09:49 +0900 Message-Id: <20220428080950.23509-17-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220428080950.23509-1-masahisa.kojima@linaro.org> References: <20220428080950.23509-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 UEFI specification requires booting from removal media using a architecture-specific default image name such as BOOTAA64.EFI. This commit adds the removable media entries into bootmenu, so that user can select the removable media and boot with default image. The bootmenu automatically enumerates the possible bootable media devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, add it as new UEFI boot option(BOOT####) and update BootOrder variable. This automatically generated UEFI boot option has the dedicated guid in the optional_data to distinguish it from the UEFI boot option user adds manually. This commit also provides the BOOT#### variable maintenance feature. Depending on the system hardware setup, some devices may not exist at a later system boot, so bootmenu checks the available device in each bootmenu invocation and automatically removes the BOOT#### variable corrensponding to the non-existent media device. Signed-off-by: Masahisa Kojima --- Changes in v5: - Return EFI_SUCCESS if there is no BootOrder defined - correctly handle the case if no removable device found - use guid to identify the automatically generated entry by bootmenu Newly created in v4 cmd/bootmenu.c | 94 +++++++++++++++ include/efi_loader.h | 20 ++++ lib/efi_loader/efi_bootmenu_maintenance.c | 139 ++++++++++++++++++++++ 3 files changed, 253 insertions(+) diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index 860cb83182..970db3ee01 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -396,6 +396,89 @@ static int is_blk_device_available(char *token) return -ENODEV; } +/** + * prepare_media_device_entry() - generate the media device entries + * + * This function enumerates all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL + * and generate the bootmenu entries. + * This function also provide the BOOT#### variable maintenance for + * the media device entries. + * - Automatically create the BOOT#### variable for the newly detected device, + * this BOOT#### variable is distinguished by the special GUID + * stored in the EFI_LOAD_OPTION.optional_data + * - If the device is not attached to the system, the associated BOOT#### variable + * is automatically deleted. + * + * Return: status code + */ +static efi_status_t prepare_media_device_entry(void) +{ + u32 i; + efi_status_t ret; + efi_uintn_t count; + efi_handle_t *volume_handles = NULL; + struct efi_bootmenu_media_boot_option *opt = NULL; + + ret = efi_locate_handle_buffer_int(BY_PROTOCOL, &efi_simple_file_system_protocol_guid, + NULL, &count, (efi_handle_t **)&volume_handles); + if (ret != EFI_SUCCESS) + return ret; + + opt = calloc(count, sizeof(struct efi_bootmenu_media_boot_option)); + if (!opt) + goto out; + + /* enumerate all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL */ + ret = efi_bootmenu_enumerate_boot_option(opt, volume_handles, count); + if (ret != EFI_SUCCESS) + goto out; + + /* + * System hardware configuration may vary depending on the user setup. + * The boot option is automatically added by the bootmenu. + * If the device is not attached to the system, the boot option needs + * to be deleted. + */ + ret = efi_bootmenu_delete_invalid_boot_option(opt, count); + if (ret != EFI_SUCCESS) + goto out; + + /* add non-existent boot option */ + for (i = 0; i < count; i++) { + u32 boot_index; + u16 var_name[9]; + + if (!opt[i].exist) { + ret = efi_bootmenu_get_unused_bootoption(var_name, sizeof(var_name), + &boot_index); + if (ret != EFI_SUCCESS) + goto out; + + ret = efi_set_variable_int(var_name, &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + opt[i].size, opt[i].lo, false); + if (ret != EFI_SUCCESS) + goto out; + + ret = efi_bootmenu_append_bootorder(boot_index); + if (ret != EFI_SUCCESS) + goto out; + } + } + +out: + if (opt) { + for (i = 0; i < count; i++) + free(opt[i].lo); + } + free(opt); + efi_free_pool(volume_handles); + + return ret; +} + /** * prepare_distro_boot_entry() - generate the distro boot entries * @@ -500,6 +583,7 @@ static int prepare_distro_boot_entry(struct bootmenu_data *menu, static struct bootmenu_data *bootmenu_create(int delay) { int ret; + efi_status_t efi_ret; unsigned short int i = 0; struct bootmenu_data *menu; struct bootmenu_entry *iter = NULL; @@ -523,6 +607,16 @@ static struct bootmenu_data *bootmenu_create(int delay) goto cleanup; if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) { + if (i < MAX_DYNAMIC_ENTRY) { + /* + * UEFI specification requires booting from removal media using + * a architecture-specific default image name such as BOOTAA64.EFI. + */ + efi_ret = prepare_media_device_entry(); + if (efi_ret != EFI_SUCCESS && efi_ret != EFI_NOT_FOUND) + goto cleanup; + } + if (i < MAX_DYNAMIC_ENTRY) { ret = prepare_uefi_bootorder_entry(menu, &iter, &i); if (ret < 0 && ret != -ENOENT) diff --git a/include/efi_loader.h b/include/efi_loader.h index 533618341b..bef492ccb9 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -928,6 +928,22 @@ struct efi_signature_store { struct x509_certificate; struct pkcs7_message; +/** + * struct efi_bootmenu_media_boot_option - boot option for (removable) media device + * + * This structure is used to enumerate possible boot option + * + * @lo: Serialized load option data + * @size: Size of serialized load option data + * @exist: Flag to indicate the load option already exists + * in Non-volatile load option + */ +struct efi_bootmenu_media_boot_option { + void *lo; + efi_uintn_t size; + bool exist; +}; + bool efi_signature_lookup_digest(struct efi_image_regions *regs, struct efi_signature_store *db, bool dbx); @@ -1076,6 +1092,10 @@ efi_status_t efi_console_get_u16_string efi_status_t efi_bootmenu_get_unused_bootoption(u16 *buf, efi_uintn_t buf_size, u32 *index); efi_status_t efi_bootmenu_append_bootorder(u16 index); +efi_status_t efi_bootmenu_enumerate_boot_option(struct efi_bootmenu_media_boot_option *opt, + efi_handle_t *volume_handles, efi_status_t count); +efi_status_t efi_bootmenu_delete_invalid_boot_option(struct efi_bootmenu_media_boot_option *opt, + efi_status_t count); efi_status_t efi_disk_get_device_name(struct efi_block_io *this, char *buf, int size); diff --git a/lib/efi_loader/efi_bootmenu_maintenance.c b/lib/efi_loader/efi_bootmenu_maintenance.c index 8c3f94c695..33b37fd11a 100644 --- a/lib/efi_loader/efi_bootmenu_maintenance.c +++ b/lib/efi_loader/efi_bootmenu_maintenance.c @@ -26,6 +26,13 @@ static struct efi_simple_text_output_protocol *cout; #define EFI_BOOTMENU_BOOT_NAME_MAX 32 #define EFI_BOOT_ORDER_MAX_SIZE_IN_DECIMAL 6 +#define EFI_BOOTMENU_AUTO_GENERATED_ENTRY_GUID \ + EFI_GUID(0x38c1acc1, 0x9fc0, 0x41f0, \ + 0xb9, 0x01, 0xfa, 0x74, 0xd6, 0xd6, 0xe4, 0xde) + +static const efi_guid_t efi_guid_bootmenu_auto_generated = + EFI_BOOTMENU_AUTO_GENERATED_ENTRY_GUID; + typedef efi_status_t (*efi_bootmenu_entry_func)(void *data, bool *exit); /** @@ -1104,3 +1111,135 @@ efi_status_t efi_bootmenu_show_maintenance_menu(void) ARRAY_SIZE(maintenance_menu_items), -1); } + +efi_status_t efi_bootmenu_enumerate_boot_option(struct efi_bootmenu_media_boot_option *opt, + efi_handle_t *volume_handles, efi_status_t count) +{ + u32 i; + struct efi_handler *handler; + efi_status_t ret = EFI_SUCCESS; + + for (i = 0; i < count; i++) { + char *optional_data; + u16 *dev_name, *p; + struct efi_load_option lo; + struct efi_block_io *block_io; + char buf[BOOTMENU_DEVICE_NAME_MAX]; + struct efi_device_path *device_path; + + ret = efi_search_protocol(volume_handles[i], &efi_guid_device_path, &handler); + if (ret != EFI_SUCCESS) + continue; + ret = efi_protocol_open(handler, (void **)&device_path, + efi_root, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) + continue; + + ret = efi_search_protocol(volume_handles[i], &efi_block_io_guid, &handler); + if (ret != EFI_SUCCESS) + continue; + ret = efi_protocol_open(handler, (void **)&block_io, + efi_root, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) + continue; + + efi_disk_get_device_name(block_io, buf, BOOTMENU_DEVICE_NAME_MAX); + dev_name = calloc(1, (strlen(buf) + 1) * sizeof(u16)); + if (!dev_name) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + p = dev_name; + utf8_utf16_strncpy(&p, buf, strlen(buf)); + + lo.label = dev_name; + lo.attributes = LOAD_OPTION_ACTIVE; + lo.file_path = device_path; + lo.file_path_length = efi_dp_size(device_path) + sizeof(END); + /* + * Set the dedicated guid to optional_data, it is used to identify + * the boot option that automatically generated by the bootmenu. + * efi_serialize_load_option() expects optional_data is null-terminated + * utf8 string, so set the "dummystr" string to allocate enough space + * to store guid, instead of realloc the load_option. + * + * This will allocate 16 bytes for guid plus trailing 0x0000. + * The guid does not require trailing 0x0000, but it is for safety + * in case some program handle the optional_data as u16 string. + */ + lo.optional_data = "dummystr"; + opt[i].size = efi_serialize_load_option(&lo, (u8 **)&opt[i].lo); + if (!opt[i].size) { + ret = EFI_OUT_OF_RESOURCES; + free(dev_name); + goto out; + } + /* set the guid */ + optional_data = (char *)opt[i].lo + (opt[i].size - u16_strsize(u"dummystr")); + memcpy(optional_data, &efi_guid_bootmenu_auto_generated, sizeof(efi_guid_t)); + free(dev_name); + } + +out: + return ret; +} + +efi_status_t efi_bootmenu_delete_invalid_boot_option(struct efi_bootmenu_media_boot_option *opt, + efi_status_t count) +{ + u16 *bootorder; + u32 i, j; + efi_status_t ret; + efi_uintn_t num, size, bootorder_size; + void *load_option; + struct efi_load_option lo; + u16 varname[] = u"Boot####"; + + bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &bootorder_size); + if (!bootorder) + return EFI_SUCCESS; /* BootOrder is not defined, nothing to do */ + + num = bootorder_size / sizeof(u16); + for (i = 0; i < num;) { + efi_uintn_t tmp; + + efi_create_indexed_name(varname, sizeof(varname), + "Boot", bootorder[i]); + load_option = efi_get_var(varname, &efi_global_variable_guid, &size); + if (!load_option) + goto next; + + tmp = size; + ret = efi_deserialize_load_option(&lo, load_option, &tmp); + if (ret != EFI_SUCCESS) + goto next; + + if (guidcmp(lo.optional_data, &efi_guid_bootmenu_auto_generated) == 0) { + for (j = 0; j < count; j++) { + if (memcmp(opt[j].lo, load_option, size) == 0) { + opt[j].exist = true; + break; + } + } + + if (j == count) { + ret = delete_boot_option(bootorder, i, bootorder_size); + if (ret != EFI_SUCCESS) { + free(load_option); + goto out; + } + + num--; + bootorder_size -= sizeof(u16); + free(load_option); + continue; + } + } +next: + free(load_option); + i++; + } + +out: + return ret; +} From patchwork Thu Apr 28 08:09:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 567142 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:6886:0:0:0:0 with SMTP id m6csp5234141map; Thu, 28 Apr 2022 01:14:26 -0700 (PDT) X-Google-Smtp-Source: ABdhPJx2qTowF5X5oSX2aC/bOJ+jJKb3HPTH+QjdSLexxRrxZNM3gpsoHGv+MbRJO2BP6Id1UE3j X-Received: by 2002:a17:907:60cc:b0:6e0:dab3:ca76 with SMTP id hv12-20020a17090760cc00b006e0dab3ca76mr30840046ejc.154.1651133665929; Thu, 28 Apr 2022 01:14:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1651133665; cv=none; d=google.com; s=arc-20160816; b=maqK86bUWq7ceBr4vzAcyD+ZaHMl/wFtPQ/r7oFO/O3/iYFpGQHcsWJ139WzkJ7CM6 R1xWomMJHp2daRM7qEG4s85pXzDVkof8tucfgIn3mALzrL1FCVNBPUM9/dphksAepo1e QstcDpaAHMyCkwZ8G8n16dMEssOZasypUGdihXsLmvYCSXSiNG7xmX10Y8ssPJhzmWwi hJvVRZ8aF8WqQ8GXV8IVSxXGqGxylkQfnceaxwxp7HXy3OjF/QaNpGMsbTCmp+p8gtL8 BIfyD0J4noPTsMzJFesqwhesYUcCgZ6P34cMSEKyBkBYzsV+aiKNvWwWkKZtkRU1T4QW xgow== 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=j4+xFl2NCt+5DKN4t2mKZg+8zPhPf9la8CGdTf5s7H8=; b=elhOPb0uZw48JorjW1MY2GudU+1qb1QDjIQAfjomZxGhw5jCm9+SMfQv4W33FJG4KF uIm+I+sqkfUR3qC71nWrRlG54GZPvOAFFpvrpU41+MhTk4NPGOjCn/wse6wx/Cr5699S aQ8sZH3gZe4lfvyksYmPt5QbgcviXR7gF2NVT7xZj4AgEUaMS7C2bxJ4DRBbESovaUDu ghKWvERQBylw6SsDvuncj0nMNeDAxUb1rfF6ld/D3Dvyg9pSKQfEnwDiYBVgf3pe6oct OXO/k0x6EQkdd2uYn3+Q12E/5J5yw3d83zaMMBFdJBN5sjJWqhpZCpBnMSRshsEMskaL TFxQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=YHWhcdiI; 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 ec12-20020a170906b6cc00b006f35c423230si3414682ejb.239.2022.04.28.01.14.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:14:25 -0700 (PDT) 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=YHWhcdiI; 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 EF20583F1C; Thu, 28 Apr 2022 10:13:07 +0200 (CEST) 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="YHWhcdiI"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id EF8D483EE2; Thu, 28 Apr 2022 10:11:40 +0200 (CEST) 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 autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pg1-x52e.google.com (mail-pg1-x52e.google.com [IPv6:2607:f8b0:4864:20::52e]) (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 C339483EED for ; Thu, 28 Apr 2022 10:11:28 +0200 (CEST) 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-pg1-x52e.google.com with SMTP id k14so3421478pga.0 for ; Thu, 28 Apr 2022 01:11:28 -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; bh=j4+xFl2NCt+5DKN4t2mKZg+8zPhPf9la8CGdTf5s7H8=; b=YHWhcdiIi/1eIXCPhblfQxPJ4IaqEJ3c2QQDxirkcCUpzu+6WuAqXmJpRmcez4aXjk JP3ou+xt5RCYwTIRUqqwuw4jw7Twh32gIbV37/xxdYSUrPZ95jAflOnrz0sqqCNq/nsO dMB8UlMxVM/niX1JXQQeyiu9WJzF7SqRf9zTC1gpMFvrcrqKuN5dZ7nmcxTeBZvKrEa4 E8skGCFgv7EDBPz74XeP59EJrl2BHdB0UwqCNinIwrWh3vFq5mo8ckLwVLqvdPzPEHAx afM7IcBz1/99DJ7t0Zw1p3JCTOe+AhcUumJtm3odX3kikcdf+ohPfJPGe9UGBq0YzHhC tpMQ== 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=j4+xFl2NCt+5DKN4t2mKZg+8zPhPf9la8CGdTf5s7H8=; b=mliV6uYUvdQ0rQCVMy2tE45Hr5+8FDQqwyvY0D5uyyCZo9iKLCYnRwrdfOMFNoeEFp K/zFwor7M3gv9LqkMgVYntL2F4rTeeMStRoc3MwSRX5VJafLB5NS0D3iFKMNUlatC/6b V3oFikwJqfbkQ0aWVI4C+y7DF5pZ2XxPazI+hookT4MfcLs18w5tVESVlzLTA5sEKAnr Qora+yd7a59ONId7NS20k++Yk68UczzVoHsU+NqkQtB1ojwxuJl0wEcUiVEIzQMNLl8c f0bQv3hjehF2HxzyUMS7zDyrw4f3PCPdvuked6nKyluQMGVfL+5l0mDbme6OCQaUys0S jEHw== X-Gm-Message-State: AOAM532UNg5Kd7mQoTJfbDZ3zJSsNLBI/6C5ydD5kUlfIHmBmgi622It PFGkon60f+hJSMhHP4HwYcL0rBRte0r7bg== X-Received: by 2002:a65:460d:0:b0:39d:13e0:d571 with SMTP id v13-20020a65460d000000b0039d13e0d571mr27046238pgq.596.1651133485084; Thu, 28 Apr 2022 01:11:25 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id b15-20020a17090a7acf00b001cd4989ff5fsm5684259pjl.38.2022.04.28.01.11.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Apr 2022 01:11:24 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Francois Ozog , Mark Kettenis , Masahisa Kojima , Bin Meng Subject: [PATCH v5 17/17] doc:bootmenu: add UEFI boot and distro boot support description Date: Thu, 28 Apr 2022 17:09:50 +0900 Message-Id: <20220428080950.23509-18-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220428080950.23509-1-masahisa.kojima@linaro.org> References: <20220428080950.23509-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 The bootmenu enumerates the UEFI boot options and distro boot (boot_targets) for boot device selection. This commit adds the description how the UEFI boot and distro boot work in bootmenu. This commit also adds "Synopsis", "Description" and "Configuration" sections to follow the U-Boot command documentation format. Signed-off-by: Masahisa Kojima --- Changes in v5: - follow the cmd documentation format same as other command, add "Synopsis", "Description" add "Configuration" sections Newly created in v4 doc/usage/cmd/bootmenu.rst | 78 +++++++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/doc/usage/cmd/bootmenu.rst b/doc/usage/cmd/bootmenu.rst index 1016ac8ceb..48f76a82a3 100644 --- a/doc/usage/cmd/bootmenu.rst +++ b/doc/usage/cmd/bootmenu.rst @@ -4,7 +4,17 @@ bootmenu command ================ -The "bootmenu" command uses U-Boot menu interfaces and provides +Synopsis +-------- + +:: + + bootmenu + +Description +----------- + +The *bootmenu* command uses U-Boot menu interfaces and provides a simple mechanism for creating menus with different boot items. The cursor keys "Up" and "Down" are used for navigation through the items. Current active menu item is highlighted and can be @@ -79,6 +89,67 @@ The above example will be rendered as below:: The selected menu entry will be highlighted - it will have inverted background and text colors. +UEFI boot variable enumeration +'''''''''''''''''''''''''''''' + +The bootmenu automatically generates the UEFI boot variable("BOOT####") +in order of "BootOrder". When the user selects the UEFI boot +variable entry, bootmenu sets the selected boot variable index +to "BootNext", then call the uefi boot manager with the command +"bootefi bootmgr". + +The bootmenu automatically enumerates the possible bootable +media devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL. + +The bootmenu prints the EFI_LOAD_OPTION.Description[] as title +of the entry together with "UEFI" prefix and BOOT#### variable name. + +Example bootmenu is as below:: + + *** U-Boot Boot Menu *** + + UEFI BOOT0000 : mmc0:1 + UEFI BOOT0001 : mmc0:2 + UEFI BOOT0002 : debian + UEFI BOOT0003 : nvme0:1 + UEFI BOOT0004 : ubuntu + UEFI BOOT0005 : nvme0:2 + UEFI BOOT0006 : usb0:2 + +To scan the discoverable devices connected to the buses such as +USB and PCIe prior to bootmenu showing up, CONFIG_PREBOOT can be +used to run the command before showing the bootmenu, i.e.:: + + CONFIG_USE_PREBOOT=y + CONFIG_PREBOOT="pci enum; usb start; scsi scan; nvme scan; virtio scan" + +distro boot command enumeration +''''''''''''''''''''''''''''''' + +The bootmenu also automatically generates the entries for +distro boot command. The bootmenu shows the devices in boot_targets +environment variable. +When the user selects the distro boot command entry, the bootmenu +runs the command defined in "bootcmd_xxx" environment variable. +As an example, if user selects "usb0" entry, bootmenu runs the +command defined in "bootcmd_usb0". + +Example boot_targets:: + + usb0, scsi0, nvme0, dhcp + +Example bootmenu is as below:: + + *** U-Boot Boot Menu *** + + distro_boot : usb0 + distro_boot : scsi0 + distro_boot : nvme0 + distro_boot : dhcp + +Configuration +------------- + The "bootmenu" cammand is enabled by:: CONFIG_CMD_BOOTMENU=y @@ -88,3 +159,8 @@ To run the bootmenu at startup add these additional settings:: CONFIG_AUTOBOOT_KEYED=y CONFIG_BOOTDELAY=30 CONFIG_AUTOBOOT_MENU_SHOW=y + +To improve the product security, entering U-Boot console from bootmenu +can be disabled by:: + + CONFIG_CMD_BOOTMENU_ENTER_UBOOT_CONSOLE=n