1/* 2 * header.S 3 * 4 * Copyright (C) 1991, 1992 Linus Torvalds 5 * 6 * Based on bootsect.S and setup.S 7 * modified by more people than can be counted 8 * 9 * Rewritten as a common file by H. Peter Anvin (Apr 2007) 10 * 11 * BIG FAT NOTE: We're in real mode using 64k segments. Therefore segment 12 * addresses must be multiplied by 16 to obtain their respective linear 13 * addresses. To avoid confusion, linear addresses are written using leading 14 * hex while segment addresses are written as segment:offset. 15 * 16 */ 17 18#include <asm/segment.h> 19#include <linux/utsrelease.h> 20#include <asm/boot.h> 21#include <asm/e820.h> 22#include <asm/page.h> 23#include <asm/setup.h> 24#include "boot.h" 25#include "offsets.h" 26 27SETUPSECTS = 4 /* default nr of setup-sectors */ 28BOOTSEG = 0x07C0 /* original address of boot-sector */ 29SYSSEG = DEF_SYSSEG /* system loaded at 0x10000 (65536) */ 30SYSSIZE = DEF_SYSSIZE /* system size: # of 16-byte clicks */ 31 /* to be loaded */ 32ROOT_DEV = 0 /* ROOT_DEV is now written by "build" */ 33SWAP_DEV = 0 /* SWAP_DEV is now written by "build" */ 34 35#ifndef SVGA_MODE 36#define SVGA_MODE ASK_VGA 37#endif 38 39#ifndef RAMDISK 40#define RAMDISK 0 41#endif 42 43#ifndef ROOT_RDONLY 44#define ROOT_RDONLY 1 45#endif 46 47 .code16 48 .section ".bstext", "ax" 49 50 .global bootsect_start 51bootsect_start: 52 53 # Normalize the start address 54 ljmp $BOOTSEG, $start2 55 56start2: 57 movw %cs, %ax 58 movw %ax, %ds 59 movw %ax, %es 60 movw %ax, %ss 61 xorw %sp, %sp 62 sti 63 cld 64 65 movw $bugger_off_msg, %si 66 67msg_loop: 68 lodsb 69 andb %al, %al 70 jz bs_die 71 movb $0xe, %ah 72 movw $7, %bx 73 int $0x10 74 jmp msg_loop 75 76bs_die: 77 # Allow the user to press a key, then reboot 78 xorw %ax, %ax 79 int $0x16 80 int $0x19 81 82 # int 0x19 should never return. In case it does anyway, 83 # invoke the BIOS reset code... 84 ljmp $0xf000,$0xfff0 85 86 .section ".bsdata", "a" 87bugger_off_msg: 88 .ascii "Direct booting from floppy is no longer supported.\r\n" 89 .ascii "Please use a boot loader program instead.\r\n" 90 .ascii "\n" 91 .ascii "Remove disk and press any key to reboot . . .\r\n" 92 .byte 0 93 94 95 # Kernel attributes; used by setup. This is part 1 of the 96 # header, from the old boot sector. 97 98 .section ".header", "a" 99 .globl hdr 100hdr: 101setup_sects: .byte SETUPSECTS 102root_flags: .word ROOT_RDONLY 103syssize: .long SYSSIZE 104ram_size: .word RAMDISK 105vid_mode: .word SVGA_MODE 106root_dev: .word ROOT_DEV 107boot_flag: .word 0xAA55 108 109 # offset 512, entry point 110 111 .globl _start 112_start: 113 # Explicitly enter this as bytes, or the assembler 114 # tries to generate a 3-byte jump here, which causes 115 # everything else to push off to the wrong offset. 116 .byte 0xeb # short (2-byte) jump 117 .byte start_of_setup-1f 1181: 119 120 # Part 2 of the header, from the old setup.S 121 122 .ascii "HdrS" # header signature 123 .word 0x0209 # header version number (>= 0x0105) 124 # or else old loadlin-1.5 will fail) 125 .globl realmode_swtch 126realmode_swtch: .word 0, 0 # default_switch, SETUPSEG 127start_sys_seg: .word SYSSEG 128 .word kernel_version-512 # pointing to kernel version string 129 # above section of header is compatible 130 # with loadlin-1.5 (header v1.5). Don't 131 # change it. 132 133type_of_loader: .byte 0 # = 0, old one (LILO, Loadlin, 134 # Bootlin, SYSLX, bootsect...) 135 # See Documentation/i386/boot.txt for 136 # assigned ids 137 138# flags, unused bits must be zero (RFU) bit within loadflags 139loadflags: 140LOADED_HIGH = 1 # If set, the kernel is loaded high 141CAN_USE_HEAP = 0x80 # If set, the loader also has set 142 # heap_end_ptr to tell how much 143 # space behind setup.S can be used for 144 # heap purposes. 145 # Only the loader knows what is free 146#ifndef __BIG_KERNEL__ 147 .byte 0 148#else 149 .byte LOADED_HIGH 150#endif 151 152setup_move_size: .word 0x8000 # size to move, when setup is not 153 # loaded at 0x90000. We will move setup 154 # to 0x90000 then just before jumping 155 # into the kernel. However, only the 156 # loader knows how much data behind 157 # us also needs to be loaded. 158 159code32_start: # here loaders can put a different 160 # start address for 32-bit code. 161#ifndef __BIG_KERNEL__ 162 .long 0x1000 # 0x1000 = default for zImage 163#else 164 .long 0x100000 # 0x100000 = default for big kernel 165#endif 166 167ramdisk_image: .long 0 # address of loaded ramdisk image 168 # Here the loader puts the 32-bit 169 # address where it loaded the image. 170 # This only will be read by the kernel. 171 172ramdisk_size: .long 0 # its size in bytes 173 174bootsect_kludge: 175 .long 0 # obsolete 176 177heap_end_ptr: .word _end+STACK_SIZE-512 178 # (Header version 0x0201 or later) 179 # space from here (exclusive) down to 180 # end of setup code can be used by setup 181 # for local heap purposes. 182 183pad1: .word 0 184cmd_line_ptr: .long 0 # (Header version 0x0202 or later) 185 # If nonzero, a 32-bit pointer 186 # to the kernel command line. 187 # The command line should be 188 # located between the start of 189 # setup and the end of low 190 # memory (0xa0000), or it may 191 # get overwritten before it 192 # gets read. If this field is 193 # used, there is no longer 194 # anything magical about the 195 # 0x90000 segment; the setup 196 # can be located anywhere in 197 # low memory 0x10000 or higher. 198 199ramdisk_max: .long 0x7fffffff 200 # (Header version 0x0203 or later) 201 # The highest safe address for 202 # the contents of an initrd 203 # The current kernel allows up to 4 GB, 204 # but leave it at 2 GB to avoid 205 # possible bootloader bugs. 206 207kernel_alignment: .long CONFIG_PHYSICAL_ALIGN #physical addr alignment 208 #required for protected mode 209 #kernel 210#ifdef CONFIG_RELOCATABLE 211relocatable_kernel: .byte 1 212#else 213relocatable_kernel: .byte 0 214#endif 215pad2: .byte 0 216pad3: .word 0 217 218cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line, 219 #added with boot protocol 220 #version 2.06 221 222hardware_subarch: .long 0 # subarchitecture, added with 2.07 223 # default to 0 for normal x86 PC 224 225hardware_subarch_data: .quad 0 226 227payload_offset: .long input_data 228payload_length: .long input_data_end-input_data 229 230setup_data: .quad 0 # 64-bit physical pointer to 231 # single linked list of 232 # struct setup_data 233 234# End of setup header ##################################################### 235 236 .section ".inittext", "ax" 237start_of_setup: 238#ifdef SAFE_RESET_DISK_CONTROLLER 239# Reset the disk controller. 240 movw $0x0000, %ax # Reset disk controller 241 movb $0x80, %dl # All disks 242 int $0x13 243#endif 244 245# Force %es = %ds 246 movw %ds, %ax 247 movw %ax, %es 248 cld 249 250# Apparently some ancient versions of LILO invoked the kernel with %ss != %ds, 251# which happened to work by accident for the old code. Recalculate the stack 252# pointer if %ss is invalid. Otherwise leave it alone, LOADLIN sets up the 253# stack behind its own code, so we can't blindly put it directly past the heap. 254 255 movw %ss, %dx 256 cmpw %ax, %dx # %ds == %ss? 257 movw %sp, %dx 258 je 2f # -> assume %sp is reasonably set 259 260 # Invalid %ss, make up a new stack 261 movw $_end, %dx 262 testb $CAN_USE_HEAP, loadflags 263 jz 1f 264 movw heap_end_ptr, %dx 2651: addw $STACK_SIZE, %dx 266 jnc 2f 267 xorw %dx, %dx # Prevent wraparound 268 2692: # Now %dx should point to the end of our stack space 270 andw $~3, %dx # dword align (might as well...) 271 jnz 3f 272 movw $0xfffc, %dx # Make sure we're not zero 2733: movw %ax, %ss 274 movzwl %dx, %esp # Clear upper half of %esp 275 sti # Now we should have a working stack 276 277# We will have entered with %cs = %ds+0x20, normalize %cs so 278# it is on par with the other segments. 279 pushw %ds 280 pushw $6f 281 lretw 2826: 283 284# Check signature at end of setup 285 cmpl $0x5a5aaa55, setup_sig 286 jne setup_bad 287 288# Zero the bss 289 movw $__bss_start, %di 290 movw $_end+3, %cx 291 xorl %eax, %eax 292 subw %di, %cx 293 shrw $2, %cx 294 rep; stosl 295 296# Jump to C code (should not return) 297 calll main 298 299# Setup corrupt somehow... 300setup_bad: 301 movl $setup_corrupt, %eax 302 calll puts 303 # Fall through... 304 305 .globl die 306 .type die, @function 307die: 308 hlt 309 jmp die 310 311 .size die, .-die 312 313 .section ".initdata", "a" 314setup_corrupt: 315 .byte 7 316 .string "No setup signature found...\n" 317