2a6dc8e986fc0bf3f1dd279ed270f31492a3c11c
[people/sha0/gpxe.git] / src / arch / i386 / prefix / hdprefix.S
1 #warning "Needs fixing up for gpxe"
2
3 #if 0
4
5 /****************************************************************\
6
7 hdprefix.S Copyright (C) 2005 Per Dalgas Jakobsen
8
9 This code has been inspired/derived by the OSLoader by Vladislav Aleksandrov.
10 http://www.programmersheaven.com/zone5/cat469/40546.htm.
11
12 This software may be used and distributed according to the terms
13 of the GNU Public License (GPL), incorporated herein by reference.
14
15 hdprefix.S is loaded at 0x0000:0x7c00 by the bios-startup routines.
16
17 Actions performed by hdprefix:
18 1) Load the MBR to LOADSEG:0
19 2) Check which partition is active (or try first partition if none active)
20 3) Check wether LBA is supported.
21 3a) LBA
22 3a1) Load PAYLOAD_SECTS sectors from chosen partition to LOADSEG:0
23 3b) CHS (standard)
24 3b1) Load PAYLOAD_SECTS sectors from chosen partition to LOADSEG:0
25 4) Check loaded bootsector for BOOTMAGIC code.
26 5) Jump to payload LOADSEG:ENTRYPOINT.
27
28 Output with failure points (!#):
29 ---
30 Loading (!1)partition #
31 Std. BIOS(!2) | Ext. BIOS(!3)
32 Booting...(!4)
33 (!5)
34 ---
35
36 !1: Failed to load MBR with Int13,ah=2.
37 !2: Failed to load bootrecord+payload with Int13,ah=2.
38 !3: Failed to load bootrecord+payload with Int13,ah=42.
39 !4: Invalid BOOTMAGIC in loaded bootrecord.
40 !5: Jumping to payload.
41
42 \*****************************************************************/
43  
44 .equ    BOOTSEG,        0x07c0
45 .equ    LOADSEG,        0x1000
46 .equ    ENTRYPOINT,     _start
47
48 .equ    BOOTMAGIC,      0x0aa55
49
50 .equ    partition_table,        0x1be
51 .equ    partition_rec_size,     0x10
52
53 .equ    boot_ind,       0       /* 80h=active */
54 .equ    start_head,     1
55 .equ    start_sector,   2       /* bits 0-5 */
56 .equ    start_cyl,      3       /* bits 8,9 in bits 6,7 of sector */
57 .equ    os_ind,         4       /* os indicator */
58 .equ    end_head,       5
59 .equ    end_sector,     6       /* bits 0-5 */
60 .equ    end_track,      7       /* bits 8,9 in bits 6,7 of sector */
61 .equ    nsect,          8       /* sectors preceding partition */
62 .equ    lenght,         0x0c    /* length of partition in sectors */
63
64 /-------------------------------------------------------------
65
66         .arch i386
67         .text
68         .section ".prefix", "ax", @progbits
69         .code16
70          
71 bootstart:
72         jmp     $BOOTSEG,$_go           /* reload cs:ip */
73
74
75 /****************************************************************/
76 /* support routines.                                            */
77 /*--------------------------------------------------------------*/
78 _failed:
79         movw    $BOOTSEG,%ax
80         movw    %ax,%ds
81         movw    $_failed_msg_end-_failed_msg,%cx
82         movw    $_failed_msg,%si
83         call    _print_str
84
85         /* stop execution - should probably have option to auto-reboot after delay. */
86 _failed_loop:
87         jmp     _failed_loop
88
89 /*--------------------------------------------------------------*/
90 _print_str:
91         /* cx = count, ds:si = string. */
92         movw    $0x0007,%bx
93         movb    $0x0e,%ah
94 _print_loop:
95         lodsb
96         int     $0x10
97         loop    _print_loop
98         ret
99
100 /*--------------------------------------------------------------*/                      
101 _print_char:
102         /* al = char. */
103         movw    $0x0007,%bx
104         movb    $0x0e,%ah
105         int     $0x10
106         ret
107
108 /*--------------------------------------------------------------*/
109 _print_nl:
110         /* - */
111         movb    $0x0d,%al
112         call    _print_char
113         movb    $0x0a,%al
114         call    _print_char
115         ret
116
117 /*--------------------------------------------------------------*/
118 _print_hex:
119         /* dx = value */
120         movb    $0x0e,%ah       /* write char, tty mode */
121         movw    $0x0007,%bx     /* page 0, attribute 7 (normal) */
122         call    _print_digit
123         call    _print_digit
124         call    _print_digit
125         /* fall through */
126 _print_digit:
127         rolw    $4,%dx          /* rotate so that lowest 4 bits are used */
128         movb    $0x0f,%al       /* mask for nibble */
129         andb    %dl,%al
130         addb    $0x90,%al       /* convert al to ascii hex (four instructions) */
131         daa
132         adcb    $0x40,%al
133         daa
134         int     $0x10
135         ret
136
137 /****************************************************************/
138
139
140 _go:
141         cli
142         movw    $BOOTSEG,%ax
143         movw    %ax,%ds
144         movw    %ax,%ss
145         movw    $0x2000,%sp     /* good large stack. */
146         sti
147         cld
148         movw    $LOADSEG,%ax
149         movw    %ax,%es
150
151         movw    $_load_msg_end-_load_msg,%cx
152         movw    $_load_msg,%si
153         call    _print_str
154
155 /*--- load MBR so we can use its partition table. ---*/
156         xorw    %bx,%bx
157         movw    $0x0001,%cx     /* chs: 0,0,1 */
158         movb    %bh,%dh         /* - */
159         movb    $0x80,%dl
160         movw    $0x0201,%ax     /* read one sector (MBR) */
161         int     $0x13
162         jc      _failed
163
164 /*--- find the active partition ---*/
165         movw    $_part_msg_end-_part_msg,%cx
166         movw    $_part_msg,%si
167         call    _print_str
168
169         movw    $partition_table,%di
170         movw    $4,%cx
171 _partition_loop:
172         cmpb    $0x80,%es:(%di)         /* active? */
173         je      _partition_found
174         addw    $partition_rec_size,%di
175         loop    _partition_loop
176
177         /*- no partitions marked active - use 1. partition. */
178         movw    $partition_table,%di
179         movw    $4,%cx
180
181 _partition_found:
182         movb    $'5',%al                        /* convert to ascii */
183         subb    %cl,%al
184         call    _print_char
185         call    _print_nl
186
187 /*--- check for lba support ---*/
188         movw    $0x55aa,%bx
189         movb    $0x80,%dl
190         movb    $0x41,%ah
191         int     $0x13
192         jc      __bios
193         cmpw    $0x0aa55,%bx
194         jnz     __bios
195         testb   $1,%cl
196         jz      __bios
197
198 /*--- use lba bios calls to read sectors ---*/
199 _lba:
200         movw    $_extbios_msg_end-_extbios_msg,%cx
201         movw    $_extbios_msg,%si
202         call    _print_str
203
204         movw    %es:nsect(%di),%ax
205         movw    %ax,_bios_lba_low
206         movw    %es:nsect+2(%di),%ax
207         movw    %ax,_bios_lba_high
208         movb    $0x80,%dl
209         movw    $_disk_address_packet,%si
210         movw    $0x4200,%ax     /* read */
211         int     $0x13
212         jc      _failed
213         jmp     __loaded
214
215 /*--- use standard bios calls to read sectors ---*/
216 __bios:
217         movw    $_stdbios_msg_end-_stdbios_msg,%cx
218         movw    $_stdbios_msg,%si
219         call    _print_str
220
221         movw    _disk_address_packet+2(,1),%ax  /* only low byte is used. */
222         xorw    %bx,%bx
223         movw    %es:start_sector(%di),%cx
224         movb    %es:start_head(%di),%dh
225         movb    $0x80,%dl
226         movb    $0x02,%ah
227         int     $0x13
228         jc      _failed
229
230 __loaded:
231         movw    $_boot_msg_end-_boot_msg,%cx
232         movw    $_boot_msg,%si
233         call    _print_str
234
235         /* check if it has a valid bootrecord. */
236         cmpw    $BOOTMAGIC,%es:510(,1)
237         jne     _failed
238         call    _print_nl
239
240         /* call the payload. */
241         pushl   $0              /* No parameters to preserve for exit path */
242         pushw   $0              /* Use prefix exit path mechanism */
243         jmp     $LOADSEG,$ENTRYPOINT
244
245         .section ".text16", "ax", @progbits
246         .globl  prefix_exit
247 prefix_exit:
248         int     $0x19           /* should try to boot machine */
249         .globl  prefix_exit_end
250 prefix_exit_end:
251         .previous
252          
253
254 /*--------------------------------------------------------------*/
255
256 _load_msg:      .ascii  "Loading "
257 _load_msg_end:
258 _part_msg:      .ascii  "partition "
259 _part_msg_end:
260 _boot_msg:      .ascii  "Booting..."
261 _boot_msg_end:
262 _stdbios_msg:   .ascii  "Std. BIOS\r\n"
263 _stdbios_msg_end:
264 _extbios_msg:   .ascii  "Ext. BIOS\r\n"
265 _extbios_msg_end:
266 _failed_msg:    .ascii  "FAILED!!!\r\n"
267 _failed_msg_end:
268
269
270 /*--------------------------------------------------------------*/
271
272 _disk_address_packet:
273                 .byte   0x10            /* size of the packet */
274                 .byte   0               /* reserved */
275                 .word   _verbatim_size_sct      /* number of sectors to read */
276                 .word   0x0000          /* offset */
277                 .word   LOADSEG         /* segment of buffer */
278 _bios_lba_low:  .word   0
279 _bios_lba_high: .word   0
280                 .word   0
281                 .word   0
282
283         .rept 32
284                 .byte   0
285         .endr
286
287
288 /*--- Partition table ------------------------------------------*/
289
290         .org 446, 0
291         .rept 64
292                 .byte   0
293         .endr
294
295
296 /*--- Magic code -----------------------------------------------*/
297         .org 510, 0
298                 .word BOOTMAGIC
299
300 /*** END ********************************************************/
301 #endif