From fd326f72be58758cc22fb0e75b95b7430013193e Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Thu, 27 Mar 2014 18:38:02 -0300 Subject: [PATCH] Change the dump function to also be able to load a component. It might be desirable to load a kernel and initrd and save it to a bootimg. They need to be padded with zeroes to align to a page size. Signed-off-by: Thadeu Lima de Souza Cascardo --- bootimg.c | 66 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 50 insertions(+), 16 deletions(-) diff --git a/bootimg.c b/bootimg.c index 9ce6fb8..b015c10 100644 --- a/bootimg.c +++ b/bootimg.c @@ -23,51 +23,85 @@ #include #include #include +#include -static int dump(int fd, size_t len, int pgsz, char *fname) +static int dump_or_load(int fd, size_t *len, int pgsz, char *fname, int dump) { - int out; + int cfd; char *page; int i, npages; int r; + int ifd, ofd; + int rem; page = malloc(pgsz); if (!page) return -ENOMEM; - out = open(fname, O_WRONLY | O_CREAT | O_EXCL, 0644); - if (out < 0) - return -errno; - npages = (len + pgsz - 1) / pgsz; + if (dump) + cfd = open(fname, O_WRONLY | O_CREAT | O_EXCL, 0644); + else + cfd = open(fname, O_RDONLY); + if (cfd < 0) + goto out; + if (dump) { + ifd = fd; + ofd = cfd; + } else { + struct stat s; + r = fstat(cfd, &s); + if (r < 0) { + goto out; + } + *len = s.st_size; + ifd = cfd; + ofd = fd; + } + npages = (*len + pgsz - 1) / pgsz; for (i = 1; i <= npages; i++) { if (i == npages) { - len = len & (pgsz - 1); - if (len > 0) { - r = read(fd, page, len); - if (r != len) + rem = *len & (pgsz - 1); + if (rem > 0) { + r = read(ifd, page, rem); + if (r != rem) goto out; - r = write(out, page, len); - if (r != len) + r = write(ofd, page, rem); + if (r != rem) goto out; + /* Write padding */ + if (!dump) { + memset(page, 0, pgsz - rem); + write(ofd, page, pgsz - rem); + } } } else { - r = read(fd, page, pgsz); + r = read(ifd, page, pgsz); if (r != pgsz) goto out; - r = write(out, page, pgsz); + r = write(ofd, page, pgsz); if (r != pgsz) goto out; } } free(page); - close(out); + close(cfd); return 0; out: free(page); - close(out); + close(cfd); if (r < 0) return -errno; return -EINVAL; } +static int dump(int fd, size_t len, int pgsz, char *fname) +{ + return dump_or_load(fd, &len, pgsz, fname, 1); +} + +static int load(int fd, size_t *len, int pgsz, char *fname) +{ + return dump_or_load(fd, len, pgsz, fname, 0); +} + int main(int argc, char **argv) { int fd; -- 2.20.1