From patchwork Fri Jul 14 06:46:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefano Babic X-Patchwork-Id: 1807561 X-Patchwork-Delegate: sbabic@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=googlegroups.com (client-ip=2a00:1450:4864:20::33f; helo=mail-wm1-x33f.google.com; envelope-from=swupdate+bncbcxploxj6ikrbzw6yosqmgqemcnvixa@googlegroups.com; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=googlegroups.com header.i=@googlegroups.com header.a=rsa-sha256 header.s=20221208 header.b=Bpkc+h27; dkim-atps=neutral Received: from mail-wm1-x33f.google.com (mail-wm1-x33f.google.com [IPv6:2a00:1450:4864:20::33f]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4R2MTp6QKxz20c1 for ; Fri, 14 Jul 2023 16:47:09 +1000 (AEST) Received: by mail-wm1-x33f.google.com with SMTP id 5b1f17b1804b1-3fbcae05906sf7651065e9.3 for ; Thu, 13 Jul 2023 23:47:09 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1689317223; cv=pass; d=google.com; s=arc-20160816; b=rx1k0XRY404OrsRqmMmLYxKiY81E3Igjl/bLgG+vAya/vK/vobLZ9KSzhetE5BO+RS Nu//ph+ZySLy1mAOcABSy40RWYqNXFCFpBb4Gw1tqonClfbVuYSdWBwHX88OVJNKTz8Q +t5luLNkL3gE0G+yLuABdt5V9KqRkEv4p+I6CqoEHd4GRNDJqUbi8AooZ7Q6tiwvButV Fao9e9csZALw214sRBrYliRjLcC+ODaNCk2X4RQRniQFCG6++PxAzpPp0UOBHNhvaXsv iuFZgmE/RhrkwhWAR+U+2ee+jX+QZ70MVatGULqyamfdJKds4YPkwOkB+DzCr9Bxo6R1 St+g== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:mime-version:message-id:date :subject:cc:to:from:sender:dkim-signature; bh=SZOMa0MF7ErW250SyCshHgaY/MzyyeoMnqusKGS8iHI=; fh=lWBtl6pS9pyAnqZoOD8LO/oehp4+grVVQDFlD36xIhM=; b=WDfTwMOgIl6LxIgjr5XlyHZEuazYZe7rAGuKwtHouuOBAEPLPfAMMRvfWgkd4QbkCH KC0GzyzdtrUMusH0E+tYSWwupEoSZAAHq9KEP9i7IXVuCk4FEXdJ+Xnrju49osH/VSPI 6I04xm/OVBFpjgJi4xJEzr2IS/2RIM1HmCnqDb7aOK4rZDXuOp14SVOwDrIwhw4Se2Pn Eq7sj0mbaiDM75BdnIZthbBSJJw2H8p8CbTX7FXY9QQs0sCqMrgEyfpvT0s8Umrrn5g7 oW3TfPckhEUB+z6Rqn5C0EkIaMashVqrT58/GOUs2a12CThK4Sgbwj+reWGvMRvZ96VU IRAw== ARC-Authentication-Results: i=2; gmr-mx.google.com; spf=neutral (google.com: 2001:a60:0:28:0:1:25:1 is neither permitted nor denied by domain of sbabic@denx.de) smtp.mailfrom=sbabic@denx.de; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=denx.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=20221208; t=1689317223; x=1691909223; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:x-original-authentication-results :x-original-sender:mime-version:message-id:date:subject:cc:to:from :sender:from:to:cc:subject:date:message-id:reply-to; bh=SZOMa0MF7ErW250SyCshHgaY/MzyyeoMnqusKGS8iHI=; b=Bpkc+h27i+9zasaK2allsYD8IPxZRciucv3qa4AngdCi4xYdyiqsaFuIlp1xHeguCX o1e4agOq+HV0i2SV4osiD4L9B1y9BsgMLeMzLY0+OQf0wFD4JV3uxYsg3na4tLFvblJy Qndnj6q8Qwm1fJo4tROA1GXbEj6SseyR3U+3GXrPUZUKnZrxJmIuAwla11cHKBFLsyda uRZq4rSZ+bhI1g871eAHfHj/9sQeTSql5l7KxsMWWn04+kj5NuQLe35hJdbbXY7yG5ar 3LPWkgXF0ITPQMXt6R+eXirz+NWT8FxQgyQaiWzrUTLi0J7YXtXYo8yjV4gGp+DysGHf Vvog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689317223; x=1691909223; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :x-spam-checked-in-group:list-id:mailing-list:precedence :x-original-authentication-results:x-original-sender:mime-version :message-id:date:subject:cc:to:from:x-beenthere:x-gm-message-state :sender:from:to:cc:subject:date:message-id:reply-to; bh=SZOMa0MF7ErW250SyCshHgaY/MzyyeoMnqusKGS8iHI=; b=IIj+sjmgse5MIWLoBd8gW5La5NxK0ux8PTcDAXV8QLmfZtsOkUcXywr51AFJVrA0Yu TjtoquCvgdeB+uyeJ7N/g/P3JacyGePZ1ZAcPPKSknYjl+5BY/7u3/gdX8s4p5gnEh5p RR/Xta8KTfcXMhDihjwlZLXVJwXmEftmRFPXFNvVq+LKDmZtAzRxHg8bgojoOOjWH9kt Slfdq5eE6JFizpCwoJsHLuuruVQd3aFwDCjbbPpwxQplNjTdXQez64BakIKkOT3weJfE jn917CEcx9olCmoKD87HVnzcSOtjXA5vA0KzbYPyFDITqXLTRtPRiIX4Xypvr2oxfi4q kgZg== Sender: swupdate@googlegroups.com X-Gm-Message-State: ABy/qLZGicCDVZSazIw6xaw6ckuqasgrLEYoO+yaJVJGc38QHbMv2Qq5 zB7tcXvdVq9aFSvqcCGms0U= X-Google-Smtp-Source: APBJJlFtcRJ0hrDlWBbflMkogOpqu4bl6Qt3WeSzVDLxVO+49Xgj+rPtyJEFNJTF2E0dCb03gzzRhQ== X-Received: by 2002:a1c:f708:0:b0:3fb:d1db:545b with SMTP id v8-20020a1cf708000000b003fbd1db545bmr3744465wmh.20.1689317223354; Thu, 13 Jul 2023 23:47:03 -0700 (PDT) X-BeenThere: swupdate@googlegroups.com Received: by 2002:a05:600c:3b93:b0:3fb:422d:4ff8 with SMTP id n19-20020a05600c3b9300b003fb422d4ff8ls721969wms.1.-pod-prod-02-eu; Thu, 13 Jul 2023 23:47:01 -0700 (PDT) X-Received: by 2002:a7b:cd0c:0:b0:3f9:8c3:6805 with SMTP id f12-20020a7bcd0c000000b003f908c36805mr3717948wmj.7.1689317221253; Thu, 13 Jul 2023 23:47:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689317221; cv=none; d=google.com; s=arc-20160816; b=lrkZBAmcwrYjDlOcOn0s4FTYD83hU+BF+dBEey48ulRvTYrRDGiUU72HXVo0/Z2IVv ILYrvgIUNtqdRWMtHG+TlBXFmluO2Vu7on19TrBXPzGoz0dwHmFMJajjp6IwZNr1/2/a 50yi+CQBl3svM08sX5Q4v3yTPoUoFugckGTT4yF3vI6GbDUu1OafHqyjEmEjydrJBZ5A FGvvKkuAL9zGkyLwu1t4YqRNLStdg1yOKsB9ShtKEQguj0ExcaeI8SqcGWVC57YsjOJz 9eN3ONSXwdTyTfRbJIECRt7AxGa/QnZrChjKneu71cNwNb/kFxV3vBwq+57f/7aUQr4t QZSw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from; bh=T7Ja3Yp4+Du+Xd7+Ed823tlyzkGSu6+2jYl8FjzkNWc=; fh=lWBtl6pS9pyAnqZoOD8LO/oehp4+grVVQDFlD36xIhM=; b=jwnTL4cOLuN4VMPkMHxB+Q0HttXp+jC5To8MH7ywg8VOgd+wUU+T17v7vYjI45YxLS HrtXP2Q4ExjNOsgU/Hl77t0FjkQVWKKKEDv8EWhEX8pAfVffopM3FQme+K44NL2Kk6pq kepdtBo9FeKtbdvErg/3p82Jgwvsve5ngcL4pzUUkZz5HCrd/fqnOggx94+1lbnjE3Gb tKR//1i5hdU5wrrPglpEC+WrHGNBsg/DDTuVmMVtc2dPoRAqslgzKbbPKZD/eWTwi4dY UHdlWQZfEPdGlV1+ifEZmgQ0kO3YyJsSkDmMA01Vl7bP5cLInxzutCRglUXSnfrFQe7L ONmQ== ARC-Authentication-Results: i=1; gmr-mx.google.com; spf=neutral (google.com: 2001:a60:0:28:0:1:25:1 is neither permitted nor denied by domain of sbabic@denx.de) smtp.mailfrom=sbabic@denx.de; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=denx.de Received: from mail-out.m-online.net (mail-out.m-online.net. [2001:a60:0:28:0:1:25:1]) by gmr-mx.google.com with ESMTPS id fk8-20020a05600c0cc800b003fbca831b48si47188wmb.2.2023.07.13.23.47.01 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 13 Jul 2023 23:47:01 -0700 (PDT) Received-SPF: neutral (google.com: 2001:a60:0:28:0:1:25:1 is neither permitted nor denied by domain of sbabic@denx.de) client-ip=2001:a60:0:28:0:1:25:1; Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 4R2MTc6Fqzz1sFNy; Fri, 14 Jul 2023 08:47:00 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.68]) by mail.m-online.net (Postfix) with ESMTP id 4R2MTc5ZZtz1qqlS; Fri, 14 Jul 2023 08:47:00 +0200 (CEST) X-Virus-Scanned: amavis at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.68]) (amavis, port 10024) with ESMTP id PuA0c_R32eAm; Fri, 14 Jul 2023 08:46:59 +0200 (CEST) Received: from babic.homelinux.org (host-88-217-136-221.customer.m-online.net [88.217.136.221]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPS; Fri, 14 Jul 2023 08:46:59 +0200 (CEST) Received: from localhost (mail.babic.homelinux.org [127.0.0.1]) by babic.homelinux.org (Postfix) with ESMTP id 83C9D4540C63; Fri, 14 Jul 2023 08:46:58 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at babic.homelinux.org Received: from babic.homelinux.org ([127.0.0.1]) by localhost (mail.babic.homelinux.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 5jdjIPNHG8Qe; Fri, 14 Jul 2023 08:46:54 +0200 (CEST) Received: from paperino.fritz.box (paperino.fritz.box [192.168.178.48]) by babic.homelinux.org (Postfix) with ESMTP id DF4644540832; Fri, 14 Jul 2023 08:46:54 +0200 (CEST) From: Stefano Babic To: swupdate@googlegroups.com Cc: Stefano Babic Subject: [swupdate] [PATCH] bootloader: support for NVIDIA cboot - bootinfo Date: Fri, 14 Jul 2023 08:46:52 +0200 Message-Id: <20230714064652.13819-1-sbabic@denx.de> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-Original-Sender: sbabic@denx.de X-Original-Authentication-Results: gmr-mx.google.com; spf=neutral (google.com: 2001:a60:0:28:0:1:25:1 is neither permitted nor denied by domain of sbabic@denx.de) smtp.mailfrom=sbabic@denx.de; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=denx.de Precedence: list Mailing-list: list swupdate@googlegroups.com; contact swupdate+owners@googlegroups.com List-ID: X-Spam-Checked-In-Group: swupdate@googlegroups.com X-Google-Group-Id: 605343134186 List-Post: , List-Help: , List-Archive: , List-Unsubscribe: , Some NVIDIA Tegra SOCs do not support U-Boot. NVIDIA has developed an own bootloader as replacement for U-Boot. cboot (it should be patched) can have access to the "bootinfo" database, that is stored on dependency of the SOC type on fixed memory. The tegra-boot-tools provide a convenient library to access programmatically to the environment. The environment is redundant like in U-Boot, and this gurantees to have a power-cut safe update of the variables. This patch intoduce Tegra's "bootinfo" as bootloader interface, and it depends on the libtegra-boot-tools library. Signed-off-by: Stefano Babic --- Kconfig | 4 + Makefile.deps | 4 + Makefile.flags | 8 ++ bootloader/Config.in | 19 +++++ bootloader/Makefile | 1 + bootloader/cboot.c | 197 +++++++++++++++++++++++++++++++++++++++++++ include/bootloader.h | 1 + 7 files changed, 234 insertions(+) create mode 100644 bootloader/cboot.c diff --git a/Kconfig b/Kconfig index 0bf3ae1d..19439b4f 100644 --- a/Kconfig +++ b/Kconfig @@ -61,6 +61,10 @@ config HAVE_LIBEBGENV bool option env="HAVE_LIBEBGENV" +config HAVE_LIBTEGRABOOT_TOOLS + bool + option env="HAVE_LIBTEGRABOOT_TOOLS" + config HAVE_LIBEXT2FS bool option env="HAVE_LIBEXT2FS" diff --git a/Makefile.deps b/Makefile.deps index 56028c50..397e08c4 100644 --- a/Makefile.deps +++ b/Makefile.deps @@ -50,6 +50,10 @@ ifeq ($(HAVE_LIBEBGENV),) export HAVE_LIBEBGENV = y endif +ifeq ($(HAVE_LIBTEGRABOOT_TOOLS),) +export HAVE_LIBTEGRABOOT_TOOLS = y +endif + ifeq ($(HAVE_LIBZEROMQ),) export HAVE_LIBZEROMQ = y endif diff --git a/Makefile.flags b/Makefile.flags index 2a021c89..2d27a8f8 100644 --- a/Makefile.flags +++ b/Makefile.flags @@ -225,6 +225,9 @@ endif ifeq ($(CONFIG_BOOTLOADER_EBG),y) LDLIBS += ebgenv endif +ifeq ($(CONFIG_BOOTLOADER_CBOOT),y) +LDLIBS += tegra-boot-tools +endif else ifeq ($(CONFIG_UBOOT),y) LDLIBS += dl @@ -232,6 +235,9 @@ endif ifeq ($(CONFIG_BOOTLOADER_EBG),y) LDLIBS += dl endif +ifeq ($(CONFIG_BOOTLOADER_CBOOT),y) +LDLIBS += dl +endif endif ifeq ($(CONFIG_SYSTEMD),y) @@ -246,6 +252,8 @@ else ifeq ($(CONFIG_BOOTLOADER_DEFAULT_UBOOT),y) KBUILD_CPPFLAGS += -DBOOTLOADER_DEFAULT="uboot" else ifeq ($(CONFIG_BOOTLOADER_DEFAULT_EBG),y) KBUILD_CPPFLAGS += -DBOOTLOADER_DEFAULT="ebg" +else ifeq ($(CONFIG_BOOTLOADER_DEFAULT_CBOOT),y) +KBUILD_CPPFLAGS += -DBOOTLOADER_DEFAULT="cboot" else KBUILD_CPPFLAGS += -DBOOTLOADER_DEFAULT="none" endif diff --git a/bootloader/Config.in b/bootloader/Config.in index 6a6cc3c0..6d07146a 100644 --- a/bootloader/Config.in +++ b/bootloader/Config.in @@ -63,6 +63,19 @@ config GRUBENV_PATH help Provide path to GRUB environment block file +config BOOTLOADER_CBOOT + bool "NVIDIA Tegra Cboot" + depends on HAVE_LIBTEGRABOOT_TOOLS + help + Support for NVIDIA's cboot used on some Tegra platform. Tegra + uses different bootloader, depending on the SOC and on the release + provided by vendor. Some SOCs (associated with some releases) are still + using U-Boot (Jetson Nano, TX, TX2), some of them are using Cboot (Xavier), + and some of them rely on UEFI. This adds support for cboot. + +comment "Cboot needs libtegra-boot-tools" + depends on !HAVE_LIBTEGRABOOT_TOOLS + endmenu choice @@ -98,6 +111,12 @@ config BOOTLOADER_DEFAULT_GRUB help Use GRUB as default bootloader interface. +config BOOTLOADER_DEFAULT_CBOOT + bool "Cboot" + depends on BOOTLOADER_CBOOT + help + Use NVIDIA Cboot as default bootloader interface. + config BOOTLOADER_DEFAULT_NONE bool "Environment in RAM" depends on BOOTLOADER_NONE diff --git a/bootloader/Makefile b/bootloader/Makefile index 5d99cde5..2f9b6ea8 100644 --- a/bootloader/Makefile +++ b/bootloader/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_UBOOT) += uboot.o obj-$(CONFIG_BOOTLOADER_NONE) += none.o obj-$(CONFIG_BOOTLOADER_GRUB) += grub.o obj-$(CONFIG_BOOTLOADER_EBG) += ebg.o +obj-$(CONFIG_BOOTLOADER_CBOOT) += cboot.o # Make sure none.o is compiled-in as fallback. ifeq ($(CONFIG_UBOOT),) diff --git a/bootloader/cboot.c b/bootloader/cboot.c new file mode 100644 index 00000000..1780e5f0 --- /dev/null +++ b/bootloader/cboot.c @@ -0,0 +1,197 @@ +/* + * (C) Copyright 2023 Stefano Babic, stefano.babic@swupdate.org + * + * SPDX-License-Identifier: GPL-2.0-only + */ + +/* + * This uses the API of the libtegra-boot-tools library + * see info on https://github.com/OE4T/tegra-boot-tools + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "generated/autoconf.h" +#include "util.h" +#include "dlfcn.h" +#include "bootloader.h" + +/* + * thes edefines are not exported by the library + */ +#define BOOTINFO_O_RDONLY (0<<0) +#define BOOTINFO_O_RDWR (3<<0) +#define BOOTINFO_O_CREAT (1<<2) +#define BOOTINFO_O_FORCE_INIT (1<<3) + +/* + * Define the API from bootinfo.h. File is not (yet ?) + * exported by the library, and they are defined here. + */ +struct bootinfo_context_s; +typedef struct bootinfo_context_s bootinfo_context_t; +extern int bootinfo_open(unsigned int flags, bootinfo_context_t **ctxp); +extern int bootinfo_close(bootinfo_context_t *ctx); +extern int bootinfo_var_get(bootinfo_context_t *ctx, const char *name, char *valuebuf, size_t valuebuf_size); +extern int bootinfo_var_set(bootinfo_context_t *ctx, const char *name, const char *value); + +/* + * Structure for external library callbacks + */ +static struct { + int (*open)(unsigned int flags, bootinfo_context_t **ctxp); + int (*close)(bootinfo_context_t *ctx); + int (*get_env)(bootinfo_context_t *ctx, const char *name, char *valuebuf, size_t valuebuf_size); + int (*set_env)(bootinfo_context_t *ctx, const char *name, const char *value); +} libcboot; + +static char *do_env_get(const char *name) +{ + bootinfo_context_t *ctx; + static char valuebuf[65536]; + char *value; + + if (!name) + return NULL; + + if (libcboot.open(BOOTINFO_O_RDONLY, &ctx) < 0) { + ERROR("libcboot.open returns with error"); + return NULL; + } + + if (libcboot.get_env(ctx, name, valuebuf, sizeof(valuebuf)) < 0) + valuebuf[0] = '\0'; + + value = strdup(valuebuf); + + if (libcboot.close(ctx) < 0) { + ERROR("libcboot.close returns with error, environmen not saved"); + } + return value; +} + +static int do_env_set(const char *name, const char *value) +{ + int ret = 0; + bootinfo_context_t *ctx; + + if (!name || !value) + return -EINVAL; + + if (libcboot.open(BOOTINFO_O_RDWR, &ctx) < 0) { + ERROR("libcboot.open returns with error"); + return -ENOENT; + } + if (libcboot.set_env(ctx, name, value) < 0) { + ERROR("libcboot.set_env"); + ret = -EFAULT; + } + if (libcboot.close(ctx) < 0) { + ERROR("libcboot.close returns with error, environment not saved"); + ret = -EFAULT; + } + return ret; +} + +static int do_env_unset(const char *name) +{ + int ret = 0; + bootinfo_context_t *ctx; + + if (!name) + return -EINVAL; + + if (libcboot.open(BOOTINFO_O_RDWR, &ctx) < 0) { + ERROR("libcboot.open returns with error"); + return -ENOENT; + } + if (libcboot.set_env(ctx, name, NULL) < 0) { + ERROR("libcboot.set_env for unset"); + ret = -EFAULT; + } + if (libcboot.close(ctx) < 0) { + ERROR("libcboot.close returns with error, environment not saved"); + ret = -EFAULT; + } + return ret; +} + +static int do_apply_list(const char *filename) +{ + errno = 0; + bootinfo_context_t *ctx; + + FILE *file = fopen(filename, "rb"); + if (!file) { + ERROR("Cannot open bootloader environment source file %s: %s", + filename, strerror(errno)); + return -EIO; + } + + char *line = NULL; + size_t length = 0; + int result = 0; + if (libcboot.open(BOOTINFO_O_RDWR, &ctx) < 0) { + ERROR("libcboot.open returns with error"); + return -ENOENT; + } + while ((getline(&line, &length, file)) != -1) { + char *key = strtok(line, "="); + char *value = strtok(NULL, "\t\n"); + if (key != NULL) { + result = libcboot.set_env(ctx, key, value); + if (result < 0) { + ERROR("Error %s boot var %s(%s)", value ? "storing" : "deleting", + key, value ? value : ""); + } + } + } + + if (libcboot.close(ctx) < 0) { + ERROR("libcboot.close returns with error, environment not saved"); + result = -EFAULT; + } + fclose(file); + free(line); + return result; +} + +static bootloader cboot = { + .env_get = &do_env_get, + .env_set = &do_env_set, + .env_unset = &do_env_unset, + .apply_list = &do_apply_list +}; + +static bootloader* probe(void) +{ +#if defined(BOOTLOADER_STATIC_LINKED) + libcboot.open = bootinfo_open; + libcboot.close = bootinfo_close; + libcboot.get_env = bootinfo_var_get; + libcboot.set_env = bootinfo_var_set; +#else + void* handle = dlopen("libtegra-boot-tools.so.1", RTLD_NOW | RTLD_GLOBAL); + if (!handle) { + return NULL; + } + + (void)dlerror(); + load_symbol(handle, &libcboot.open, "bootinfo_open"); + load_symbol(handle, &libcboot.close, "bootinfo_close"); + load_symbol(handle, &libcboot.get_env, "bootinfo_var_get"); + load_symbol(handle, &libcboot.set_env, "bootinfo_var_set"); +#endif + return &cboot; +} + +__attribute__((constructor)) +static void cboot_probe(void) +{ + (void)register_bootloader(BOOTLOADER_CBOOT, probe()); +} diff --git a/include/bootloader.h b/include/bootloader.h index 529ec127..171181ec 100644 --- a/include/bootloader.h +++ b/include/bootloader.h @@ -12,6 +12,7 @@ #define BOOTLOADER_NONE "none" #define BOOTLOADER_GRUB "grub" #define BOOTLOADER_UBOOT "uboot" +#define BOOTLOADER_CBOOT "cboot" #define load_symbol(handle, container, fname) \ *(void**)(container) = dlsym(handle, fname); \