From bc3b8cdd3de3f5d59016038bb3f7d266fbf1301c Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Thu, 23 Nov 2023 00:19:37 +0000 Subject: [PATCH] libfstools: add uImage.FIT fitblk driver 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 --- CMakeLists.txt | 1 + libfstools/common.h | 2 + libfstools/fit.c | 98 +++++++++++++++++++++++++++++++++++++++++++ libfstools/partname.c | 2 - 4 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 libfstools/fit.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 3421fec..ce321c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/libfstools/common.h b/libfstools/common.h index b5cc692..28b82d2 100644 --- a/libfstools/common.h +++ b/libfstools/common.h @@ -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 index 0000000..b0da854 --- /dev/null +++ b/libfstools/fit.c @@ -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); diff --git a/libfstools/partname.c b/libfstools/partname.c index 53ee600..74bd608 100644 --- a/libfstools/partname.c +++ b/libfstools/partname.c @@ -4,8 +4,6 @@ #define BUFLEN 64 -const char *const block_dir_name = "/sys/class/block"; - struct devpath { char prefix[5]; char device[11]; -- 2.30.2