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#ifdef CONFIG_EFI_STUB 36 /* 37 * We don't need the return address, so set up the stack so 38 * efi_main() can find its arugments. 39 */ 40 add $0x4, %esp 41 42 call efi_main 43 cmpl $0, %eax 44 je preferred_addr 45 movl %eax, %esi 46 call 1f 471: 48 popl %eax 49 subl $1b, %eax 50 subl BP_pref_address(%esi), %eax 51 add BP_code32_start(%esi), %eax 52 leal preferred_addr(%eax), %eax 53 jmp *%eax 54 55preferred_addr: 56#endif 57 cld 58 /* 59 * Test KEEP_SEGMENTS flag to see if the bootloader is asking 60 * us to not reload segments 61 */ 62 testb $(1<<6), BP_loadflags(%esi) 63 jnz 1f 64 65 cli 66 movl $__BOOT_DS, %eax 67 movl %eax, %ds 68 movl %eax, %es 69 movl %eax, %fs 70 movl %eax, %gs 71 movl %eax, %ss 721: 73 74/* 75 * Calculate the delta between where we were compiled to run 76 * at and where we were actually loaded at. This can only be done 77 * with a short local call on x86. Nothing else will tell us what 78 * address we are running at. The reserved chunk of the real-mode 79 * data at 0x1e4 (defined as a scratch field) are used as the stack 80 * for this calculation. Only 4 bytes are needed. 81 */ 82 leal (BP_scratch+4)(%esi), %esp 83 call 1f 841: popl %ebp 85 subl $1b, %ebp 86 87/* 88 * %ebp contains the address we are loaded at by the boot loader and %ebx 89 * contains the address where we should move the kernel image temporarily 90 * for safe in-place decompression. 91 */ 92 93#ifdef CONFIG_RELOCATABLE 94 movl %ebp, %ebx 95 movl BP_kernel_alignment(%esi), %eax 96 decl %eax 97 addl %eax, %ebx 98 notl %eax 99 andl %eax, %ebx 100#else 101 movl $LOAD_PHYSICAL_ADDR, %ebx 102#endif 103 104 /* Target address to relocate to for decompression */ 105 addl $z_extract_offset, %ebx 106 107 /* Set up the stack */ 108 leal boot_stack_end(%ebx), %esp 109 110 /* Zero EFLAGS */ 111 pushl $0 112 popfl 113 114/* 115 * Copy the compressed kernel to the end of our buffer 116 * where decompression in place becomes safe. 117 */ 118 pushl %esi 119 leal (_bss-4)(%ebp), %esi 120 leal (_bss-4)(%ebx), %edi 121 movl $(_bss - startup_32), %ecx 122 shrl $2, %ecx 123 std 124 rep movsl 125 cld 126 popl %esi 127 128/* 129 * Jump to the relocated address. 130 */ 131 leal relocated(%ebx), %eax 132 jmp *%eax 133ENDPROC(startup_32) 134 135 .text 136relocated: 137 138/* 139 * Clear BSS (stack is currently empty) 140 */ 141 xorl %eax, %eax 142 leal _bss(%ebx), %edi 143 leal _ebss(%ebx), %ecx 144 subl %edi, %ecx 145 shrl $2, %ecx 146 rep stosl 147 148/* 149 * Adjust our own GOT 150 */ 151 leal _got(%ebx), %edx 152 leal _egot(%ebx), %ecx 1531: 154 cmpl %ecx, %edx 155 jae 2f 156 addl %ebx, (%edx) 157 addl $4, %edx 158 jmp 1b 1592: 160 161/* 162 * Do the decompression, and jump to the new kernel.. 163 */ 164 leal z_extract_offset_negative(%ebx), %ebp 165 /* push arguments for decompress_kernel: */ 166 pushl %ebp /* output address */ 167 pushl $z_input_len /* input_len */ 168 leal input_data(%ebx), %eax 169 pushl %eax /* input_data */ 170 leal boot_heap(%ebx), %eax 171 pushl %eax /* heap area */ 172 pushl %esi /* real mode pointer */ 173 call decompress_kernel 174 addl $20, %esp 175 176#if CONFIG_RELOCATABLE 177/* 178 * Find the address of the relocations. 179 */ 180 leal z_output_len(%ebp), %edi 181 182/* 183 * Calculate the delta between where vmlinux was compiled to run 184 * and where it was actually loaded. 185 */ 186 movl %ebp, %ebx 187 subl $LOAD_PHYSICAL_ADDR, %ebx 188 jz 2f /* Nothing to be done if loaded at compiled addr. */ 189/* 190 * Process relocations. 191 */ 192 1931: subl $4, %edi 194 movl (%edi), %ecx 195 testl %ecx, %ecx 196 jz 2f 197 addl %ebx, -__PAGE_OFFSET(%ebx, %ecx) 198 jmp 1b 1992: 200#endif 201 202/* 203 * Jump to the decompressed kernel. 204 */ 205 xorl %ebx, %ebx 206 jmp *%ebp 207 208/* 209 * Stack and heap for uncompression 210 */ 211 .bss 212 .balign 4 213boot_heap: 214 .fill BOOT_HEAP_SIZE, 1, 0 215boot_stack: 216 .fill BOOT_STACK_SIZE, 1, 0 217boot_stack_end: 218