Index: arch/ia32/src/boot/boot.S
===================================================================
--- arch/ia32/src/boot/boot.S	(revision b2c92f33b5d4bbba5718f4b6fc40ccfbe054b6ca)
+++ arch/ia32/src/boot/boot.S	(revision 66def8d85720069e272ce3e7173a3b965e56b072)
@@ -1,4 +1,5 @@
 #
 # Copyright (C) 2001-2004 Jakub Jermar
+# Copyright (C) 2005-2006 Martin Decky
 # All rights reserved.
 #
@@ -32,4 +33,6 @@
 #include <arch/pm.h>
 
+#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
+
 .section K_TEXT_START, "ax"
 
@@ -39,18 +42,18 @@
 .code32
 .align 4
+.global multiboot_image_start
 multiboot_header:
 	.long MULTIBOOT_HEADER_MAGIC
 	.long MULTIBOOT_HEADER_FLAGS
 	.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)	# checksum
-	.long multiboot_header + BOOT_OFFSET
-	.long unmapped_ktext_start + BOOT_OFFSET
+	.long multiboot_header
+	.long unmapped_ktext_start
 	.long 0
 	.long 0
-	.long multiboot_image_start + BOOT_OFFSET
+	.long multiboot_image_start
 	
 multiboot_image_start:
-	movl $BOOTSTRAP_OFFSET - 0x400, %esp				# initialize stack pointer
-	
-	lgdt protected_bootstrap_gdtr - 0x80000000			# initialize Global Descriptor Table register
+	movl $START_STACK, %esp			# initialize stack pointer
+	lgdt KA2PA(bootstrap_gdtr)		# initialize Global Descriptor Table register
 
 	movw $KDATA, %cx
@@ -58,18 +61,12 @@
 	movw %cx, %gs
 	movw %cx, %fs
-	movw %cx, %ds							# kernel data + stack
+	movw %cx, %ds					# kernel data + stack
 	movw %cx, %ss
 	
-	jmpl $KTEXT, $multiboot_meeting_point + BOOT_OFFSET
+	jmpl $KTEXT, $multiboot_meeting_point
 	multiboot_meeting_point:
 	
 	pushl %ebx							# save parameters from GRUB
 	pushl %eax
-	
-	movl $BOOTSTRAP_OFFSET + BOOT_OFFSET, %esi
-	movl $BOOTSTRAP_OFFSET, %edi
-	movl $_hardcoded_unmapped_size, %ecx
-	cld
-	rep movsb
 	
 	call map_kernel							# map kernel and turn paging on
@@ -171,5 +168,17 @@
 	invalid_boot:
 	
-	call main_bsp - BOOT_OFFSET					# never returns
+#ifdef CONFIG_SMP
+	
+	# copy AP bootstrap routines below 1 MB
+	
+	movl $BOOT_OFFSET, %esi
+	movl $AP_BOOT_OFFSET, %edi
+	movl $_hardcoded_unmapped_size, %ecx
+	cld
+	rep movsb
+	
+#endif
+	
+	call main_bsp								# never returns
 
 	cli
@@ -215,8 +224,2 @@
 page_directory:
 	.space 4096, 0
-
-.global real_bootstrap_gdtr_boot
-real_bootstrap_gdtr_boot:
-	.word selector(GDT_ITEMS)
-	.long KA2PA(gdt)-BOOT_OFFSET
-
Index: arch/ia32/src/mm/frame.c
===================================================================
--- arch/ia32/src/mm/frame.c	(revision b2c92f33b5d4bbba5718f4b6fc40ccfbe054b6ca)
+++ arch/ia32/src/mm/frame.c	(revision 66def8d85720069e272ce3e7173a3b965e56b072)
@@ -51,6 +51,8 @@
 		frame_region_not_free(0, FRAME_SIZE);
 		
