2N/A * GRUB -- GRand Unified Bootloader 2N/A * Copyright (C) 1999,2000,2001,2002,2005,2006,2007,2008,2009 Free Software Foundation, Inc. 2N/A * GRUB is free software: you can redistribute it and/or modify 2N/A * it under the terms of the GNU General Public License as published by 2N/A * the Free Software Foundation, either version 3 of the License, or 2N/A * (at your option) any later version. 2N/A * GRUB is distributed in the hope that it will be useful, 2N/A * but WITHOUT ANY WARRANTY; without even the implied warranty of 2N/A * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 2N/A * GNU General Public License for more details. 2N/A * You should have received a copy of the GNU General Public License 2N/A * defines for the code go here 2N/A /* Print message string */ 2N/A /* Tell GAS to generate 16-bit instructions so that this code works 2N/A * _start is loaded at 0x7c00 and is jumped to with CS:IP 0:0x7c00 2N/A * Beginning of the sector is compatible with the FAT/HPFS BIOS 2N/A nop /* do I care about this ??? */ 2N/A * This space is for the BIOS parameter block!!!! Don't change 2N/A * the first jump, nor start the code anywhere but right after 2N/A * End of BIOS parameter block. 2N/A .
byte 0xff /* the disk to load kernel from */ 2N/A /* 0xff means use the boot drive */ 2N/A cli /* we're not safe here! */ 2N/A * This is a workaround for buggy BIOSes which don't pass boot 2N/A * drive correctly. If GRUB is installed into a HDD, check if 2N/A * DL is masked correctly. If not, assume that the BIOS passed 2N/A * a bogus value and set DL to 0x80, since this is the only 2N/A * possible boot drive. If GRUB is installed into a floppy, 2N/A * this does nothing (only jump). 2N/A jmp 3f /* grub-setup may overwrite this jump */ 2N/A /* Ignore %dl different from 0-0x0f and 0x80-0x8f. */ 2N/A * ljmp to the next instruction because some bogus BIOSes 2N/A * jump to 07C0:0000 instead of 0000:7C00. 2N/A /* set up %ds and %ss as offset from 0 */ 2N/A /* set up the REAL stack */ 2N/A * Check if we have a forced disk reference here 2N/A /* save drive reference first thing! */ 2N/A /* print a notification message on the screen */ 2N/A /* set %si to the disk address packet */ 2N/A /* check if LBA is supported */ 2N/A * %dl may have been clobbered by INT 13, AH=41H. 2N/A * This happens, for example, with AST BIOS 1.04. 2N/A /* use CHS if fails */ 2N/A /* set the mode to non-zero */ 2N/A /* the size and the reserved byte */ 2N/A /* the absolute address */ 2N/A /* the segment of buffer address */ 2N/A * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory 2N/A * Call with %ah = 0x42 2N/A * %dl = drive number 2N/A * %ds:%si = segment:offset of disk address packet 2N/A * %al = 0x0 on success; err code on failure 2N/A /* LBA read is not supported, so fallback to CHS. */ 2N/A * Determine the hard disk geometry from the BIOS! 2N/A * We do this first, so that LS-120 IDE floppies work correctly. 2N/A * The call failed, so maybe use the floppy probe instead. 2N/A /* Nope, we definitely have a hard disk, and we're screwed. */ 2N/A /* set the mode to zero */ 2N/A /* save number of heads */ 2N/A /* save number of cylinders */ 2N/A /* save number of sectors */ 2N/A /* load logical sector start (top half) */ 2N/A /* load logical sector start (bottom half) */ 2N/A /* divide by number of sectors */ 2N/A /* save sector start */ 2N/A /* do we need too many cylinders? */ 2N/A /* normalize sector start (1-based) */ 2N/A /* low bits of cylinder start */ 2N/A /* high bits of cylinder start */ 2N/A /* save head start */ 2N/A * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory 2N/A * Call with %ah = 0x2 2N/A * %al = number of sectors 2N/A * %cl = sector (bits 6-7 are high bits of "cylinder") 2N/A * %dl = drive (0x80 for hard disk, 0x0 for floppy disk) 2N/A * %es:%bx = segment:offset of buffer 2N/A * %al = 0x0 on success; err code on failure 2N/A xorw %
bx, %
bx /* %bx = 0, put it at 0 in the segment */ 2N/A * We need to save %cx and %si because the startup code in 2N/A * kernel uses them without initializing them. 2N/A/* END OF MAIN LOOP */ 2N/A * BIOS Geometry translation error (past the end of the disk geometry!). 2N/A * Read error on the disk. 2N/A/* go here when you need to stop the machine hard after an error condition */ 2N/A /* tell the BIOS a boot failure, which may result in no effect */ 2N/A * message: write the string pointed to by %si 2N/A * WARNING: trashes %si, %ax, and %bx 2N/A * Use BIOS "int 10H Function 0Eh" to write character in teletype mode 2N/A * %ah = 0xe %al = character 2N/A * %bh = page %bl = foreground color (graphics modes) 2N/A int $
0x10 /* display a byte */ 2N/A jne 1b
/* if not end of string, jmp to display */ 2N/A * Windows NT breaks compatibility by embedding a magic 2N/A * This is where an MBR would go if on a hard disk. The code 2N/A * here isn't even referenced unless we're on a floppy. Kinda 2N/A * Perform floppy probe. 2N/A /* reset floppy controller INT 13h AH=0 */ 2N/A /* if number of sectors is 0, display error and die */ 2N/A * Floppy disk probe failure. 2N/A /* if error, jump to "LOCAL(probe_loop)" */ 2N/A /* %cl is already the correct value! */ 2N/A/* the last 2 bytes in the sector 0 contain the signature */