[LinuxBIOS] v3: make initram work

Carl-Daniel Hailfinger c-d.hailfinger.devel.2006 at gmx.net
Tue Nov 27 00:20:52 CET 2007


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 at 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;







More information about the coreboot mailing list