blob: fc4c4d5c800eda80ca67fe6653c80d0f1a7a9488 [file] [log] [blame]
/*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
/**
* @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 "UBOOT2 "
chs_string: .asciz "CHS "
jmp_string: .asciz "JMP "