libfstools: add uImage.FIT fitblk driver
authorDaniel Golle <daniel@makrotopia.org>
Thu, 23 Nov 2023 00:19:37 +0000 (00:19 +0000)
committerDaniel Golle <daniel@makrotopia.org>
Fri, 1 Dec 2023 22:59:52 +0000 (22:59 +0000)
The upcoming 'fitblk' block driver exposing the filesystem sub-image(s)
of a uImage.FIT storage on a block device as /dev/fit%u.
In case of the block device being a fixed-sized partition, the remaining
space (for rootfs_data) is mapped to /dev/fitrw.
Recognize both devices and assign the highest priority to the new driver.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
CMakeLists.txt
libfstools/common.h
libfstools/fit.c [new file with mode: 0644]
libfstools/partname.c

index 3421fecd303b122a523b7163f888278eac1c991c..ce321c82533740781f1e9eec2b0f5183ba54d696 100644 (file)
@@ -9,6 +9,7 @@ ADD_LIBRARY(fstools SHARED
                libfstools/common.c
                libfstools/snapshot.c
                libfstools/extroot.c
+               libfstools/fit.c
                libfstools/overlay.c
                libfstools/volume.c
                libfstools/mtd.c
index b5cc692261a2e751a1cf41902e637967f4282844..28b82d2aee519de72aefce78cf1e2839f78ce649 100644 (file)
@@ -25,3 +25,5 @@ int read_uint_from_file(char *dirname, char *filename, unsigned int *i);
 char *read_string_from_file(const char *dirname, const char *filename, char *buf, size_t bufsz);
 int block_file_identify(FILE *f, uint64_t offset);
 int block_volume_format(struct volume *v, uint64_t offset, const char *bdev);
+
+static const char *const block_dir_name = "/sys/class/block";
diff --git a/libfstools/fit.c b/libfstools/fit.c
new file mode 100644 (file)
index 0000000..b0da854
--- /dev/null
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "common.h"
+
+#define BUFLEN 64
+
+static const char *const fit0 = "/dev/fit0";
+static const char *const fitrw = "/dev/fitrw";
+
+struct devpath {
+       char prefix[5];
+       char device[11];
+};
+
+struct fit_volume {
+       struct volume v;
+       union {
+               char devpathstr[16];
+               struct devpath devpath;
+       } dev;
+};
+
+static struct driver fit_driver;
+
+static int fit_volume_identify(struct volume *v)
+{
+       struct fit_volume *p = container_of(v, struct fit_volume, v);
+       int ret = FS_NONE;
+       FILE *f;
+
+       f = fopen(p->dev.devpathstr, "r");
+       if (!f)
+               return ret;
+
+       ret = block_file_identify(f, 0);
+
+       fclose(f);
+
+       return ret;
+}
+
+static int fit_volume_init(struct volume *v)
+{
+       struct fit_volume *p = container_of(v, struct fit_volume, v);
+       char voldir[BUFLEN];
+       unsigned int volsize;
+
+       snprintf(voldir, sizeof(voldir), "%s/%s", block_dir_name, p->dev.devpath.device);
+
+       if (read_uint_from_file(voldir, "size", &volsize))
+               return -1;
+
+       v->type = BLOCKDEV;
+       v->size = volsize << 9; /* size is returned in sectors of 512 bytes */
+       v->blk = p->dev.devpathstr;
+
+       return block_volume_format(v, 0, p->dev.devpathstr);
+}
+
+static struct volume *fit_volume_find(char *name)
+{
+       struct fit_volume *p;
+       struct stat buf;
+       const char *fname;
+       int ret;
+
+       if (!strcmp(name, "rootfs"))
+               fname = fit0;
+       else if (!strcmp(name, "rootfs_data"))
+               fname = fitrw;
+       else
+               return NULL;
+
+       ret = stat(fname, &buf);
+       if (ret)
+               return NULL;
+
+       p = calloc(1, sizeof(struct fit_volume));
+       if (!p)
+               return NULL;
+
+       strcpy(p->dev.devpathstr, fname);
+       p->v.drv = &fit_driver;
+       p->v.blk = p->dev.devpathstr;
+       p->v.name = name;
+
+       return &p->v;
+}
+
+static struct driver fit_driver = {
+       .name = "fit",
+       .priority = 30,
+       .find = fit_volume_find,
+       .init = fit_volume_init,
+       .identify = fit_volume_identify,
+};
+
+DRIVER(fit_driver);
index 53ee600fcb24b968a3a20ab5b36ef7b8c3aa0091..74bd60827e93d311759b325cde12d0d490f554f3 100644 (file)
@@ -4,8 +4,6 @@
 
 #define BUFLEN 64
 
-const char *const block_dir_name = "/sys/class/block";
-
 struct devpath {
        char prefix[5];
        char device[11];