From patchwork Sun Jan 17 03:07:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Norris X-Patchwork-Id: 1427675 X-Patchwork-Delegate: mail@aparcar.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.openwrt.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=UvshRS0I; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=DEUY+Y5h; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DJKfN1z0vz9sWV for ; Sun, 17 Jan 2021 14:10:04 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=dOwgcaZ1AKaPDbydsvbcKRXdvxlw0kMVG8/JFh2ikh8=; b=UvshRS0IOwx4FVLJPH2+QIO0o kbKBxRLiBUlbcBukWsK//b12O57/8pEhr8I77iopREokb7v+0bbxfgYHs0H1uP0IXtOejmq3vos9F HR32Y8x1RGXUvBQQsfNlr7/mTyEFLzObM1+ldd9jWhUcRLVnmtXzTGcwcXh2eE99PRoJHtt4vanzy Ss9SE00QCsbwqVbip+t19gQRTA/JJ0y1HlVouNIcXNuelxjjo1Cp+E4Xz0aCXOT1Grby6fWYhEDA3 v0qf2laC9iyNPEgRSuPQ6Gc9Sc6GK2Jg2ws4OqA9bF5ind1SYrWX+Om1d+/gyOqygRQKP4DhMKq5B 6G1+u8/JQ==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0yPc-00048F-GG; Sun, 17 Jan 2021 03:07:32 +0000 Received: from mail-pl1-x633.google.com ([2607:f8b0:4864:20::633]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1l0yPY-000469-4H for openwrt-devel@lists.openwrt.org; Sun, 17 Jan 2021 03:07:29 +0000 Received: by mail-pl1-x633.google.com with SMTP id b8so6755122plx.0 for ; Sat, 16 Jan 2021 19:07:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=cHxoKB2nY6JjYJHElMBQmdGEsk5I8FQoIQajB2DnFzw=; b=DEUY+Y5hukC4Q9BR1fijc1CwcANmy6++KpfVvBqWHEzRbvbVaxMpfZFrjkl2XPdprT Apmx/lL4Ooza3c6Ft2Ub/fihhb3aQ51M7f+jhsLUmZedww7PVkwbvSia4XmKafUAcaz0 PrhrB5Ih9bI1feukU29U+qhP0LlhIunqIGtS6YbA7U533GX5iih5WUleJoSaVsJ/FEFS IZgH2bQvu3QGCUo4L6xMKj8L+q9unUwB47Hm2pz/QbxGfxAPqg3BoXPUbonP6QMNY5TO OiFx4HAngSgSPvjv40tl02yP9zc6Ws/a3F61gJpoCcaAkmVmbwuXXKfauC5l7XffOkCH Jpig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cHxoKB2nY6JjYJHElMBQmdGEsk5I8FQoIQajB2DnFzw=; b=dX2PssoQLFcxtBL3j7kRLcwO/Or2eZb99ngvUEjzZV4nM51ygg51+JBF4usehTnMnR SMlqZ3oXY/sqc7GdmruA0Evj21/txj9PntGb88ZzqmPUoLn5o4pAQuqhd/8yUsUOnz8k i9x2vb8ayM071fdxcwYf2bhQlVXlh1BdjPRa762UE+dwhIrpATnqA/nn+L1Ggf80FZ9V T4/+piR5mVbHvgHWXXSG5DkFh8jDdRp5Lgv0+rCTz82axiwy+QJK0wI7SS7Cim8Mgh/f VM8VLa5okOCax93xJEJU6YU/mY/NzYL4vQoqWd4XwiIgPcxr3m13ywAWwwlz9ywg4fhO c+GA== X-Gm-Message-State: AOAM533BwXU3YJ2K4g78hoDe1Pe0Z/J4VNJzip5LldgUxNlZfpEHs7dP htk+1eS++QB+Ac0L09GL62FHiOT2ztg= X-Google-Smtp-Source: ABdhPJxx8TlWxfHPeXXMxrQc+5A8uITfWUyw2gMg1vAdKZWwWjOZVh8dSpNWgzddeHMyP2mdfyE2YQ== X-Received: by 2002:a17:90a:f2d6:: with SMTP id gt22mr3419350pjb.110.1610852840255; Sat, 16 Jan 2021 19:07:20 -0800 (PST) Received: from localhost ([2601:647:5800:2ac5:9eef:d5ff:fefc:64ae]) by smtp.gmail.com with ESMTPSA id p22sm12668640pgk.21.2021.01.16.19.07.19 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 16 Jan 2021 19:07:19 -0800 (PST) From: Brian Norris To: openwrt-devel@lists.openwrt.org Subject: [PATCH v2 1/4] firmware-utils/ptgen: add Chromium OS kernel partition support Date: Sat, 16 Jan 2021 19:07:03 -0800 Message-Id: <20210117030707.1251501-2-computersforpeace@gmail.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210117030707.1251501-1-computersforpeace@gmail.com> References: <20210117030707.1251501-1-computersforpeace@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210116_220728_301687_EEB49389 X-CRM114-Status: GOOD ( 19.75 ) X-Spam-Score: -0.2 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-0.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:633 listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [computersforpeace[at]gmail.com] -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Brian Norris Sender: "openwrt-devel" Errors-To: openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org Chrom{ium,e} OS (shortened as "CrOS") bootloaders use a custom GPT partition type to locate their kernel(s), with custom attributes for noting properties around which partition(s) should be active and how many times they've been tried as part of their A/B in-place upgrade system. OpenWRT doesn't use A/B updates for upgrades (instead, just shutting things down far enough to reprogram the necessary partitions), so all we need to do is tell the bootloader which one is the kernel partition, and how to use it (i.e., set the "successful" and "priority" attributes). ptgen already supports some basic GPT partition creation, so just add support for a '-T ' argument. Currently, this only supports '-T cros_kernel', but it could be extended if there are other GPT partition types needed. For GPT attribute and GUID definitions, see the CrOS verified boot sources: https://chromium.googlesource.com/chromiumos/platform/vboot_reference/+/refs/heads/master/firmware/lib/cgptlib/include/cgptlib_internal.h https://chromium.googlesource.com/chromiumos/platform/vboot_reference/+/refs/heads/master/firmware/include/gpt.h The GUID is also recognized in fdisk, and likely other utilities, but creation/manipulation is typically done via the 'cgpt' utility, provided as part of the vboot_reference project. Signed-off-by: Brian Norris --- tools/firmware-utils/src/ptgen.c | 39 +++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/tools/firmware-utils/src/ptgen.c b/tools/firmware-utils/src/ptgen.c index 223ee295611f..bc1da6d64061 100644 --- a/tools/firmware-utils/src/ptgen.c +++ b/tools/firmware-utils/src/ptgen.c @@ -80,6 +80,10 @@ typedef struct { GUID_INIT( 0x21686148, 0x6449, 0x6E6F, \ 0x74, 0x4E, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49) +#define GUID_PARTITION_CHROME_OS_KERNEL \ + GUID_INIT( 0xFE3A2A5D, 0x4F32, 0x41A7, \ + 0xB7, 0x25, 0xAC, 0xCC, 0x32, 0x85, 0xA3, 0x09) + #define GPT_HEADER_SIZE 92 #define GPT_ENTRY_SIZE 128 #define GPT_ENTRY_MAX 128 @@ -109,6 +113,9 @@ struct partinfo { unsigned long start; unsigned long size; int type; + bool has_gtype; + guid_t gtype; /* GPT partition type */ + uint64_t gattr; /* GPT partition attributes */ }; /* GPT Partition table header */ @@ -248,6 +255,19 @@ static inline int guid_parse(char *buf, guid_t *guid) return 0; } +/* Map GPT partition types to partition GUIDs. */ +static inline bool parse_gpt_parttype(const char *type, struct partinfo *part) +{ + if (!strcmp(type, "cros_kernel")) { + part->has_gtype = true; + part->gtype = GUID_PARTITION_CHROME_OS_KERNEL; + part->gattr = (1ULL << 48) | /* priority=1 */ + (1ULL << 56); /* success=1 */ + return true; + } + return false; +} + /* init an utf-16 string from utf-8 string */ static inline void init_utf16(char *str, uint16_t *buf, unsigned bufsize) { @@ -396,12 +416,15 @@ static int gen_gptable(uint32_t signature, guid_t guid, unsigned nr) gpte[i].end = cpu_to_le64(sect -1); gpte[i].guid = guid; gpte[i].guid.b[sizeof(guid_t) -1] += i + 1; - if (parts[i].type == 0xEF || (i + 1) == (unsigned)active) { + if (parts[i].has_gtype) { + gpte[i].type = parts[i].gtype; + } else if (parts[i].type == 0xEF || (i + 1) == (unsigned)active) { gpte[i].type = GUID_PARTITION_SYSTEM; init_utf16("EFI System Partition", (uint16_t *)gpte[i].name, GPT_ENTRY_NAME_SIZE / sizeof(uint16_t)); } else { gpte[i].type = GUID_PARTITION_BASIC_DATA; } + gpte[i].attr = parts[i].gattr; if (verbose) fprintf(stderr, "Partition %d: start=%" PRIu64 ", end=%" PRIu64 ", size=%" PRIu64 "\n", @@ -498,7 +521,9 @@ fail: static void usage(char *prog) { - fprintf(stderr, "Usage: %s [-v] [-n] [-g] -h -s -o [-a 0..4] [-l ] [-G ] [[-t ] -p [@]...] \n", prog); + fprintf(stderr, "Usage: %s [-v] [-n] [-g] -h -s -o \n" + " [-a 0..4] [-l ] [-G ]\n" + " [[-t | -T ] -p [@]...] \n", prog); exit(EXIT_FAILURE); } @@ -512,7 +537,7 @@ int main (int argc, char **argv) guid_t guid = GUID_INIT( signature, 0x2211, 0x4433, \ 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0x00); - while ((ch = getopt(argc, argv, "h:s:p:a:t:o:vngl:S:G:")) != -1) { + while ((ch = getopt(argc, argv, "h:s:p:a:t:T:o:vngl:S:G:")) != -1) { switch (ch) { case 'o': filename = optarg; @@ -560,6 +585,14 @@ int main (int argc, char **argv) case 'S': signature = strtoul(optarg, NULL, 0); break; + case 'T': + if (!parse_gpt_parttype(optarg, &parts[part])) { + fprintf(stderr, + "Invalid GPT partition type \"%s\"\n", + optarg); + exit(EXIT_FAILURE); + } + break; case 'G': if (guid_parse(optarg, &guid)) { fputs("Invalid guid string\n", stderr);