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. 



git-svn-id: svn://coreboot.org/repository/coreboot-v3@583 f3766cd6-281f-0410-b1cd-43a5c92072e9
This commit is contained in:
Ronald G. Minnich 2008-02-09 21:16:42 +00:00
commit 6b4477c8cb
3 changed files with 87 additions and 3 deletions

View file

@ -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();

View file

@ -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);

View file

@ -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.