summaryrefslogtreecommitdiffstats
path: root/arch/x86/boot/boot_hdisk.S
diff options
context:
space:
mode:
authorJuergen Beisert <jbe@pengutronix.de>2010-01-12 11:15:41 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2010-01-14 10:06:16 +0100
commit7dcc15e8197e647abc80b1d3298a91edd45a8c2d (patch)
treef0bb5981a61c989ce37d40554971b9adc49e2b3e /arch/x86/boot/boot_hdisk.S
parent2bdd75bd02f3d214b285429be72b3a0eab4e9610 (diff)
downloadbarebox-7dcc15e8197e647abc80b1d3298a91edd45a8c2d.tar.gz
barebox-7dcc15e8197e647abc80b1d3298a91edd45a8c2d.tar.xz
Add functions to be able to boot with BIOSs help
These functions are special: They are running in the 16 bit real mode world to bring up barebox on an x86 box. Signed-off-by: Juergen Beisert <jbe@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/x86/boot/boot_hdisk.S')
-rw-r--r--arch/x86/boot/boot_hdisk.S176
1 files changed, 176 insertions, 0 deletions
diff --git a/arch/x86/boot/boot_hdisk.S b/arch/x86/boot/boot_hdisk.S
new file mode 100644
index 0000000000..40388e993d
--- /dev/null
+++ b/arch/x86/boot/boot_hdisk.S
@@ -0,0 +1,176 @@
+/*
+ * 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.
+ */
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+ .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 "
+
+#endif