-		/* Reserve real mode bootstrap memory */
-		frame_region_not_free(BOOTSTRAP_OFFSET, hardcoded_unmapped_ktext_size + hardcoded_unmapped_kdata_size);
+#ifdef CONFIG_SMP
+		/* Reserve AP real mode bootstrap memory */
+		frame_region_not_free(AP_BOOT_OFFSET, hardcoded_unmapped_ktext_size + hardcoded_unmapped_kdata_size);
+#endif
 		
 		for (i = 0; i < e820counter; i++) {
Index: arch/ia32/src/pm.c
===================================================================
--- arch/ia32/src/pm.c	(revision b2c92f33b5d4bbba5718f4b6fc40ccfbe054b6ca)
+++ arch/ia32/src/pm.c	(revision 66def8d85720069e272ce3e7173a3b965e56b072)
@@ -72,5 +72,5 @@
 
 /* gdtr is changed by kmp before next CPU is initialized */
-struct ptr_16_32 protected_bootstrap_gdtr = { .limit = sizeof(gdt), .base = KA2PA((__address) gdt) };
+struct ptr_16_32 bootstrap_gdtr = { .limit = sizeof(gdt), .base = KA2PA((__address) gdt) };
 struct ptr_16_32 gdtr = { .limit = sizeof(gdt), .base = (__address) gdt };
 
Index: arch/ia32/src/smp/ap.S
===================================================================
--- arch/ia32/src/smp/ap.S	(revision b2c92f33b5d4bbba5718f4b6fc40ccfbe054b6ca)
+++ arch/ia32/src/smp/ap.S	(revision 66def8d85720069e272ce3e7173a3b965e56b072)
@@ -1,4 +1,5 @@
 #
 # Copyright (C) 2001-2004 Jakub Jermar
+# Copyright (C) 2005-2006 Martin Decky
 # All rights reserved.
 #
@@ -31,9 +32,14 @@
 #
 
-.section K_TEXT_START_2, "ax"
+#include <arch/boot/boot.h>
+#include <arch/boot/memmap.h>
+#include <arch/mm/page.h>
+#include <arch/pm.h>
+
+.section K_TEXT_START, "ax"
 
 #ifdef CONFIG_SMP
 
-.global ap_boot
+.global unmapped_ap_boot
 
 KTEXT=8
@@ -45,5 +51,5 @@
 
 .align 4096
-ap_boot:
+unmapped_ap_boot:
 .code16
 	cli
@@ -51,10 +57,10 @@
 	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
-	jmpl $KTEXT, $jump_to_kernel
+	jmpl $KTEXT, $jump_to_kernel - BOOT_OFFSET + AP_BOOT_OFFSET
 	
 jump_to_kernel:
@@ -64,5 +70,5 @@
 	movw %ax, %es
 	movw %ax, %ss
-	movl $(ctx-0x80000000), %eax	# KA2PA((__address) &ctx)
+	movl $KA2PA(ctx), %eax			# KA2PA((__address) &ctx)
 	movl (%eax), %esp
 	subl $0x80000000, %esp			# KA2PA(ctx.sp)
@@ -75,2 +81,15 @@
 
 #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 */
Index: arch/ia32/src/smp/apic.c
===================================================================
--- arch/ia32/src/smp/apic.c	(revision b2c92f33b5d4bbba5718f4b6fc40ccfbe054b6ca)
+++ arch/ia32/src/smp/apic.c	(revision 66def8d85720069e272ce3e7173a3b965e56b072)
@@ -31,4 +31,5 @@
 #include <arch/smp/ap.h>
 #include <arch/smp/mps.h>
+#include <arch/boot/boot.h>
 #include <mm/page.h>
 #include <time/delay.h>
Index: arch/ia32/src/smp/smp.c
===================================================================
--- arch/ia32/src/smp/smp.c	(revision b2c92f33b5d4bbba5718f4b6fc40ccfbe054b6ca)
+++ arch/ia32/src/smp/smp.c	(revision 66def8d85720069e272ce3e7173a3b965e56b072)
@@ -31,4 +31,5 @@
 #include <arch/smp/mps.h>
 #include <arch/smp/ap.h>
+#include <arch/boot/boot.h>
 #include <genarch/acpi/acpi.h>
 #include <genarch/acpi/madt.h>
@@ -142,7 +143,8 @@
 			panic("couldn't allocate memory for GDT\n");
 
-		memcpy(gdt_new, gdt, GDT_ITEMS*sizeof(struct descriptor));
+		memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(struct descriptor));
 		memsetb((__address)(&gdt_new[TSS_DES]), sizeof(struct descriptor), 0);
-		real_bootstrap_gdtr.base = KA2PA((__address) gdt_new);
+		protected_ap_gdtr.limit = GDT_ITEMS * sizeof(struct descriptor);
+		protected_ap_gdtr.base = KA2PA((__address) gdt_new);
 		gdtr.base = (__address) gdt_new;
 
