diff -uNr linux-2.5.7.boot.vmlinuxlds/Makefile linux-2.5.7.boot.32bit_entry/Makefile
--- linux-2.5.7.boot.vmlinuxlds/Makefile	Fri Mar 29 09:15:30 2002
+++ linux-2.5.7.boot.32bit_entry/Makefile	Fri Mar 29 09:18:54 2002
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 7
-EXTRAVERSION = .boot.vmlinuxlds
+EXTRAVERSION = .boot.32bit_entry
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -uNr linux-2.5.7.boot.vmlinuxlds/arch/i386/boot/compressed/head.S linux-2.5.7.boot.32bit_entry/arch/i386/boot/compressed/head.S
--- linux-2.5.7.boot.vmlinuxlds/arch/i386/boot/compressed/head.S	Wed Jul  5 13:03:12 2000
+++ linux-2.5.7.boot.32bit_entry/arch/i386/boot/compressed/head.S	Fri Mar 29 09:41:13 2002
@@ -25,24 +25,30 @@
 
 #include <linux/linkage.h>
 #include <asm/segment.h>
+#include <asm/boot.h>
 
 	.globl startup_32
 	
 startup_32:
 	cld
 	cli
-	movl $(__KERNEL_DS),%eax
-	movl %eax,%ds
-	movl %eax,%es
-	movl %eax,%fs
-	movl %eax,%gs
 
-	lss SYMBOL_NAME(stack_start),%esp
-	xorl %eax,%eax
-1:	incl %eax		# check that A20 really IS enabled
-	movl %eax,0x000000	# loop forever if it isn't
-	cmpl %eax,0x100000
-	je 1b
+	/*
+	 * Save the initial registers
+	 */
+	movl %eax, eax
+	movl %ebx, ebx
+	movl %ecx, ecx
+	movl %edx, edx
+	movl %esi, esi
+	movl %edi, edi
+	movl %esp, esp
+	movl %ebp, ebp
+
+	/*
+	 * Setup the stack
+	 */
+	movl SYMBOL_NAME(stack_start), %esp
 
 /*
  * Initialize eflags.  Some BIOS's leave bits like NT set.  This would
@@ -66,16 +72,10 @@
  */
 	subl $16,%esp	# place for structure on the stack
 	movl %esp,%eax
-	pushl %esi	# real mode pointer as second arg
 	pushl %eax	# address of structure as first arg
 	call SYMBOL_NAME(decompress_kernel)
 	orl  %eax,%eax 
-	jnz  3f
-	popl %esi	# discard address
-	popl %esi	# real mode pointer
-	xorl %ebx,%ebx
-	ljmp $(__KERNEL_CS), $0x100000
-
+	jz out
 /*
  * We come here, if we were loaded high.
  * We need to move the move-in-place routine down to 0x1000
@@ -83,8 +83,20 @@
  * which we got from the stack.
  */
 3:
-	movl $move_routine_start,%esi
-	movl $0x1000,%edi
+	/* Relocate the move routine */
+	movl $move_routine_start,%esi	#src
+	movl $MOVE_ROUTINE_BASE,%edi	#dest
+	movl %edi, %eax 
+	subl %esi, %eax			# The relocation factor
+	addl %eax, reloc1
+	addl %eax, reloc2
+	addl %eax, reloc3
+	addl %eax, reloc4
+	addl %eax, reloc5
+	addl %eax, reloc6
+	addl %eax, reloc7
+	addl %eax, reloc8
+	addl %eax, reloc9
 	movl $move_routine_end,%ecx
 	subl %esi,%ecx
 	addl $3,%ecx
@@ -93,19 +105,21 @@
 	rep
 	movsl
 
+	/* Load it's arguments and jump to the move routine */
 	popl %esi	# discard the address
-	popl %ebx	# real mode pointer
 	popl %esi	# low_buffer_start
 	popl %ecx	# lcount
 	popl %edx	# high_buffer_start
 	popl %eax	# hcount
 	movl $0x100000,%edi
 	cli		# make sure we don't get interrupted
-	ljmp $(__KERNEL_CS), $0x1000 # and jump to the move routine
+	movl $MOVE_ROUTINE_BASE, %ebx	# and jump to the move routine
+	jmpl %ebx
 
 /*
  * Routine (template) for moving the decompressed kernel in place,
- * if we were high loaded. This _must_ PIC-code !
+ * if we were high loaded. This _must_ be PIC-code !
+ * Or it must be anotated with lables so it can be manually relocated.
  */
 move_routine_start:
 	movl %ecx,%ebp
