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 * Adjust our own GOT 128 */ 129 leal _got(%ebx), %edx 130 leal _egot(%ebx), %ecx 1311: 132 cmpl %ecx, %edx 133 jae 2f 134 addl %ebx, (%edx) 135 addl $4, %edx 136 jmp 1b 1372: 138 139/* 140 * Do the decompression, and jump to the new kernel.. 141 */ 142 leal z_extract_offset_negative(%ebx), %ebp 143 /* push arguments for decompress_kernel: */ 144 pushl %ebp /* output address */ 145 pushl $z_input_len /* input_len */ 146 leal input_data(%ebx), %eax 147 pushl %eax /* input_data */ 148 leal boot_heap(%ebx), %eax 149 pushl %eax /* heap area */ 150 pushl %esi /* real mode pointer */ 151 call decompress_kernel 152 addl $20, %esp 153 154#if CONFIG_RELOCATABLE 155/* 156 * Find the address of the relocations. 157 */ 158 leal z_output_len(%ebp), %edi 159 160/* 161 * Calculate the delta between where vmlinux was compiled to run 162 * and where it was actually loaded. 163 */ 164 movl %ebp, %ebx 165 subl $LOAD_PHYSICAL_ADDR, %ebx 166 jz 2f /* Nothing to be done if loaded at compiled addr. */ 167/* 168 * Process relocations. 169 */ 170 1711: subl $4, %edi 172 movl (%edi), %ecx 173 testl %ecx, %ecx 174 jz 2f 175 addl %ebx, -__PAGE_OFFSET(%ebx, %ecx) 176 jmp 1b 1772: 178#endif 179 180/* 181 * Jump to the decompressed kernel. 182 */ 183 xorl %ebx, %ebx 184 jmp *%ebp 185 186/* 187 * Stack and heap for uncompression 188 */ 189 .bss 190 .balign 4 191boot_heap: 192 .fill BOOT_HEAP_SIZE, 1, 0 193boot_stack: 194 .fill BOOT_STACK_SIZE, 1, 0 195boot_stack_end: 196