diff -urN mkp/linux-2.2.20-pre2/arch/i386/boot/compressed/head.S linux-2.2.20-pre2/arch/i386/boot/compressed/head.S --- mkp/linux-2.2.20-pre2/arch/i386/boot/compressed/head.S Sun Mar 25 08:31:45 2001 +++ linux-2.2.20-pre2/arch/i386/boot/compressed/head.S Tue May 8 12:42:40 2001 @@ -65,6 +65,7 @@ movl %eax,0x000000 # loop forever if it isn't cmpl %eax,0x100000 je 1b + /* * Initialize eflags. Some BIOS's leave bits like NT set. This would * confuse the debugger if this code is traced. @@ -86,10 +87,14 @@ * Do the decompression, and jump to the new kernel.. */ subl $16,%esp # place for structure on the stack - pushl %esp # address of structure as first arg + 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 @@ -104,11 +109,14 @@ movl $0x1000,%edi movl $move_routine_end,%ecx subl %esi,%ecx + addl $3,%ecx + shrl $2,%ecx cld rep - movsb + movsl popl %esi # discard the address + popl %ebx # real mode pointer popl %esi # low_buffer_start popl %ecx # lcount popl %edx # high_buffer_start @@ -122,18 +130,21 @@ * if we were high loaded. This _must_ PIC-code ! */ move_routine_start: + movl %ecx,%ebp + shrl $2,%ecx + rep + movsl + movl %ebp,%ecx + andl $3,%ecx rep movsb movl %edx,%esi movl %eax,%ecx # NOTE: rep movsb won't move if %ecx == 0 + addl $3,%ecx + shrl $2,%ecx rep - movsb + movsl + movl %ebx,%esi # Restore setup pointer xorl %ebx,%ebx -/* - * Well, the kernel relies on %esp pointing into low mem, - * with the decompressor loaded high this is no longer true, - * so we set esp here. - */ - mov $0x90000,%esp ljmp $(__KERNEL_CS), $0x100000 move_routine_end: diff -urN mkp/linux-2.2.20-pre2/arch/i386/boot/compressed/misc.c linux-2.2.20-pre2/arch/i386/boot/compressed/misc.c --- mkp/linux-2.2.20-pre2/arch/i386/boot/compressed/misc.c Sun Mar 25 08:31:45 2001 +++ linux-2.2.20-pre2/arch/i386/boot/compressed/misc.c Tue May 8 12:42:40 2001 @@ -74,11 +74,13 @@ /* * This is set up by the setup-routine at boot-time */ -#define EXT_MEM_K (*(unsigned short *)0x90002) +static unsigned char *real_mode; /* Pointer to real-mode data */ + +#define EXT_MEM_K (*(unsigned short *)(real_mode + 0x2)) #ifndef STANDARD_MEMORY_BIOS_CALL -#define ALT_MEM_K (*(unsigned long *) 0x901e0) +#define ALT_MEM_K (*(unsigned long *)(real_mode + 0x1e0)) #endif -#define SCREEN_INFO (*(struct screen_info *)0x90000) +#define SCREEN_INFO (*(struct screen_info *)(real_mode+0)) extern char input_data[]; extern int input_len; @@ -98,13 +100,13 @@ extern int end; static long free_mem_ptr = (long)&end; -static long free_mem_end_ptr = 0x90000; +static long free_mem_end_ptr; #define INPLACE_MOVE_ROUTINE 0x1000 #define LOW_BUFFER_START 0x2000 -#define LOW_BUFFER_END 0x90000 -#define LOW_BUFFER_SIZE ( LOW_BUFFER_END - LOW_BUFFER_START ) +#define LOW_BUFFER_MAX 0x90000 #define HEAP_SIZE 0x2400 +static unsigned int low_buffer_end, low_buffer_size; static int high_loaded =0; static uch *high_buffer_start /* = (uch *)(((ulg)&end) + HEAP_SIZE)*/; @@ -255,7 +257,7 @@ in = window; for (n = 0; n < outcnt; n++) { ch = *output_data++ = *in++; - if ((ulg)output_data == LOW_BUFFER_END) output_data=high_buffer_start; + if ((ulg)output_data == low_buffer_end) output_data=high_buffer_start; c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); } crc = c; @@ -311,10 +313,13 @@ if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory.\n"); #endif 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; high_loaded = 1; free_mem_end_ptr = (long)high_buffer_start; - if ( (0x100000 + LOW_BUFFER_SIZE) > ((ulg)high_buffer_start)) { - high_buffer_start = (uch *)(0x100000 + LOW_BUFFER_SIZE); + if ( (0x100000 + low_buffer_size) > ((ulg)high_buffer_start)) { + high_buffer_start = (uch *)(0x100000 + low_buffer_size); mv->hcount = 0; /* say: we need not to move high_buffer */ } else mv->hcount = -1; @@ -323,17 +328,21 @@ void close_output_buffer_if_we_run_high(struct moveparams *mv) { - mv->lcount = bytes_out; - if (bytes_out > LOW_BUFFER_SIZE) { - mv->lcount = LOW_BUFFER_SIZE; - if (mv->hcount) mv->hcount = bytes_out - LOW_BUFFER_SIZE; + if (bytes_out > low_buffer_size) { + mv->lcount = low_buffer_size; + if (mv->hcount) + mv->hcount = bytes_out - low_buffer_size; + } else { + mv->lcount = bytes_out; + mv->hcount = 0; } - else mv->hcount = 0; } -int decompress_kernel(struct moveparams *mv) +int decompress_kernel(struct moveparams *mv, void *rmode) { + real_mode = rmode; + if (SCREEN_INFO.orig_video_mode == 7) { vidmem = (char *) 0xb0000; vidport = 0x3b4; @@ -355,4 +364,3 @@ if (high_loaded) close_output_buffer_if_we_run_high(mv); return high_loaded; } - diff -urN mkp/linux-2.2.20-pre2/arch/i386/boot/setup.S linux-2.2.20-pre2/arch/i386/boot/setup.S --- mkp/linux-2.2.20-pre2/arch/i386/boot/setup.S Sun Mar 25 08:37:29 2001 +++ linux-2.2.20-pre2/arch/i386/boot/setup.S Tue May 8 12:42:40 2001 @@ -69,7 +69,7 @@ ! SETUP-header, must start at CS:2 (old 0x9020:2) ! .ascii "HdrS" ! Signature for SETUP-header - .word 0x0201 ! Version number of header format + .word 0x0202 ! Version number of header format ! (must be >= 0x0105 ! else old loadlin-1.5 will fail) realmode_swtch: .word 0,0 ! default_switch,SETUPSEG @@ -120,9 +120,28 @@ ramdisk_size: .long 0 ! its size in bytes bootsect_kludge: .word bootsect_helper,SETUPSEG -heap_end_ptr: .word modelist+1024 ! space from here (exclusive) down to - ! end of setup code can be used by setup - ! for local heap purposes. +heap_end_ptr: .word modelist+1024 ! (Header version 0x0201 or later) + ! space from here (exclusive) down to + ! end of setup code can be used by setup + ! for local heap purposes. + +pad1: .word 0 ! Reserved for future use + +cmd_line_ptr: .long 0 ! (Header version 0x0202 or later) + ! If nonzero, a 32-bit pointer + ! to the kernel command line. + ! The command line should be + ! located between the start of + ! setup and the end of low + ! memory (0xa0000), or it may + ! get overwritten before it + ! gets read. If this field is + ! used, there is no longer + ! anything magical about the + ! 0x90000 segment; the setup + ! can be located anywhere in + ! low memory 0x10000 or higher. + ! ------------------------ end of header ---------------------------------- start_of_setup: @@ -534,6 +553,13 @@ mov ax,cs ! aka #SETUPSEG ! right, forgot this at first. didn't work :-) mov ds,ax +! Check whether we need to be downward compatible with version <= 0x0201 + cmp dword ptr [cmd_line_ptr],#0 + jne end_move_self + cmp byte ptr [type_of_loader],#0x20 + je end_move_self + +! Boot loader does not support boot protocol version 2.02. ! If we have our code not at 0x90000, we need to move it there now. ! We also then need to move the parameters behind it (command line) ! Because we would overwrite the code on the current IP, we move @@ -572,9 +598,14 @@ mov ds,ax mov ss,dx ! now we are at the right place -end_move_self: +end_move_self: lidt idt_48 ! load idt with 0,0 + xor eax,eax + mov ax,ds + shl eax,#4 + add eax,#gdt + mov [gdt_48+2],eax lgdt gdt_48 ! load gdt with whatever appropriate ! that was painless, now we enable A20 @@ -679,7 +710,11 @@ jmp flush_instr flush_instr: xor bx,bx ! Flag to indicate a boot - + xor esi,esi ! Pointer to real-mode code + mov si,cs + sub si,#DELTA_INITSEG + shl esi,#4 ! Convert to 32-bit pointer + ! NOTE: For high loaded big kernels we need a ! jmpi 0x100000,__KERNEL_CS ! @@ -873,7 +908,7 @@ gdt_48: .word 0x800 ! gdt limit=2048, 256 GDT entries - .word 512+gdt,0x9 ! gdt base = 0X9xxxx + .word 0, 0 ! gdt base (filled in later) ! ! Include video setup & detection code diff -urN mkp/linux-2.2.20-pre2/arch/i386/kernel/head.S linux-2.2.20-pre2/arch/i386/kernel/head.S --- mkp/linux-2.2.20-pre2/arch/i386/kernel/head.S Sun Mar 25 08:31:45 2001 +++ linux-2.2.20-pre2/arch/i386/kernel/head.S Tue May 8 12:42:40 2001 @@ -14,11 +14,11 @@ #include #include - -#define CL_MAGIC_ADDR 0x90020 -#define CL_MAGIC 0xA33F -#define CL_BASE_ADDR 0x90000 -#define CL_OFFSET 0x90022 +#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. @@ -36,6 +36,8 @@ /* * swapper_pg_dir is the main page directory, address 0x00101000 + * + * On entry, %esi points to the real-mode code as a 32-bit pointer. */ ENTRY(stext) ENTRY(_stext) @@ -52,6 +54,9 @@ #ifdef __SMP__ orw %bx,%bx jz 1f +#endif + +#ifdef __SMP__ /* * New page tables may be in 4Mbyte page mode and may * be using the global pages. @@ -89,6 +94,7 @@ jmp checkCPUtype 1: #endif __SMP__ + /* * Clear BSS first so that there are no surprises... */ @@ -99,6 +105,7 @@ cld rep stosb + /* * start system 32-bit setup. We need to re-do some of the things done * in 16-bit mode for the "real" operations. @@ -115,8 +122,9 @@ * Copy bootup parameters out of the way. First 2kB of * _empty_zero_page is for boot parameters, second 2kB * is for the command line. + * + * Note: %esi still has the pointer to the real-mode data. */ - movl $0x90000,%esi movl $ SYMBOL_NAME(empty_zero_page),%edi movl $512,%ecx cld @@ -126,11 +134,15 @@ movl $512,%ecx rep stosl - cmpw $(CL_MAGIC),CL_MAGIC_ADDR + movl SYMBOL_NAME(empty_zero_page)+NEW_CL_POINTER,%esi + andl %esi,%esi + jnz 2f + 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 - movzwl CL_OFFSET,%esi - addl $(CL_BASE_ADDR),%esi movl $2048,%ecx rep movsb