From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KyUTW-0008WS-0B for qemu-devel@nongnu.org; Fri, 07 Nov 2008 11:46:22 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KyUTV-0008VF-F4 for qemu-devel@nongnu.org; Fri, 07 Nov 2008 11:46:21 -0500 Received: from [199.232.76.173] (port=51706 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KyUTU-0008UZ-OC for qemu-devel@nongnu.org; Fri, 07 Nov 2008 11:46:21 -0500 Received: from gecko.sbs.de ([194.138.37.40]:16550) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1KyUTT-0002sm-U5 for qemu-devel@nongnu.org; Fri, 07 Nov 2008 11:46:20 -0500 Message-ID: <491470D0.5070506@siemens.com> Date: Fri, 07 Nov 2008 17:46:08 +0100 From: Jan Kiszka MIME-Version: 1.0 References: <20081029171942.GA19158@raleigh.neotoma.org> <490F0031.9000807@siemens.com> In-Reply-To: <490F0031.9000807@siemens.com> Content-Type: multipart/mixed; boundary="------------000700050401060104050808" Subject: [Qemu-devel] Re: kqemu does not build on hybrid x86_64/i386 system Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Daniel Baumann This is a multi-part message in MIME format. --------------000700050401060104050808 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 7bit Jan Kiszka wrote: > Chris Dukes wrote: >> Hi, >> I'm attempting to build kqemu 1.4.0~pre1 on a debian sid i386 system running >> debian's 2.6.26-1-amd64 kernel. >> >> It fails attemping to assemble nexus_asm.S with a combination of >> x86_64/nexus_asm.S:63: Error: bad register name `%rax' >> type errors >> and >> x86_64/nexus_asm.S:84: Error: `movzwq' is only supported in 64-bit mode >> >> I believe this is happening because the kqemu script makes >> extensive use of uname -m to determine the architecture for >> build and incorrectly assumes that just because it's x86_64ish >> that gcc will emit 64bit code. >> >> After much kludging (And it's incorrect for anything except Linux), >> I was able to have common/Makefile apply -m32 or -m64 as I thought was >> appropriate. Now the .S files assemble fine, but link fails with >> x86_64/monitor_asm.o: In function `__monitor_exception': >> (.text+0x68d): undefined reference to `KQEMU_STATE_monitor_ss_null_sel' >> x86_64/monitor_asm.o: In function `exception_return': >> (.text+0x6d3): undefined reference to `KQEMU_STATE_monitor_ss_null_sel' >> x86_64/monitor_asm.o: In function `exception_return16': >> (.text+0x776): undefined reference to `KQEMU_STATE_monitor_cs32_sel' >> x86_64/monitor_asm.o: In function `__monitor_interrupt': >> (.text+0x81c): undefined reference to `KQEMU_STATE_monitor_ss_null_sel' >> >> It's somewhat confusing as it builds fine for an x86_64 kernel with >> x86_64 userspace and 686 kernel with i386 userspace. > > I recently hacked the kqemu's build system for such cross-compilation > scenarios. Find my patches attached. The magic configure command I > invoked was this: > > ./configure --kernel-path=... --cpu=i386 --cc="gcc -m32" \ > --extra-ldflags=-melf_i386 > > Please note that those patches are no real solutions, maybe even cause > problems to other OSes. The build system is desperately looking for a > rework, specifically for Linux platforms. I think it should be switched > completely to kbuild (with included tools, to build the monitor image), > and then checked if the other target OSes can be cleanly folded into > that or better kept separately. And today I actually ran an i386 kqemu.ko that was cross-built on a x86_64 host. It took an additional patch and an extension of the second one to get things working, see attachments. The extended configure line is ./configure --kernel-path=... --cpu=i386 --cc="gcc -m32" \ --extra-ldflags=-melf_i386 --host-cc="gcc -m32" But kqemu's way of generating assembler offsets is not cross-build compatible, it only happens to work for x86-64 -> i386, not for i386 -> x86_64 or non-x86 -> x86. Another reason to go for kbuild (though I haven't checked yet if its offset generation works for out of tree modules as well). Jan -- Siemens AG, Corporate Technology, CT SE 2 ES-OS Corporate Competence Center Embedded Linux --------------000700050401060104050808 Content-Type: text/x-patch; name="0002-Improve-cross-compilation.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="0002-Improve-cross-compilation.patch" >>From f29be375bc123394a703d21b27591d7f168946ff Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Tue, 28 Oct 2008 17:14:14 +0100 Subject: [PATCH] Improve cross-compilation Improve cross-compilation support of the build system. Signed-off-by: Jan Kiszka --- Makefile | 2 +- common/Makefile | 9 +++++---- configure | 1 + 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 5a2607a..b09636c 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ ifdef CONFIG_KBUILD26 all: make -C common monitor-image.h - make -C $(KERNEL_PATH) M=`pwd` modules + make -C $(KERNEL_PATH) ARCH=$(ARCH) M=`pwd` modules else # 2.4 build diff --git a/common/Makefile b/common/Makefile index 9d109ab..36d83a6 100644 --- a/common/Makefile +++ b/common/Makefile @@ -27,8 +27,8 @@ cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc \ /dev/null 2>&1`"; then echo "$(2)"; else echo "$(3)"; fi ;) -HOST_CC=gcc -MON_CC=gcc +HOST_CC:=$(CC) +MON_CC:=$(CC) MON_LD=ld ifdef CONFIG_WIN32 TARGET=../kqemu-mod-$(ARCH)-win32.o @@ -50,6 +50,7 @@ endif CFLAGS=$(COMMON_CFLAGS) MON_CFLAGS=$(COMMON_CFLAGS) KERNEL_CFLAGS=$(COMMON_CFLAGS) +MON_LDFLAGS=$(LDFLAGS) # Disable SSP if GCC supports it MON_CFLAGS+=$(call cc-option,$(MON_CC),-fno-stack-protector,) @@ -75,7 +76,7 @@ kqemu_global_init kqemu_global_delete all: $(TARGET) $(TARGET): kernel.o $(ARCH)/kernel_asm.o - $(LD) -r -o $@ kernel.o $(ARCH)/kernel_asm.o + $(LD) $(LDFLAGS) -r -o $@ kernel.o $(ARCH)/kernel_asm.o monitor-image.h: monitor-image.bin genmon ./genmon < $< > $@ @@ -84,7 +85,7 @@ monitor-image.bin: monitor-image.out objcopy -O binary $< $@ monitor-image.out: $(ARCH)/nexus_asm.o $(ARCH)/monitor_asm.o monitor.o monitor-utils.o interp.o - $(MON_LD) -T $(ARCH)/monitor.ld -o $@ $^ + $(MON_LD) $(MON_LDFLAGS) -T $(ARCH)/monitor.ld -o $@ $^ $(ARCH)/nexus_asm.o: $(ARCH)/nexus_asm.S monitor_def.h diff --git a/configure b/configure index a4a0585..106d301 100755 --- a/configure +++ b/configure @@ -248,6 +248,7 @@ echo " --cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]" echo " --cc=CC use C compiler CC [$cc]" echo " --host-cc=CC use C compiler CC [$host_cc]" echo " --make=MAKE use specified make [$make]" +echo " --cpu=CPU specify target CPU [host CPU]" echo "" exit 1 fi -- 1.5.6 --------------000700050401060104050808 Content-Type: text/x-patch; name="0004-Switch-kernel2monitor-and-monitor2kernel-to-regparm.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename*0="0004-Switch-kernel2monitor-and-monitor2kernel-to-regparm.pat"; filename*1="ch" >>From 67f80f5e1bfb8fce2fb6768a8caf97d434536a1d Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 5 Nov 2008 01:03:26 +0100 Subject: [PATCH] Switch kernel2monitor and monitor2kernel to regparm Switch kernel2monitor and monitor2kernel to regparm(1) call convention - the default under Linux anyway. This fixes i386 Linux hosts after moving the build system to kbuild. Signed-off-by: Jan Kiszka --- common/i386/nexus_asm.S | 12 +++++++----- common/kernel.c | 2 +- common/kqemu_int.h | 3 +-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/common/i386/nexus_asm.S b/common/i386/nexus_asm.S index 0d79f46..bac55fe 100644 --- a/common/i386/nexus_asm.S +++ b/common/i386/nexus_asm.S @@ -33,7 +33,8 @@ _start: .long ASM_NAME(monitor2kernel_jmp_offset) - _start .long ASM_NAME(monitor_exec) - _start /* - * Assumptions when entering kernel2monitor: + * Assumptions when entering kernel2monitor: + * %rax = kqemu_state * %ss, %ds, %es, %cs are 4G flat 32 bit segments * IRQ disabled */ @@ -47,8 +48,8 @@ ASM_NAME(kernel2monitor): pushl %ds pushl %es - movl 8(%ebp), %ebx - + movl %eax, %ebx + str KQEMU_STATE_kernel_tr_sel(%ebx) sidt KQEMU_STATE_kernel_idt(%ebx) sgdt KQEMU_STATE_kernel_gdt(%ebx) @@ -125,6 +126,7 @@ ASM_NAME(kernel2monitor_jmp_offset): /* * Assumptions when entering monitor2kernel: + * %rax = kqemu_state * IRQ disabled */ ASM_NAME(monitor2kernel): @@ -134,8 +136,8 @@ ASM_NAME(monitor2kernel): pushl %esi pushl %edi - movl 8(%ebp), %ebx - + movl %eax, %ebx + movl %esp, KQEMU_STATE_monitor_esp(%ebx) /* clear the debug register if needed */ diff --git a/common/kernel.c b/common/kernel.c index 3c11422..8ed04c6 100644 --- a/common/kernel.c +++ b/common/kernel.c @@ -1066,7 +1066,7 @@ static void apic_restore_nmi(struct kqemu_state *s, int lvt_mask) long CDECL kqemu_exec(struct kqemu_state *s) { const struct monitor_code_header *m = (void *)monitor_code; - void (*kernel2monitor)(struct kqemu_state *s) = + void __attribute__((regparm(1))) (*kernel2monitor)(struct kqemu_state *s) = (void *)(m->kernel2monitor + s->nexus_kaddr); unsigned long *ptr; int ret, apic_nmi_mask, cpl; diff --git a/common/kqemu_int.h b/common/kqemu_int.h index f19f7ca..6f0b67d 100644 --- a/common/kqemu_int.h +++ b/common/kqemu_int.h @@ -824,8 +824,7 @@ static inline void wrmsrl(unsigned long msr, uint64_t val) /* nexus_asm.S */ -void kernel2monitor(struct kqemu_state *s); -void monitor2kernel(struct kqemu_state *s); +void __attribute__((regparm(1))) monitor2kernel(struct kqemu_state *s); /* kernel_asm.S */ void __attribute__((regparm(1))) exec_irq(int intno); -- 1.5.6 --------------000700050401060104050808--