Re: [PATCH 2.5.12] x86 Boot enhancements, 32bit entries 6/11

From: Eric W. Biederman (ebiederm@xmission.com)
Date: Thu May 02 2002 - 10:00:56 EST


Please apply,

This patch cleans up the 32bit kernel entry points so they don't
assume who their caller is, making them usable by other than setup.S

For arch/i386/kernel/head.S this untangles the secondary cpu and the bootstrap
entry points making the code more readable.

Eric

diff -uNr linux-2.5.12.boot.heap/arch/i386/boot/compressed/head.S linux-2.5.12.boot.clean_32bit_entries/arch/i386/boot/compressed/head.S
--- linux-2.5.12.boot.heap/arch/i386/boot/compressed/head.S Mon Apr 29 00:17:11 2002
+++ linux-2.5.12.boot.clean_32bit_entries/arch/i386/boot/compressed/head.S Wed May 1 09:39:47 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 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 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 decompress_kernel
- orl %eax,%eax
- jnz 3f
- popl %esi # discard address
- popl %esi # real mode pointer
- xorl %ebx,%ebx
- ljmp $(__KERNEL_CS), $0x100000
-
+ orl %eax,%eax
+ 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,21 @@
  * 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 %eax,%edi #dest
+ movl %eax, %ebp #saved 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,20 +106,23 @@
         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
+ movl $HIGH_BASE,%edi
         cli # make sure we don't get interrupted
- ljmp $(__KERNEL_CS), $0x1000 # and jump to the move routine
+ jmpl *%ebp
 
 /*
  * 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.
  */
+ .globl move_routine_start, move_routine_end
+ .balign 4
 move_routine_start:
         movl %ecx,%ebp
         shrl $2,%ecx
@@ -122,7 +138,35 @@
         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
+ .balign 4
+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 HIGH_BASE
 move_routine_end:
diff -uNr linux-2.5.12.boot.heap/arch/i386/boot/compressed/misc.c linux-2.5.12.boot.clean_32bit_entries/arch/i386/boot/compressed/misc.c
--- linux-2.5.12.boot.heap/arch/i386/boot/compressed/misc.c Wed May 1 09:38:29 2002
+++ linux-2.5.12.boot.clean_32bit_entries/arch/i386/boot/compressed/misc.c Wed May 1 09:39:47 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,11 @@
 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
