From 6b4477c8cba37b4a645e230a6c4c80a52328010a Mon Sep 17 00:00:00 2001 From: "Ronald G. Minnich" Date: Sat, 9 Feb 2008 21:16:42 +0000 Subject: [PATCH] Add a zero-fill command to lar. Signed-off-by: Ronald G. Minnich Acked-by: Carl-Daniel Hailfinger Note: the following discussion applies to this patch. This patch is basically limited. It is mostly useful for newly-created LARs. On Feb 9, 2008 1:06 PM, Carl-Daniel Hailfinger wrote: > If I read the code correctly, the command will try to fill the first > occurrence of free space in the lar, not the biggest one. That means > we > might have to call it multiple times. hmm. I obviously did not think of this. > And a general problem with the code: If it finds the offset of the > first > empty area, it checks whether the area is big enough. If not, it does > not search for another empty area, but returns instead with an error. Actually, I think as written it is broken for the general case of lots of empty spots. It should just look for the room left from start of empty space to next LAR header. It's just that I have never had a LAR that has more than one block of empty space, and that empty space is always at the gap before the bootblock. How about this. I'd like to commit now, and then fix this later, as I really need this code in there for speed and it works fine with all "fresh" images built with v3. > Should we really call this "zerofill"? "emptyfill"? I'll let it go for now but you make good point. > Acked-by: Carl-Daniel Hailfinger OK, this is clearly a work in progress but even in this form it is so useful I'm going to commit it with a note, "This needs more work", and with luck someone else will improve it once we need it improved -- the basic structure is there. Index: util/lar/stream.c Add hlen (header len) and maxsize (max size left in lar) functions. Index: util/lar/lib.h Add function prototypes and new ZEROFILL enum. Index: util/lar/lar.c Add -z option and command support. git-svn-id: svn://coreboot.org/repository/coreboot-v3@583 f3766cd6-281f-0410-b1cd-43a5c92072e9 --- util/lar/lar.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- util/lar/lib.h | 5 ++++- util/lar/stream.c | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 3 deletions(-) diff --git a/util/lar/lar.c b/util/lar/lar.c index 86a30317b7..987e954183 100644 --- a/util/lar/lar.c +++ b/util/lar/lar.c @@ -182,6 +182,39 @@ int list_lar(const char *archivename, struct file *files) return 0; } +int zerofill_lar(const char *archivename) +{ + struct lar_header *header; + int ret, hlen; + int pathlen; + u32 *walk, csum; + u32 offset; + char *name = "zerofill"; + int zerolen; + char *zero; + + struct lar *lar = lar_open_archive(archivename); + + if (lar == NULL) { + fprintf(stderr, "Unable to open LAR archive %s\n", archivename); + exit(1); + } + + zerolen = maxsize(lar, name); + if (zerolen <= 0) { + fprintf(stderr, "No room for zerofill.\n"); + return -1; + } + + zero = malloc(zerolen); + memset(zero, 0xff, zerolen); + + lar_add_entry(lar, name, zero, zerolen, zerolen,0, 0, 0); + + lar_close_archive(lar); + return 0; +} + int extract_lar(const char *archivename, struct file *files) { int ret; @@ -218,6 +251,7 @@ int main(int argc, char *argv[]) {"elfparse", 1, 0, 'e'}, {"verbose", 0, 0, 'v'}, {"version", 0, 0, 'V'}, + {"zerofill", 0, 0, 'z'}, {"help", 0, 0, 'h'}, {0, 0, 0, 0} }; @@ -227,7 +261,7 @@ int main(int argc, char *argv[]) exit(1); } - while ((opt = getopt_long(argc, argv, "acC:xels:b:vVh?", + while ((opt = getopt_long(argc, argv, "acC:xzels:b:vVh?", long_options, &option_index)) != EOF) { switch (opt) { case 'a': @@ -253,6 +287,9 @@ int main(int argc, char *argv[]) case 'x': larmode = EXTRACT; break; + case 'z': + larmode = ZEROFILL; + break; case 's': parse_larsize(optarg); break; @@ -287,6 +324,8 @@ int main(int argc, char *argv[]) larmode = CREATE; else if (strncmp(argv[optind], "l", 2) == 0) larmode = LIST; + else if (strncmp(argv[optind], "z", 2) == 0) + larmode = ZEROFILL; /* If larmode changed in this if branch, * eat a parameter @@ -324,7 +363,7 @@ int main(int argc, char *argv[]) if (optind < argc) { archivename = argv[optind++]; - } else { + } else if (larmode != ZEROFILL) { usage(argv[0]); fprintf(stderr, "Error: No archive name.\n\n"); @@ -356,6 +395,9 @@ int main(int argc, char *argv[]) case LIST: list_lar(archivename, get_files()); break; + case ZEROFILL: + zerofill_lar(archivename); + break; } free_files(); diff --git a/util/lar/lib.h b/util/lar/lib.h index 656ace9507..c59aeef2f7 100644 --- a/util/lar/lib.h +++ b/util/lar/lib.h @@ -33,7 +33,8 @@ enum { ADD, CREATE, LIST, - EXTRACT + EXTRACT, + ZEROFILL, } larmodes; /* prototypes for lar.c functions */ @@ -58,6 +59,8 @@ int iself(char *filebuf); int lar_process_name(char *name, char **pfilename, char **ppathname, enum compalgo *thisalgo); u32 lar_compress(char *ptr, ssize_t size, char *temp, enum compalgo *thisalgo); +int hlen(char *name); +int maxsize(struct lar *lar, char *name); int lar_add_entry(struct lar *lar, char *pathname, void *data, u32 complen, u32 reallen, u32 loadaddress, u32 entry, enum compalgo thisalgo); diff --git a/util/lar/stream.c b/util/lar/stream.c index f3542e79b8..e3cd86e2b0 100644 --- a/util/lar/stream.c +++ b/util/lar/stream.c @@ -783,6 +783,45 @@ char *mapfile(char *filename, u32 *size) return ptr; } +/** + * Given a name, return the size of the header for that name. + * + * @param name header name + * @return header size + */ +int hlen(char *pathname) +{ + int pathlen; + int len; + + pathlen = strlen(pathname) + 1 > MAX_PATHLEN ? + MAX_PATHLEN : strlen(pathname) + 1; + len = sizeof(struct lar_header) + pathlen; + len = (len + 15) & 0xFFFFFFF0; + + return len; +} + +/** + * Return the amount of space left in a lar, given a name for the entry + * @param Name of the entry + * @return Maximum possible size for the entry + */ +int maxsize(struct lar *lar, char *name) +{ + int size; + u32 offset; + int bootblock_size; + + /* Find the beginning of the available space in the LAR */ + offset = lar_empty_offset(lar); + + /* Figure out how big our header will be */ + size = get_bootblock_offset(lar->size) - offset - hlen(name) - 1; + + return size; +} + /** * Compress an area according to an algorithm. If the area grows, * use no compression.