ASR_BASE
Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/package/utils/fitblk/Makefile b/package/utils/fitblk/Makefile
new file mode 100644
index 0000000..325963d
--- /dev/null
+++ b/package/utils/fitblk/Makefile
@@ -0,0 +1,42 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=fitblk
+PKG_RELEASE:=2
+PKG_LICENSE:=GPL-2.0-only
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+
+PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
+
+PKG_FLAGS:=nonshared
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/fitblk
+ HIDDEN:=1
+ SECTION:=base
+ CATEGORY:=Base system
+ TITLE:=fitblk firmware release tool
+endef
+
+define Package/fitblk/description
+Release uImage.FIT block devices using ioctl.
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ CC="$(TARGET_CC)" \
+ CFLAGS="$(TARGET_CFLAGS) -Wall -Werror" \
+ LDFLAGS="$(TARGET_LDFLAGS)"
+endef
+
+define Package/fitblk/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/fitblk $(1)/usr/sbin/
+ $(INSTALL_DIR) $(1)/lib/upgrade
+ $(INSTALL_DATA) ./files/fit.sh $(1)/lib/upgrade
+endef
+
+$(eval $(call BuildPackage,fitblk))
diff --git a/package/utils/fitblk/files/fit.sh b/package/utils/fitblk/files/fit.sh
new file mode 100644
index 0000000..b715a15
--- /dev/null
+++ b/package/utils/fitblk/files/fit.sh
@@ -0,0 +1,63 @@
+export_fitblk_bootdev() {
+ [ -e /sys/firmware/devicetree/base/chosen/rootdisk ] || return
+
+ local rootdisk="$(cat /sys/firmware/devicetree/base/chosen/rootdisk)"
+ local handle bootdev
+
+ for handle in /sys/class/mtd/mtd*/of_node/volumes/*/phandle; do
+ [ ! -e "$handle" ] && continue
+ if [ "$rootdisk" = "$(cat "$handle")" ]; then
+ if [ -e "${handle%/phandle}/volname" ]; then
+ export CI_KERNPART="$(cat "${handle%/phandle}/volname")"
+ elif [ -e "${handle%/phandle}/volid" ]; then
+ export CI_KERNVOLID="$(cat "${handle%/phandle}/volid")"
+ else
+ return
+ fi
+ export CI_UBIPART="$(cat "${handle%%/of_node*}/name")"
+ export CI_METHOD="ubi"
+ return
+ fi
+ done
+
+ for handle in /sys/class/mtd/mtd*/of_node/phandle; do
+ [ ! -e "$handle" ] && continue
+ if [ "$rootdisk" = "$(cat $handle)" ]; then
+ bootdev="${handle%/of_node/phandle}"
+ bootdev="${bootdev#/sys/class/mtd/}"
+ export PART_NAME="/dev/$bootdev"
+ export CI_METHOD="default"
+ return
+ fi
+ done
+
+ for handle in /sys/class/block/*/of_node/phandle; do
+ [ ! -e "$handle" ] && continue
+ if [ "$rootdisk" = "$(cat $handle)" ]; then
+ bootdev="${handle%/of_node/phandle}"
+ bootdev="${bootdev#/sys/class/block/}"
+ export EMMC_KERN_DEV="/dev/$bootdev"
+ export CI_METHOD="emmc"
+ return
+ fi
+ done
+}
+
+fit_do_upgrade() {
+ export_fitblk_bootdev
+ [ -n "$CI_METHOD" ] || return 1
+ [ -e /dev/fit0 ] && fitblk /dev/fit0
+ [ -e /dev/fitrw ] && fitblk /dev/fitrw
+
+ case "$CI_METHOD" in
+ emmc)
+ emmc_do_upgrade "$1"
+ ;;
+ default)
+ default_do_upgrade "$1"
+ ;;
+ ubi)
+ nand_do_upgrade "$1"
+ ;;
+ esac
+}
diff --git a/package/utils/fitblk/src/Makefile b/package/utils/fitblk/src/Makefile
new file mode 100644
index 0000000..064764c
--- /dev/null
+++ b/package/utils/fitblk/src/Makefile
@@ -0,0 +1,7 @@
+all: fitblk
+
+fitblk:
+ $(CC) $(CFLAGS) -o $@ fitblk.c $(LDFLAGS)
+
+clean:
+ rm -f fitblk
diff --git a/package/utils/fitblk/src/fitblk.c b/package/utils/fitblk/src/fitblk.c
new file mode 100644
index 0000000..059ba60
--- /dev/null
+++ b/package/utils/fitblk/src/fitblk.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <linux/fitblk.h>
+
+static int fitblk_release(char *device)
+{
+ int fd, ret;
+
+ fd = open(device, O_RDONLY);
+ if (fd == -1)
+ return errno;
+
+ ret = ioctl(fd, FITBLK_RELEASE, NULL);
+ close(fd);
+
+ if (ret == -1)
+ return errno;
+
+ return 0;
+}
+
+int main(int argc, char *argp[])
+{
+ int ret;
+
+ if (argc != 2) {
+ fprintf(stderr, "Release uImage.FIT sub-image block device\n");
+ fprintf(stderr, "Syntax: %s /dev/fitXXX\n", argp[0]);
+ return -EINVAL;
+ }
+
+ ret = fitblk_release(argp[1]);
+ if (ret)
+ fprintf(stderr, "fitblk: error releasing %s: %s\n", argp[1],
+ strerror(ret));
+ else
+ fprintf(stderr, "fitblk: %s released\n", argp[1]);
+
+ return ret;
+}