Index: arch/amd64/_link.ld.in
===================================================================
--- arch/amd64/_link.ld.in	(revision 46d26ee596dd9907535ce84849eaef378cdeaf36)
+++ arch/amd64/_link.ld.in	(revision 42edee68a13aac5a6de6c8e953f681abf64096ff)
@@ -53,3 +53,13 @@
 		kdata_end = .;
 	}
+	
+#ifdef CONFIG_SMP	
+	
+	_hardcoded_unmapped_size = (unmapped_ktext_end - unmapped_ktext_start) + (unmapped_kdata_end - unmapped_kdata_start);
+	ap_boot = unmapped_ap_boot - BOOT_OFFSET + AP_BOOT_OFFSET;
+	ap_gdtr = unmapped_ap_gdtr - BOOT_OFFSET + AP_BOOT_OFFSET;
+	protected_ap_gdtr = PA2KA(ap_gdtr);
+
+#endif /* CONFIG_SMP */
+
 }
Index: arch/amd64/include/pm.h
===================================================================
--- arch/amd64/include/pm.h	(revision 46d26ee596dd9907535ce84849eaef378cdeaf36)
+++ arch/amd64/include/pm.h	(revision 42edee68a13aac5a6de6c8e953f681abf64096ff)
@@ -146,6 +146,6 @@
 
 extern struct ptr_16_64 gdtr;
-extern struct ptr_16_32 real_bootstrap_gdtr;
-extern struct ptr_16_32 protected_bootstrap_gdtr;
+extern struct ptr_16_32 bootstrap_gdtr;
+extern struct ptr_16_32 protected_ap_gdtr;
 
 extern void pm_init(void);
Index: arch/amd64/src/boot/boot.S
===================================================================
--- arch/amd64/src/boot/boot.S	(revision 46d26ee596dd9907535ce84849eaef378cdeaf36)
+++ arch/amd64/src/boot/boot.S	(revision 42edee68a13aac5a6de6c8e953f681abf64096ff)
@@ -1,4 +1,5 @@
 #
 # Copyright (C) 2005 Ondrej Palkovsky
+# Copyright (C) 2006 Martin Decky
 # All rights reserved.
 #
@@ -38,23 +39,5 @@
 	
 .section K_TEXT_START, "ax"
-# .code16
-# .global kernel_image_start
-# .global multiboot_image_start
-# kernel_image_start:
-
-# 	movl $0x80000000, %eax  
-# 	cpuid
-# 	cmp $0x80000000, %eax 	# any function > 80000000h?
-# 	jbe no_long_mode
-# 	movl $(AMD_CPUID_EXTENDED), %eax # Extended function code 80000001
-# 	cpuid
-# 	bt $29, %edx 		# Test if long mode is supported.
-# 	jnc no_long_mode
-# 
-# 
-# no_long_mode:
-# 1:
-# 	jmp 1b
-# 	
+
 .code32
 .align 4
@@ -90,4 +73,19 @@
 	# the Default operand size must not be 1 when entering long mode
 	
+	movl $0x80000000, %eax  
+ 	cpuid
+ 	cmp $0x80000000, %eax						# any function > 80000000h?
+	jbe long_mode_unsupported
+	movl $(AMD_CPUID_EXTENDED), %eax			# Extended function code 80000001
+	cpuid
+	bt $29, %edx								# Test if long mode is supported.
+ 	jc long_mode_supported
+
+	long_mode_unsupported:
+		cli
+		hlt
+	
+	long_mode_supported:
+	
 	# Enable 64-bit page transaltion entries - CR4.PAE = 1.
 	# Paging is not enabled until after long mode is enabled
@@ -218,4 +216,16 @@
 		
 	invalid_boot:
+	
+#ifdef CONFIG_SMP
+	
+	# copy AP bootstrap routines below 1 MB
+	
+	movq $BOOT_OFFSET, %rsi
+	movq $AP_BOOT_OFFSET, %rdi
+	movq $_hardcoded_unmapped_size, %rcx
+	cld
+	rep movsb
+	
+#endif
 	
 	call main_bsp   # never returns
Index: arch/amd64/src/smp/ap.S
===================================================================
--- arch/amd64/src/smp/ap.S	(revision 46d26ee596dd9907535ce84849eaef378cdeaf36)
+++ arch/amd64/src/smp/ap.S	(revision 42edee68a13aac5a6de6c8e953f681abf64096ff)
@@ -1,4 +1,5 @@
 #
 # Copyright (C) 2001-2004 Jakub Jermar
+# Copyright (C) 2005-2006 Martin Decky
 # All rights reserved.
 #
@@ -32,14 +33,15 @@
 
 #include <arch/boot/boot.h>
+#include <arch/boot/memmap.h>
+#include <arch/mm/page.h>
 #include <arch/pm.h>
 #include <arch/cpu.h>
 #include <arch/cpuid.h>
-#include <arch/mm/page.h>
-	
-.section K_TEXT_START_2, "ax"
+
+.section K_TEXT_START, "ax"
 
 #ifdef CONFIG_SMP
 
-.global ap_boot
+.global unmapped_ap_boot
 
 # This piece of code is real-mode and is meant to be alligned at 4K boundary.
@@ -48,5 +50,5 @@
 
 .align 4096
-ap_boot:
+unmapped_ap_boot:
 .code16
 	cli
@@ -54,28 +56,26 @@
 	movw %ax, %ds
 
-	lgdt real_bootstrap_gdtr_boot	# initialize Global Descriptor Table register
+	lgdt ap_gdtr		# initialize Global Descriptor Table register
 	
 	movl %cr0, %eax
 	orl $1, %eax
-	movl %eax, %cr0			# switch to protected mode
+	movl %eax, %cr0				# switch to protected mode
+	jmpl $gdtselector(KTEXT32_DES), $jump_to_kernel - BOOT_OFFSET + AP_BOOT_OFFSET
 	
-	jmpl $gdtselector(KTEXT32_DES), $now_in_prot
-
-.code32	
-now_in_prot:
+jump_to_kernel:
+.code32
 	movw $gdtselector(KDATA_DES), %ax
 	movw %ax, %ds
+	movw %ax, %es
 	movw %ax, %ss
 	
-
 	# Enable 64-bit page transaltion entries - CR4.PAE = 1.
 	# Paging is not enabled until after long mode is enabled
+	
 	movl %cr4, %eax
 	btsl $5, %eax
 	movl %eax, %cr4
 
-	# Set up NEW paging tables, that are
-	# already moved BOOT_OFFSET up
-	leal ptl_0+BOOT_OFFSET, %eax
+	leal ptl_0, %eax
 	movl %eax, %cr3
 	
@@ -92,11 +92,22 @@
 	
 	# At this point we are in compatibility mode
-	jmpl $gdtselector(KTEXT_DES), $start64
+	jmpl $gdtselector(KTEXT_DES), $start64 - BOOT_OFFSET + AP_BOOT_OFFSET
 
 .code64
 start64:
 	movq (ctx), %rsp
-	call main_ap   # never returns
-	
-	
+	call main_ap - AP_BOOT_OFFSET + BOOT_OFFSET   # never returns
+
 #endif /* CONFIG_SMP */
+
+.section K_DATA_START, "ax"
+
+#ifdef CONFIG_SMP
+
+.global unmapped_ap_gdtr
+
+unmapped_ap_gdtr:
+	.word 0
+	.long 0
+
+#endif /* CONFIG_SMP */
