1/* 2 * linux/boot/head.S 3 * 4 * Copyright (C) 1991, 1992, 1993 Linus Torvalds 5 */ 6 7/* 8 * head.S contains the 32-bit startup code. 9 * 10 * NOTE!!! Startup happens at absolute address 0x00001000, which is also where 11 * the page directory will exist. The startup code will be overwritten by 12 * the page directory. [According to comments etc elsewhere on a compressed 13 * kernel it will end up at 0x1000 + 1Mb I hope so as I assume this. - AC] 14 * 15 * Page 0 is deliberately kept safe, since System Management Mode code in 16 * laptops may need to access the BIOS data stored there. This is also 17 * useful for future device drivers that either access the BIOS via VM86 18 * mode. 19 */ 20 21/* 22 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 23 */ 24 .text 25 26#include <linux/init.h> 27#include <linux/linkage.h> 28#include <asm/segment.h> 29#include <asm/page_types.h> 30#include <asm/boot.h> 31#include <asm/asm-offsets.h> 32 33 __HEAD 34ENTRY(startup_32) 35 cld 36 /* 37 * Test KEEP_SEGMENTS flag to see if the bootloader is asking 38 * us to not reload segments 39 */ 40 testb $(1<<6), BP_loadflags(%esi) 41 jnz 1f 42 43 cli 44 movl $__BOOT_DS, %eax 45 movl %eax, %ds 46 movl %eax, %es 47 movl %eax, %fs 48 movl %eax, %gs 49 movl %eax, %ss 501: 51 52/* 53 * Calculate the delta between where we were compiled to run 54 * at and where we were actually loaded at. This can only be done 55 * with a short local call on x86. Nothing else will tell us what 56 * address we are running at. The reserved chunk of the real-mode 57 * data at 0x1e4 (defined as a scratch field) are used as the stack 58 * for this calculation. Only 4 bytes are needed. 59 */ 60 leal (BP_scratch+4)(%esi), %esp 61 call 1f 621: popl %ebp 63 subl $1b, %ebp 64 65/* 66 * %ebp contains the address we are loaded at by the boot loader and %ebx 67 * contains the address where we should move the kernel image temporarily 68 * for safe in-place decompression. 69 */ 70 71#ifdef CONFIG_RELOCATABLE 72 movl %ebp, %ebx 73 movl BP_kernel_alignment(%esi), %eax 74 decl %eax 75 addl %eax, %ebx 76 notl %eax 77 andl %eax, %ebx 78#else 79 movl $LOAD_PHYSICAL_ADDR, %ebx 80#endif 81 82 /* Target address to relocate to for decompression */ 83 addl $z_extract_offset, %ebx 84 85 /* Set up the stack */ 86 leal boot_stack_end(%ebx), %esp 87 88 /* Zero EFLAGS */ 89 pushl $0 90 popfl 91 92/* 93 * Copy the compressed kernel to the end of our buffer 94 * where decompression in place becomes safe. 95 */ 96 pushl %esi 97 leal (_bss-4)(%ebp), %esi 98 leal (_bss-4)(%ebx), %edi 99 movl $(_bss - startup_32), %ecx 100 shrl $2, %ecx 101 std 102 rep movsl 103 cld 104 popl %esi 105 106/* 107 * Jump to the relocated address. 108 */ 109 leal relocated(%ebx), %eax 110 jmp *%eax 111ENDPROC(startup_32) 112 113 .text 114relocated: 115 116/* 117 * Clear BSS (stack is currently empty) 118 */ 119 xorl %eax, %eax 120 leal _bss(%ebx), %edi 121 leal _ebss(%ebx), %ecx 122 subl %edi, %ecx 123 shrl $2, %ecx 124 rep stosl 125 126/* 127 * Do the decompression, and jump to the new kernel.. 128 */ 129 leal z_extract_offset_negative(%ebx), %ebp 130 /* push arguments for decompress_kernel: */ 131 pushl %ebp /* output address */ 132 pushl $z_input_len /* input_len */ 133 leal input_data(%ebx), %eax 134 pushl %eax /* input_data */ 135 leal boot_heap(%ebx), %eax 136 pushl %eax /* heap area */ 137 pushl %esi /* real mode pointer */ 138 call decompress_kernel 139 addl $20, %esp 140 141#if CONFIG_RELOCATABLE 142/* 143 * Find the address of the relocations. 144 */ 145 leal z_output_len(%ebp), %edi 146 147/* 148 * Calculate the delta between where vmlinux was compiled to run 149 * and where it was actually loaded. 150 */ 151 movl %ebp, %ebx 152 subl $LOAD_PHYSICAL_ADDR, %ebx 153 jz 2f /* Nothing to be done if loaded at compiled addr. */ 154/* 155 * Process relocations. 156 */ 157 1581: subl $4, %edi 159 movl (%edi), %ecx 160 testl %ecx, %ecx 161 jz 2f 162 addl %ebx, -__PAGE_OFFSET(%ebx, %ecx) 163 jmp 1b 1642: 165#endif 166 167/* 168 * Jump to the decompressed kernel. 169 */ 170 xorl %ebx, %ebx 171 jmp *%ebp 172 173/* 174 * Stack and heap for uncompression 175 */ 176 .bss 177 .balign 4 178boot_heap: 179 .fill BOOT_HEAP_SIZE, 1, 0 180boot_stack: 181 .fill BOOT_STACK_SIZE, 1, 0 182boot_stack_end: 183