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