On 26.11.2007 23:53, ron minnich wrote:
This is a set of proposed changes for doing initram which are backward-compatible (and tested) on qemu. The change is to exploit the elf-parsing abilities of lar to better set up the initram files in LAR, and get away from worrying about potential gld bugs, now and in the future.
Great stuff! I like it so much that I fixed up all targets and dropped the compat stuff. It may have been tested on qemu, but on my machine your patch was missing a few hunks needed to get stuff running in qemu.
Oh, and a nice side note: You and I have been developing some parts of the patch independently, yet the resulting code was exactly the same. Maybe that's one of the reasons why I like your patch so much. The other reasons being clarity and simplicity.
The change is to use the elf-parsing capabilities of LAR to parse the initram.o file, and create a valid LAR header with an entry value. This will fix the problems I am having on the ALIX 1C and probably allow it to boot. It also sets the text base of the .o to 0, instead of whatever wacky value gld is choosing, so all platforms will have the same value.
I would appreciate comments on this, and I wonder if we shouldn't just drop the "binary blob" initram immediately. I don't see a need for it at this point.
Dropped, at least for initram. We still use it for the option table and stage2.
Note that we can next apply this to stage 2, and completely remove the dreaded "binary blobs" from the LAR, and also remove our use of objcopy for this use.
Yes!
The patch below combines all of your patches posted to the list plus the needed target makefile fixups. Compat stuff for initram has been removed. Better Qemu target entry point debugging has been added.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: LinuxBIOSv3-testron/mainboard/adl/msm800sev/Makefile =================================================================== --- LinuxBIOSv3-testron/mainboard/adl/msm800sev/Makefile (Revision 522) +++ LinuxBIOSv3-testron/mainboard/adl/msm800sev/Makefile (Arbeitskopie) @@ -32,14 +32,11 @@ $(obj)/southbridge/amd/cs5536/smbus_initram.o \ $(obj)/arch/x86/geodelx/geodelx.o
-$(obj)/linuxbios.initram $(obj)/linuxbios.initram.map: $(obj)/stage0.init $(obj)/stage0-prefixed.o $(patsubst %.o,%_xip.o,$(INITRAM_OBJ)) +$(obj)/linuxbios.initram.o $(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)$(LD) --entry main -N -R $(obj)/stage0-prefixed.o \ + $(Q)$(LD) -Ttext 0 --entry main -N -R $(obj)/stage0-prefixed.o \ $(patsubst %.o,%_xip.o,$(INITRAM_OBJ)) -o $(obj)/linuxbios.initram.o - $(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)$(NM) $(obj)/linuxbios.initram.o | sort -u > $(obj)/linuxbios.initram.map
Index: LinuxBIOSv3-testron/mainboard/amd/norwich/Makefile =================================================================== --- LinuxBIOSv3-testron/mainboard/amd/norwich/Makefile (Revision 522) +++ LinuxBIOSv3-testron/mainboard/amd/norwich/Makefile (Arbeitskopie) @@ -32,14 +32,11 @@ $(Q)printf " BUILD DUMMY VPD\n" $(Q)dd if=/dev/zero of=$(obj)/linuxbios.vpd bs=256 count=1 $(SILENT)
-$(obj)/linuxbios.initram $(obj)/linuxbios.initram.map: $(obj)/stage0.init $(obj)/stage0-prefixed.o $(patsubst %.o,%_xip.o,$(INITRAM_OBJ)) +$(obj)/linuxbios.initram.o $(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)$(LD) --entry main -N -R $(obj)/stage0-prefixed.o \ + $(Q)$(LD) -Ttext 0 --entry main -N -R $(obj)/stage0-prefixed.o \ $(patsubst %.o,%_xip.o,$(INITRAM_OBJ)) -o $(obj)/linuxbios.initram.o - $(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)$(NM) $(obj)/linuxbios.initram.o | sort -u > $(obj)/linuxbios.initram.map
Index: LinuxBIOSv3-testron/mainboard/artecgroup/dbe61/Makefile =================================================================== --- LinuxBIOSv3-testron/mainboard/artecgroup/dbe61/Makefile (Revision 522) +++ LinuxBIOSv3-testron/mainboard/artecgroup/dbe61/Makefile (Arbeitskopie) @@ -30,14 +30,11 @@ INITRAM_OBJ = $(obj)/mainboard/$(MAINBOARDDIR)/initram.o \ $(obj)/arch/x86/geodelx/geodelx.o
-$(obj)/linuxbios.initram $(obj)/linuxbios.initram.map: $(obj)/stage0.init $(obj)/stage0-prefixed.o $(patsubst %.o,%_xip.o,$(INITRAM_OBJ)) +$(obj)/linuxbios.initram.o $(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)$(LD) --entry main -N -R $(obj)/stage0-prefixed.o \ + $(Q)$(LD) -Ttext 0 --entry main -N -R $(obj)/stage0-prefixed.o \ $(patsubst %.o,%_xip.o,$(INITRAM_OBJ)) -o $(obj)/linuxbios.initram.o - $(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)$(NM) $(obj)/linuxbios.initram.o | sort -u > $(obj)/linuxbios.initram.map
Index: LinuxBIOSv3-testron/mainboard/pcengines/alix1c/Makefile =================================================================== --- LinuxBIOSv3-testron/mainboard/pcengines/alix1c/Makefile (Revision 522) +++ LinuxBIOSv3-testron/mainboard/pcengines/alix1c/Makefile (Arbeitskopie) @@ -32,14 +32,11 @@ $(Q)printf " BUILD DUMMY VPD\n" $(Q)dd if=/dev/zero of=$(obj)/linuxbios.vpd bs=256 count=1 $(SILENT)
-$(obj)/linuxbios.initram $(obj)/linuxbios.initram.map: $(obj)/stage0.init $(obj)/stage0-prefixed.o $(patsubst %.o,%_xip.o,$(INITRAM_OBJ)) +$(obj)/linuxbios.initram.o $(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)$(LD) --entry main -N -R $(obj)/stage0-prefixed.o \ + $(Q)$(LD) -Ttext 0 --entry main -N -R $(obj)/stage0-prefixed.o \ $(patsubst %.o,%_xip.o,$(INITRAM_OBJ)) -o $(obj)/linuxbios.initram.o - $(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)$(NM) $(obj)/linuxbios.initram.o | sort -u > $(obj)/linuxbios.initram.map
Index: LinuxBIOSv3-testron/mainboard/emulation/qemu-x86/initram.c =================================================================== --- LinuxBIOSv3-testron/mainboard/emulation/qemu-x86/initram.c (Revision 522) +++ LinuxBIOSv3-testron/mainboard/emulation/qemu-x86/initram.c (Arbeitskopie) @@ -21,10 +21,24 @@
#include <console.h>
+/* printktest1() is here to increase the likelihood of main() not ending up at + * the beginning of the file, so we can check whether the entry point at main() + * was honored. + */ +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-testron/mainboard/emulation/qemu-x86/Makefile =================================================================== --- LinuxBIOSv3-testron/mainboard/emulation/qemu-x86/Makefile (Revision 522) +++ LinuxBIOSv3-testron/mainboard/emulation/qemu-x86/Makefile (Arbeitskopie) @@ -42,14 +42,11 @@
INITRAM_OBJ = $(obj)/mainboard/$(MAINBOARDDIR)/initram.o
-$(obj)/linuxbios.initram $(obj)/linuxbios.initram.map: $(obj)/stage0.init $(obj)/stage0-prefixed.o $(patsubst %.o,%_xip.o,$(INITRAM_OBJ)) +$(obj)/linuxbios.initram.o $(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)$(LD) --entry main -N -R $(obj)/stage0-prefixed.o \ + $(Q)$(LD) -Ttext 0 --entry main -N -R $(obj)/stage0-prefixed.o \ $(patsubst %.o,%_xip.o,$(INITRAM_OBJ)) -o $(obj)/linuxbios.initram.o - $(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)$(NM) $(obj)/linuxbios.initram.o | sort -u > $(obj)/linuxbios.initram.map
Index: LinuxBIOSv3-testron/lib/lar.c =================================================================== --- LinuxBIOSv3-testron/lib/lar.c (Revision 522) +++ LinuxBIOSv3-testron/lib/lar.c (Arbeitskopie) @@ -263,9 +263,9 @@ filename); return 1; } - where = result.start; + where = result.start + (u32)result.entry; } - printk(BIOS_SPEW, "where is %p\n", where); + 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; Index: LinuxBIOSv3-testron/arch/x86/stage1.c =================================================================== --- LinuxBIOSv3-testron/arch/x86/stage1.c (Revision 522) +++ LinuxBIOSv3-testron/arch/x86/stage1.c (Arbeitskopie) @@ -138,17 +138,17 @@ // find first initram if (check_normal_boot_flag()) { printk(BIOS_DEBUG, "Choosing normal boot.\n"); - ret = execute_in_place(&archive, "normal/initram"); + ret = execute_in_place(&archive, "normal/initram.o/segment0"); } else { printk(BIOS_DEBUG, "Choosing fallback boot.\n"); - ret = execute_in_place(&archive, "fallback/initram"); + ret = execute_in_place(&archive, "fallback/initram.o/segment0"); /* Try a normal boot if fallback doesn't exist in the lar. * TODO: There are other ways to do this. * It could be ifdef or the boot flag could be forced. */ if (ret) { printk(BIOS_DEBUG, "Fallback failed. Try normal boot\n"); - ret = execute_in_place(&archive, "normal/initram"); + ret = execute_in_place(&archive, "normal/initram.o/segment0"); } }
Index: LinuxBIOSv3-testron/arch/x86/Makefile =================================================================== --- LinuxBIOSv3-testron/arch/x86/Makefile (Revision 522) +++ LinuxBIOSv3-testron/arch/x86/Makefile (Arbeitskopie) @@ -36,7 +36,7 @@
ROM_SIZE := $(shell expr $(CONFIG_LINUXBIOS_ROMSIZE_KB) * 1024)
-LARFILES := nocompress:normal/initram normal/stage2 nocompress:normal/option_table +LARFILES := nocompress:normal/initram.o normal/stage2 nocompress:normal/option_table ifneq ($(CONFIG_PAYLOAD_NONE),y) LARFILES += normal/payload endif @@ -57,11 +57,11 @@ COMPRESSFLAG := -C nrv2b endif
-$(obj)/linuxbios.rom $(obj)/linuxbios.map: $(obj)/linuxbios.bootblock $(obj)/util/lar/lar lzma nrv2b $(obj)/linuxbios.initram $(obj)/linuxbios.stage2 $(obj)/option_table +$(obj)/linuxbios.rom $(obj)/linuxbios.map: $(obj)/linuxbios.bootblock $(obj)/util/lar/lar lzma nrv2b $(obj)/linuxbios.initram.o $(obj)/linuxbios.stage2 $(obj)/option_table $(Q)rm -rf $(obj)/lar.tmp $(Q)mkdir $(obj)/lar.tmp $(Q)mkdir $(obj)/lar.tmp/normal - $(Q)cp $(obj)/linuxbios.initram $(obj)/lar.tmp/normal/initram + $(Q)cp $(obj)/linuxbios.initram.o $(obj)/lar.tmp/normal/initram.o $(Q)cp $(obj)/linuxbios.stage2 $(obj)/lar.tmp/normal/stage2 $(Q)cp $(obj)/option_table $(obj)/lar.tmp/normal/option_table ifeq ($(CONFIG_PAYLOAD_NONE),y) @@ -122,10 +122,12 @@ endif endif
+ +# We now parse initram as ELF, so we need PARSEELF enabled unconditionally. ifeq ($(CONFIG_PAYLOAD_PREPARSE_ELF), y) PARSEELF = -e else - PARSEELF = + PARSEELF = -e endif
STAGE0_OBJ := $(patsubst %,$(obj)/lib/%,$(STAGE0_LIB_OBJ)) \