[LinuxBIOS] r537 - in LinuxBIOSv3: . arch/x86 mainboard/adl/msm800sev mainboard/amd/norwich mainboard/artecgroup/dbe61 mainboard/emulation/qemu-x86 mainboard/pcengines/alix1c

svn at openbios.org svn at openbios.org
Tue Dec 4 23:42:39 CET 2007


Author: hailfinger
Date: 2007-12-04 23:42:38 +0100 (Tue, 04 Dec 2007)
New Revision: 537

Modified:
   LinuxBIOSv3/Rules.make
   LinuxBIOSv3/arch/x86/Makefile
   LinuxBIOSv3/arch/x86/stage1.c
   LinuxBIOSv3/mainboard/adl/msm800sev/Makefile
   LinuxBIOSv3/mainboard/amd/norwich/Makefile
   LinuxBIOSv3/mainboard/artecgroup/dbe61/Makefile
   LinuxBIOSv3/mainboard/emulation/qemu-x86/Makefile
   LinuxBIOSv3/mainboard/pcengines/alix1c/Makefile
Log:
Absolute calls from initram were only working from the file which had
_MAINOBJECT #defined. Calls from all other files ended up in nirvana
because the compiler was not able to calculate the address of the
wrapper for the absolute call. The linker tried, but failed miserably.
Use the -combine flag and compile all of initram at once. This enables
GCC to calculate the address of the abscall wrapper, resulting in
working code.

Segher Boessenkool thinks the patched code works only by accident
because GCC has no way to specify generation of XIP code. According to
him, future GCC versions or other circumstances may break the code.

While this patch makes code work for now, it does NOT check whether the
generated code tries to write to memory outside the stack (general
writable data). That will of course fail, but I hope porters are smart
enough to avoid that.

Corey Osgood writes:
Great work tracking this down! This is okay for now, but we need to look
for a better solution in the future. Counting on porters who may or may
not remember this discussion to avoid something isn't good
future-proofing.

Checking the ELF sections for read-write data and stopping the build
with an error could make this future-proof.

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006 at gmx.net>
Acked-by: Corey Osgood <corey.osgood at gmail.com>


Modified: LinuxBIOSv3/Rules.make
===================================================================
--- LinuxBIOSv3/Rules.make	2007-12-04 21:06:52 UTC (rev 536)
+++ LinuxBIOSv3/Rules.make	2007-12-04 22:42:38 UTC (rev 537)
@@ -78,13 +78,3 @@
 	$(Q)printf "  CC      $(subst $(shell pwd)/,,$(@))\n"
 	$(Q)$(CC) $(INITCFLAGS) -c $< -o $@
 
-#
-# RAM initialization code can not be linked at a specific address,
-# hence it has to be executed in place (XIP) position independently.
-#
-
-$(obj)/%_xip.o: $(src)/%.c
-	$(Q)mkdir -p $(dir $@)
-	$(Q)printf "  CC      $(subst $(shell pwd)/,,$(@)) (XIP)\n"
-	$(Q)$(CC) $(INITCFLAGS) -D_SHARED -fPIE -c $< -o $@
-

Modified: LinuxBIOSv3/arch/x86/Makefile
===================================================================
--- LinuxBIOSv3/arch/x86/Makefile	2007-12-04 21:06:52 UTC (rev 536)
+++ LinuxBIOSv3/arch/x86/Makefile	2007-12-04 22:42:38 UTC (rev 537)
@@ -36,7 +36,7 @@
 
 ROM_SIZE := $(shell expr $(CONFIG_LINUXBIOS_ROMSIZE_KB) \* 1024)
 
