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