Index: kernel/arch/ia32/src/boot/boot.S
===================================================================
--- kernel/arch/ia32/src/boot/boot.S	(revision b1747a566f73b656e2bbf679b8136ecb0a61b9b4)
+++ kernel/arch/ia32/src/boot/boot.S	(revision 4b241f380e0451bac9635fb18c9249e09909f5f6)
@@ -102,114 +102,30 @@
 	mov %bx, KA2PA(vesa_bpp)
 #endif	
-	
+
 	call map_kernel							# map kernel and turn paging on
-	
+
 	movl grub_eax, %eax
 	movl grub_ebx, %ebx
 	cmpl $MULTIBOOT_LOADER_MAGIC, %eax				# compare GRUB signature
 	je valid_boot
-		
+
 		xorl %ecx, %ecx							# no memory map available
 		movl %ecx, e820counter
-		
+
 		jmp invalid_boot
-		
+
 	valid_boot:
-		
-		movl (%ebx), %eax						# ebx = physical address of struct multiboot_info
-		
-		bt $3, %eax								# mbi->flags[3] (mods_count, mods_addr valid)
-		jc mods_valid
-			
-			xorl %ecx, %ecx
-			movl %ecx, init
-			jmp mods_end
-		
-		mods_valid:
-		
-		movl 20(%ebx), %ecx						# mbi->mods_count
-		movl %ecx, init
-		
-		cmpl $0, %ecx
-		je mods_end
-		
-		movl 24(%ebx), %esi						# mbi->mods_addr
-		movl $init, %edi
-		
-		mods_loop:
-		
-			movl 0(%esi), %edx					# mods->mod_start
-			addl $0x80000000, %edx
-			movl %edx, 4(%edi)
-			
-			movl 4(%esi), %edx
-			subl 0(%esi), %edx					# mods->mod_end - mods->mod_start
-			movl %edx, 8(%edi)
-			
-			addl $16, %esi
-			addl $8	, %edi
-			
-			loop mods_loop
-			
-		mods_end:
-		
-		bt $6, %eax								# mbi->flags[6] (mmap_length, mmap_addr valid)	
-		jc mmap_valid
-			
-			xorl %edx, %edx
-			jmp mmap_invalid
-			
-		mmap_valid:
-		movl 44(%ebx), %ecx						# mbi->mmap_length
-		movl 48(%ebx), %esi						# mbi->mmap_addr
-		movl $e820table, %edi
-		xorl %edx, %edx
-		
-		mmap_loop:
-			cmpl $0, %ecx
-			jle mmap_end
-			
-			movl 4(%esi), %eax					# mmap->base_addr_low
-			movl %eax, (%edi)
-			
-			movl 8(%esi), %eax					# mmap->base_addr_high
-			movl %eax, 4(%edi)
-			
-			movl 12(%esi), %eax					# mmap->length_low
-			movl %eax, 8(%edi)
-			
-			movl 16(%esi), %eax					# mmap->length_high
-			movl %eax, 12(%edi)
-			
-			movl 20(%esi), %eax					# mmap->type
-			movl %eax, 16(%edi)
-			
-			movl (%esi), %eax					# mmap->size
-			addl $0x4, %eax
-			addl %eax, %esi
-			subl %eax, %ecx
-			addl $MEMMAP_E820_RECORD_SIZE, %edi
-			incl %edx
-			jmp mmap_loop
-		
-		mmap_end:
-		
-		mmap_invalid:
-		movl %edx, e820counter
-		
+
+	movl grub_eax, %eax
+	movl grub_ebx, %ebx
+
+	# ia32_boot(grub_eax, grub_ebx)
+	pushl %ebx
+	pushl %eax
+	call ia32_cboot		# Does not return.
+
+	# Not reached.
+
 	invalid_boot:
-	
-#ifdef CONFIG_SMP
-	
-	# copy AP bootstrap routines below 1 MB
-	
-	movl $BOOT_OFFSET, %esi
-	movl $AP_BOOT_OFFSET, %edi
-	movl $_hardcoded_unmapped_size, %ecx
-	rep movsb
-	
-#endif
-
-	call main_bsp								# never returns
 
 	cli
Index: kernel/arch/ia32/src/boot/cboot.c
===================================================================
--- kernel/arch/ia32/src/boot/cboot.c	(revision 4b241f380e0451bac9635fb18c9249e09909f5f6)
+++ kernel/arch/ia32/src/boot/cboot.c	(revision 4b241f380e0451bac9635fb18c9249e09909f5f6)
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup ia32
+ * @{
+ */
+/** @file
+ */
+
+#include <main/main.h>
+#include <arch/boot/boot.h>
+#include <arch/boot/cboot.h>
+#include <arch/boot/memmap.h>
+#include <config.h>
+#include <memstr.h>
+
+/* This is a symbol so the type is only dummy. Obtain the value using &. */
+extern int _hardcoded_unmapped_size;
+
+/** C part of ia32 boot sequence.
+ * @param signature	Should contain the multiboot signature.
+ * @param mi		Pointer to the multiboot information structure.
+ */
+void ia32_cboot(uint32_t signature, const mb_info_t *mi)
+{
+	uint32_t flags;
+	mb_mod_t *mods;
+	uint32_t i;
+
+	flags = mi->flags;
+
+	/* Copy module information. */
+
+	if ((flags & MBINFO_FLAGS_MODS) != 0) {
+		init.cnt = mi->mods_count;
+		mods = mi->mods_addr;
+
+		for (i = 0; i < init.cnt; i++) {
+			init.tasks[i].addr = mods[i].start + 0x80000000;
+			init.tasks[i].size = mods[i].end - mods[i].start;
+		}
+	} else {
+		init.cnt = 0;
+	}
+
+	/* Copy memory map. */
+
+	int32_t mmap_length;
+	mb_mmap_t *mme;
+	uint32_t size;
+
+	if ((flags & MBINFO_FLAGS_MMAP) != 0) {
+		mmap_length = mi->mmap_length;
+		mme = mi->mmap_addr;
+		e820counter = 0;
+
+		i = 0;
+		while (mmap_length > 0) {
+			e820table[i++] = mme->mm_info;
+
+			/* Compute address of next structure. */
+			size = sizeof(mme->size) + mme->size;
+			mme = ((void *) mme) + size;
+			mmap_length -= size;
+		}
+
+		e820counter = i;
+	} else {
+		e820counter = 0;
+	}
+
+#ifdef CONFIG_SMP
+	/* Copy AP bootstrap routines below 1 MB. */
+	memcpy((void *) AP_BOOT_OFFSET, (void *) BOOT_OFFSET,
+	    (size_t) &_hardcoded_unmapped_size);
+#endif
+
+	main_bsp();
+}
+
+/** @}
+ */
