summaryrefslogtreecommitdiffstats
path: root/arch/x86/boot/boot_hdisk.S
blob: 40388e993ddd8da703ea11dc752e074add6a2871 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
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