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;
I appreciate the work you have done here but it is too complex for my taste. Please look at my ELF parsing changes for initram. I would prefer to go that way. Note that my changes not only honor the entry point in the LAR header, they actually use it :-)
ron
On 27.11.2007 00:58, ron minnich wrote:
I appreciate the work you have done here but it is too complex for my taste. Please look at my ELF parsing changes for initram. I would prefer to go that way. Note that my changes not only honor the entry point in the LAR header, they actually use it :-)
Hi Ron,
thanks for going the ELF parse way. While some parts of the patch are still relevant because they fix other bugs, I like your ELF parsing patch much better than my approach. Unfortunately (for me), my net access failed for half a day so I was unable to see the work you were doing in parallel. Although my mails have earlier date, they were flushed just now out of my outbox.
I'll test your ELF parsing changes and post a patch on top of it.
Regards, Carl-Daniel