Index: arch/ia32/_link.ld.in
===================================================================
--- arch/ia32/_link.ld.in	(revision 078a0a1e251c250bb45a04e905be0063720202c3)
+++ arch/ia32/_link.ld.in	(revision 66def8d85720069e272ce3e7173a3b965e56b072)
@@ -14,8 +14,7 @@
 
 SECTIONS {
-	.unmapped BOOTSTRAP_OFFSET: AT (BOOTSTRAP_OFFSET) {
+	.unmapped BOOT_OFFSET: AT (0) {
 		unmapped_ktext_start = .;
 		*(K_TEXT_START);
-		*(K_TEXT_START_2);
 		unmapped_ktext_end = .;
 	
@@ -25,5 +24,5 @@
 	}
 	
-	.mapped (PA2KA(BOOT_OFFSET+BOOTSTRAP_OFFSET)+SIZEOF(.unmapped)): AT (BOOTSTRAP_OFFSET+SIZEOF(.unmapped)) { 
+	.mapped (PA2KA(BOOT_OFFSET)+SIZEOF(.unmapped)): AT (SIZEOF(.unmapped)) { 
 		ktext_start = .;
 		*(.text);
@@ -35,5 +34,5 @@
 		*(COMMON);			/* global variables */
 		hardcoded_load_address = .;
-		LONG(PA2KA(BOOT_OFFSET+BOOTSTRAP_OFFSET));
+		LONG(PA2KA(BOOT_OFFSET));
 		hardcoded_ktext_size = .;
 		LONG((ktext_end - ktext_start) + (unmapped_ktext_end - unmapped_ktext_start));
@@ -54,11 +53,13 @@
 		*(.comment);
 	}
+	
+#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);
 
-	
-	_hardcoded_kernel_size = (ktext_end - ktext_start) + (unmapped_ktext_end - unmapped_ktext_start) + (kdata_end - kdata_start) + (unmapped_kdata_end - unmapped_kdata_start);
-	_hardcoded_unmapped_size = (unmapped_ktext_end - unmapped_ktext_start) + (unmapped_kdata_end - unmapped_kdata_start);
-	
-	e820table_boot = KA2PA(e820table) - BOOT_OFFSET;
-	e820counter_boot = KA2PA(e820counter) - BOOT_OFFSET;
-	real_bootstrap_gdtr = PA2KA(real_bootstrap_gdtr_boot);
+#endif /* CONFIG_SMP */
+
 }
Index: arch/ia32/include/boot/boot.h
===================================================================
--- arch/ia32/include/boot/boot.h	(revision 078a0a1e251c250bb45a04e905be0063720202c3)
+++ arch/ia32/include/boot/boot.h	(revision 66def8d85720069e272ce3e7173a3b965e56b072)
@@ -30,6 +30,7 @@
 #define __ia32_BOOT_H__
 
-#define BOOTSTRAP_OFFSET		0x8000
-#define BOOT_OFFSET			0x100000
+#define BOOT_OFFSET			0x108000
+#define AP_BOOT_OFFSET		0x8000
+#define BOOT_STACK_SIZE	0x400
 
 #define MULTIBOOT_HEADER_MAGIC	0x1BADB002
Index: arch/ia32/include/pm.h
===================================================================
--- arch/ia32/include/pm.h	(revision 078a0a1e251c250bb45a04e905be0063720202c3)
+++ arch/ia32/include/pm.h	(revision 66def8d85720069e272ce3e7173a3b965e56b072)
@@ -132,6 +132,6 @@
 
 extern struct ptr_16_32 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 struct tss *tss_p;
 
Index: arch/ia32/src/boot/boot.S
===================================================================
--- arch/ia32/src/boot/boot.S	(revision 078a0a1e251c250bb45a04e905be0063720202c3)
+++ 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 078a0a1e251c250bb45a04e905be0063720202c3)
+++ 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 078a0a1e251c250bb45a04e905be0063720202c3)
+++ 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 078a0a1e251c250bb45a04e905be0063720202c3)
+++ 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 078a0a1e251c250bb45a04e905be0063720202c3)
+++ 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 078a0a1e251c250bb45a04e905be0063720202c3)
+++ 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;
 
