/*1* header.S2*3* Copyright (C) 1991, 1992 Linus Torvalds4*5* Based on bootsect.S and setup.S6* modified by more people than can be counted7*8* Rewritten as a common file by H. Peter Anvin (Apr 2007)9*10* BIG FAT NOTE: We're in real mode using 64k segments. Therefore segment11* addresses must be multiplied by 16 to obtain their respective linear12* addresses. To avoid confusion, linear addresses are written using leading13* hex while segment addresses are written as segment:offset.14*15*/1617#include <asm/segment.h>18#include <generated/utsrelease.h>19#include <asm/boot.h>20#include <asm/e820.h>21#include <asm/page_types.h>22#include <asm/setup.h>23#include "boot.h"24#include "voffset.h"25#include "zoffset.h"2627BOOTSEG = 0x07C0 /* original address of boot-sector */28SYSSEG = 0x1000 /* historical load address >> 4 */2930#ifndef SVGA_MODE31#define SVGA_MODE ASK_VGA32#endif3334#ifndef RAMDISK35#define RAMDISK 036#endif3738#ifndef ROOT_RDONLY39#define ROOT_RDONLY 140#endif4142.code1643.section ".bstext", "ax"4445.global bootsect_start46bootsect_start:4748# Normalize the start address49ljmp $BOOTSEG, $start25051start2:52movw %cs, %ax53movw %ax, %ds54movw %ax, %es55movw %ax, %ss56xorw %sp, %sp57sti58cld5960movw $bugger_off_msg, %si6162msg_loop:63lodsb64andb %al, %al65jz bs_die66movb $0xe, %ah67movw $7, %bx68int $0x1069jmp msg_loop7071bs_die:72# Allow the user to press a key, then reboot73xorw %ax, %ax74int $0x1675int $0x197677# int 0x19 should never return. In case it does anyway,78# invoke the BIOS reset code...79ljmp $0xf000,$0xfff08081.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 0888990# Kernel attributes; used by setup. This is part 1 of the91# header, from the old boot sector.9293.section ".header", "a"94.globl hdr95hdr:96setup_sects: .byte 0 /* Filled in by build.c */97root_flags: .word ROOT_RDONLY98syssize: .long 0 /* Filled in by build.c */99ram_size: .word 0 /* Obsolete */100vid_mode: .word SVGA_MODE101root_dev: .word 0 /* Filled in by build.c */102boot_flag: .word 0xAA55103104# offset 512, entry point105106.globl _start107_start:108# Explicitly enter this as bytes, or the assembler109# tries to generate a 3-byte jump here, which causes110# everything else to push off to the wrong offset.111.byte 0xeb # short (2-byte) jump112.byte start_of_setup-1f1131:114115# Part 2 of the header, from the old setup.S116117.ascii "HdrS" # header signature118.word 0x020a # header version number (>= 0x0105)119# or else old loadlin-1.5 will fail)120.globl realmode_swtch121realmode_swtch: .word 0, 0 # default_switch, SETUPSEG122start_sys_seg: .word SYSSEG # obsolete and meaningless, but just123# in case something decided to "use" it124.word kernel_version-512 # pointing to kernel version string125# above section of header is compatible126# with loadlin-1.5 (header v1.5). Don't127# change it.128129type_of_loader: .byte 0 # 0 means ancient bootloader, newer130# bootloaders know to change this.131# See Documentation/i386/boot.txt for132# assigned ids133134# flags, unused bits must be zero (RFU) bit within loadflags135loadflags:136LOADED_HIGH = 1 # If set, the kernel is loaded high137CAN_USE_HEAP = 0x80 # If set, the loader also has set138# heap_end_ptr to tell how much139# space behind setup.S can be used for140# heap purposes.141# Only the loader knows what is free142.byte LOADED_HIGH143144setup_move_size: .word 0x8000 # size to move, when setup is not145# loaded at 0x90000. We will move setup146# to 0x90000 then just before jumping147# into the kernel. However, only the148# loader knows how much data behind149# us also needs to be loaded.150151code32_start: # here loaders can put a different152# start address for 32-bit code.153.long 0x100000 # 0x100000 = default for big kernel154155ramdisk_image: .long 0 # address of loaded ramdisk image156# Here the loader puts the 32-bit157# address where it loaded the image.158# This only will be read by the kernel.159160ramdisk_size: .long 0 # its size in bytes161162bootsect_kludge:163.long 0 # obsolete164165heap_end_ptr: .word _end+STACK_SIZE-512166# (Header version 0x0201 or later)167# space from here (exclusive) down to168# end of setup code can be used by setup169# for local heap purposes.170171ext_loader_ver:172.byte 0 # Extended boot loader version173ext_loader_type:174.byte 0 # Extended boot loader type175176cmd_line_ptr: .long 0 # (Header version 0x0202 or later)177# If nonzero, a 32-bit pointer178# to the kernel command line.179# The command line should be180# located between the start of181# setup and the end of low182# memory (0xa0000), or it may183# get overwritten before it184# gets read. If this field is185# used, there is no longer186# anything magical about the187# 0x90000 segment; the setup188# can be located anywhere in189# low memory 0x10000 or higher.190191ramdisk_max: .long 0x7fffffff192# (Header version 0x0203 or later)193# The highest safe address for194# the contents of an initrd195# The current kernel allows up to 4 GB,196# but leave it at 2 GB to avoid197# possible bootloader bugs.198199kernel_alignment: .long CONFIG_PHYSICAL_ALIGN #physical addr alignment200#required for protected mode201#kernel202#ifdef CONFIG_RELOCATABLE203relocatable_kernel: .byte 1204#else205relocatable_kernel: .byte 0206#endif207min_alignment: .byte MIN_KERNEL_ALIGN_LG2 # minimum alignment208pad3: .word 0209210cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line,211#added with boot protocol212#version 2.06213214hardware_subarch: .long 0 # subarchitecture, added with 2.07215# default to 0 for normal x86 PC216217hardware_subarch_data: .quad 0218219payload_offset: .long ZO_input_data220payload_length: .long ZO_z_input_len221222setup_data: .quad 0 # 64-bit physical pointer to223# single linked list of224# struct setup_data225226pref_address: .quad LOAD_PHYSICAL_ADDR # preferred load addr227228#define ZO_INIT_SIZE (ZO__end - ZO_startup_32 + ZO_z_extract_offset)229#define VO_INIT_SIZE (VO__end - VO__text)230#if ZO_INIT_SIZE > VO_INIT_SIZE231#define INIT_SIZE ZO_INIT_SIZE232#else233#define INIT_SIZE VO_INIT_SIZE234#endif235init_size: .long INIT_SIZE # kernel initialization size236237# End of setup header #####################################################238239.section ".entrytext", "ax"240start_of_setup:241#ifdef SAFE_RESET_DISK_CONTROLLER242# Reset the disk controller.243movw $0x0000, %ax # Reset disk controller244movb $0x80, %dl # All disks245int $0x13246#endif247248# Force %es = %ds249movw %ds, %ax250movw %ax, %es251cld252253# Apparently some ancient versions of LILO invoked the kernel with %ss != %ds,254# which happened to work by accident for the old code. Recalculate the stack255# pointer if %ss is invalid. Otherwise leave it alone, LOADLIN sets up the256# stack behind its own code, so we can't blindly put it directly past the heap.257258movw %ss, %dx259cmpw %ax, %dx # %ds == %ss?260movw %sp, %dx261je 2f # -> assume %sp is reasonably set262263# Invalid %ss, make up a new stack264movw $_end, %dx265testb $CAN_USE_HEAP, loadflags266jz 1f267movw heap_end_ptr, %dx2681: addw $STACK_SIZE, %dx269jnc 2f270xorw %dx, %dx # Prevent wraparound2712722: # Now %dx should point to the end of our stack space273andw $~3, %dx # dword align (might as well...)274jnz 3f275movw $0xfffc, %dx # Make sure we're not zero2763: movw %ax, %ss277movzwl %dx, %esp # Clear upper half of %esp278sti # Now we should have a working stack279280# We will have entered with %cs = %ds+0x20, normalize %cs so281# it is on par with the other segments.282pushw %ds283pushw $6f284lretw2856:286287# Check signature at end of setup288cmpl $0x5a5aaa55, setup_sig289jne setup_bad290291# Zero the bss292movw $__bss_start, %di293movw $_end+3, %cx294xorl %eax, %eax295subw %di, %cx296shrw $2, %cx297rep; stosl298299# Jump to C code (should not return)300calll main301302# Setup corrupt somehow...303setup_bad:304movl $setup_corrupt, %eax305calll puts306# Fall through...307308.globl die309.type die, @function310die:311hlt312jmp die313314.size die, .-die315316.section ".initdata", "a"317setup_corrupt:318.byte 7319.string "No setup signature found...\n"320321322