1
/****************************************************************\
3
hdprefix.S Copyright (C) 2005 Per Dalgas Jakobsen
5
This code has been inspired/derived by the OSLoader by Vladislav Aleksandrov.
6
http://www.programmersheaven.com/zone5/cat469/40546.htm.
8
This software may be used and distributed according to the terms
9
of the GNU Public License (GPL), incorporated herein by reference.
11
hdprefix.S is loaded at 0x0000:0x7c00 by the bios-startup routines.
13
Actions performed by hdprefix:
14
1) Load the MBR to LOADSEG:0
15
2) Check which partition is active (or try first partition if none active)
16
3) Check wether LBA is supported.
18
3a1) Load PAYLOAD_SECTS sectors from chosen partition to LOADSEG:0
20
3b1) Load PAYLOAD_SECTS sectors from chosen partition to LOADSEG:0
21
4) Check loaded bootsector for BOOTMAGIC code.
22
5) Jump to payload LOADSEG:ENTRYPOINT.
24
Output with failure points (!#):
26
Loading (!1)partition #
27
Std. BIOS(!2) | Ext. BIOS(!3)
32
!1: Failed to load MBR with Int13,ah=2.
33
!2: Failed to load bootrecord+payload with Int13,ah=2.
34
!3: Failed to load bootrecord+payload with Int13,ah=42.
35
!4: Invalid BOOTMAGIC in loaded bootrecord.
36
!5: Jumping to payload.
38
\*****************************************************************/
42
.equ ENTRYPOINT, _start
44
.equ BOOTMAGIC, 0x0aa55
46
.equ partition_table, 0x1be
47
.equ partition_rec_size, 0x10
49
.equ boot_ind, 0 /* 80h=active */
51
.equ start_sector, 2 /* bits 0-5 */
52
.equ start_cyl, 3 /* bits 8,9 in bits 6,7 of sector */
53
.equ os_ind, 4 /* os indicator */
55
.equ end_sector, 6 /* bits 0-5 */
56
.equ end_track, 7 /* bits 8,9 in bits 6,7 of sector */
57
.equ nsect, 8 /* sectors preceding partition */
58
.equ lenght, 0x0c /* length of partition in sectors */
60
/-------------------------------------------------------------
64
.section ".prefix", "ax", @progbits
68
jmp $BOOTSEG,$_go /* reload cs:ip */
71
/****************************************************************/
72
/* support routines. */
73
/*--------------------------------------------------------------*/
77
movw $_failed_msg_end-_failed_msg,%cx
81
/* stop execution - should probably have option to auto-reboot after delay. */
85
/*--------------------------------------------------------------*/
87
/* cx = count, ds:si = string. */
96
/*--------------------------------------------------------------*/
104
/*--------------------------------------------------------------*/
113
/*--------------------------------------------------------------*/
116
movb $0x0e,%ah /* write char, tty mode */
117
movw $0x0007,%bx /* page 0, attribute 7 (normal) */
123
rolw $4,%dx /* rotate so that lowest 4 bits are used */
124
movb $0x0f,%al /* mask for nibble */
126
addb $0x90,%al /* convert al to ascii hex (four instructions) */
133
/****************************************************************/
141
movw $0x2000,%sp /* good large stack. */
147
movw $_load_msg_end-_load_msg,%cx
151
/*--- load MBR so we can use its partition table. ---*/
153
movw $0x0001,%cx /* chs: 0,0,1 */
156
movw $0x0201,%ax /* read one sector (MBR) */
160
/*--- find the active partition ---*/
161
movw $_part_msg_end-_part_msg,%cx
165
movw $partition_table,%di
168
cmpb $0x80,%es:(%di) /* active? */
170
addw $partition_rec_size,%di
173
/*- no partitions marked active - use 1. partition. */
174
movw $partition_table,%di
178
movb $'5',%al /* convert to ascii */
183
/*--- check for lba support ---*/
194
/*--- use lba bios calls to read sectors ---*/
196
movw $_extbios_msg_end-_extbios_msg,%cx
197
movw $_extbios_msg,%si
200
movw %es:nsect(%di),%ax
201
movw %ax,_bios_lba_low
202
movw %es:nsect+2(%di),%ax
203
movw %ax,_bios_lba_high
205
movw $_disk_address_packet,%si
206
movw $0x4200,%ax /* read */
211
/*--- use standard bios calls to read sectors ---*/
213
movw $_stdbios_msg_end-_stdbios_msg,%cx
214
movw $_stdbios_msg,%si
217
movw _disk_address_packet+2(,1),%ax /* only low byte is used. */
219
movw %es:start_sector(%di),%cx
220
movb %es:start_head(%di),%dh
227
movw $_boot_msg_end-_boot_msg,%cx
231
/* check if it has a valid bootrecord. */
232
cmpw $BOOTMAGIC,%es:510(,1)
236
/* call the payload. */
237
pushl $0 /* No parameters to preserve for exit path */
238
pushw $0 /* Use prefix exit path mechanism */
239
jmp $LOADSEG,$ENTRYPOINT
241
.section ".text16", "ax", @progbits
244
int $0x19 /* should try to boot machine */
245
.globl prefix_exit_end
250
/*--------------------------------------------------------------*/
252
_load_msg: .ascii "Loading "
254
_part_msg: .ascii "partition "
256
_boot_msg: .ascii "Booting..."
258
_stdbios_msg: .ascii "Std. BIOS\r\n"
260
_extbios_msg: .ascii "Ext. BIOS\r\n"
262
_failed_msg: .ascii "FAILED!!!\r\n"
266
/*--------------------------------------------------------------*/
268
_disk_address_packet:
269
.byte 0x10 /* size of the packet */
270
.byte 0 /* reserved */
271
.word _verbatim_size_sct /* number of sectors to read */
272
.word 0x0000 /* offset */
273
.word LOADSEG /* segment of buffer */
274
_bios_lba_low: .word 0
275
_bios_lba_high: .word 0
284
/*--- Partition table ------------------------------------------*/
292
/*--- Magic code -----------------------------------------------*/
296
/*** END ********************************************************/