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(a)gmx.net>
Index: LinuxBIOSv3-betterlarsegments/include/lar.h
===================================================================
--- LinuxBIOSv3-betterlarsegments/include/lar.h (Revision 529)
+++ LinuxBIOSv3-betterlarsegments/include/lar.h (Arbeitskopie)
@@ -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 */
Index: LinuxBIOSv3-betterlarsegments/lib/lar.c
===================================================================
--- LinuxBIOSv3-betterlarsegments/lib/lar.c (Revision 529)
+++ LinuxBIOSv3-betterlarsegments/lib/lar.c (Arbeitskopie)
@@ -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);
-}
Index: LinuxBIOSv3-betterlarsegments/arch/x86/stage1.c
===================================================================
--- LinuxBIOSv3-betterlarsegments/arch/x86/stage1.c (Revision 529)
+++ LinuxBIOSv3-betterlarsegments/arch/x86/stage1.c (Arbeitskopie)
@@ -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");