This is my current v3 diff against r518. It has endianness and 64bit bugs, but it makes initram work correctly for a modified qemu target. Other half-related changes are mixed in as well.
Look at mainboard/emulation/qemu-x86/Makefile to see the changes needed for initram for all targets. Maybe we should move these changes to arch/x86/Makefile.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: LinuxBIOSv3-testnewshared/include/shared.h =================================================================== --- LinuxBIOSv3-testnewshared/include/shared.h (Revision 518) +++ LinuxBIOSv3-testnewshared/include/shared.h (Arbeitskopie) @@ -43,7 +43,7 @@ ret (*func)(args) attr= stage0_##func #else #define EXTERN(func, ret, attr, args...) \ - ret *func(args) attr + extern ret (*func)(args) attr #endif
#else Index: LinuxBIOSv3-testnewshared/mainboard/emulation/qemu-x86/initram.c =================================================================== --- LinuxBIOSv3-testnewshared/mainboard/emulation/qemu-x86/initram.c (Revision 518) +++ LinuxBIOSv3-testnewshared/mainboard/emulation/qemu-x86/initram.c (Arbeitskopie) @@ -20,10 +20,24 @@ #define _MAINOBJECT #include <console.h>
+/* printktest1() is here to increase the likelihood of main() not ending up at + * the beginning of the file obtained with "objcopy -O binary". + * + */ +int printktest1(void) +{ + printk(BIOS_INFO, "printktest1: If the immediately preceding line does" + " not say "Nothing to do.", then execution did not start at" + " main()\n"); + + return 0; +} + int main(void) { printk(BIOS_INFO, "RAM init code started.\n"); printk(BIOS_INFO, "Nothing to do.\n"); + printktest1();
return 0; } Index: LinuxBIOSv3-testnewshared/mainboard/emulation/qemu-x86/Makefile =================================================================== --- LinuxBIOSv3-testnewshared/mainboard/emulation/qemu-x86/Makefile (Revision 518) +++ LinuxBIOSv3-testnewshared/mainboard/emulation/qemu-x86/Makefile (Arbeitskopie) @@ -44,12 +44,19 @@
$(obj)/linuxbios.initram $(obj)/linuxbios.initram.map: $(obj)/stage0.init $(obj)/stage0-prefixed.o $(patsubst %.o,%_xip.o,$(INITRAM_OBJ)) $(Q)# initram links against stage0 - $(Q)printf " LD $(subst $(shell pwd)/,,$(@))\n" + $(Q)printf " LD $(subst $(shell pwd)/,,$(@)).o\n" $(Q)$(LD) --entry main -N -R $(obj)/stage0-prefixed.o \ $(patsubst %.o,%_xip.o,$(INITRAM_OBJ)) -o $(obj)/linuxbios.initram.o + $(Q)# calculate the offset of the entry point + $(Q)printf " CALCUL $(subst $(shell pwd)/,,$(@)).entryoffset\n" + $(Q)echo -e "ibase=16\n"\ + `objdump -f $(obj)/linuxbios.initram.o|grep "start address"|sed "s/.*0x//"|tr "[[:lower:]]" "[[:upper:]]"`\ + -\ + `objdump -t $(obj)/linuxbios.initram.o|grep '.text.*.text$$'|cut -f 1 -d" "|tr "[[:lower:]]" "[[:upper:]]"`\ + |bc > $(obj)/linuxbios.initram.entryoffset $(Q)printf " OBJCOPY $(subst $(shell pwd)/,,$(@))\n" $(Q)$(OBJCOPY) -O binary $(obj)/linuxbios.initram.o \ $(obj)/linuxbios.initram - $(Q)printf " NM $(subst $(shell pwd)/,,$(@))\n" + $(Q)printf " NM $(subst $(shell pwd)/,,$(@)).o\n" $(Q)$(NM) $(obj)/linuxbios.initram.o | sort -u > $(obj)/linuxbios.initram.map
Index: LinuxBIOSv3-testnewshared/lib/lar.c =================================================================== --- LinuxBIOSv3-testnewshared/lib/lar.c (Revision 518) +++ LinuxBIOSv3-testnewshared/lib/lar.c (Arbeitskopie) @@ -232,6 +232,8 @@ * 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. + * BIG FAT WARNING: run_file uses the beginning of the file as entry point + * and does NOT care about the entry member of the LAR header! * @param archive A descriptor for current archive. * @param filename filename to find * @param where pointer to where to load the data @@ -263,9 +265,9 @@ filename); return 1; } - where = result.start; + where = result.start + (u32)result.entry; } - printk(BIOS_SPEW, "where is %p\n", where); + printk(BIOS_SPEW, "where is %p, not honoring entry point specified in archive unless we XIP, in that case entry is an offset\n", where); ret = run_address(where); printk(BIOS_SPEW, "run_file returns with %d\n", ret); return ret; Index: LinuxBIOSv3-testnewshared/arch/x86/Makefile =================================================================== --- LinuxBIOSv3-testnewshared/arch/x86/Makefile (Revision 518) +++ LinuxBIOSv3-testnewshared/arch/x86/Makefile (Arbeitskopie) @@ -36,7 +36,9 @@
ROM_SIZE := $(shell expr $(CONFIG_LINUXBIOS_ROMSIZE_KB) * 1024)
-LARFILES := nocompress:normal/initram normal/stage2 nocompress:normal/option_table +# We should retrieve entry from $(obj)/linuxbios.initram.entryoffset which is +# unfortunately only available after initram is built. +LARFILES := entry=33:nocompress:normal/initram normal/stage2 nocompress:normal/option_table ifneq ($(CONFIG_PAYLOAD_NONE),y) LARFILES += normal/payload endif Index: LinuxBIOSv3-testnewshared/util/lar/lib.c =================================================================== --- LinuxBIOSv3-testnewshared/util/lar/lib.c (Revision 518) +++ LinuxBIOSv3-testnewshared/util/lar/lib.c (Arbeitskopie) @@ -207,8 +207,10 @@ char *realname; char *c;
- if (strstr(name, "nocompress:") == name) { - realname = strdup(name + 11); + printf("add_files called for %s\n", name); + /* search backwards to find the last option delimiter */ + if (strrchr(name, ':')) { + realname = strdup(strrchr(name, ':') + 1); } else { realname = strdup(name); } Index: LinuxBIOSv3-testnewshared/util/lar/lib.h =================================================================== --- LinuxBIOSv3-testnewshared/util/lar/lib.h (Revision 518) +++ LinuxBIOSv3-testnewshared/util/lar/lib.h (Arbeitskopie) @@ -56,7 +56,7 @@
/* Prototypes for in-memory LAR operations */ int lar_process_name(char *name, char **pfilename, char **ppathname, - enum compalgo *thisalgo); + enum compalgo *thisalgo, u32 *entry); u32 lar_compress(char *ptr, ssize_t size, char *temp, enum compalgo *thisalgo); int lar_add_entry(struct lar *lar, char *pathname, void *data, u32 complen, u32 reallen, u32 loadaddress, u32 entry, Index: LinuxBIOSv3-testnewshared/util/lar/stream.c =================================================================== --- LinuxBIOSv3-testnewshared/util/lar/stream.c (Revision 518) +++ LinuxBIOSv3-testnewshared/util/lar/stream.c (Arbeitskopie) @@ -664,20 +664,25 @@ * @return 0 success, or -1 on failure (i.e. a bad name) */ int lar_process_name(char *name, char **pfilename, char **ppathname, - enum compalgo *thisalgo) + enum compalgo *thisalgo, u32 *entry) { char *filename = name, *pathname = name;
- if (!strncmp(name, "nocompress:",11)) { - filename += 11; + if (strstr(name, "nocompress:")) { *thisalgo = none; } + if (strstr(name, "entry=")) { + *entry = strtoul(strstr(name, "entry=") + 6, NULL, 0); + } + if (strrchr(name, ':')) + filename = strrchr(name, ':') + 1;
/* this is dangerous */ if (filename[0] == '.' && filename[1] == '/') filename += 2;
- pathname = strchr(filename, ':'); + /* New pathname syntax: path=file */ + pathname = strchr(filename, '=');
if (pathname != NULL) { *pathname = '\0'; @@ -776,6 +781,7 @@ u32 *walk, csum; u32 offset;
+ printf("lar_add_entry called for %s, entry is %p\n", pathname, (void *)entry); /* Find the beginning of the available space in the LAR */ offset = lar_empty_offset(lar);
@@ -841,13 +847,18 @@ u32 complen; int pathlen; u32 size; + u32 entry = 0;
+ printf("lar_add_file: name is %s\n", name); + thisalgo = algo; - lar_process_name(name, &filename, &pathname, &thisalgo); + lar_process_name(name, &filename, &pathname, &thisalgo, &entry); + printf("lar_add_file: after processing: filename=%s, pathname=%s\n", filename, pathname);
ptr = mapfile(filename, &size);
if (elfparse() && iself(ptr)) { + printf("lar_add_file: handle elf\n"); output_elf_segments(lar, pathname, ptr, size, thisalgo); return 0; } @@ -871,7 +882,7 @@
munmap(ptr, size);
- ret = lar_add_entry(lar, pathname, temp, complen, size, 0, 0, thisalgo); + ret = lar_add_entry(lar, pathname, temp, complen, size, 0, entry, thisalgo);
free(temp); return ret;