[PATCH 07/15] bootm: fit: move length calculation into fit_open
Ahmad Fatoum
a.fatoum at pengutronix.de
Tue Jan 27 00:39:17 PST 2026
A FIT image is a device tree and its second big-endian 32-bit word
encodes the size and fit_open() takes an extra argument, so it need not
read a whole partition, but only as many bytes as the header describes.
We are going to add a new caller for fit_open(). Instead of repeating
the max_size determination at every call site, let's just move the size
calculation into the function.
Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
common/bootm-fit.c | 9 +--------
common/image-fit.c | 44 ++++++++++++++++++++++++++++++++++----------
drivers/of/overlay.c | 6 +++---
include/image-fit.h | 2 +-
include/libfile.h | 2 ++
lib/libfile.c | 40 ++++++++++++++++++++++++++++++++++++++++
6 files changed, 81 insertions(+), 22 deletions(-)
diff --git a/common/bootm-fit.c b/common/bootm-fit.c
index 5bfd8ac61d3f..70d6ba8edff2 100644
--- a/common/bootm-fit.c
+++ b/common/bootm-fit.c
@@ -129,17 +129,10 @@ static enum filetype bootm_fit_update_os_header(struct image_data *data)
int bootm_open_fit(struct image_data *data)
{
struct fit_handle *fit;
- struct fdt_header *header;
static const char *kernel_img = "kernel";
- size_t flen, hlen;
int ret;
- header = (struct fdt_header *)data->os_header;
- flen = bootm_get_os_size(data);
- hlen = fdt32_to_cpu(header->totalsize);
-
- fit = fit_open(data->os_file, data->verbose, data->verify,
- min(flen, hlen));
+ fit = fit_open(data->os_file, data->verbose, data->verify);
if (IS_ERR(fit)) {
pr_err("Loading FIT image %s failed with: %pe\n", data->os_file, fit);
return PTR_ERR(fit);
diff --git a/common/image-fit.c b/common/image-fit.c
index 75592766941c..d42282dfa80e 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -992,7 +992,6 @@ struct fit_handle *fit_open_buf(const void *buf, size_t size, bool verbose,
* @filename: The filename of the FIT image
* @verbose: If true, be more verbose
* @verify: The verify mode
- * @max_size: maximum length to read from file
*
* This opens a FIT image found in @filename. The returned handle is used as
* context for the other FIT functions.
@@ -1000,11 +999,12 @@ struct fit_handle *fit_open_buf(const void *buf, size_t size, bool verbose,
* Return: A handle to a FIT image or a ERR_PTR
*/
struct fit_handle *fit_open(const char *_filename, bool verbose,
- enum bootm_verify verify, loff_t max_size)
+ enum bootm_verify verify)
{
struct fit_handle *handle;
+ ssize_t nbytes;
char *filename;
- int ret;
+ int fd, ret;
filename = canonicalize_path(AT_FDCWD, _filename);
if (!filename) {
@@ -1024,15 +1024,28 @@ struct fit_handle *fit_open(const char *_filename, bool verbose,
handle->verbose = verbose;
handle->verify = verify;
- ret = read_file_2(filename, &handle->size, &handle->fit_alloc,
- max_size);
- if (ret && ret != -EFBIG) {
- pr_err("unable to read %s: %pe\n", filename, ERR_PTR(ret));
- free(handle);
- free(filename);
- return ERR_PTR(ret);
+ fd = open_fdt(filename, &handle->size);
+ if (fd < 0) {
+ ret = fd;
+ goto free_handle;
}
+ handle->fit_alloc = malloc(handle->size);
+ if (!handle->fit_alloc) {
+ ret = -ENOMEM;
+ goto close_fd;
+ }
+
+ nbytes = read_full(fd, handle->fit_alloc, handle->size);
+ if (nbytes >= 0 && handle->size != nbytes)
+ ret = -ENODATA;
+ if (nbytes < 0) {
+ ret = nbytes;
+ goto free_fit_alloc;
+ }
+
+ close(fd);
+
handle->fit = handle->fit_alloc;
handle->filename = filename;
@@ -1046,6 +1059,17 @@ struct fit_handle *fit_open(const char *_filename, bool verbose,
}
return handle;
+
+free_fit_alloc:
+ free(handle->fit_alloc);
+close_fd:
+ close(fd);
+free_handle:
+ pr_err("unable to read %s: %pe\n", filename, ERR_PTR(ret));
+ free(filename);
+ free(handle);
+ return ERR_PTR(ret);
+
}
static bool __fit_close(struct fit_handle *handle)
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index b11edebd2080..34543403e9ba 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -532,7 +532,7 @@ static bool of_overlay_valid_config(struct fit_handle *fit,
}
static int of_overlay_global_fixup_fit(struct device_node *root,
- const char *fit_path, loff_t fit_size)
+ const char *fit_path)
{
enum bootm_verify verify = bootm_get_verify_mode();
struct device_node *conf_node;
@@ -544,7 +544,7 @@ static int of_overlay_global_fixup_fit(struct device_node *root,
return -EINVAL;
}
- fit = fit_open(fit_path, 0, verify, fit_size);
+ fit = fit_open(fit_path, 0, verify);
if (IS_ERR(fit)) {
pr_err("Loading FIT image %s failed with: %pe\n", fit_path, fit);
return PTR_ERR(fit);
@@ -595,7 +595,7 @@ static int of_overlay_global_fixup(struct device_node *root, void *data)
}
/* Assume a FIT image if of_overlay_path points to a file */
- ret = of_overlay_global_fixup_fit(root, dir, s.st_size);
+ ret = of_overlay_global_fixup_fit(root, dir);
out:
free(dir);
diff --git a/include/image-fit.h b/include/image-fit.h
index 50f0482b65ad..ede43beab12e 100644
--- a/include/image-fit.h
+++ b/include/image-fit.h
@@ -28,7 +28,7 @@ struct fit_handle {
};
struct fit_handle *fit_open(const char *filename, bool verbose,
- enum bootm_verify verify, loff_t max_size);
+ enum bootm_verify verify);
struct fit_handle *fit_open_buf(const void *buf, size_t len, bool verbose,
enum bootm_verify verify);
void *fit_open_configuration(struct fit_handle *handle, const char *name,
diff --git a/include/libfile.h b/include/libfile.h
index 370f8b9725ab..f44046fb0f7b 100644
--- a/include/libfile.h
+++ b/include/libfile.h
@@ -59,4 +59,6 @@ struct resource *file_to_sdram(const char *filename, unsigned long adr,
int fixup_path_case(int dirfd, const char **path);
+int open_fdt(const char *filename, size_t *size);
+
#endif /* __LIBFILE_H */
diff --git a/lib/libfile.c b/lib/libfile.c
index 6924db587e8c..3be410855d2e 100644
--- a/lib/libfile.c
+++ b/lib/libfile.c
@@ -918,3 +918,43 @@ int fixup_path_case(int fd, const char **path)
free(resolved_path);
return -errno;
}
+
+int open_fdt(const char *filename, size_t *size)
+{
+ __be32 fdt_hdr[2];
+ u32 fdt_size;
+ struct stat st;
+ int fd, ret;
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ return fd;
+
+ ret = fstat(fd, &st);
+ if (ret)
+ goto err;
+
+ ret = pread_full(fd, &fdt_hdr, sizeof(fdt_hdr), 0);
+ if (ret >= 0 && ret < sizeof(fdt_hdr))
+ ret = -EILSEQ;
+ if (ret < 0)
+ goto err;
+
+ fdt_size = be32_to_cpu(fdt_hdr[1]);
+ if (st.st_size < fdt_size) {
+ ret = -ENODATA;
+ goto err;
+ }
+
+ close(fd);
+
+ /* HACK: TFTP doesn't support backwards seeking, so reopen afresh */
+ fd = open(filename, O_RDONLY);
+ if (fd >= 0)
+ *size = fdt_size;
+
+ return fd;
+err:
+ close(fd);
+ return ret;
+}
--
2.47.3
More information about the barebox
mailing list