Author: rminnich Date: 2008-02-09 22:16:42 +0100 (Sat, 09 Feb 2008) New Revision: 583
Modified: coreboot-v3/util/lar/lar.c coreboot-v3/util/lar/lib.h coreboot-v3/util/lar/stream.c Log: Add a zero-fill command to lar.
Signed-off-by: Ronald G. Minnich rminnich@gmail.com Acked-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
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 c-d.hailfinger.devel.2006@gmx.net 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 c-d.hailfinger.devel.2006@gmx.net
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.
Modified: coreboot-v3/util/lar/lar.c =================================================================== --- coreboot-v3/util/lar/lar.c 2008-02-09 16:32:59 UTC (rev 582) +++ coreboot-v3/util/lar/lar.c 2008-02-09 21:16:42 UTC (rev 583) @@ -182,6 +182,39 @@ 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 @@ {"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 @@ 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 @@ case 'x': larmode = EXTRACT; break; + case 'z': + larmode = ZEROFILL; + break; case 's': parse_larsize(optarg); break; @@ -287,6 +324,8 @@ 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 @@
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 @@ case LIST: list_lar(archivename, get_files()); break; + case ZEROFILL: + zerofill_lar(archivename); + break; }
free_files();
Modified: coreboot-v3/util/lar/lib.h =================================================================== --- coreboot-v3/util/lar/lib.h 2008-02-09 16:32:59 UTC (rev 582) +++ coreboot-v3/util/lar/lib.h 2008-02-09 21:16:42 UTC (rev 583) @@ -33,7 +33,8 @@ ADD, CREATE, LIST, - EXTRACT + EXTRACT, + ZEROFILL, } larmodes;
/* prototypes for lar.c functions */ @@ -58,6 +59,8 @@ 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);
Modified: coreboot-v3/util/lar/stream.c =================================================================== --- coreboot-v3/util/lar/stream.c 2008-02-09 16:32:59 UTC (rev 582) +++ coreboot-v3/util/lar/stream.c 2008-02-09 21:16:42 UTC (rev 583) @@ -784,6 +784,45 @@ }
/** + * 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. * @param ptr data to be compressed