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