171 lines
3.5 KiB
ArmAsm
171 lines
3.5 KiB
ArmAsm
/*
|
|
* 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 "UBOOT2 "
|
|
chs_string: .asciz "CHS "
|
|
jmp_string: .asciz "JMP "
|
|
|