@@ -122,7 +136,34 @@
 	shrl $2,%ecx
 	rep
 	movsl
-	movl %ebx,%esi	# Restore setup pointer
-	xorl %ebx,%ebx
-	ljmp $(__KERNEL_CS), $0x100000
+out:
+	.byte 0xa1		# movl eax,  %eax
+reloc1:	.long eax
+	.byte 0x8b, 0x1d	# movl ebx,  %ebx
+reloc2:	.long ebx
+	.byte 0x8b, 0x0d	# movl ecx,  %ecx
+reloc3:	.long ecx
+	.byte 0x8b, 0x15	# movl edx, %edx
+reloc4:	.long edx
+	.byte 0x8b, 0x35	# movl esi, %esi
+reloc5:	.long esi
+	.byte 0x8b, 0x3d	# movl edi, %edi
+reloc6:	.long edi
+	.byte 0x8b, 0x25	# movl esp, %esp
+reloc7:	.long esp
+	.byte 0x8b, 0x2d	# movl ebp, %ebp
+reloc8:	.long ebp
+	.byte 0xff, 0x25	# jmpl *(kernel_start)
+reloc9:	.long kernel_start
+ENTRY(initial_regs)
+eax:	.long 0x12345678 /* eax */
+ebx:	.long 0x12345678 /* ebx */
+ecx:	.long 0x12345678 /* ecx */
+edx:	.long 0x12345678 /* edx */
+esi:	.long 0x12345678 /* esi */
+edi:	.long 0x12345678 /* edi */
+esp:	.long 0x12345678 /* esp */
+ebp:	.long 0x12345678 /* ebp */
+kernel_start:
+	.long 0x100000
 move_routine_end:
diff -uNr linux-2.5.7.boot.vmlinuxlds/arch/i386/boot/compressed/misc.c linux-2.5.7.boot.32bit_entry/arch/i386/boot/compressed/misc.c
--- linux-2.5.7.boot.vmlinuxlds/arch/i386/boot/compressed/misc.c	Fri Mar 29 09:13:58 2002
+++ linux-2.5.7.boot.32bit_entry/arch/i386/boot/compressed/misc.c	Fri Mar 29 09:36:08 2002
@@ -16,6 +16,7 @@
 #include <linux/apm_bios.h>
 #include <asm/e820.h>
 #include <asm/boot_param.h>
+#include <asm/boot.h>
 
 /*
  * gzip declarations
@@ -111,10 +112,6 @@
 static long free_mem_ptr = (long)&end;
 static long free_mem_end_ptr;
 
-#define INPLACE_MOVE_ROUTINE  0x1000
-#define LOW_BUFFER_START      0x2000
-#define LOW_BUFFER_MAX       0x90000
-#define HEAP_SIZE             0x3000
 static unsigned int low_buffer_end, low_buffer_size;
 static int high_loaded =0;
 static uch *high_buffer_start /* = (uch *)(((ulg)&end) + HEAP_SIZE)*/;
@@ -170,11 +167,15 @@
 		vidmem[i] = ' ';
 }
 
+static int vid_initialized = 0;
 static void puts(const char *s)
 {
 	int x,y,pos;
 	char c;
 
+	if (!vid_initialized)
+		return;
+
 	x = real_mode->screen.info.orig_x;
 	y = real_mode->screen.info.orig_y;
 
@@ -209,6 +210,7 @@
 
 static void vid_puts_init(void)
 {
+	vid_initialized = 1;
 	if (real_mode->screen.info.orig_video_mode == 7) {
 		vidmem = (char *) 0xb0000;
 		vidport = 0x3b4;
@@ -315,8 +317,10 @@
 
 struct {
 	long * a;
-	short b;
-	} stack_start = { & user_stack [STACK_SIZE] , __KERNEL_DS };
+	} stack_start = { & user_stack [STACK_SIZE] };
+
+extern struct initial_regs32 initial_regs;
+extern __u32 kernel_start;
 
 static void setup_normal_output_buffer(void)
 {
@@ -346,6 +350,7 @@
 	}
 	else mv->hcount = -1;
 	mv->high_buffer_start = high_buffer_start;
+	if ((ulg)output_data >= low_buffer_end) output_data=high_buffer_start;
 }
 
 static void close_output_buffer_if_we_run_high(struct moveparams *mv)
@@ -361,19 +366,26 @@
 }
 
 
