4 * Automatically retry all BIOS reads 0x80<->0x81 (and if (drive&0x80) drive^=1; in genral)
9 http://cvs.sourceforge.net/viewcvs.py/*checkout*/surprise/surprise/misc/int13sniff.S
12 /* !!! All defines below must be COMMENTED-OUT !
13 * !!! Define to value 0 has no effect.
16 /* Reduce size by omitting DOS-boot header signature to fit in 512 bytes.
17 * Cylinder 0 is requierd, sectors per track == 63 assumed!
18 * This constant is counted from 0 !!!
20 #define BACKUP_SECTOR 63
22 /* Reduce size by omitting DOS-boot header signature to fit in 512 bytes.
24 #define STRIP_BOOT_HEADER 1
26 /* Maintainers: Disable .org macroinstructions: ONLY FOR compilation tuning!
27 * - image produced doen't have any functionality!
31 /* Internal defines */
32 #define MEM_KBYTES 0x413 /* BIOS variable */
34 #define MAX_BOOT_SIZE_100 0xb6 /* LILO: leave some space for NT's and DR DOS' dirty */
35 #define MAX_BOOT_SIZE (MAX_BOOT_SIZE_100+0x100)
41 movw $0x0E00 | \char,%ax
49 #define MYORG(offset) .org (offset) + START /* "+ START" MUST be on the end of line - WHY?!? */
72 #define PUSHALL_SIZE (7*2)
73 #define PUSHALL_SI ((1/*%bp*/+1/*%di*/)*2)
75 .macro CallJumpVector0x13
76 pushf /* create 'lret' stack by this pushf... */
77 pushw %cs /* ...this segment... */
78 call JumpVector0x13 /* ...and this return address */
83 /* Code starts here */
84 /********************/
94 cli /* just a paranoia, shouldn't be needed */
95 jmp InitRawStack /* We don't want to have 0x90 on offset 2 (one of recognization rules by DOS) */
98 .macro places offset length string
99 .org (\offset) + START
101 .org (\offset) + (\length) + START /* we can't check whether it isn't too short :-( */
103 .macro placex offset length bytes
104 .org (\offset) + START
106 .org (\offset) + (\length) + START /* we can't check whether it isn't too short :-( */
109 /* We rather supply empty (=zeroed) FAT filesystem table
111 #ifndef STRIP_BOOT_HEADER
112 places 0x03,8,"BIOSRAID" /* OEM ID */
113 placex 0x43,3,"0x5E,0x81,0xA2" /* Volume Serial Number: 5E81A2?? as "SERIAL??" */
114 placex 0x43+3,1,BACKUP_SECTOR /* Volume Serial Number: 5E81A23F as "SERIAL??" */
115 places 0x47,11,"BIOSauRAID\0" /* Volume Label */
116 places 0x52,8,"BootOnly" /* Filesystem ID */
118 places 0x03,8,"BIOSRAI2" /* OEM ID */
119 placex 0x03+8,1,BACKUP_SECTOR /* Sanity checked by: biosautoraid.pl */
120 placex 0x03+9,1,MAX_BOOT_SIZE_100 /* Sanity checked by: biosautoraid.pl */
124 #ifndef STRIP_BOOT_HEADER
133 ljmp $0x7C0/*segment*/ , $InitContinue7C0-START/*offset*/
140 /* move to top memory */
141 xorw %dx,%dx /* DX=null */
143 movw %ds:MEM_KBYTES,%ax
144 decw %ax /* Allocation size: 1KB */
145 movw %ax,%ds:MEM_KBYTES
149 xorw %di,%di /* buffer=ES:DI */
155 movw $InitContinueTop-START,%ax
160 movw $TrailNL_Msg-START,%si
161 jmp PrintString_noPref
163 /* String is given in SI, returns updated SI */
175 movw $PrintString_loop-START,%bx /* from now do just 'ret' to close the loop */
179 /* Character is given in AL
180 * Preserves: DS, ES, SI, DI
181 * Destroys: AX (even AL!), BX, CX, DX
182 * DS is sometimes left preserved, sometimes set to DS=CS
185 movb $0x0E,%ah /* print character */
202 /* Main initialization */
203 /***********************/
204 /* DS invalid, ES==CS */
211 movw $1*1024,%sp /* Allocated 1 KB */
214 movw $HelloMsg-START,%si
217 /* now install our SniffFunction0x13 sniffer */
224 movw $OrigVector0x13-START,%di
226 movw $SniffFunction0x13-START,%ax
231 popw %di /* = $0x13*4 */
233 popw %es /* = null */
234 stosw /* $SniffFunction0x13-START */
238 movw $0x18*4,%di /* ROM basic - failed boot */
239 movw $SniffFunction0x18-START,%ax
245 /* we WANT DS left with 0x0000 */
246 /* we WANT ES left with 0x0000 */
248 /* and give the system control to disk=0x80/masterboot */
249 movw $0x0201,%ax /* READ16 1 sector */
250 movw $0x7C00,%bx /* buffer=ES:BX= 0x0000:0x7C00 */
252 pushw %bx /* BX/DS on stack for later 'lret', S=2, prepared for far ret */
253 /* Interface to retry-capable INT13, set everything except CX */
254 /* function may destroy DS value! */
256 /* These two numbers get remapped to: BACKUP_SECTOR */
257 movw $0x0080,%dx /* Head 0, Drive 0x80 */
258 movw $0x0001,%cx /* Cylinder 0, Sector 1 */
261 pushw %dx /* save drive for resetting the controller */
262 movw $SF13_02_Err_Msg-START,%si
264 movb $0x00,%ah /* reset controller - FDC or HDC */
265 popw %dx /* restore the drive */
270 cmpw $0xAA55,%es:(0x7C00+0x1FE) /* 0x55,0xAA */
271 movw $BadSignatureMsg-START,%si
273 cli /* IMPORTANT: Boot sectors must be run with CLI! */
274 lret /* lret to 0x0000:0x7C00 */
277 movw $Interrupt0x18Msg-START,%si /* %ds gets fixed in PrintFatal */
285 /**************************************************************/
286 /* Section for INT13 sniffing */
287 /* THIS point may start to be after 0x200 boundary */
288 /**************************************************************/
291 cmpb $0x41,%ah /* presence32 */
292 jne JumpVector0x13popa
294 jne JumpVector0x13popa
302 incw %sp /* trash discarded */
304 incw %sp /* original %ax discarded */
307 .byte 0xEA /* ljmp */
313 pushw %dx /* original %dx */
314 pushw %ax /* original %ax */
315 pushw %ax /* trash */
331 cmpb $0x02,%ah /* read16 */
349 movw $SF13_02_Err_Msg-START,%si
354 jz SF13_leave /* just a floppy? */
356 jnz SF13_leave /* 0x82+ disk? It may be correct unsuccessful read. */
359 xorb $0x01,/*%dl:*/ %ss:2/*%bp*/+2/*%bp*/+2/*%di*/+2/*%si*/(%bp)
360 SF13_do02_retry_popw_bp:
365 * as we must hide ourselves to let read GRUB itself frmo the masterboot.
369 jz SF13_leave /* just a floppy? */
371 jnz SF13_leave /* 0x82+ disk? It may be correct unsuccessful read. */
372 cmpw $0x0001,%cx /* Cylinder 0, Sector 1 ? */
374 cmpb $0x00,%dh /* Head 0 ? */
376 movb $BACKUP_SECTOR/63,%dh
377 movw $1+(BACKUP_SECTOR%63),%cx
388 andb $0xFE,%ss:2/*%bp*/+PUSHALL_SIZE+2/*%ds*/+2/*trash*/+2/*orig-%ax*/+2/*orig-%dx*/+4/*ret-seg:offs*/(%bp) /* flags; clear CF */
395 movb /*%al:*/ %ss:2/*%bp*/+2/*%bp*/+2/*%di*/+2/*%si*/+2/*%dx*/+2/*%cx*/+2/*%bx*/(%bp),%al /* count */
396 movw /*%cx:*/ %ss:2/*%bp*/+2/*%bp*/+2/*%di*/+2/*%si*/+2/*%dx*/(%bp),%cx /* cylinder, sector */
397 cmpb $BACKUP_SECTOR/63,/*%dh:*/ %ss:2/*%bp*/+2/*%bp*/+2/*%di*/+2/*%si*/+1/*%dl*/(%bp) /* head */
400 SF13_leave_zero_loop:
403 cmpw $1+(BACKUP_SECTOR%63),%cx
404 je SF13_leave_zero_found
407 decb %al /* --count */
408 jmp SF13_leave_zero_loop
410 SF13_leave_zero_found:
421 incw %sp /* trash discarded */
423 incw %sp /* original %ax discarded */
428 popw %ax /* return address */
431 movw %ax,%ss:2/*%bp*/+PUSHALL_SIZE+2/*%ds*/(%bp) /* store %ax to 'trash' */
432 movw %ss:2/*%bp*/+PUSHALL_SIZE+2/*%ds*/+2/*trash*/(%bp),%ax /* restore original %ax */
433 movw %ax,%ss:2/*%bp*/+2/*%bp*/+2/*%di*/+2/*%si*/+2/*%dx*/+2/*%cx*/+2/*%bx*/(%bp) /* rewrite from original %ax */
439 pushALL /* stack is back to normal NOW */
440 pushw %bp /* trash - just to prepare return address16 */
444 movw %ss:2/*%bp*/+2/*%ax*/+2/*return16*/+PUSHALL_SIZE+2/*%ds*/(%bp),%ax
445 movw %ax,%ss:2/*%bp*/+2/*ax*/(%bp)
448 movw %ax,%ss:2/*%bp*/+2/*%ax*/+2/*return16*/+PUSHALL_SIZE+2/*%ds*/+2/*trash*/+2/*orig-%ax*/+2/*orig-%dx*/+4/*ret-seg:offs*/(%bp)
451 ret /* to prepared return16 and now will be stack in normal again */
453 /* Main upper half initialization messages */
454 /*******************************************/
458 .ascii "BIOSautoRAID, $Id$"
466 .asciz "Disk 0x80 has invalid signature!"
472 /* Interrupt sniffing messages */
473 /*******************************/
477 .asciz "Interrupt 0x18 - Failed boot!"
483 /**************************************************************/
484 /* Final sector signature */
485 /**************************************************************/
488 /* Partition table */