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