-asmlinkage int decompress_kernel(struct moveparams *mv, void *rmode)
+asmlinkage int decompress_kernel(struct moveparams *mv)
 {
-	real_mode = rmode;
-
-	vid_puts_init();
+	/* If we don't know better assume we can't use any
+	 * real mode memory, and we have enough protected mode memory.
+	 */
+	real_mode = 0;
+	if ((initial_regs.ebp == ENTRY16) || (initial_regs.ebp == ENTRY32)) {
+		real_mode = (struct boot_params *)initial_regs.esi;
+	}
+	if (initial_regs.ebp == ENTRY16) {
+		vid_puts_init();
 
-	mem_k = real_mode->screen.overlap.ext_mem_k;
+		mem_k = real_mode->screen.overlap.ext_mem_k;
 #ifndef STANDARD_MEMORY_BIOS_CALL
-	if (real_mode->alt_mem_k > mem_k) {
-		mem_k = real_mode->alt_mem_k;
-	}
+		if (real_mode->alt_mem_k > mem_k) {
+			mem_k = real_mode->alt_mem_k;
+		}
 #endif
-	mem_k += 1024;
+		mem_k += 1024;
+	}
 
 	if (free_mem_ptr < 0x100000) setup_normal_output_buffer();
 	else setup_output_buffer_if_we_run_high(mv);
diff -uNr linux-2.5.7.boot.vmlinuxlds/arch/i386/boot/setup.S linux-2.5.7.boot.32bit_entry/arch/i386/boot/setup.S
--- linux-2.5.7.boot.vmlinuxlds/arch/i386/boot/setup.S	Sun Mar 10 20:05:20 2002
+++ linux-2.5.7.boot.32bit_entry/arch/i386/boot/setup.S	Fri Mar 29 09:47:28 2002
@@ -56,6 +56,12 @@
 #define SIG1	0xAA55
 #define SIG2	0x5A5A
 
+/* Segments used by setup.S */
+#define __SETUP_CS      0x10
+#define __SETUP_DS      0x18
+#define __SETUP_REAL_CS 0x20
+#define __SETUP_REAL_DS 0x28
+
 INITSEG  = DEF_INITSEG		# 0x9000, we move boot here, out of the way
 SYSSEG   = DEF_SYSSEG		# 0x1000, system loaded at 0x10000 (65536).
 SETUPSEG = DEF_SETUPSEG		# 0x9020, this is the current segment
@@ -781,13 +787,22 @@
 	jmp	flush_instr
 
 flush_instr:
-	xorw	%bx, %bx			# Flag to indicate a boot
 	xorl	%esi, %esi			# Pointer to real-mode code
 	movw	%cs, %si
 	subw	$DELTA_INITSEG, %si
 	shll	$4, %esi			# Convert to 32-bit pointer
+	movl	$ENTRY16, %ebp			# Magic to indicate 16bit entry
+
+# Setup the data segments
+	movw	$(__SETUP_DS), %ax
+	movw	%ax, %ds
+	movw	%ax, %es
+	movw	%ax, %fs
+	movw	%ax, %gs
+	movw	%ax, %ss
+
 # NOTE: For high loaded big kernels we need a
-#	jmpi    0x100000,__KERNEL_CS
+#	jmpi    0x100000,__SETUP_CS
 #
 #	but we yet haven't reloaded the CS register, so the default size 
 #	of the target offset still is 16 bit.
@@ -798,7 +813,7 @@
 	.byte 0x66, 0xea			# prefix + jmpi-opcode
 code32:	.long	0x1000				# will be set to 0x100000
 						# for big kernels
-	.word	__KERNEL_CS
+	.word	__SETUP_CS
 
 # Here's a bunch of information about your current kernel..
 kernel_version:	.ascii	UTS_RELEASE
diff -uNr linux-2.5.7.boot.vmlinuxlds/arch/i386/kernel/head.S linux-2.5.7.boot.32bit_entry/arch/i386/kernel/head.S
--- linux-2.5.7.boot.vmlinuxlds/arch/i386/kernel/head.S	Wed Mar 20 07:18:31 2002
+++ linux-2.5.7.boot.32bit_entry/arch/i386/kernel/head.S	Fri Mar 29 23:42:41 2002
@@ -16,12 +16,6 @@
 #include <asm/pgtable.h>
 #include <asm/desc.h>
 
-#define OLD_CL_MAGIC_ADDR	0x90020
-#define OLD_CL_MAGIC		0xA33F
-#define OLD_CL_BASE_ADDR	0x90000
-#define OLD_CL_OFFSET		0x90022
-#define NEW_CL_POINTER		0x228	/* Relative to real mode data */
-
 /*
  * References to members of the boot_cpu_data structure.
  */
@@ -39,46 +33,41 @@
 /*
  * swapper_pg_dir is the main page directory, address 0x00101000
  *
- * On entry, %esi points to the real-mode code as a 32-bit pointer.
+ * On entry
+ *   %ds, %es, %ss, %fs, %gs 32bit data segment base=0 mask=0xffffffff
+ *
  */
-startup_32:
+ENTRY(startup_32)
 /*
- * Set segments to known values
+ * Set eflags to a safe state
  */
 	cld
-	movl $(__KERNEL_DS),%eax
+	cli
+/*
+ * Save the initial registers
+ */
+	movl %eax, initial_regs-__PAGE_OFFSET+0
+	movl %ebx, initial_regs-__PAGE_OFFSET+4
+	movl %ecx, initial_regs-__PAGE_OFFSET+8
+	movl %edx, initial_regs-__PAGE_OFFSET+12
+	movl %esi, initial_regs-__PAGE_OFFSET+16
+	movl %edi, initial_regs-__PAGE_OFFSET+20
+	movl %esp, initial_regs-__PAGE_OFFSET+24
+	movl %ebp, initial_regs-__PAGE_OFFSET+28
+
+/*
+ * Set segments to known values
+ */
+	lgdt gdt_48-__PAGE_OFFSET
+	ljmp $__KERNEL_CS,$1f-__PAGE_OFFSET
+1:	movl $__KERNEL_DS,%eax
 	movl %eax,%ds
 	movl %eax,%es
 	movl %eax,%fs
 	movl %eax,%gs
-#ifdef CONFIG_SMP
-	orw %bx,%bx
-	jz 1f
+	movl %eax,%ss
 
 /*
- *	New page tables may be in 4Mbyte page mode and may
- *	be using the global pages. 
- *
- *	NOTE! If we are on a 486 we may have no cr4 at all!
- *	So we do not try to touch it unless we really have
- *	some bits in it to set.  This won't work if the BSP
- *	implements cr4 but this AP does not -- very unlikely
- *	but be warned!  The same applies to the pse feature
- *	if not equally supported. --macro
- *
- *	NOTE! We have to correct for the fact that we're
- *	not yet offset PAGE_OFFSET..
- */
-#define cr4_bits mmu_cr4_features-__PAGE_OFFSET
-	cmpl $0,cr4_bits
-	je 3f
-	movl %cr4,%eax		# Turn on paging options (PSE,PAE,..)
-	orl cr4_bits,%eax
-	movl %eax,%cr4
-	jmp 3f
-1:
-#endif
-/*
  * Initialize page tables
  */
 	movl $pg0-__PAGE_OFFSET,%edi /* initialize page tables */
@@ -106,14 +95,13 @@
 	/* Set up the stack pointer */
 	lss stack_start,%esp
 
-#ifdef CONFIG_SMP
-	orw  %bx,%bx
-	jz  1f				/* Initial CPU cleans BSS */
+/*
+ * Initialize eflags.  Some BIOS's leave bits like NT set.  This would
+ * confuse the debugger if this code is traced.
+ * XXX - best to initialize before switching to protected mode.
+ */
 	pushl $0
 	popfl
-	jmp checkCPUtype
-1:
-#endif CONFIG_SMP
 
 /*
  * Clear BSS first so that there are no surprises...
@@ -131,42 +119,76 @@
  * in 16-bit mode for the "real" operations.
  */
 	call setup_idt
+	
+	call checkCPUtype
+	call SYMBOL_NAME(start_kernel)
+L6:
+	jmp L6			# main should never return here, but
+				# just in case, we know what happens.
+
+
+#ifdef CONFIG_SMP
+ENTRY(secondary_startup_32)
 /*
- * Initialize eflags.  Some BIOS's leave bits like NT set.  This would
- * confuse the debugger if this code is traced.
- * XXX - best to initialize before switching to protected mode.
+ * Set eflags to a safe state
  */
-	pushl $0
-	popfl
+	cld
+	cli
+
 /*
- * Copy bootup parameters out of the way. First 2kB of
- * _empty_zero_page is for boot parameters, second 2kB
- * is for the command line.
+ * Set segments to known values
+ */
+	movl	$(__KERNEL_DS), %eax
+	movl	%eax,%ds
+	movl	%eax,%es
+	movl	%eax,%fs
+	movl	%eax,%gs
+	movl	%eax,%ss
+
+/*
+ *	New page tables may be in 4Mbyte page mode and may
+ *	be using the global pages. 
+ *
+ *	NOTE! If we are on a 486 we may have no cr4 at all!
+ *	So we do not try to touch it unless we really have
+ *	some bits in it to set.  This won't work if the BSP
+ *	implements cr4 but this AP does not -- very unlikely
+ *	but be warned!  The same applies to the pse feature
+ *	if not equally supported. --macro
  *
- * Note: %esi still has the pointer to the real-mode data.
+ *	NOTE! We have to correct for the fact that we're
+ *	not yet offset PAGE_OFFSET..
  */
-	movl $ SYMBOL_NAME(empty_zero_page),%edi
-	movl $512,%ecx
-	cld
-	rep
-	movsl
-	xorl %eax,%eax
-	movl $512,%ecx
-	rep
-	stosl
-	movl SYMBOL_NAME(empty_zero_page)+NEW_CL_POINTER,%esi
-	andl %esi,%esi
-	jnz 2f			# New command line protocol
-	cmpw $(OLD_CL_MAGIC),OLD_CL_MAGIC_ADDR
-	jne 1f
-	movzwl OLD_CL_OFFSET,%esi
-	addl $(OLD_CL_BASE_ADDR),%esi
-2:
-	movl $ SYMBOL_NAME(empty_zero_page)+2048,%edi
-	movl $512,%ecx
-	rep
-	movsl
+#define cr4_bits mmu_cr4_features-__PAGE_OFFSET
+	cmpl $0,cr4_bits
+	je 3f
+	movl %cr4,%eax		# Turn on paging options (PSE,PAE,..)
+	orl cr4_bits,%eax
+	movl %eax,%cr4
+/*
+ * Enable paging
+ */
+3:
+	movl $swapper_pg_dir-__PAGE_OFFSET,%eax
+	movl %eax,%cr3		/* set the page table pointer.. */
+	movl %cr0,%eax
+	orl $0x80000000,%eax
+	movl %eax,%cr0		/* ..and set paging (PG) bit */
+	jmp 1f			/* flush the prefetch-queue */
 1:
+	movl $1f,%eax
+	jmp *%eax		/* make sure eip is relocated */
+1:
+	/* Set up the stack pointer */
+	lss stack_start,%esp
+	call checkCPUtype
+	call SYMBOL_NAME(initialize_secondary)
+L7:
+	jmp L7			# initialize_secondary should never return here, but
+				# just in case, we know what happens.
+#endif /* CONFIG_SMP */
+
+
 checkCPUtype:
 
 	movl $-1,X86_CPUID		#  -1 for no CPUID initially
@@ -233,47 +255,19 @@
 	orl $0x50022,%eax	# set AM, WP, NE and MP
 	jmp 2f
 
-is386:	pushl %ecx		# restore original EFLAGS
+is386:
+	pushl %ecx		# restore original EFLAGS
 	popfl
 	movl %cr0,%eax		# 386
 	andl $0x80000011,%eax	# Save PG,PE,ET
 	orl $2,%eax		# set MP
 2:	movl %eax,%cr0
 	call check_x87
-	incb ready
-	lgdt gdt_descr
+	/* Now that we know the cpu, setup the idt & ldt */
 	lidt idt_descr
-	ljmp $(__KERNEL_CS),$1f
-1:	movl $(__KERNEL_DS),%eax	# reload all the segment registers
-	movl %eax,%ds		# after changing gdt.
-	movl %eax,%es
-	movl %eax,%fs
-	movl %eax,%gs
-#ifdef CONFIG_SMP
-	movl $(__KERNEL_DS), %eax
-	movl %eax,%ss		# Reload the stack pointer (segment only)
-#else
-	lss stack_start,%esp	# Load processor stack
-#endif
 	xorl %eax,%eax
 	lldt %ax
-	cld			# gcc2 wants the direction flag cleared at all times
-#ifdef CONFIG_SMP
-	movb ready, %cl	
-	cmpb $1,%cl
-	je 1f			# the first CPU calls start_kernel
-				# all other CPUs call initialize_secondary
-	call SYMBOL_NAME(initialize_secondary)
-	jmp L6
-1:
-#endif
-	call SYMBOL_NAME(start_kernel)
-L6:
-	jmp L6			# main should never return here, but
-				# just in case, we know what happens.
-
-ready:	.byte 0
-
+	ret
 /*
  * We depend on ET to be correct. This checks for 287/387.
  */
@@ -372,6 +366,10 @@
 SYMBOL_NAME(gdt):
 	.long SYMBOL_NAME(gdt_table)
 
+	.word 0
+gdt_48:
+	.word GDT_ENTRIES*8-1
+	.long SYMBOL_NAME(gdt_table)-__PAGE_OFFSET
 /*
  * This is initialized to create an identity-mapping at 0-8M (for bootup
  * purposes) and another mapping of the 0-8M area at virtual address
diff -uNr linux-2.5.7.boot.vmlinuxlds/arch/i386/kernel/setup.c linux-2.5.7.boot.32bit_entry/arch/i386/kernel/setup.c
--- linux-2.5.7.boot.vmlinuxlds/arch/i386/kernel/setup.c	Fri Mar 29 09:13:58 2002
+++ linux-2.5.7.boot.32bit_entry/arch/i386/kernel/setup.c	Fri Mar 29 10:26:46 2002
@@ -114,6 +114,7 @@
 #include <asm/dma.h>
 #include <asm/mpspec.h>
 #include <asm/mmu_context.h>
+#include <asm/boot.h>
 #include <asm/boot_param.h>
 
 /*
@@ -165,8 +166,8 @@
 static int disable_x86_serial_nr __initdata = 1;
 static int disable_x86_fxsr __initdata = 0;
 
-#define COMMAND_LINE (((char *)empty_zero_page)+2048)
-#define COMMAND_LINE_SIZE 256
+/* Don't let the initial_regs sit in the BSS */
+struct initial_regs32 initial_regs __initdata = { 0 };
 
 static char command_line[COMMAND_LINE_SIZE];
        char saved_command_line[COMMAND_LINE_SIZE];
@@ -559,13 +560,12 @@
 
 static void __init parse_mem_cmdline (char ** cmdline_p)
 {
-	char c = ' ', *to = command_line, *from = COMMAND_LINE;
+	char c = ' ', *to = command_line, *from = saved_command_line;
 	int len = 0;
 	int usermem = 0;
 
 	/* Save unparsed command line copy for /proc/cmdline */
-	memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
-	saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
+	memcpy(saved_command_line, command_line, sizeof(saved_command_line));
 
 	for (;;) {
 		/*
@@ -635,21 +635,42 @@
 	}
 }
 
-void __init setup_arch(char **cmdline_p)
+static void init_settings(void)
 {
-	unsigned long bootmap_size, low_mem_size;
-	unsigned long start_pfn, max_low_pfn;
-	int i;
-	struct boot_params *params;
-
-#ifdef CONFIG_VISWS
-	visws_get_board_type_and_rev();
+	ROOT_DEV = to_kdev_t(0x0000);
+	memset(&drive_info, 0, sizeof(drive_info));
+	memset(&screen_info, 0, sizeof(screen_info));
+	memset(&apm_info.bios, 0, sizeof(apm_info.bios));
+	aux_device_present = 0;
+#ifdef CONFIG_BLK_DEV_RAM
+	rd_image_start = 0;
+	rd_prompt = 0;
+	rd_doload = 0;
+#endif
+	e820.nr_map = 0;
+	saved_command_line[0] = '\0';
+#ifdef CONFIG_BLK_DEV_INITRD
+	initrd_start = 0;
+	initrd_end = 0;
 #endif
+	/* set default screen information */
+	screen_info.orig_x = 0;
+	screen_info.orig_y = 25;
+	screen_info.orig_video_page = 0;
+	screen_info.orig_video_mode = 0;
+	screen_info.orig_video_cols = 80;
+	screen_info.orig_video_lines = 25;
+	screen_info.orig_video_ega_bx = 0;
+	screen_info.orig_video_isVGA = 1;
+	screen_info.orig_video_points = 16;
+}
 
+static void read_entry16_params(struct boot_params *params)
+{
+	char *cmdline;
 	/*
-	 * This is set up by the setup-routine at boot-time
+	 * These values are set up by the setup-routine at boot-time
 	 */
-	params = (struct boot_params *)empty_zero_page;
  	ROOT_DEV = to_kdev_t(params->root_dev);
  	drive_info = params->drive_info;
  	screen_info = params->screen.info;
@@ -671,6 +692,60 @@
 
 	if (!params->mount_root_rdonly)
 		root_mountflags &= ~MS_RDONLY;
+
+	cmdline = "";
+	if (params->cmd_line_ptr) {
+		/* New command line protocol */
+		cmdline = (char *)(params->cmd_line_ptr);
+	}
+	else if (*((unsigned short *)OLD_CL_MAGIC_ADDR) == OLD_CL_MAGIC) {
+		cmdline = (char *)OLD_CL_BASE + *((unsigned short *)OLD_CL_OFFSET_ADDR);
+	}
+	memcpy(command_line, cmdline, COMMAND_LINE_SIZE);
+	command_line[COMMAND_LINE_SIZE -1] = '\0';
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (params->loader_type && params->initrd_start) {
+		initrd_start = params->initrd_start ?
+		     params->initrd_start + PAGE_OFFSET : 0;
+		initrd_end = initrd_start + params->initrd_size;
+	}
+#endif	
+}
+static void parse_params(char **cmdline_p)
+{
+	struct boot_params *params;
+	int entry16;
+	
+	params = (struct boot_params *)initial_regs.esi;
+	entry16 = initial_regs.ebp == ENTRY16;
+
+	init_settings();
+
+	if (entry16) {
+		read_entry16_params(params);
+	}
+
+	/* Read user specified params */
+	parse_mem_cmdline(cmdline_p);
+
+	if (e820.nr_map == 0) {
+		panic("Unknown memory size\n");
+	}
+}
+
+void __init setup_arch(char **cmdline_p)
+{
+	unsigned long bootmap_size, low_mem_size;
+	unsigned long start_pfn, max_low_pfn;
+	int i;
+
+#ifdef CONFIG_VISWS
+	visws_get_board_type_and_rev();
+#endif
+
+	parse_params(cmdline_p);
+
 	init_mm.start_code = (unsigned long) &_text;
 	init_mm.end_code = (unsigned long) &_etext;
 	init_mm.end_data = (unsigned long) &_edata;
@@ -681,8 +756,6 @@
 	data_resource.start = virt_to_phys(&_etext);
 	data_resource.end = virt_to_phys(&_edata)-1;
 
-	parse_mem_cmdline(cmdline_p);
-
 #define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
 #define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
 #define PFN_PHYS(x)	((x) << PAGE_SHIFT)
@@ -854,11 +927,6 @@
 	find_smp_config();
 #endif
 #ifdef CONFIG_BLK_DEV_INITRD
-	if (params->loader_type && params->initrd_start) {
-		initrd_start = params->initrd_start ?
-		     params->initrd_start + PAGE_OFFSET : 0;
-		initrd_end = initrd_start + params->initrd_size;
-	}
 	if (initrd_start) {
 		if ((initrd_end - PAGE_OFFSET) <= (max_low_pfn << PAGE_SHIFT)) {
 			reserve_bootmem(initrd_start - PAGE_OFFSET,
diff -uNr linux-2.5.7.boot.vmlinuxlds/arch/i386/kernel/trampoline.S linux-2.5.7.boot.32bit_entry/arch/i386/kernel/trampoline.S
--- linux-2.5.7.boot.vmlinuxlds/arch/i386/kernel/trampoline.S	Thu Oct  4 19:42:54 2001
+++ linux-2.5.7.boot.32bit_entry/arch/i386/kernel/trampoline.S	Fri Mar 29 09:17:57 2002
@@ -12,10 +12,6 @@
  *	In fact we don't actually need a stack so we don't
  *	set one up.
  *
- *	We jump into the boot/compressed/head.S code. So you'd
- *	better be running a compressed kernel image or you
- *	won't get very far.
- *
  *	On entry to trampoline_data, the processor is in real mode
  *	with 16-bit addressing and 16-bit data.  CS has some value
  *	and IP is zero.  Thus, data addresses need to be absolute
@@ -23,12 +19,16 @@
  *
  *	If you work on this file, check the object module with objdump
  *	--full-contents --reloc to make sure there are no relocation
- *	entries except for the gdt one..
+ *	entries except for gdt & secondary_startup_32..
  */
 
 #include <linux/linkage.h>
+#include <linux/threads.h>
 #include <asm/segment.h>
 #include <asm/page.h>
+#include <asm/desc.h>
+
+#define GDT_ENTRIES	(__TSS(NR_CPUS))
 
 .data
 
@@ -42,7 +42,6 @@
 	mov	%cs, %ax	# Code and data in the same place
 	mov	%ax, %ds
 
-	mov	$1, %bx		# Flag an SMP trampoline
 	cli			# We should be safe anyway
 
 	movl	$0xA5A5A5A5, trampoline_data - r_base
@@ -56,16 +55,17 @@
 	lmsw	%ax		# into protected mode
 	jmp	flush_instr
 flush_instr:
-	ljmpl	$__KERNEL_CS, $0x00100000
-			# jump to startup_32 in arch/i386/kernel/head.S
+		# jump to secondary_startup_32 in arch/i386/kernel/head.S
+	ljmpl	$__KERNEL_CS, $(SYMBOL_NAME(secondary_startup_32) - __PAGE_OFFSET)
+	
 
 idt_48:
 	.word	0			# idt limit = 0
 	.word	0, 0			# idt base = 0L
 
 gdt_48:
-	.word	0x0800			# gdt limit = 2048, 256 GDT entries
-	.long	gdt_table-__PAGE_OFFSET	# gdt base = gdt (first SMP CPU)
+	.word	GDT_ENTRIES*8-1		# gdt limit
+	.long	SYMBOL_NAME(gdt_table)-__PAGE_OFFSET	# gdt base = gdt (first SMP CPU)
 
 .globl SYMBOL_NAME(trampoline_end)
 SYMBOL_NAME_LABEL(trampoline_end)
diff -uNr linux-2.5.7.boot.vmlinuxlds/include/asm-i386/boot.h linux-2.5.7.boot.32bit_entry/include/asm-i386/boot.h
--- linux-2.5.7.boot.vmlinuxlds/include/asm-i386/boot.h	Wed Apr 16 15:15:00 1997
+++ linux-2.5.7.boot.32bit_entry/include/asm-i386/boot.h	Fri Mar 29 09:54:07 2002
@@ -1,10 +1,18 @@
 #ifndef _LINUX_BOOT_H
 #define _LINUX_BOOT_H
 
+/* Address space division during load */
+#define LOW_BASE   0x001000
+#define REAL_BASE  0x090000
+#define HIGH_BASE  0x100000
+#define LOW_MAX    REAL_BASE
+#define REAL_MAX   0x0A0000
+#define HIGH_MAX   __MAXMEM
+
 /* Don't touch these, unless you really know what you're doing. */
-#define DEF_INITSEG	0x9000
+#define DEF_INITSEG	(REAL_BASE >> 4)
+#define DEF_SETUPSEG	((REAL_BASE + 512) >> 4)
 #define DEF_SYSSEG	0x1000
-#define DEF_SETUPSEG	0x9020
 #define DEF_SYSSIZE	0x7F00
 
 /* Internal svga startup constants */
@@ -12,4 +20,27 @@
 #define EXTENDED_VGA	0xfffe		/* 80x50 mode */
 #define ASK_VGA		0xfffd		/* ask for it at bootup */
 
-#endif
+/* Entry point ID constants */
+#define ENTRY16		0x73726468 /* 'hdrs' */
+#define ENTRY32		0x53524448 /* 'HDRS' */
+
+/* Decompressor constants */
+#define MOVE_ROUTINE_BASE LOW_BASE
+#define MOVE_ROUTINE_SIZE 0x001000
+#define LOW_BUFFER_START  (MOVE_ROUTINE_BASE + MOVE_ROUTINE_SIZE)
+#define LOW_BUFFER_MAX    LOW_MAX
+#define HEAP_SIZE         0x003000
+
+/* Maximum command line size */
+#define COMMAND_LINE_SIZE 256
+
+/* Initial page table size 8MB */
+#define INITIAL_PAGE_TABLE_SIZE 0x800000
+
+/* Old command line protocol */
+#define OLD_CL_MAGIC_ADDR  0x90020
+#define OLD_CL_OFFSET_ADDR 0x90022
+#define OLD_CL_BASE 0x90000
+#define OLD_CL_MAGIC 0xA33F
+
+#endif /* _LINUX_BOOT_H */
diff -uNr linux-2.5.7.boot.vmlinuxlds/include/asm-i386/boot_param.h linux-2.5.7.boot.32bit_entry/include/asm-i386/boot_param.h
--- linux-2.5.7.boot.vmlinuxlds/include/asm-i386/boot_param.h	Fri Mar 29 09:13:58 2002
+++ linux-2.5.7.boot.32bit_entry/include/asm-i386/boot_param.h	Fri Mar 29 09:36:44 2002
@@ -1,6 +1,16 @@
 #ifndef __I386_BOOT_PARAM_H
 #define __I386_BOOT_PARAM_H
 
+struct initial_regs32 {
+	const __u32 eax;
+	const __u32 ebx;
+	const __u32 ecx;
+	const __u32 edx;
+	const __u32 esi;
+	const __u32 edi;
+	const __u32 esp;
+	const __u32 ebp;
+}; 
 struct drive_info_struct { __u8 dummy[32]; };
 struct sys_desc_table {
 	__u16 length;
