From patchwork Thu Jun 25 13:21:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Quirin Gylstorff X-Patchwork-Id: 11625333 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6411C138C for ; Thu, 25 Jun 2020 13:21:17 +0000 (UTC) Received: from web01.groups.io (web01.groups.io [66.175.222.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D7C02207E8 for ; Thu, 25 Jun 2020 13:21:16 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=lists.cip-project.org header.i=@lists.cip-project.org header.b="ENyiS9cT" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D7C02207E8 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=siemens.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=bounce+64572+4817+4520428+8129116@lists.cip-project.org X-Received: by 127.0.0.2 with SMTP id huAdYY4521763xsvbgOHyqLX; Thu, 25 Jun 2020 06:21:16 -0700 X-Received: from goliath.siemens.de (goliath.siemens.de [192.35.17.28]) by mx.groups.io with SMTP id smtpd.web10.10410.1593091274717689766 for ; Thu, 25 Jun 2020 06:21:15 -0700 X-Received: from mail2.sbs.de (mail2.sbs.de [192.129.41.66]) by goliath.siemens.de (8.15.2/8.15.2) with ESMTPS id 05PDLC7a004540 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Thu, 25 Jun 2020 15:21:12 +0200 X-Received: from md2dvrtc.ad001.siemens.net ([167.87.6.122]) by mail2.sbs.de (8.15.2/8.15.2) with ESMTP id 05PDLB2G002493; Thu, 25 Jun 2020 15:21:12 +0200 From: "Quirin Gylstorff" To: cip-dev@lists.cip-project.org, Jan.Kiszka@siemens.com Cc: Quirin Gylstorff Subject: [cip-dev] [isar-cip-core RFC 1/4] recipes-bsp: Add efibootguard Date: Thu, 25 Jun 2020 15:21:08 +0200 Message-Id: <20200625132111.16367-2-Quirin.Gylstorff@siemens.com> In-Reply-To: <20200625132111.16367-1-Quirin.Gylstorff@siemens.com> References: <20200625132111.16367-1-Quirin.Gylstorff@siemens.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: Sender: cip-dev@lists.cip-project.org List-Id: Mailing-List: list cip-dev@lists.cip-project.org; contact cip-dev+owner@lists.cip-project.org Delivered-To: mailing list cip-dev@lists.cip-project.org Reply-To: cip-dev@lists.cip-project.org X-Gm-Message-State: gpqPHt2nk7Qd1u2NPyW033jQx4520428AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=lists.cip-project.org; q=dns/txt; s=20140610; t=1593091276; bh=ewyCDUTINnH2RRkiBMiChDIvCYyD/yKKA23gsG25Euo=; h=Cc:Content-Type:Date:From:Reply-To:Subject:To; b=ENyiS9cTN4u7gGZPMgxPObgU6gDTrFKC/6bBWx8pOin7l+GZbF7W3S7VsDlRUpY2XrV 1X9xV5VkQGp/7nfVMAvv8Cn3wpxdZVjut2o0hkT8VwUzIxO4jYN6aP/4Rwox4JME2pv3y 5aMFGIt6mv8lENDAEXSE7wo+sSGR6iwDSOY= From: Quirin Gylstorff Add the bootloader efibootguard for A/B partition update on x86 with EFI. Signed-off-by: Quirin Gylstorff --- .../efibootguard/efibootguard_0.6-git+isar.bb | 46 +++++ recipes-bsp/efibootguard/files/debian/compat | 1 + .../efibootguard/files/debian/control.tmpl | 20 +++ .../files/debian/efibootguard-dev.install | 3 + .../files/debian/efibootguard.install | 2 + recipes-bsp/efibootguard/files/debian/rules | 21 +++ .../wic/plugins/source/efibootguard-boot.py | 162 ++++++++++++++++++ .../wic/plugins/source/efibootguard-efi.py | 102 +++++++++++ 8 files changed, 357 insertions(+) create mode 100644 recipes-bsp/efibootguard/efibootguard_0.6-git+isar.bb create mode 100644 recipes-bsp/efibootguard/files/debian/compat create mode 100644 recipes-bsp/efibootguard/files/debian/control.tmpl create mode 100644 recipes-bsp/efibootguard/files/debian/efibootguard-dev.install create mode 100644 recipes-bsp/efibootguard/files/debian/efibootguard.install create mode 100755 recipes-bsp/efibootguard/files/debian/rules create mode 100644 scripts/lib/wic/plugins/source/efibootguard-boot.py create mode 100644 scripts/lib/wic/plugins/source/efibootguard-efi.py diff --git a/recipes-bsp/efibootguard/efibootguard_0.6-git+isar.bb b/recipes-bsp/efibootguard/efibootguard_0.6-git+isar.bb new file mode 100644 index 0000000..bf8b50d --- /dev/null +++ b/recipes-bsp/efibootguard/efibootguard_0.6-git+isar.bb @@ -0,0 +1,46 @@ +# +# CIP Core, generic profile +# +# Copyright (c) Siemens AG, 2020 +# +# Authors: +# Quirin Gylstorff +# +# SPDX-License-Identifier: MIT +# + +DESCRIPTION = "efibootguard boot loader" +DESCRIPTION_DEV = "efibootguard development library" +HOMEPAGE = "https://github.com/siemens/efibootguard" +LICENSE = "GPL-2.0" +LIC_FILES_CHKSUM = "file://${LAYERDIR_isar}/licenses/COPYING.GPLv2;md5=751419260aa954499f7abaabaa882bbe" +MAINTAINER = "Jan Kiszka " + +SRC_URI = "git://github.com/siemens/efibootguard.git;branch=master;protocol=https \ + file://debian \ + " + +S = "${WORKDIR}/git" + +SRCREV = "85cae10c9411c52208947d63a2287cfd6e81068a" + +PROVIDES = "${PN}" +PROVIDES += "${PN}-dev" + +BUILD_DEB_DEPENDS = "gnu-efi,libpci-dev,check,pkg-config,libc6-dev-i386" + +inherit dpkg + +TEMPLATE_FILES = "debian/control.tmpl" +TEMPLATE_VARS += "DESCRIPTION_DEV BUILD_DEB_DEPENDS" + +do_prepare_build() { + cp -R ${WORKDIR}/debian ${S} + deb_add_changelog +} + +dpkg_runbuild_append() { + install -m 0755 -d ${DEPLOY_DIR_IMAGE} + install -m 0755 ${S}/efibootguardx64.efi ${DEPLOY_DIR_IMAGE}/bootx64.efi + install -m 0755 ${S}/bg_setenv ${DEPLOY_DIR_IMAGE}/bg_setenv +} diff --git a/recipes-bsp/efibootguard/files/debian/compat b/recipes-bsp/efibootguard/files/debian/compat new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/recipes-bsp/efibootguard/files/debian/compat @@ -0,0 +1 @@ +9 diff --git a/recipes-bsp/efibootguard/files/debian/control.tmpl b/recipes-bsp/efibootguard/files/debian/control.tmpl new file mode 100644 index 0000000..54b1994 --- /dev/null +++ b/recipes-bsp/efibootguard/files/debian/control.tmpl @@ -0,0 +1,20 @@ +Source: ${PN} +Section: base +Priority: optional +Standards-Version: 3.9.6 +Build-Depends: ${BUILD_DEB_DEPENDS} +Homepage: ${HOMEPAGE} +Maintainer: ${MAINTAINER} + +Package: ${PN} +Depends: ${shlibs:Depends} +Section: base +Architecture: ${DISTRO_ARCH} +Priority: required +Description: ${DESCRIPTION} + +Package: ${PN}-dev +Section: base +Architecture: ${DISTRO_ARCH} +Priority: optional +Description: ${DESCRIPTION_DEV} diff --git a/recipes-bsp/efibootguard/files/debian/efibootguard-dev.install b/recipes-bsp/efibootguard/files/debian/efibootguard-dev.install new file mode 100644 index 0000000..7b45bd8 --- /dev/null +++ b/recipes-bsp/efibootguard/files/debian/efibootguard-dev.install @@ -0,0 +1,3 @@ +include/ebgenv.h usr/include/efibootguard +libebgenv.a usr/lib/x86_64-linux-gnu + diff --git a/recipes-bsp/efibootguard/files/debian/efibootguard.install b/recipes-bsp/efibootguard/files/debian/efibootguard.install new file mode 100644 index 0000000..8a8d9d3 --- /dev/null +++ b/recipes-bsp/efibootguard/files/debian/efibootguard.install @@ -0,0 +1,2 @@ +bg_setenv usr/bin +bg_printenv usr/bin diff --git a/recipes-bsp/efibootguard/files/debian/rules b/recipes-bsp/efibootguard/files/debian/rules new file mode 100755 index 0000000..82e9e0e --- /dev/null +++ b/recipes-bsp/efibootguard/files/debian/rules @@ -0,0 +1,21 @@ +#!/usr/bin/make -f +export DH_VERBOSE=1 +export DEB_BUILD_OPTIONS=hardening=-stackprotector +export DPKG_EXPORT_BUILDFLAGS=1 +include /usr/share/dpkg/default.mk + +override_dh_auto_test: + # we do not run the tests; that avoids having to pull the fff submodule + +override_dh_auto_install: + # install using Debian's .install files rather than + # make install in order to have a proper package split. + +override_dh_installchangelogs: + # we're not interested in changelogs + +override_dh_installdocs: + # we're not interested in docs + +%: + dh $@ --with autoreconf diff --git a/scripts/lib/wic/plugins/source/efibootguard-boot.py b/scripts/lib/wic/plugins/source/efibootguard-boot.py new file mode 100644 index 0000000..38d2b2e --- /dev/null +++ b/scripts/lib/wic/plugins/source/efibootguard-boot.py @@ -0,0 +1,162 @@ +# ex:ts=4:sw=4:sts=4:et +# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- +# +# Copyright (c) 2014, Intel Corporation. +# Copyright (c) 2018, Siemens AG. +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# DESCRIPTION +# This implements the 'efibootguard-boot' source plugin class for 'wic' +# +# AUTHORS +# Tom Zanussi +# Claudius Heine +# Andreas Reichel +# Christian Storm + +import os +import fnmatch +import sys +import logging + +msger = logging.getLogger('wic') + +from wic.pluginbase import SourcePlugin +from wic.utils.misc import exec_cmd, get_bitbake_var, BOOTDD_EXTRA_SPACE + +class EfibootguardBootPlugin(SourcePlugin): + """ + Create EFI Boot Guard partition hosting the + environment file plus Kernel files. + """ + + name = 'efibootguard-boot' + + @classmethod + def do_prepare_partition(cls, part, source_params, creator, cr_workdir, + oe_builddir, deploy_dir, kernel_dir, + rootfs_dir, native_sysroot): + """ + Called to do the actual content population for a partition, i.e., + populate an EFI Boot Guard environment partition plus Kernel files. + """ + + kernel_image = get_bitbake_var("KERNEL_IMAGE") + if not kernel_image: + msger.warning("KERNEL_IMAGE not set. Use default:") + kernel_image = "vmlinuz" + boot_image = kernel_image + + initrd_image = get_bitbake_var("INITRD_IMAGE") + if not initrd_image: + msger.warning("INITRD_IMAGE not set\n") + initrd_image = "initrd.img" + bootloader = creator.ks.bootloader + + deploy_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") + if not deploy_dir: + msger.error("DEPLOY_DIR_IMAGE not set, exiting\n") + sys.exit(1) + creator.deploy_dir = deploy_dir + + wdog_timeout = get_bitbake_var("WDOG_TIMEOUT") + if not wdog_timeout: + msger.error("Specify watchdog timeout for \ + efibootguard in local.conf with WDOG_TIMEOUT=") + exit(1) + + + boot_files = source_params.get("files", "").split(' ') + cmdline = bootloader.append + root_dev = source_params.get("root", None) + if not root_dev: + msger.error("Specify root in source params") + exit(1) + root_dev = root_dev.replace(":", "=") + + cmdline += " root=%s rw" % root_dev + boot_files.append(kernel_image) + boot_files.append(initrd_image) + cmdline += "initrd=%s" % initrd_image if initrd_image else "" + + part_rootfs_dir = "%s/disk/%s.%s" % (cr_workdir, + part.label, part.lineno) + create_dir_cmd = "install -d %s" % part_rootfs_dir + exec_cmd(create_dir_cmd) + + cwd = os.getcwd() + os.chdir(part_rootfs_dir) + config_cmd = '%s/bg_setenv -f . -k "C:%s:%s" %s -r %s -w %s' \ + % ( + deploy_dir, + part.label.upper(), + boot_image, + '-a "%s"' % cmdline if cmdline else "", + source_params.get("revision", 1), + wdog_timeout + ) + exec_cmd(config_cmd, True) + os.chdir(cwd) + + boot_files = list(filter(None, boot_files)) + for boot_file in boot_files: + if os.path.isfile("%s/%s" % (kernel_dir, kernel_image)): + install_cmd = "install -m 0644 %s/%s %s/%s" % \ + (kernel_dir, boot_file, part_rootfs_dir, boot_file) + exec_cmd(install_cmd) + else: + msger.error("file %s not found in directory %s", + boot_file, kernel_dir) + exit(1) + cls._create_img(part_rootfs_dir, part, cr_workdir) + + @classmethod + def _create_img(cls, part_rootfs_dir, part, cr_workdir): + # Write label as utf-16le to EFILABEL file + with open("%s/EFILABEL" % part_rootfs_dir, 'wb') as filedescriptor: + filedescriptor.write(part.label.upper().encode("utf-16le")) + + du_cmd = "du --apparent-size -ks %s" % part_rootfs_dir + blocks = int(exec_cmd(du_cmd).split()[0]) + + extra_blocks = part.get_extra_block_count(blocks) + if extra_blocks < BOOTDD_EXTRA_SPACE: + extra_blocks = BOOTDD_EXTRA_SPACE + + blocks += extra_blocks + blocks = blocks + (16 - (blocks % 16)) + + msger.debug("Added %d extra blocks to %s to get to %d total blocks", + extra_blocks, part.mountpoint, blocks) + + # dosfs image, created by mkdosfs + bootimg = "%s/%s.%s.img" % (cr_workdir, part.label, part.lineno) + + dosfs_cmd = "mkdosfs -F 16 -S 512 -n %s -C %s %d" % \ + (part.label.upper(), bootimg, blocks) + exec_cmd(dosfs_cmd) + + mcopy_cmd = "mcopy -v -i %s -s %s/* ::/" % (bootimg, part_rootfs_dir) + exec_cmd(mcopy_cmd, True) + + chmod_cmd = "chmod 644 %s" % bootimg + exec_cmd(chmod_cmd) + + du_cmd = "du -Lbks %s" % bootimg + bootimg_size = int(exec_cmd(du_cmd).split()[0]) + + part.size = bootimg_size + part.source_file = bootimg diff --git a/scripts/lib/wic/plugins/source/efibootguard-efi.py b/scripts/lib/wic/plugins/source/efibootguard-efi.py new file mode 100644 index 0000000..5ee451f --- /dev/null +++ b/scripts/lib/wic/plugins/source/efibootguard-efi.py @@ -0,0 +1,102 @@ +# ex:ts=4:sw=4:sts=4:et +# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- +# +# Copyright (c) 2014, Intel Corporation. +# Copyright (c) 2018, Siemens AG. +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# DESCRIPTION +# This implements the 'efibootguard-efi' source plugin class for 'wic' +# +# AUTHORS +# Tom Zanussi +# Claudius Heine +# Andreas Reichel +# Christian Storm + +import logging +import os + +msger = logging.getLogger('wic') + +from wic.pluginbase import SourcePlugin +from wic.utils.misc import exec_cmd, get_bitbake_var, BOOTDD_EXTRA_SPACE + +class EfibootguardEFIPlugin(SourcePlugin): + """ + Create EFI bootloader partition containing the EFI Boot Guard Bootloader. + """ + + name = 'efibootguard-efi' + + @classmethod + def do_prepare_partition(cls, part, source_params, creator, cr_workdir, + oe_builddir, deploy_dir, kernel_dir, + rootfs_dir, native_sysroot): + """ + Called to do the actual content population for a partition, i.e., + populate an EFI boot partition containing the EFI Boot Guard + bootloader binary. + """ + deploy_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") + creator.deploy_dir = deploy_dir + bootloader_files = source_params.get("bootloader") + if not bootloader_files: + bootloader_files = "bootx64.efi" + bootloader_files = bootloader_files.split(' ') + part_rootfs_dir = "%s/disk/%s.%s" % (cr_workdir, + part.label, + part.lineno) + create_dir_cmd = "install -d %s/EFI/BOOT" % part_rootfs_dir + exec_cmd(create_dir_cmd) + + for bootloader in bootloader_files: + cp_cmd = "cp %s/%s %s/EFI/BOOT/%s" % (deploy_dir, + bootloader, + part_rootfs_dir, + bootloader) + exec_cmd(cp_cmd, True) + du_cmd = "du --apparent-size -ks %s" % part_rootfs_dir + blocks = int(exec_cmd(du_cmd).split()[0]) + + extra_blocks = part.get_extra_block_count(blocks) + if extra_blocks < BOOTDD_EXTRA_SPACE: + extra_blocks = BOOTDD_EXTRA_SPACE + blocks += extra_blocks + blocks = blocks + (16 - (blocks % 16)) + + msger.debug("Added %d extra blocks to %s to get to %d total blocks", + extra_blocks, part.mountpoint, blocks) + + # dosfs image, created by mkdosfs + efi_part_image = "%s/%s.%s.img" % (cr_workdir, part.label, part.lineno) + + dosfs_cmd = "mkdosfs -S 512 -n %s -C %s %d" % \ + (part.label.upper(), efi_part_image, blocks) + exec_cmd(dosfs_cmd) + + mcopy_cmd = "mcopy -v -i %s -s %s/* ::/" % \ + (efi_part_image, part_rootfs_dir) + exec_cmd(mcopy_cmd, True) + + chmod_cmd = "chmod 644 %s" % efi_part_image + exec_cmd(chmod_cmd) + + du_cmd = "du -Lbks %s" % efi_part_image + efi_part_image_size = int(exec_cmd(du_cmd).split()[0]) + + part.size = efi_part_image_size + part.source_file = efi_part_image From patchwork Thu Jun 25 13:21:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Quirin Gylstorff X-Patchwork-Id: 11625337 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3980F14E3 for ; Thu, 25 Jun 2020 13:21:18 +0000 (UTC) Received: from web01.groups.io (web01.groups.io [66.175.222.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 11B7F2076E for ; Thu, 25 Jun 2020 13:21:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=lists.cip-project.org header.i=@lists.cip-project.org header.b="EDFZPm6B" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 11B7F2076E Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=siemens.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=bounce+64572+4818+4520428+8129116@lists.cip-project.org X-Received: by 127.0.0.2 with SMTP id ysDoYY4521763xkgmQSefF9h; Thu, 25 Jun 2020 06:21:17 -0700 X-Received: from goliath.siemens.de (goliath.siemens.de [192.35.17.28]) by mx.groups.io with SMTP id smtpd.web11.10378.1593091274744460220 for ; Thu, 25 Jun 2020 06:21:15 -0700 X-Received: from mail2.sbs.de (mail2.sbs.de [192.129.41.66]) by goliath.siemens.de (8.15.2/8.15.2) with ESMTPS id 05PDLCGD004559 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Thu, 25 Jun 2020 15:21:12 +0200 X-Received: from md2dvrtc.ad001.siemens.net ([167.87.6.122]) by mail2.sbs.de (8.15.2/8.15.2) with ESMTP id 05PDLB2H002493; Thu, 25 Jun 2020 15:21:12 +0200 From: "Quirin Gylstorff" To: cip-dev@lists.cip-project.org, Jan.Kiszka@siemens.com Cc: Quirin Gylstorff Subject: [cip-dev] [isar-cip-core RFC 2/4] patches: add libubootenv Date: Thu, 25 Jun 2020 15:21:09 +0200 Message-Id: <20200625132111.16367-3-Quirin.Gylstorff@siemens.com> In-Reply-To: <20200625132111.16367-1-Quirin.Gylstorff@siemens.com> References: <20200625132111.16367-1-Quirin.Gylstorff@siemens.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: Sender: cip-dev@lists.cip-project.org List-Id: Mailing-List: list cip-dev@lists.cip-project.org; contact cip-dev+owner@lists.cip-project.org Delivered-To: mailing list cip-dev@lists.cip-project.org Reply-To: cip-dev@lists.cip-project.org X-Gm-Message-State: bsqylb14AqyKjqjgATY5NFVKx4520428AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=lists.cip-project.org; q=dns/txt; s=20140610; t=1593091277; bh=8puMyydpdSe/eXvZhbL63hDn7LV0xtugJPIbqW1SyOk=; h=Cc:Content-Type:Date:From:Reply-To:Subject:To; b=EDFZPm6B+fAeQB3VnjF/6lf4N+R2PllrI6mc3NSbV5oQOjkTXwOYcLppAlrWp1OZstI +COeeZD+llEQ1wsG0QA4Tge06ktCd4Mw7wF0STNCi8PDSmpMROR7n8+TzXZPR7rTimlwr r71x5HexSRPT44hMiEjOsJhj956OIuhirLU= From: Quirin Gylstorff swupdate 2020.04 requires libubootenv as build dependency. libubootenv is a library that provides a hardware independent way to access to U-Boot environment. U-Boot has its default environment compiled board-dependently and this means that tools to access the environment are also board specific, too. Signed-off-by: Quirin Gylstorff --- .../0001-u-boot-add-libubootenv.patch | 169 ++++++++++++++++++ kas/cip.yml | 4 + 2 files changed, 173 insertions(+) create mode 100644 isar-patches/0001-u-boot-add-libubootenv.patch diff --git a/isar-patches/0001-u-boot-add-libubootenv.patch b/isar-patches/0001-u-boot-add-libubootenv.patch new file mode 100644 index 0000000..10a5b4a --- /dev/null +++ b/isar-patches/0001-u-boot-add-libubootenv.patch @@ -0,0 +1,169 @@ +From 76897e89977f895495e21e37cb76f90392d55ef9 Mon Sep 17 00:00:00 2001 +From: Quirin Gylstorff +Date: Fri, 19 Jun 2020 17:00:36 +0200 +Subject: [PATCH v2] u-boot: add libubootenv + +Add the new library libubootenv and remove fw_printenv and fw_setenv +form u-boot-tools as the are now part of the new library. + +libubootenv is a library that provides a hardware independent +way to access to U-Boot environment. U-Boot has its default environment +compiled board-dependently and this means that tools to access the environment +are also board specific, too. + +libubootenv conflicts with u-boot-tools from Debian 10 +as both try to install fw_printenv and fw_sentenv. This conflict is not +part of the control file as it breaks the installation of custom u-boot-tools +from the u-boot-sources. + +Signed-off-by: Quirin Gylstorff +--- + meta-isar/conf/machine/de0-nano-soc.conf | 2 +- + .../libubootenv/files/debian/compat | 1 + + .../libubootenv/files/debian/control.tmpl | 15 +++++++++ + .../libubootenv/files/debian/rules.tmpl | 24 ++++++++++++++ + .../libubootenv/libubootenv_0.2.bb | 32 +++++++++++++++++++ + .../files/debian/u-boot-tools.conffiles | 1 - + .../u-boot/files/debian/u-boot-tools.install | 2 -- + .../u-boot/files/debian/u-boot-tools.links | 1 - + 8 files changed, 73 insertions(+), 5 deletions(-) + create mode 100644 meta/recipes-bsp/libubootenv/files/debian/compat + create mode 100644 meta/recipes-bsp/libubootenv/files/debian/control.tmpl + create mode 100644 meta/recipes-bsp/libubootenv/files/debian/rules.tmpl + create mode 100644 meta/recipes-bsp/libubootenv/libubootenv_0.2.bb + delete mode 100644 meta/recipes-bsp/u-boot/files/debian/u-boot-tools.conffiles + delete mode 100644 meta/recipes-bsp/u-boot/files/debian/u-boot-tools.links + +diff --git a/meta-isar/conf/machine/de0-nano-soc.conf b/meta-isar/conf/machine/de0-nano-soc.conf +index 3a2c009..6558d90 100644 +--- a/meta-isar/conf/machine/de0-nano-soc.conf ++++ b/meta-isar/conf/machine/de0-nano-soc.conf +@@ -15,4 +15,4 @@ WKS_FILE ?= "de0-nano-soc.wks.in" + IMAGER_INSTALL += "u-boot-de0-nano-soc" + IMAGER_BUILD_DEPS += "u-boot-de0-nano-soc" + +-IMAGE_INSTALL += "u-boot-tools u-boot-script" ++IMAGE_INSTALL += "u-boot-tools libubootenv u-boot-script" +diff --git a/meta/recipes-bsp/libubootenv/files/debian/compat b/meta/recipes-bsp/libubootenv/files/debian/compat +new file mode 100644 +index 0000000..b4de394 +--- /dev/null ++++ b/meta/recipes-bsp/libubootenv/files/debian/compat +@@ -0,0 +1 @@ ++11 +diff --git a/meta/recipes-bsp/libubootenv/files/debian/control.tmpl b/meta/recipes-bsp/libubootenv/files/debian/control.tmpl +new file mode 100644 +index 0000000..fade69a +--- /dev/null ++++ b/meta/recipes-bsp/libubootenv/files/debian/control.tmpl +@@ -0,0 +1,15 @@ ++Source: libubootenv ++Section: embedded ++Priority: optional ++Maintainer: Stefano Babic ++Build-Depends: ${BUILD_DEB_DEPENDS} ++Standards-Version: 4.2.1 ++Homepage: https://sbabic.github.io/libubootenv ++ ++Package: libubootenv ++Architecture: any ++Depends: ${DEBIAN_DEPENDS} ++Description: libubootenv is a library that provides a hardware independent ++ way to access to U-Boot environment. U-Boot has its default environment ++ compiled board-dependently and this means that tools to access the environment ++ are also board specific, too. +diff --git a/meta/recipes-bsp/libubootenv/files/debian/rules.tmpl b/meta/recipes-bsp/libubootenv/files/debian/rules.tmpl +new file mode 100644 +index 0000000..56ccd19 +--- /dev/null ++++ b/meta/recipes-bsp/libubootenv/files/debian/rules.tmpl +@@ -0,0 +1,24 @@ ++#!/usr/bin/make -f ++ ++ifneq ($(DEB_BUILD_GNU_TYPE),$(DEB_HOST_GNU_TYPE)) ++export CROSS_COMPILE=$(DEB_HOST_GNU_TYPE)- ++export CC=$(DEB_HOST_GNU_TYPE)-gcc ++export LD=$(DEB_HOST_GNU_TYPE)-gcc ++endif ++ ++export DH_VERBOSE = 1 ++ ++export DEB_BUILD_MAINT_OPTIONS = hardening=+bindnow ++ ++override_dh_auto_configure: ++ dh_auto_configure -- ++ ++%: ++ echo $@ ++ dh $@ ++ ++override_dh_installchangelogs: ++ true ++ ++override_dh_installdocs: ++ true +diff --git a/meta/recipes-bsp/libubootenv/libubootenv_0.2.bb b/meta/recipes-bsp/libubootenv/libubootenv_0.2.bb +new file mode 100644 +index 0000000..1be058c +--- /dev/null ++++ b/meta/recipes-bsp/libubootenv/libubootenv_0.2.bb +@@ -0,0 +1,32 @@ ++# libubootenv ++# ++# This software is a part of ISAR. ++# Copyright (c) Siemens AG, 2020 ++# ++# SPDX-License-Identifier: MIT ++ ++DESCRIPTION = "swupdate utility for software updates" ++HOMEPAGE= "https://github.com/sbabic/swupdate" ++LICENSE = "GPL-2.0" ++LIC_FILES_CHKSUM = "file://${LAYERDIR_isar}/licenses/COPYING.GPLv2;md5=751419260aa954499f7abaabaa882bbe" ++SRC_URI = "gitsm://github.com/sbabic/libubootenv.git;branch=master;protocol=https" ++ ++SRCREV = "bf6ff631c0e38cede67268ceb8bf1383b5f8848e" ++ ++BUILD_DEB_DEPENDS = "cmake, zlib1g-dev" ++ ++SRC_URI += "file://debian" ++TEMPLATE_FILES = "debian/control.tmpl debian/rules.tmpl" ++TEMPLATE_VARS += "BUILD_DEB_DEPENDS DEFCONFIG DEBIAN_DEPENDS" ++ ++ ++inherit dpkg ++ ++S = "${WORKDIR}/git" ++ ++do_prepare_build() { ++ DEBDIR=${S}/debian ++ install -d ${DEBDIR} ++ cp -R ${WORKDIR}/debian ${S} ++ deb_add_changelog ++} +diff --git a/meta/recipes-bsp/u-boot/files/debian/u-boot-tools.conffiles b/meta/recipes-bsp/u-boot/files/debian/u-boot-tools.conffiles +deleted file mode 100644 +index d49a8fb..0000000 +--- a/meta/recipes-bsp/u-boot/files/debian/u-boot-tools.conffiles ++++ /dev/null +@@ -1 +0,0 @@ +-/etc/fw_env.config +diff --git a/meta/recipes-bsp/u-boot/files/debian/u-boot-tools.install b/meta/recipes-bsp/u-boot/files/debian/u-boot-tools.install +index d1ae3e0..2893b9a 100644 +--- a/meta/recipes-bsp/u-boot/files/debian/u-boot-tools.install ++++ b/meta/recipes-bsp/u-boot/files/debian/u-boot-tools.install +@@ -1,5 +1,3 @@ + tools/dumpimage /usr/bin/ +-tools/env/fw_printenv /usr/bin/ + tools/mkenvimage /usr/bin/ + tools/mkimage /usr/bin/ +-tools/env/fw_env.config /etc +diff --git a/meta/recipes-bsp/u-boot/files/debian/u-boot-tools.links b/meta/recipes-bsp/u-boot/files/debian/u-boot-tools.links +deleted file mode 100644 +index 92f5a6c..0000000 +--- a/meta/recipes-bsp/u-boot/files/debian/u-boot-tools.links ++++ /dev/null +@@ -1 +0,0 @@ +-/usr/bin/fw_printenv /usr/bin/fw_setenv +-- +2.20.1 + diff --git a/kas/cip.yml b/kas/cip.yml index 019b31e..0da07db 100644 --- a/kas/cip.yml +++ b/kas/cip.yml @@ -22,6 +22,10 @@ repos: refspec: 351af175bc54a201c6f44307d4e998bd6c0afdb8 layers: meta: + patches: + 01-libubootenv: + path: isar-patches/0001-u-boot-add-libubootenv.patch + repo: cip-core bblayers_conf_header: standard: | From patchwork Thu Jun 25 13:21:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Quirin Gylstorff X-Patchwork-Id: 11625335 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7CD1414F6 for ; Thu, 25 Jun 2020 13:21:17 +0000 (UTC) Received: from web01.groups.io (web01.groups.io [66.175.222.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D1C17207D8 for ; Thu, 25 Jun 2020 13:21:16 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=lists.cip-project.org header.i=@lists.cip-project.org header.b="kS+zSXLv" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D1C17207D8 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=siemens.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=bounce+64572+4819+4520428+8129116@lists.cip-project.org X-Received: by 127.0.0.2 with SMTP id E1hEYY4521763xDJkmZcWzRr; Thu, 25 Jun 2020 06:21:16 -0700 X-Received: from goliath.siemens.de (goliath.siemens.de [192.35.17.28]) by mx.groups.io with SMTP id smtpd.web10.10411.1593091274836457808 for ; Thu, 25 Jun 2020 06:21:15 -0700 X-Received: from mail2.sbs.de (mail2.sbs.de [192.129.41.66]) by goliath.siemens.de (8.15.2/8.15.2) with ESMTPS id 05PDLDAR004582 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Thu, 25 Jun 2020 15:21:13 +0200 X-Received: from md2dvrtc.ad001.siemens.net ([167.87.6.122]) by mail2.sbs.de (8.15.2/8.15.2) with ESMTP id 05PDLB2I002493; Thu, 25 Jun 2020 15:21:12 +0200 From: "Quirin Gylstorff" To: cip-dev@lists.cip-project.org, Jan.Kiszka@siemens.com Cc: Quirin Gylstorff Subject: [cip-dev] [isar-cip-core RFC 3/4] recipes-core: add swupdate Date: Thu, 25 Jun 2020 15:21:10 +0200 Message-Id: <20200625132111.16367-4-Quirin.Gylstorff@siemens.com> In-Reply-To: <20200625132111.16367-1-Quirin.Gylstorff@siemens.com> References: <20200625132111.16367-1-Quirin.Gylstorff@siemens.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: Sender: cip-dev@lists.cip-project.org List-Id: Mailing-List: list cip-dev@lists.cip-project.org; contact cip-dev+owner@lists.cip-project.org Delivered-To: mailing list cip-dev@lists.cip-project.org Reply-To: cip-dev@lists.cip-project.org X-Gm-Message-State: GpB7sk0vHxtmfTt0aKsxRRYZx4520428AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=lists.cip-project.org; q=dns/txt; s=20140610; t=1593091276; bh=y5Vhg2kFz+ForJhaGQYQuMQuhGQpGcxs6kmM0OBa0tc=; h=Cc:Content-Type:Date:From:Reply-To:Subject:To; b=kS+zSXLv4Mjj1IHzufz00LLbm8rB0ZeytKoFDDKNcZzwIkzQbZXNIV0KIJSKhrOnPoN kvLkAYt1zSxF4o9KjEKBAzDxOs4lrdsW8SpiHiCYxgPrXi+sx7o/eApsOZ664NDL+Pz8M OnYiYwFQBp8PJBYMrzIoCdq6QieT/C8C8r0= From: Quirin Gylstorff Add swupdate for A/B software updates. Currently the Round Robin handler in lua supports efibootguard as bootloader. The u-boot implementation is outstanding. Signed-off-by: Quirin Gylstorff --- classes/kconfig-snippets.bbclass | 90 ++++ classes/swupdate-config.bbclass | 76 +++ classes/swupdate-img.bbclass | 75 +++ .../swupdate/files/debian/changelog.tmpl | 6 + recipes-core/swupdate/files/debian/compat | 1 + .../swupdate/files/debian/control.tmpl | 15 + recipes-core/swupdate/files/debian/copyright | 36 ++ recipes-core/swupdate/files/debian/rules.tmpl | 30 ++ .../swupdate/files/debian/swupdate.examples | 2 + .../swupdate/files/debian/swupdate.install | 2 + .../swupdate/files/debian/swupdate.manpages | 5 + .../swupdate/files/debian/swupdate.tmpfile | 2 + recipes-core/swupdate/files/debian/watch | 12 + recipes-core/swupdate/files/postinst | 2 + recipes-core/swupdate/files/swupdate.cfg | 6 + .../swupdate/files/swupdate.service.example | 11 + .../swupdate/files/swupdate.socket.example | 11 + .../swupdate/files/swupdate.socket.tmpl | 13 + .../swupdate/files/swupdate_defconfig | 83 ++++ .../swupdate_defconfig_efibootguard.snippet | 3 + .../files/swupdate_defconfig_lua.snippet | 2 + .../swupdate_defconfig_luahandler.snippet | 4 + .../files/swupdate_defconfig_mtd.snippet | 1 + .../files/swupdate_defconfig_u-boot.snippet | 3 + .../files/swupdate_defconfig_ubi.snippet | 6 + .../swupdate/files/swupdate_handlers.lua | 449 ++++++++++++++++++ recipes-core/swupdate/swupdate.bb | 54 +++ 27 files changed, 1000 insertions(+) create mode 100644 classes/kconfig-snippets.bbclass create mode 100644 classes/swupdate-config.bbclass create mode 100644 classes/swupdate-img.bbclass create mode 100644 recipes-core/swupdate/files/debian/changelog.tmpl create mode 100644 recipes-core/swupdate/files/debian/compat create mode 100644 recipes-core/swupdate/files/debian/control.tmpl create mode 100644 recipes-core/swupdate/files/debian/copyright create mode 100755 recipes-core/swupdate/files/debian/rules.tmpl create mode 100644 recipes-core/swupdate/files/debian/swupdate.examples create mode 100644 recipes-core/swupdate/files/debian/swupdate.install create mode 100644 recipes-core/swupdate/files/debian/swupdate.manpages create mode 100644 recipes-core/swupdate/files/debian/swupdate.tmpfile create mode 100644 recipes-core/swupdate/files/debian/watch create mode 100644 recipes-core/swupdate/files/postinst create mode 100644 recipes-core/swupdate/files/swupdate.cfg create mode 100644 recipes-core/swupdate/files/swupdate.service.example create mode 100644 recipes-core/swupdate/files/swupdate.socket.example create mode 100644 recipes-core/swupdate/files/swupdate.socket.tmpl create mode 100644 recipes-core/swupdate/files/swupdate_defconfig create mode 100644 recipes-core/swupdate/files/swupdate_defconfig_efibootguard.snippet create mode 100644 recipes-core/swupdate/files/swupdate_defconfig_lua.snippet create mode 100644 recipes-core/swupdate/files/swupdate_defconfig_luahandler.snippet create mode 100644 recipes-core/swupdate/files/swupdate_defconfig_mtd.snippet create mode 100644 recipes-core/swupdate/files/swupdate_defconfig_u-boot.snippet create mode 100644 recipes-core/swupdate/files/swupdate_defconfig_ubi.snippet create mode 100644 recipes-core/swupdate/files/swupdate_handlers.lua create mode 100644 recipes-core/swupdate/swupdate.bb diff --git a/classes/kconfig-snippets.bbclass b/classes/kconfig-snippets.bbclass new file mode 100644 index 0000000..d754654 --- /dev/null +++ b/classes/kconfig-snippets.bbclass @@ -0,0 +1,90 @@ +# +# CIP Core, generic profile +# +# Copyright (c) Siemens AG, 2020 +# +# Authors: +# Christian Storm +# +# SPDX-License-Identifier: MIT + +KCONFIG_SNIPPETS = "" + +# The following function defines the kconfig snippet system +# with automatich debian dependency injection +# +# To define a feature set, the user has to define the following +# variable to an empty string: +# +# KFEATURE_featurename = "" +# +# Then, required additions to the variables can be defined: +# +# KFEATURE_featurename[KCONFIG_SNIPPETS] = "file://snippet-file-name.snippet" +# KFEATURE_featurename[SRC_URI] = "file://required-file.txt" +# KFEATURE_featurename[DEPENDS] = "deb-pkg1 deb-pkg2 deb-pkg3" +# KFEATURE_featurename[DEBIAN_DEPENDS] = "deb-pkg1" +# KFEATURE_featurename[BUILD_DEB_DEPENDS] = "deb-pkg1,deb-pkg2,deb-pkg3" + +# The 'KCONFIG_SNIPPETS' flag gives a list of URI entries, where only +# file:// is supported. These snippets are appended to the DEFCONFIG file. +# +# Features can depend on other features via the following mechanism: +# +# KFEATURE_DEPS[feature1] = "feature2" + +python () { + requested_features = d.getVar("KFEATURES", True) or "" + + features = set(requested_features.split()) + old_features = set() + feature_deps = d.getVarFlags("KFEATURE_DEPS") or {} + while old_features != features: + diff_features = old_features.symmetric_difference(features) + old_features = features.copy() + for i in diff_features: + features.update(feature_deps.get(i, "").split()) + + for f in sorted(features): + bb.debug(2, "Feature: " + f) + varname = "KFEATURE_" + f + dummyvar = d.getVar(varname, False) + if dummyvar == None: + bb.error("Feature var " + f + " must be defined with needed flags.") + else: + feature_flags = d.getVarFlags(varname) + for feature_varname in sorted(feature_flags): + if feature_flags.get(feature_varname, "") != "": + sep = " " + + # Required to add KCONFIG_SNIPPETS to SRC_URI here, + # because 'SRC_URI += "${KCONFIG_SNIPPETS}"' would + # conflict with SRC_APT feature. + if feature_varname == "KCONFIG_SNIPPETS": + d.appendVar('SRC_URI', + " " + feature_flags[feature_varname].strip()) + + # BUILD_DEP_DEPENDS and DEBIAN_DEPENDS is ',' separated + # Only add ',' if there is already something there + if feature_varname in ["BUILD_DEB_DEPENDS", + "DEBIAN_DEPENDS"]: + sep = "," if d.getVar(feature_varname) else "" + + d.appendVar(feature_varname, + sep + feature_flags[feature_varname].strip()) +} + +# DEFCONFIG must be a predefined bitbake variable and the corresponding file +# must exist in the WORKDIR. +# The resulting generated config is the same file suffixed with ".gen" + +do_prepare_build_prepend() { + sh -x + GENCONFIG="${WORKDIR}/${DEFCONFIG}".gen + rm -f "$GENCONFIG" + cp "${WORKDIR}/${DEFCONFIG}" "$GENCONFIG" + for CONFIG_SNIPPET in $(echo "${KCONFIG_SNIPPETS}" | sed 's#file://##g') + do + cat ${WORKDIR}/$CONFIG_SNIPPET >> "$GENCONFIG" + done +} diff --git a/classes/swupdate-config.bbclass b/classes/swupdate-config.bbclass new file mode 100644 index 0000000..7ce51c5 --- /dev/null +++ b/classes/swupdate-config.bbclass @@ -0,0 +1,76 @@ +# +# CIP Core, generic profile +# +# Copyright (c) Siemens AG, 2020 +# +# Authors: +# Christian Storm +# +# SPDX-License-Identifier: MIT + +# This class manages the config snippets together with their dependencies +# to build SWUpdate + +inherit kconfig-snippets + +BUILD_DEB_DEPENDS = " \ + zlib1g-dev, debhelper, libconfig-dev, libarchive-dev, \ + python-sphinx:native, dh-systemd, libsystemd-dev" + +KFEATURE_lua = "" +KFEATURE_lua[BUILD_DEB_DEPENDS] = "liblua5.3-dev" +KFEATURE_lua[KCONFIG_SNIPPETS] = "file://swupdate_defconfig_lua.snippet" + +KFEATURE_luahandler = "" +KFEATURE_luahandler[KCONFIG_SNIPPETS] = "file://swupdate_defconfig_luahandler.snippet" +KFEATURE_luahandler[SRC_URI] = "file://${SWUPDATE_LUASCRIPT}" + +KFEATURE_DEPS = "" +KFEATURE_DEPS[luahandler] = "lua" + +KFEATURE_efibootguard = "" +KFEATURE_efibootguard[BUILD_DEB_DEPENDS] = "efibootguard-dev" +KFEATURE_efibootguard[DEBIAN_DEPENDS] = "efibootguard-dev" +KFEATURE_efibootguard[DEPENDS] = "efibootguard-dev" +KFEATURE_efibootguard[KCONFIG_SNIPPETS] = "file://swupdate_defconfig_efibootguard.snippet" + +KFEATURE_mtd = "" +KFEATURE_mtd[BUILD_DEB_DEPENDS] = "libmtd-dev" +KFEATURE_mtd[DEPENDS] = "mtd-utils" +KFEATURE_mtd[KCONFIG_SNIPPETS] = "file://swupdate_defconfig_mtd.snippet" + +KFEATURE_ubi = "" +KFEATURE_ubi[BUILD_DEB_DEPENDS] = "libubi-dev" +KFEATURE_ubi[KCONFIG_SNIPPETS] = "file://swupdate_defconfig_ubi.snippet" + +KFEATURE_DEPS[ubi] = "mtd" + +KFEATURE_u-boot = "" +KFEATURE_u-boot[BUILD_DEB_DEPENDS] = "u-boot-${MACHINE}-dev" +KFEATURE_u-boot[DEBIAN_DEPENDS] = "u-boot-tools" +KFEATURE_u-boot[DEPENDS] = "${U_BOOT}" +KFEATURE_u-boot[KCONFIG_SNIPPETS] = "file://swupdate_defconfig_u-boot.snippet" + +SWUPDATE_LUASCRIPT ?= "swupdate_handlers.lua" + +def get_bootloader_featureset(d): + bootloader = d.getVar("BOOTLOADER", True) or "" + if bootloader == "efibootguard": + return "efibootguard" + if bootloader == "u-boot": + return "u-boot" + return "" + +SWUPDATE_KFEATURES ??= "" +KFEATURES = "${SWUPDATE_KFEATURES}" +KFEATURES += "${@get_bootloader_featureset(d)}" + +# Astonishingly, as an anonymous python function, BOOTLOADER is always None +# one time before it gets set. So the following must be a task. +python do_check_bootloader () { + bootloader = d.getVar("BOOTLOADER", True) or "None" + if not bootloader in ["efibootguard", "u-boot"]: + bb.warn("swupdate: BOOTLOADER set to incompatible value: " + bootloader) +} +addtask check_bootloader before do_fetch + diff --git a/classes/swupdate-img.bbclass b/classes/swupdate-img.bbclass new file mode 100644 index 0000000..a21d6ec --- /dev/null +++ b/classes/swupdate-img.bbclass @@ -0,0 +1,75 @@ +# +# CIP Core, generic profile +# +# Copyright (c) Siemens AG, 2020 +# +# Authors: +# Christian Storm +# Quirin Gylstorff +# +# SPDX-License-Identifier: MIT + +SWU_IMAGE_FILE ?= "${PN}-${DISTRO}-${MACHINE}.swu" +SWU_DESCRIPTION_FILE ?= "sw-description" +SWU_ADDITIONAL_FILES ?= "" +SWU_SIGNED ?= "" +SWU_SIGNATURE_EXT ?= "sig" +SWU_SIGNATURE_TYPE ?= "rsa" + +IMAGER_INSTALL += "${@'openssl' if bb.utils.to_boolean(d.getVar('SWU_SIGNED')) else ''}" + +do_swupdate_image[stamp-extra-info] = "${DISTRO}-${MACHINE}" +do_swupdate_image[cleandirs] += "${WORKDIR}/swu" +do_swupdate_image() { + rm -f '${DEPLOY_DIR_IMAGE}/${SWU_IMAGE_FILE}' + cp '${WORKDIR}/${SWU_DESCRIPTION_FILE}' '${WORKDIR}/swu/${SWU_DESCRIPTION_FILE}' + + # Create symlinks for files used in the update image + for file in ${SWU_ADDITIONAL_FILES}; do + if [ -e "${WORKDIR}/$file" ]; then + ln -s "${WORKDIR}/$file" "${WORKDIR}/swu/$file" + else + ln -s "${DEPLOY_DIR_IMAGE}/$file" "${WORKDIR}/swu/$file" + fi + done + + # Prepare for signing + sign='${@'x' if bb.utils.to_boolean(d.getVar('SWU_SIGNED')) else ''}' + if [ -n "$sign" ]; then + image_do_mounts + cp -f '${SIGN_KEY}' '${WORKDIR}/dev.key' + test -e '${SIGN_CRT}' && cp -f '${SIGN_CRT}' '${WORKDIR}/dev.crt' + + # Fill in file check sums + for file in ${SWU_ADDITIONAL_FILES}; do + sed -i "s:$file-sha256:$(sha256sum '${WORKDIR}/swu/'$file | cut -f 1 -d ' '):g" \ + '${WORKDIR}/swu/${SWU_DESCRIPTION_FILE}' + done + fi + + cd "${WORKDIR}/swu" + for file in '${SWU_DESCRIPTION_FILE}' ${SWU_ADDITIONAL_FILES}; do + echo "$file" + if [ -n "$sign" -a \ + '${SWU_DESCRIPTION_FILE}' = "$file" ]; then + if [ "${SWU_SIGNATURE_TYPE}" = "rsa" ]; then + sudo chroot ${BUILDCHROOT_DIR} /usr/bin/openssl dgst \ + -sha256 -sign '${PP_WORK}/dev.key' \ + '${PP_WORK}/swu/'"$file" \ + > '${WORKDIR}/swu/'"$file".'${SWU_SIGNATURE_EXT}' + elif [ "${SWU_SIGNATURE_TYPE}" = "cms" ]; then + sudo chroot ${BUILDCHROOT_DIR} /usr/bin/openssl cms \ + -sign -in '${PP_WORK}/swu/'"$file" \ + -out '${WORKDIR}/swu/'"$file".'${SWU_SIGNATURE_EXT}' \ + -signer '${PP_WORK}/dev.crt' \ + -inkey '${PP_WORK}/dev.key' \ + -outform DER -nosmimecap -binary + fi + echo "$file".'${SWU_SIGNATURE_EXT}' + fi + done | cpio -ovL -H crc \ + > '${DEPLOY_DIR_IMAGE}/${SWU_IMAGE_FILE}' + cd - +} + +addtask swupdate_image before do_build after do_copy_boot_files do_install_imager_deps do_transform_template diff --git a/recipes-core/swupdate/files/debian/changelog.tmpl b/recipes-core/swupdate/files/debian/changelog.tmpl new file mode 100644 index 0000000..81087d3 --- /dev/null +++ b/recipes-core/swupdate/files/debian/changelog.tmpl @@ -0,0 +1,6 @@ +swupdate (${PV}) unstable; urgency=medium + + * SWUpdate + + -- Christian Storm Thu, 31 Jan 2019 15:23:56 +0100 + diff --git a/recipes-core/swupdate/files/debian/compat b/recipes-core/swupdate/files/debian/compat new file mode 100644 index 0000000..b4de394 --- /dev/null +++ b/recipes-core/swupdate/files/debian/compat @@ -0,0 +1 @@ +11 diff --git a/recipes-core/swupdate/files/debian/control.tmpl b/recipes-core/swupdate/files/debian/control.tmpl new file mode 100644 index 0000000..2b92850 --- /dev/null +++ b/recipes-core/swupdate/files/debian/control.tmpl @@ -0,0 +1,15 @@ +Source: swupdate +Section: embedded +Priority: optional +Maintainer: Stefano Babic +Build-Depends: ${BUILD_DEB_DEPENDS} +Standards-Version: 4.2.1 +Homepage: http://sbabic.github.io/swupdate + +Package: swupdate +Architecture: any +Depends: ${DEBIAN_DEPENDS} +Description: reliable way to update an embedded system + This project is thought to help to update an embedded system from a storage media or from network. + However, it should be mainly considered as a framework, where further protocols or installers + (in SWUpdate they are called handlers) can be easily added to the application. diff --git a/recipes-core/swupdate/files/debian/copyright b/recipes-core/swupdate/files/debian/copyright new file mode 100644 index 0000000..f920942 --- /dev/null +++ b/recipes-core/swupdate/files/debian/copyright @@ -0,0 +1,36 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: swupdate +Maintainer: Stefano Babic +Source: http://github.com/sbabic/swupdate + +Files: * +Copyright: 2014-2017 Stefano Babic + +License: GPL-2 with OpenSSL exception + This package is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + . + In addition, as a special exception, the author of this + program gives permission to link the code of its + release with the OpenSSL project's "OpenSSL" library (or + with modified versions of it that use the same license as + the "OpenSSL" library), and distribute the linked + executables. You must obey the GNU General Public + License in all respects for all of the code used other + than "OpenSSL". If you modify this file, you may extend + this exception to your version of the file, but you are + not obligated to do so. If you do not wish to do so, + delete this exception statement from your version. + . + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this program. If not, see + . + On Debian systems, the complete text of the GNU General + Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". diff --git a/recipes-core/swupdate/files/debian/rules.tmpl b/recipes-core/swupdate/files/debian/rules.tmpl new file mode 100755 index 0000000..54cca57 --- /dev/null +++ b/recipes-core/swupdate/files/debian/rules.tmpl @@ -0,0 +1,30 @@ +#!/usr/bin/make -f + +ifneq ($(DEB_BUILD_GNU_TYPE),$(DEB_HOST_GNU_TYPE)) +export CROSS_COMPILE=$(DEB_HOST_GNU_TYPE)- +export CC=$(DEB_HOST_GNU_TYPE)-gcc +export LD=$(DEB_HOST_GNU_TYPE)-gcc +endif + +export DH_VERBOSE = 1 + +export DEB_BUILD_MAINT_OPTIONS = hardening=+bindnow + +documentation: configure + make man + +configure: + make ${DEFCONFIG} + +build: documentation configure + dh $@ + +%: + echo $@ + dh $@ + +override_dh_installchangelogs: + true + +override_dh_installdocs: + true diff --git a/recipes-core/swupdate/files/debian/swupdate.examples b/recipes-core/swupdate/files/debian/swupdate.examples new file mode 100644 index 0000000..c257b75 --- /dev/null +++ b/recipes-core/swupdate/files/debian/swupdate.examples @@ -0,0 +1,2 @@ +examples/configuration +examples/description diff --git a/recipes-core/swupdate/files/debian/swupdate.install b/recipes-core/swupdate/files/debian/swupdate.install new file mode 100644 index 0000000..8957cc6 --- /dev/null +++ b/recipes-core/swupdate/files/debian/swupdate.install @@ -0,0 +1,2 @@ +swupdate usr/bin +swupdate.cfg /etc diff --git a/recipes-core/swupdate/files/debian/swupdate.manpages b/recipes-core/swupdate/files/debian/swupdate.manpages new file mode 100644 index 0000000..c3438e0 --- /dev/null +++ b/recipes-core/swupdate/files/debian/swupdate.manpages @@ -0,0 +1,5 @@ +doc/build/man/swupdate.1 +doc/build/man/client.1 +doc/build/man/sendtohawkbit.1 +doc/build/man/hawkbitcfg.1 +doc/build/man/progress.1 diff --git a/recipes-core/swupdate/files/debian/swupdate.tmpfile b/recipes-core/swupdate/files/debian/swupdate.tmpfile new file mode 100644 index 0000000..4743672 --- /dev/null +++ b/recipes-core/swupdate/files/debian/swupdate.tmpfile @@ -0,0 +1,2 @@ +X /tmp/datadst +X /tmp/scripts diff --git a/recipes-core/swupdate/files/debian/watch b/recipes-core/swupdate/files/debian/watch new file mode 100644 index 0000000..bc4c53e --- /dev/null +++ b/recipes-core/swupdate/files/debian/watch @@ -0,0 +1,12 @@ +# Example watch control file for uscan +# Rename this file to "watch" and then you can run the "uscan" command +# to check for upstream updates and more. +# See uscan(1) for format + +# Compulsory line, this is a version 4 file +version=4 + +# GitHub hosted projects +opts="filenamemangle="s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%-$1.tar.gz%" \ + https://github.com//swupdate/tags \ + (?:.*?/)?v?(\d[\d.]*)\.tar\.gz debian uupdate diff --git a/recipes-core/swupdate/files/postinst b/recipes-core/swupdate/files/postinst new file mode 100644 index 0000000..f15ac10 --- /dev/null +++ b/recipes-core/swupdate/files/postinst @@ -0,0 +1,2 @@ +#!/bin/sh +deb-systemd-helper enable swupdate.socket || true diff --git a/recipes-core/swupdate/files/swupdate.cfg b/recipes-core/swupdate/files/swupdate.cfg new file mode 100644 index 0000000..e0222f1 --- /dev/null +++ b/recipes-core/swupdate/files/swupdate.cfg @@ -0,0 +1,6 @@ +globals : +{ + verbose = true; + loglevel = 10; + syslog = false; +}; diff --git a/recipes-core/swupdate/files/swupdate.service.example b/recipes-core/swupdate/files/swupdate.service.example new file mode 100644 index 0000000..d0b821e --- /dev/null +++ b/recipes-core/swupdate/files/swupdate.service.example @@ -0,0 +1,11 @@ +[Unit] +Description=SWUpdate daemon +Documentation=https://github.com/sbabic/swupdate + +[Service] +Type=simple +ExecStart=/usr/bin/swupdate -f /etc/swupdate.cfg +KillMode=mixed + +[Install] +WantedBy=multi-user.target diff --git a/recipes-core/swupdate/files/swupdate.socket.example b/recipes-core/swupdate/files/swupdate.socket.example new file mode 100644 index 0000000..2b75671 --- /dev/null +++ b/recipes-core/swupdate/files/swupdate.socket.example @@ -0,0 +1,11 @@ +[Unit] +Description=SWUpdate socket listener +Documentation=https://github.com/sbabic/swupdate +Documentation=https://sbabic.github.io/swupdate + +[Socket] +ListenStream=/tmp/sockinstctrl +ListenStream=/tmp/swupdateprog + +[Install] +WantedBy=sockets.target diff --git a/recipes-core/swupdate/files/swupdate.socket.tmpl b/recipes-core/swupdate/files/swupdate.socket.tmpl new file mode 100644 index 0000000..8e7fc1d --- /dev/null +++ b/recipes-core/swupdate/files/swupdate.socket.tmpl @@ -0,0 +1,13 @@ +[Unit] +Description=SWUpdate socket listener +Documentation=https://github.com/sbabic/swupdate +Documentation=https://sbabic.github.io/swupdate + +[Socket] +SocketUser=${SWUPDATE_SOCKET_OWNER} +SocketGroup=root +ListenStream=/tmp/sockinstctrl +ListenStream=/tmp/swupdateprog + +[Install] +WantedBy=sockets.target diff --git a/recipes-core/swupdate/files/swupdate_defconfig b/recipes-core/swupdate/files/swupdate_defconfig new file mode 100644 index 0000000..9ae7cb5 --- /dev/null +++ b/recipes-core/swupdate/files/swupdate_defconfig @@ -0,0 +1,83 @@ +# +# Automatically generated file; DO NOT EDIT. +# Swupdate Configuration +# +CONFIG_HAVE_DOT_CONFIG=y + +# +# Swupdate Settings +# + +# +# General Configuration +# +# CONFIG_CURL is not set +# CONFIG_CURL_SSL is not set +CONFIG_SYSTEMD=y +CONFIG_SCRIPTS=y +# CONFIG_HW_COMPATIBILITY is not set +CONFIG_SW_VERSIONS_FILE="/etc/sw-versions" + +# +# Socket Paths +# +CONFIG_SOCKET_CTRL_PATH="/tmp/sockinstctrl" +CONFIG_SOCKET_PROGRESS_PATH="/tmp/swupdateprog" +CONFIG_SOCKET_REMOTE_HANDLER_DIRECTORY="/tmp/" +# CONFIG_MTD is not set +# CONFIG_LUA is not set +# CONFIG_LUAPKG is not set +# CONFIG_FEATURE_SYSLOG is not set + +# +# Build Options +# +CONFIG_CROSS_COMPILE="" +CONFIG_SYSROOT="" +CONFIG_EXTRA_CFLAGS="" +CONFIG_EXTRA_LDFLAGS="" +CONFIG_EXTRA_LDLIBS="" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_WERROR is not set +# CONFIG_NOCLEANUP is not set +# CONFIG_BOOTLOADER_EBG is not set +# CONFIG_UBOOT is not set +# CONFIG_BOOTLOADER_NONE is not set +# CONFIG_BOOTLOADER_GRUB is not set +# CONFIG_DOWNLOAD is not set +# CONFIG_DOWNLOAD_SSL is not set +# CONFIG_CHANNEL_CURL is not set +# CONFIG_HASH_VERIFY=y +# CONFIG_SIGNED_IMAGES is not set +# CONFIG_ENCRYPTED_IMAGES is not set +# CONFIG_SURICATTA is not set +# CONFIG_WEBSERVER is not set +CONFIG_GUNZIP=y + +# +# Parser Features +# +CONFIG_LIBCONFIG=y +CONFIG_PARSERROOT="" +# CONFIG_JSON is not set +# CONFIG_LUAEXTERNAL is not set +# CONFIG_SETEXTPARSERNAME is not set +# CONFIG_SETSWDESCRIPTION is not set + +# +# Image Handlers +# +CONFIG_RAW=y +# CONFIG_LUASCRIPTHANDLER is not set +# CONFIG_SHELLSCRIPTHANDLER is not set +# CONFIG_HANDLER_IN_LUA is not set +# CONFIG_EMBEDDED_LUA_HANDLER is not set +# CONFIG_EMBEDDED_LUA_HANDLER_SOURCE is not set +CONFIG_ARCHIVE=y +# CONFIG_REMOTE_HANDLER is not set +# CONFIG_SWUFORWARDER_HANDLER is not set +# CONFIG_BOOTLOADERHANDLER is not set diff --git a/recipes-core/swupdate/files/swupdate_defconfig_efibootguard.snippet b/recipes-core/swupdate/files/swupdate_defconfig_efibootguard.snippet new file mode 100644 index 0000000..8e3688c --- /dev/null +++ b/recipes-core/swupdate/files/swupdate_defconfig_efibootguard.snippet @@ -0,0 +1,3 @@ +CONFIG_BOOTLOADER_NONE=n +CONFIG_BOOTLOADER_EBG=y +CONFIG_BOOTLOADERHANDLER=y diff --git a/recipes-core/swupdate/files/swupdate_defconfig_lua.snippet b/recipes-core/swupdate/files/swupdate_defconfig_lua.snippet new file mode 100644 index 0000000..b39f9df --- /dev/null +++ b/recipes-core/swupdate/files/swupdate_defconfig_lua.snippet @@ -0,0 +1,2 @@ +CONFIG_LUA=y +CONFIG_LUAPKG="lua53" diff --git a/recipes-core/swupdate/files/swupdate_defconfig_luahandler.snippet b/recipes-core/swupdate/files/swupdate_defconfig_luahandler.snippet new file mode 100644 index 0000000..b4a2de8 --- /dev/null +++ b/recipes-core/swupdate/files/swupdate_defconfig_luahandler.snippet @@ -0,0 +1,4 @@ +CONFIG_LUASCRIPTHANDLER=y +CONFIG_HANDLER_IN_LUA=y +CONFIG_EMBEDDED_LUA_HANDLER=y +CONFIG_EMBEDDED_LUA_HANDLER_SOURCE="swupdate_handlers.lua" diff --git a/recipes-core/swupdate/files/swupdate_defconfig_mtd.snippet b/recipes-core/swupdate/files/swupdate_defconfig_mtd.snippet new file mode 100644 index 0000000..eab98dd --- /dev/null +++ b/recipes-core/swupdate/files/swupdate_defconfig_mtd.snippet @@ -0,0 +1 @@ +CONFIG_MTD=y diff --git a/recipes-core/swupdate/files/swupdate_defconfig_u-boot.snippet b/recipes-core/swupdate/files/swupdate_defconfig_u-boot.snippet new file mode 100644 index 0000000..6b5832a --- /dev/null +++ b/recipes-core/swupdate/files/swupdate_defconfig_u-boot.snippet @@ -0,0 +1,3 @@ +CONFIG_UBOOT=y +CONFIG_UBOOT_FWENV="/etc/fw_env.config" +CONFIG_BOOTLOADERHANDLER=y diff --git a/recipes-core/swupdate/files/swupdate_defconfig_ubi.snippet b/recipes-core/swupdate/files/swupdate_defconfig_ubi.snippet new file mode 100644 index 0000000..d1c7732 --- /dev/null +++ b/recipes-core/swupdate/files/swupdate_defconfig_ubi.snippet @@ -0,0 +1,6 @@ +CONFIG_UBIVOL=y +CONFIG_UBIATTACH=y +CONFIG_UBIBLACKLIST="" +CONFIG_UBIWHITELIST="" +CONFIG_UBIVIDOFFSET=0 +CONFIG_CFI=y diff --git a/recipes-core/swupdate/files/swupdate_handlers.lua b/recipes-core/swupdate/files/swupdate_handlers.lua new file mode 100644 index 0000000..c9b9962 --- /dev/null +++ b/recipes-core/swupdate/files/swupdate_handlers.lua @@ -0,0 +1,449 @@ +--[[ + + Round-robin Image and File Handler. + + Copyright (C) 2019, Siemens AG + + Author: Christian Storm + + SPDX-License-Identifier: GPL-2.0-or-later + + An `sw-description` file using these handlers may look like: + software = + { + version = "0.1.0"; + images: ({ + filename = "rootfs.ext4"; + device = "sda4,sda5"; + type = "roundrobin"; + compressed = false; + }); + files: ({ + filename = "vmlinuz"; + path = "vmlinuz"; + type = "kernelfile"; + device = "sda2,sda3"; + filesystem = "vfat"; + }, + { + filename = "initrd.img"; + path = "initrd.img"; + type = "kernelfile"; + device = "sda2,sda3"; + filesystem = "vfat"; + }); + } + + The semantics is as follows: Instead of having a fixed target device, + the 'roundrobin' image handler calculates the target device by parsing + /proc/cmdline, matching the root= kernel parameter against its + 'device' attribute's list of devices, and sets the actual target + device to the next 'device' attribute list entry in a round-robin + manner. The actual flashing is done via chain-calling another handler, + defaulting to the "raw" handler. + + The 'kernelfile' file handler reuses the 'roundrobin' handler's target + device calculation by reading the actual target device from the same + index into its 'device' attribute's list of devices. The actual placing + of files into this partition is done via chain-calling another handler, + defaulting to the "rawfile" handler. + + In the above example, if /dev/sda4 is currently booted according to + /proc/cmdline, /dev/sda5 will be flashed and the vmlinuz and initrd.img + files will be placed on /dev/sda3. If /dev/sda5 is booted, /dev/sda4 + will be flashed and the vmlinuz and initrd.img files are placed on + /dev/sda2. + In addition to "classical" device nodes as in this example, partition + UUIDs as reported, e.g., by `blkid -s PARTUUID` are also supported. + UBI volumes are supported as well by specifying a CSV list of + ubi: