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