/* * Copyright (C) 2009 Juergen Beisert, Pengutronix * * This code was inspired by the GRUB2 project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * */ /** * @file * @brief Loading the barebox image from a disk drive in LBA mode */ /** * @fn void real_start(void) * @brief A very simple and small loader to fetch all required sectors * from the boot media. */ .file "boot_hdisk.S" .code16 /* * These symbols are generated by the linker, because they need a * special layout. This layout is needed to be able to setup this * bootloader by patching the binary when it gets stored into the * master boot record. */ .extern indirect_sector_lba .extern boot_stack .extern start_pre_uboot .extern boot_disk .section .boot_code, "ax" .globl real_start .type real_start, @function real_start: xorw %ax, %ax /* set up %ds and %ss as offset from 0 */ movw %ax, %ds movw %ax, %ss /* set up the REAL stack */ movw $boot_stack, %sp sti /* we're safe again */ /* save drive reference first thing! */ movb %dl, boot_disk pushw %dx movw $notification_string, %si call output_message /* * This boot code only supports LBA. We fail here, if the BIOS * does not support LBA for the harddisk */ /* check if LBA is supported */ movb $0x41, %ah movw $0x55aa, %bx int $0x13 /* * %dl may have been clobbered by INT 13, AH=41H. * This happens, for example, with AST BIOS 1.04. */ popw %dx pushw %dx /* stop if no LBA support */ jc no_lba cmpw $0xaa55, %bx jne no_lba andw $1, %cx jz no_lba lba_mode: /* * Load the indirect sector. Its content is ready for use, * provided by the installer */ movw $indirect_sector_lba, %si movb $0x42, %ah int $0x13 jc no_lba /* error? Then die */ /* * Now loop through all valid entries in the indirect sector */ movw $indirect_area, %si load_loop: /* * Stop if this "Disk Address Packet Structure" is invalid * We call it invalid, if the size member is zero. If it is invalid * we are optimistic and calling the loaded image */ movw (%si), %ax cmpw $0x0000, %ax je start_main /* * Load this entry */ movb $0x42, %ah int $0x13 jc no_lba addw (%si), %si /* next entry */ cmpw $indirect_area + 512, %si jne load_loop /* * fall through to start u-boot. */ start_main: movw $jmp_string, %si call output_message jmp start_pre_uboot /* * die if there is no LBA support */ no_lba: movw $chs_string, %si call output_message hlt /* * message: write the string pointed to by %si * * WARNING: trashes %si, %ax, and %bx */ /* * Use BIOS "int 10H Function 0Eh" to write character in teletype mode * %ah = 0xe %al = character * %bh = page %bl = foreground color (graphics modes) */ 1: movw $0x0001, %bx movb $0xe, %ah int $0x10 /* display this char */ output_message: lodsb cmpb $0, %al jne 1b /* if not end of string, next char */ ret /* ---------------------------------------------------------------------- */ .section .boot_data notification_string: .asciz "BAREBOX " chs_string: .asciz "CHS " jmp_string: .asciz "JMP "