+/* Decompressor constants */
+#define HEAP_SIZE 0x003000
+static unsigned long move_routine;
+extern unsigned char move_routine_end[], move_routine_start[];
+
 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 +172,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 +215,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 +322,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)
 {
@@ -333,11 +342,13 @@
 static void setup_output_buffer_if_we_run_high(struct moveparams *mv)
 {
         high_buffer_start = (uch *)(((ulg)&end) + HEAP_SIZE);
+ move_routine = LOW_BASE;
         if (mem_k < (4*1024)) error("Less than 4MB of memory.\n");
- mv->low_buffer_start = output_data = (char *)LOW_BUFFER_START;
- low_buffer_end = ((unsigned int)real_mode > LOW_BUFFER_MAX
- ? LOW_BUFFER_MAX : (unsigned int)real_mode) & ~0xfff;
- low_buffer_size = low_buffer_end - LOW_BUFFER_START;
+ mv->low_buffer_start = output_data =
+ (char *)move_routine + (move_routine_end - move_routine_start);
+ low_buffer_end = ((unsigned int)real_mode > LOW_MAX
+ ? LOW_MAX : (unsigned int)real_mode) & ~0xfff;
+ low_buffer_size = low_buffer_end - (unsigned long)mv->low_buffer_start;
         high_loaded = 1;
         free_mem_end_ptr = (long)high_buffer_start;
         if ( (0x100000 + low_buffer_size) > ((ulg)high_buffer_start)) {
@@ -346,6 +357,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,21 +373,28 @@
 }
 
 
-asmlinkage int decompress_kernel(struct moveparams *mv, void *rmode)
+asmlinkage unsigned long 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();
+ if (free_mem_ptr < HIGH_BASE) setup_normal_output_buffer();
         else setup_output_buffer_if_we_run_high(mv);
 
         makecrc();
@@ -383,5 +402,5 @@
         gunzip();
         puts("Ok, booting the kernel.\n");
         if (high_loaded) close_output_buffer_if_we_run_high(mv);
- return high_loaded;
+ return move_routine;
 }
diff -uNr linux-2.5.12.boot.heap/arch/i386/boot/setup.S linux-2.5.12.boot.clean_32bit_entries/arch/i386/boot/setup.S
--- linux-2.5.12.boot.heap/arch/i386/boot/setup.S Wed May 1 09:39:29 2002
+++ linux-2.5.12.boot.clean_32bit_entries/arch/i386/boot/setup.S Wed May 1 09:39:47 2002
@@ -67,6 +67,12 @@
 
 #define DELTA_BOOTSECT 512
 
+/* 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
@@ -798,13 +804,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.
@@ -815,7 +830,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.12.boot.heap/arch/i386/kernel/head.S linux-2.5.12.boot.clean_32bit_entries/arch/i386/kernel/head.S
--- linux-2.5.12.boot.heap/arch/i386/kernel/head.S Wed May 1 09:38:47 2002
+++ linux-2.5.12.boot.clean_32bit_entries/arch/i386/kernel/head.S Wed May 1 09:39:47 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
+ *
  */
 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 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
+
+/*
+ * Set segments to known values
+ */
+ movl $(__KERNEL_DS), %eax
+ movl %eax,%ds
+ movl %eax,%es
+ movl %eax,%fs
+ movl %eax,%gs
+ movl %eax,%ss
+
 /*
- * Copy bootup parameters out of the way. First 2kB of
- * _empty_zero_page is for boot parameters, second 2kB
- * is for the command line.
+ * New page tables may be in 4Mbyte page mode and may
+ * be using the global pages.
  *
- * Note: %esi still has the pointer to the real-mode data.
+ * 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..
  */
- movl $empty_zero_page,%edi
- movl $512,%ecx
- cld
- rep
- movsl
- xorl %eax,%eax
- movl $512,%ecx
- rep
- stosl
- movl 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 $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 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
@@ -240,40 +262,11 @@
         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 initialize_secondary
- jmp L6
-1:
-#endif
- call 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 +365,10 @@
 gdt:
         .long gdt_table
 
+ .word 0
+gdt_48:
+ .word GDT_ENTRIES*8-1
+ .long 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.12.boot.heap/arch/i386/kernel/setup.c linux-2.5.12.boot.clean_32bit_entries/arch/i386/kernel/setup.c
--- linux-2.5.12.boot.heap/arch/i386/kernel/setup.c Wed May 1 09:38:30 2002
+++ linux-2.5.12.boot.clean_32bit_entries/arch/i386/kernel/setup.c Wed May 1 09:39:48 2002
@@ -116,6 +116,7 @@
 #include <asm/dma.h>
 #include <asm/mpspec.h>
 #include <asm/mmu_context.h>
+#include <asm/boot.h>
 #include <asm/boot_param.h>
 
 /*
@@ -164,8 +165,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];
@@ -562,13 +563,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 (;;) {
                 /*
@@ -638,21 +638,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;
@@ -674,6 +695,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 (params->screen.overlap.cl_magic == CL_MAGIC_VALUE) {
+ cmdline = (char *)params + params->screen.overlap.cl_offset;
+ }
+ memcpy(command_line, cmdline, COMMAND_LINE_SIZE);
+ command_line[COMMAND_LINE_SIZE -1] = '\0';
+
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (params->type_of_loader && 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;
@@ -684,8 +759,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)
@@ -857,11 +930,6 @@
         find_smp_config();
 #endif
 #ifdef CONFIG_BLK_DEV_INITRD
- if (params->type_of_loader && 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.12.boot.heap/arch/i386/kernel/trampoline.S linux-2.5.12.boot.clean_32bit_entries/arch/i386/kernel/trampoline.S
--- linux-2.5.12.boot.heap/arch/i386/kernel/trampoline.S Mon Apr 29 00:17:11 2002
+++ linux-2.5.12.boot.clean_32bit_entries/arch/i386/kernel/trampoline.S Wed May 1 09:39:48 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,15 +55,16 @@
         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, $(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
+ .word GDT_ENTRIES*8-1 # gdt limit
         .long gdt_table-__PAGE_OFFSET # gdt base = gdt (first SMP CPU)
 
 .globl trampoline_end
diff -uNr linux-2.5.12.boot.heap/include/asm-i386/boot.h linux-2.5.12.boot.clean_32bit_entries/include/asm-i386/boot.h
--- linux-2.5.12.boot.heap/include/asm-i386/boot.h Wed May 1 09:39:29 2002
+++ linux-2.5.12.boot.clean_32bit_entries/include/asm-i386/boot.h Wed May 1 09:39:48 2002
@@ -26,4 +26,14 @@
 #define EXTENDED_VGA 0xfffe /* 80x50 mode */
 #define ASK_VGA 0xfffd /* ask for it at bootup */
 
+/* Entry point ID constants */
+#define ENTRY16 0x73726468 /* 'hdrs' */
+#define ENTRY32 0x53524448 /* 'HDRS' */
+
+/* Maximum command line size */
+#define COMMAND_LINE_SIZE 256
+
+/* Initial page table size 8MB */
+#define INITIAL_PAGE_TABLE_SIZE 0x800000
+
 #endif
diff -uNr linux-2.5.12.boot.heap/include/asm-i386/boot_param.h linux-2.5.12.boot.clean_32bit_entries/include/asm-i386/boot_param.h
--- linux-2.5.12.boot.heap/include/asm-i386/boot_param.h Wed May 1 09:39:29 2002
+++ linux-2.5.12.boot.clean_32bit_entries/include/asm-i386/boot_param.h Wed May 1 09:39:48 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;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue May 07 2002 - 22:00:13 EST