Author: hailfinger Date: 2007-11-28 23:50:00 +0100 (Wed, 28 Nov 2007) New Revision: 530
Modified: LinuxBIOSv3/arch/x86/stage1.c LinuxBIOSv3/include/lar.h LinuxBIOSv3/lib/lar.c Log: Consolidate all multiple segment handling into lib/lar.c:load_file_segments() and greatly simplify arch/x86/stage1.c code as a result. While I'm at it, improve the LAR segmentation abstraction. Stage 1 code should not have to care about internal representation of segments, that knowledge belongs into lib/lar.c. Constification of most function parameters in lib/lar.c led to a few other now obvious code removals.
Build tested and runtime tested in Qemu.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net Acked-by: Ronald G. Minnich rminnich@gmail.com
Modified: LinuxBIOSv3/arch/x86/stage1.c =================================================================== --- LinuxBIOSv3/arch/x86/stage1.c 2007-11-27 19:06:45 UTC (rev 529) +++ LinuxBIOSv3/arch/x86/stage1.c 2007-11-28 22:50:00 UTC (rev 530) @@ -77,7 +77,6 @@ struct mem_file archive, result; int elfboot_mem(struct lb_memory *mem, void *where, int size); void *entry; - int i;
/* we can't statically init this hack. */ unsigned char faker[64]; @@ -161,11 +160,9 @@ /* Turn off Cache-As-Ram */ disable_car();
- entry = load_file(&archive, "normal/stage2.o/segment0"); + entry = load_file_segments(&archive, "normal/stage2.o"); if (entry == (void *)-1) - die("FATAL: Failed loading stage2 segment0."); - if (load_file(&archive, "normal/stage2.o/segment1") == (void *)-1) - die("FATAL: Failed loading stage2 segment1."); + die("FATAL: Failed loading stage2."); ret = run_address(entry); if (ret) die("FATAL: Failed in stage2 code."); @@ -176,26 +173,8 @@ if (! ret) legacy(&archive, "normal/payload", (void *)UNCOMPRESS_AREA, mem);
- - /* new style lar boot. Install all the files in memory. - * By convention we take the entry point from the first - * one. Look for a cmdline as well. - */ - for(i = 0, entry = (void *)0; ;i++) { - char filename[64]; - void *newentry; - sprintf(filename, "normal/payload/segment%d", i); - archive.len = *(u32 *)0xfffffff4; - archive.start =(void *)(0UL-archive.len); - newentry = load_file(&archive, filename); - printk(BIOS_SPEW, "newentry is %p\n", newentry); - if (newentry == (void *)-1) - break; - if (! entry) - entry = newentry; - } - printk(BIOS_SPEW, "all loaded, entry %p\n", entry); - if (entry) + entry = load_file_segments(&archive, "normal/payload"); + if (entry != (void*)-1) run_address(entry);
die("FATAL: No usable payload found.\n");
Modified: LinuxBIOSv3/include/lar.h =================================================================== --- LinuxBIOSv3/include/lar.h 2007-11-27 19:06:45 UTC (rev 529) +++ LinuxBIOSv3/include/lar.h 2007-11-28 22:50:00 UTC (rev 530) @@ -82,10 +82,11 @@ };
/* Prototypes. */ -int find_file(struct mem_file *archive, const char *filename, struct mem_file *result); -int copy_file(struct mem_file *archive, const char *filename, void *where); -int run_file(struct mem_file *archive, const char *filename, void *where); -int execute_in_place(struct mem_file *archive, const char *filename); +int find_file(const struct mem_file *archive, const char *filename, struct mem_file *result); +int copy_file(const struct mem_file *archive, const char *filename, void *where); +int run_file(const struct mem_file *archive, const char *filename, void *where); +int execute_in_place(const struct mem_file *archive, const char *filename); int run_address(void *f); -void *load_file(struct mem_file *archive, const char *filename); +void *load_file(const struct mem_file *archive, const char *filename); +void *load_file_segments(const struct mem_file *archive, const char *filename); #endif /* LAR_H */
Modified: LinuxBIOSv3/lib/lar.c =================================================================== --- LinuxBIOSv3/lib/lar.c 2007-11-27 19:06:45 UTC (rev 529) +++ LinuxBIOSv3/lib/lar.c 2007-11-28 22:50:00 UTC (rev 530) @@ -56,7 +56,7 @@ * returns 0 on success, -1 otherwise */
-int find_file(struct mem_file *archive, const char *filename, struct mem_file *result) +int find_file(const struct mem_file *archive, const char *filename, struct mem_file *result) { char *walk, *fullname; struct lar_header *header; @@ -145,7 +145,7 @@ return 1; }
-static int process_file(struct mem_file *archive, void *where) +static int process_file(const struct mem_file *archive, void *where) { printk(BIOS_SPEW, "LAR: Compression algorithm #%i used\n", archive->compression); /* no compression */ @@ -175,6 +175,37 @@ }
/** + * Given a file name, search the LAR for all segments of it, and load them + * into memory, using the loadaddress pointer in the mem_file struct. + * @param archive A descriptor for current archive. + * @param filename filename to find + * returns entry on success, (void*)-1 otherwise + * FIXME: Look for a cmdline as well. + */ +void *load_file_segments(const struct mem_file *archive, const char *filename) +{ + void *entry = NULL; + void *newentry; + int i; + char tmpname[64]; + + for(i = 0, entry = (void *)0; ;i++) { + sprintf(tmpname, "%s/segment%d", filename, i); + newentry = load_file(archive, tmpname); + if (newentry == (void *)-1) + break; + if (!entry) + entry = newentry; + } + if (!entry) { + printk(BIOS_INFO, "LAR: load_file_segments: Failed for %s\n", filename); + return (void *)-1; + } + printk(BIOS_SPEW, "LAR: load_file_segments: All loaded, entry %p\n", entry); + return entry; +} + +/** * Given a file name in the LAR , search for it, and load it into memory, using * the loadaddress pointer in the mem_file struct. * @param archive A descriptor for current archive. @@ -182,7 +213,7 @@ * returns entry on success, (void*)-1 otherwise */
-void *load_file(struct mem_file *archive, const char *filename) +void *load_file(const struct mem_file *archive, const char *filename) { int ret; struct mem_file result; @@ -212,7 +243,7 @@ * @param where pointer to where to load the data * returns 0 on success, -1 otherwise */ -int copy_file(struct mem_file *archive, const char *filename, void *where) +int copy_file(const struct mem_file *archive, const char *filename, void *where) { int ret; struct mem_file result; @@ -229,55 +260,30 @@
/** - * Given a file name in the LAR , search for it, and load it into memory, - * using the passed-in pointer as the address; jump to the file. - * If the passed-in pointer is (void *)-1, then execute the file in place. + * Given a file name in the LAR , search for it, and execute it in place. * @param archive A descriptor for current archive. * @param filename filename to find - * @param where pointer to where to load the data * returns 0 on success, -1 otherwise */ -int run_file(struct mem_file *archive, const char *filename, void *where) +int execute_in_place(const struct mem_file *archive, const char *filename) { struct mem_file result; int ret; + void *where;
- if ((u32) where != 0xFFFFFFFF) { - if (copy_file(archive, filename, where)) { - printk(BIOS_INFO, - "LAR: Run file %s failed: No such file.\n", - filename); - return 1; - } - } else { /* XIP */ - if (find_file(archive, filename, &result)) { - printk(BIOS_INFO, - "LAR: Run file %s failed: No such file.\n", - filename); - return 1; - } - if (result.compression != 0) { - printk(BIOS_INFO, - "LAR: Run file %s failed: Compressed file" - " not supported for in-place execution\n", - filename); - return 1; - } - where = result.start + (u32)result.entry; + if (find_file(archive, filename, &result)) { + printk(BIOS_INFO, "LAR: Run file %s failed: No such file.\n", + filename); + return 1; } + if (result.compression != 0) { + printk(BIOS_INFO, "LAR: Run file %s failed: Compressed file" + " not supported for in-place execution\n", filename); + return 1; + } + where = result.start + (u32)result.entry; printk(BIOS_SPEW, "Entry point is %p\n", where); ret = run_address(where); printk(BIOS_SPEW, "run_file returns with %d\n", ret); return ret; } - -/** - * Given a file name in the LAR , search for it, and execute it in place. - * @param archive A descriptor for current archive. - * @param filename filename to find - * returns 0 on success, -1 otherwise - */ -int execute_in_place(struct mem_file *archive, const char *filename) -{ - return run_file(archive, filename, (void *) 0xFFFFFFFF); -}