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/linkage.h> 27#include <asm/segment.h> 28#include <asm/page.h> 29#include <asm/boot.h> 30#include <asm/asm-offsets.h> 31 32.section ".text.head","ax",@progbits 33 .globl startup_32 34 35startup_32: 36 cld 37 /* test KEEP_SEGMENTS flag to see if the bootloader is asking 38 * us to not reload segments */ 39 testb $(1<<6), BP_loadflags(%esi) 40 jnz 1f 41 42 cli 43 movl $(__BOOT_DS),%eax 44 movl %eax,%ds 45 movl %eax,%es 46 movl %eax,%fs 47 movl %eax,%gs 48 movl %eax,%ss 491: 50 51/* Calculate the delta between where we were compiled to run 52 * at and where we were actually loaded at. This can only be done 53 * with a short local call on x86. Nothing else will tell us what 54 * address we are running at. The reserved chunk of the real-mode 55 * data at 0x1e4 (defined as a scratch field) are used as the stack 56 * for this calculation. Only 4 bytes are needed. 57 */ 58 leal (0x1e4+4)(%esi), %esp 59 call 1f 601: popl %ebp 61 subl $1b, %ebp 62 63/* %ebp contains the address we are loaded at by the boot loader and %ebx 64 * contains the address where we should move the kernel image temporarily 65 * for safe in-place decompression. 66 */ 67 68#ifdef CONFIG_RELOCATABLE 69 movl %ebp, %ebx 70 addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebx 71 andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebx 72#else 73 movl $LOAD_PHYSICAL_ADDR, %ebx 74#endif 75 76 /* Replace the compressed data size with the uncompressed size */ 77 subl input_len(%ebp), %ebx 78 movl output_len(%ebp), %eax 79 addl %eax, %ebx 80 /* Add 8 bytes for every 32K input block */ 81 shrl $12, %eax 82 addl %eax, %ebx 83 /* Add 32K + 18 bytes of extra slack */ 84 addl $(32768 + 18), %ebx 85 /* Align on a 4K boundary */ 86 addl $4095, %ebx 87 andl $~4095, %ebx 88 89/* Copy the compressed kernel to the end of our buffer 90 * where decompression in place becomes safe. 91 */ 92 pushl %esi 93 leal _end(%ebp), %esi 94 leal _end(%ebx), %edi 95 movl $(_end - startup_32), %ecx 96 std 97 rep 98 movsb 99 cld 100 popl %esi 101 102/* Compute the kernel start address. 103 */ 104#ifdef CONFIG_RELOCATABLE 105 addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebp 106 andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebp 107#else 108 movl $LOAD_PHYSICAL_ADDR, %ebp 109#endif 110 111/* 112 * Jump to the relocated address. 113 */ 114 leal relocated(%ebx), %eax 115 jmp *%eax 116.section ".text" 117relocated: 118 119/* 120 * Clear BSS 121 */ 122 xorl %eax,%eax 123 leal _edata(%ebx),%edi 124 leal _end(%ebx), %ecx 125 subl %edi,%ecx 126 cld 127 rep 128 stosb 129 130/* 131 * Setup the stack for the decompressor 132 */ 133 leal boot_stack_end(%ebx), %esp 134 135/* 136 * Do the decompression, and jump to the new kernel.. 137 */ 138 movl output_len(%ebx), %eax 139 pushl %eax 140 pushl %ebp # output address 141 movl input_len(%ebx), %eax 142 pushl %eax # input_len 143 leal input_data(%ebx), %eax 144 pushl %eax # input_data 145 leal boot_heap(%ebx), %eax 146 pushl %eax # heap area as third argument 147 pushl %esi # real mode pointer as second arg 148 call decompress_kernel 149 addl $20, %esp 150 popl %ecx 151 152#if CONFIG_RELOCATABLE 153/* Find the address of the relocations. 154 */ 155 movl %ebp, %edi 156 addl %ecx, %edi 157 158/* Calculate the delta between where vmlinux was compiled to run 159 * and where it was actually loaded. 160 */ 161 movl %ebp, %ebx 162 subl $LOAD_PHYSICAL_ADDR, %ebx 163 jz 2f /* Nothing to be done if loaded at compiled addr. */ 164/* 165 * Process relocations. 166 */ 167 1681: subl $4, %edi 169 movl 0(%edi), %ecx 170 testl %ecx, %ecx 171 jz 2f 172 addl %ebx, -__PAGE_OFFSET(%ebx, %ecx) 173 jmp 1b 1742: 175#endif 176 177/* 178 * Jump to the decompressed kernel. 179 */ 180 xorl %ebx,%ebx 181 jmp *%ebp 182 183.bss 184/* Stack and heap for uncompression */ 185.balign 4 186boot_heap: 187 .fill BOOT_HEAP_SIZE, 1, 0 188boot_stack: 189 .fill BOOT_STACK_SIZE, 1, 0 190boot_stack_end: 191