-LARFILES := nocompress:normal/initram.o normal/stage2.o nocompress:normal/option_table
+LARFILES := nocompress:normal/initram normal/stage2.o 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.o $(obj)/linuxbios.stage2.o $(obj)/option_table
+$(obj)/linuxbios.rom $(obj)/linuxbios.map: $(obj)/linuxbios.bootblock $(obj)/util/lar/lar lzma nrv2b $(obj)/linuxbios.initram $(obj)/linuxbios.stage2.o $(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.o $(obj)/lar.tmp/normal/initram.o
+	$(Q)cp $(obj)/linuxbios.initram $(obj)/lar.tmp/normal/initram
 	$(Q)cp $(obj)/linuxbios.stage2.o $(obj)/lar.tmp/normal/stage2.o
 	$(Q)cp $(obj)/option_table $(obj)/lar.tmp/normal/option_table
 ifeq ($(CONFIG_PAYLOAD_NONE),y)
@@ -232,12 +232,14 @@
 	$(Q)printf "  AS      $(subst $(shell pwd)/,,$(@))\n"
 	$(Q)$(AS) $(obj)/arch/x86/stage0_asm.s -o $@
 
-$(obj)/linuxbios.initram.o $(obj)/linuxbios.initram.map: $(obj)/stage0.init $(obj)/stage0-prefixed.o $(patsubst %.o,%_xip.o,$(INITRAM_OBJ))
+$(obj)/linuxbios.initram $(obj)/linuxbios.initram.map: $(obj)/stage0.init $(obj)/stage0-prefixed.o $(INITRAM_OBJ)
+	$(Q)printf "  CC      $(subst $(shell pwd)/,,$(@)) (XIP)\n"
+	$(Q)$(CC) $(INITCFLAGS) -D_SHARED -fPIE -c -combine $(INITRAM_OBJ) -o $(obj)/linuxbios.initram_partiallylinked.o
 	$(Q)# initram links against stage0
 	$(Q)printf "  LD      $(subst $(shell pwd)/,,$(@))\n"
 	$(Q)$(LD) -Ttext 0 --entry main -N -R $(obj)/stage0-prefixed.o \
-		$(patsubst %.o,%_xip.o,$(INITRAM_OBJ)) -o $(obj)/linuxbios.initram.o
+		$(obj)/linuxbios.initram_partiallylinked.o -o $(obj)/linuxbios.initram
 	$(Q)printf "  NM      $(subst $(shell pwd)/,,$(@))\n"
-	$(Q)$(NM) $(obj)/linuxbios.initram.o | sort -u > $(obj)/linuxbios.initram.map
+	$(Q)$(NM) $(obj)/linuxbios.initram | sort -u > $(obj)/linuxbios.initram.map
 
 endif

Modified: LinuxBIOSv3/arch/x86/stage1.c
===================================================================
--- LinuxBIOSv3/arch/x86/stage1.c	2007-12-04 21:06:52 UTC (rev 536)
+++ LinuxBIOSv3/arch/x86/stage1.c	2007-12-04 22:42:38 UTC (rev 537)
@@ -137,17 +137,17 @@
 	// find first initram
 	if (check_normal_boot_flag()) {
 		printk(BIOS_DEBUG, "Choosing normal boot.\n");
-		ret = execute_in_place(&archive, "normal/initram.o/segment0");
+		ret = execute_in_place(&archive, "normal/initram/segment0");
 	} else {
 		printk(BIOS_DEBUG, "Choosing fallback boot.\n");
-		ret = execute_in_place(&archive, "fallback/initram.o/segment0");
+		ret = execute_in_place(&archive, "fallback/initram/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.o/segment0");
+			ret = execute_in_place(&archive, "normal/initram/segment0");
 		}
 	}
 

Modified: LinuxBIOSv3/mainboard/adl/msm800sev/Makefile
===================================================================
--- LinuxBIOSv3/mainboard/adl/msm800sev/Makefile	2007-12-04 21:06:52 UTC (rev 536)
+++ LinuxBIOSv3/mainboard/adl/msm800sev/Makefile	2007-12-04 22:42:38 UTC (rev 537)
@@ -21,10 +21,10 @@
 
 STAGE0_MAINBOARD_OBJ := $(obj)/mainboard/$(MAINBOARDDIR)/stage1.o
 
-INITRAM_OBJ =   $(obj)/mainboard/$(MAINBOARDDIR)/initram.o \
-		$(obj)/northbridge/amd/geodelx/raminit.o \
-		$(obj)/southbridge/amd/cs5536/smbus_initram.o \
-		$(obj)/arch/x86/geodelx/geodelx.o
+INITRAM_OBJ =   $(src)/mainboard/$(MAINBOARDDIR)/initram.c \
+		$(src)/northbridge/amd/geodelx/raminit.c \
+		$(src)/southbridge/amd/cs5536/smbus_initram.c \
+		$(src)/arch/x86/geodelx/geodelx.c
 
 STAGE2_MAINBOARD_OBJ =
 

