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 26SETUPSECTS = 4 /* default nr of setup-sectors */ 27BOOTSEG = 0x07C0 /* original address of boot-sector */ 28SYSSEG = DEF_SYSSEG /* system loaded at 0x10000 (65536) */ 29SYSSIZE = DEF_SYSSIZE /* system size: # of 16-byte clicks */ 30 /* to be loaded */ 31ROOT_DEV = 0 /* ROOT_DEV is now written by "build" */ 32SWAP_DEV = 0 /* SWAP_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 0x0206 # 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+1024 # (Header version 0x0201 or later) 177 # space from here (exclusive) down to 178 # end of setup code can be used by setup 179 # for local heap purposes. 180 181pad1: .word 0 182cmd_line_ptr: .long 0 # (Header version 0x0202 or later) 183 # If nonzero, a 32-bit pointer 184 # to the kernel command line. 185 # The command line should be 186 # located between the start of 187 # setup and the end of low 188 # memory (0xa0000), or it may 189 # get overwritten before it 190 # gets read. If this field is 191 # used, there is no longer 192 # anything magical about the 193 # 0x90000 segment; the setup 194 # can be located anywhere in 195 # low memory 0x10000 or higher. 196 197ramdisk_max: .long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff 198 # (Header version 0x0203 or later) 199 # The highest safe address for 200 # the contents of an initrd 201 202kernel_alignment: .long CONFIG_PHYSICAL_ALIGN #physical addr alignment 203 #required for protected mode 204 #kernel 205#ifdef CONFIG_RELOCATABLE 206relocatable_kernel: .byte 1 207#else 208relocatable_kernel: .byte 0 209#endif 210pad2: .byte 0 211pad3: .word 0 212 213cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line, 214 #added with boot protocol 215 #version 2.06 216 217# End of setup header ##################################################### 218 219 .section ".inittext", "ax" 220start_of_setup: 221#ifdef SAFE_RESET_DISK_CONTROLLER 222# Reset the disk controller. 223 movw $0x0000, %ax # Reset disk controller 224 movb $0x80, %dl # All disks 225 int $0x13 226#endif 227 228# We will have entered with %cs = %ds+0x20, normalize %cs so 229# it is on par with the other segments. 230 pushw %ds 231 pushw $setup2 232 lretw 233 234setup2: 235# Force %es = %ds 236 movw %ds, %ax 237 movw %ax, %es 238 cld 239 240# Stack paranoia: align the stack and make sure it is good 241# for both 16- and 32-bit references. In particular, if we 242# were meant to have been using the full 16-bit segment, the 243# caller might have set %sp to zero, which breaks %esp-based 244# references. 245 andw $~3, %sp # dword align (might as well...) 246 jnz 1f 247 movw $0xfffc, %sp # Make sure we're not zero 2481: movzwl %sp, %esp # Clear upper half of %esp 249 sti 250 251# Check signature at end of setup 252 cmpl $0x5a5aaa55, setup_sig 253 jne setup_bad 254 255# Zero the bss 256 movw $__bss_start, %di 257 movw $_end+3, %cx 258 xorl %eax, %eax 259 subw %di, %cx 260 shrw $2, %cx 261 rep; stosl 262 263# Jump to C code (should not return) 264 calll main 265 266# Setup corrupt somehow... 267setup_bad: 268 movl $setup_corrupt, %eax 269 calll puts 270 # Fall through... 271 272 .globl die 273 .type die, @function 274die: 275 hlt 276 jmp die 277 278 .size die, .-die 279 280 .section ".initdata", "a" 281setup_corrupt: 282 .byte 7 283 .string "No setup signature found...\n" 284