Modified: LinuxBIOSv3/mainboard/amd/norwich/Makefile
===================================================================
--- LinuxBIOSv3/mainboard/amd/norwich/Makefile	2007-12-04 21:06:52 UTC (rev 536)
+++ LinuxBIOSv3/mainboard/amd/norwich/Makefile	2007-12-04 22:42:38 UTC (rev 537)
@@ -21,10 +21,10 @@
 
 STAGE0_MAINBOARD_OBJ := $(obj)/mainboard/$(MAINBOARDDIR)/stage1.o
 
-INITRAM_OBJ =   $(obj)/mainboard/$(MAINBOARDDIR)/initram.o \
-		$(obj)/northbridge/amd/geodelx/raminit.o \
-		$(obj)/southbridge/amd/cs5536/smbus_initram.o \
-		$(obj)/arch/x86/geodelx/geodelx.o
+INITRAM_OBJ =   $(src)/mainboard/$(MAINBOARDDIR)/initram.c \
+		$(src)/northbridge/amd/geodelx/raminit.c \
+		$(src)/southbridge/amd/cs5536/smbus_initram.c \
+		$(src)/arch/x86/geodelx/geodelx.c
 
 STAGE2_MAINBOARD_OBJ = 
 

Modified: LinuxBIOSv3/mainboard/artecgroup/dbe61/Makefile
===================================================================
--- LinuxBIOSv3/mainboard/artecgroup/dbe61/Makefile	2007-12-04 21:06:52 UTC (rev 536)
+++ LinuxBIOSv3/mainboard/artecgroup/dbe61/Makefile	2007-12-04 22:42:38 UTC (rev 537)
@@ -21,8 +21,8 @@
 
 STAGE0_MAINBOARD_OBJ := $(obj)/mainboard/$(MAINBOARDDIR)/stage1.o
 
-INITRAM_OBJ =   $(obj)/mainboard/$(MAINBOARDDIR)/initram.o \
-		$(obj)/arch/x86/geodelx/geodelx.o
+INITRAM_OBJ =   $(src)/mainboard/$(MAINBOARDDIR)/initram.c \
+		$(src)/arch/x86/geodelx/geodelx.c
 
 STAGE2_MAINBOARD_OBJ = 
 

Modified: LinuxBIOSv3/mainboard/emulation/qemu-x86/Makefile
===================================================================
--- LinuxBIOSv3/mainboard/emulation/qemu-x86/Makefile	2007-12-04 21:06:52 UTC (rev 536)
+++ LinuxBIOSv3/mainboard/emulation/qemu-x86/Makefile	2007-12-04 22:42:38 UTC (rev 537)
@@ -28,8 +28,8 @@
 # directory and is built from what was auto.c in v2.
 #
 
-INITRAM_OBJ = $(obj)/mainboard/$(MAINBOARDDIR)/initram.o \
-		$(obj)/mainboard/$(MAINBOARDDIR)/initram_printktest.o
+INITRAM_OBJ = $(src)/mainboard/$(MAINBOARDDIR)/initram.c \
+		$(src)/mainboard/$(MAINBOARDDIR)/initram_printktest.c
 
 STAGE2_MAINBOARD_OBJ = vga.o
 

Modified: LinuxBIOSv3/mainboard/pcengines/alix1c/Makefile
===================================================================
--- LinuxBIOSv3/mainboard/pcengines/alix1c/Makefile	2007-12-04 21:06:52 UTC (rev 536)
+++ LinuxBIOSv3/mainboard/pcengines/alix1c/Makefile	2007-12-04 22:42:38 UTC (rev 537)
@@ -21,9 +21,9 @@
 
 STAGE0_MAINBOARD_OBJ := $(obj)/mainboard/$(MAINBOARDDIR)/stage1.o
 
-INITRAM_OBJ =   $(obj)/mainboard/$(MAINBOARDDIR)/initram.o \
-		$(obj)/northbridge/amd/geodelx/raminit.o \
-		$(obj)/arch/x86/geodelx/geodelx.o
+INITRAM_OBJ =   $(src)/mainboard/$(MAINBOARDDIR)/initram.c \
+		$(src)/northbridge/amd/geodelx/raminit.c \
+		$(src)/arch/x86/geodelx/geodelx.c
 
 STAGE2_MAINBOARD_OBJ = 
 





More information about the coreboot mailing list