1 ; -*- fundamental -*- (asm-mode sucks)
2 ; ****************************************************************************
6 ; A program to boot Linux kernels off a CD-ROM using the El Torito
7 ; boot standard in "no emulation" mode, making the entire filesystem
8 ; available. It is based on the SYSLINUX boot loader for MS-DOS
11 ; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
12 ; Copyright 2009 Intel Corporation; author: H. Peter Anvin
14 ; This program is free software; you can redistribute it and/or modify
15 ; it under the terms of the GNU General Public License as published by
16 ; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
17 ; Boston MA 02111-1307, USA; either version 2 of the License, or
18 ; (at your option) any later version; incorporated herein by reference.
20 ; ****************************************************************************
26 ; Some semi-configurable constants... change on your own risk.
29 NULLFILE
equ 0 ; Zero byte == null file name
30 NULLOFFSET
equ 0 ; Position in which to look
31 retry_count
equ 6 ; How patient are we with the BIOS?
32 %assign HIGHMEM_SLOP
128*1024 ; Avoid this much memory near the top
33 SECTOR_SHIFT
equ 11 ; 2048 bytes/sector (El Torito requirement)
34 SECTOR_SIZE
equ (1 << SECTOR_SHIFT
)
36 ROOT_DIR_WORD
equ 0x002F
39 ; The following structure is used for "virtual kernels"; i.e. LILO-style
40 ; option labels. The options we permit here are `kernel' and `append
41 ; Since there is no room in the bottom 64K for all of these, we
42 ; stick them in high memory and copy them down before we need them.
45 vk_vname: resb FILENAME_MAX
; Virtual name **MUST BE FIRST!**
46 vk_rname: resb FILENAME_MAX
; Real name
48 vk_type: resb
1 ; Type of file
50 vk_append: resb max_cmd_len
+1 ; Command line
52 vk_end: equ $
; Should be <= vk_size
55 ; ---------------------------------------------------------------------------
57 ; ---------------------------------------------------------------------------
60 ; Memory below this point is reserved for the BIOS and the MBR
65 trackbuf resb trackbufsize
; Track buffer goes here
68 ; Some of these are touched before the whole image
69 ; is loaded. DO NOT move this to .bss16/.uibss.
73 FirstSecSum resd
1 ; Checksum of bytes 64-2048
74 ImageDwords resd
1 ; isolinux.bin size, dwords
75 InitStack resd
1 ; Initial stack pointer (SS:SP)
76 DiskSys resw
1 ; Last INT 13h call
77 ImageSectors resw
1 ; isolinux.bin size, sectors
78 ; These following two are accessed as a single dword...
79 GetlinsecPtr resw
1 ; The sector-read pointer
80 BIOSName resw
1 ; Display string for BIOS type
81 %define HAVE_BIOSNAME
1
83 DiskError resb
1 ; Error code for disk I/O
84 DriveNumber resb
1 ; CD-ROM BIOS drive number
85 ISOFlags resb
1 ; Flags for ISO directory search
86 RetryCount resb
1 ; Used for disk access retries
89 Hidden resq
1 ; Used in hybrid mode
90 bsSecPerTrack resw
1 ; Used in hybrid mode
91 bsHeads resw
1 ; Used in hybrid mode
95 ; El Torito spec packet
100 spec_packet: resb
1 ; Size of packet
101 sp_media: resb
1 ; Media type
102 sp_drive: resb
1 ; Drive number
103 sp_controller: resb
1 ; Controller index
104 sp_lba: resd
1 ; LBA for emulated disk image
105 sp_devspec: resw
1 ; IDE/SCSI information
106 sp_buffer: resw
1 ; User-provided buffer
107 sp_loadseg: resw
1 ; Load segment
108 sp_sectors: resw
1 ; Sector count
109 sp_chs: resb
3 ; Simulated CHS geometry
110 sp_dummy: resb
1 ; Scratch, safe to overwrite
113 ; EBIOS drive parameter packet
116 drive_params: resw
1 ; Buffer size
117 dp_flags: resw
1 ; Information flags
118 dp_cyl: resd
1 ; Physical cylinders
119 dp_head: resd
1 ; Physical heads
120 dp_sec: resd
1 ; Physical sectors/track
121 dp_totalsec: resd
2 ; Total sectors
122 dp_secsize: resw
1 ; Bytes per sector
123 dp_dpte: resd
1 ; Device Parameter Table
124 dp_dpi_key: resw
1 ; 0BEDDh if rest valid
125 dp_dpi_len: resb
1 ; DPI len
128 dp_bus: resb
4 ; Host bus type
129 dp_interface: resb
8 ; Interface type
130 db_i_path: resd
2 ; Interface path
131 db_d_path: resd
2 ; Device path
133 db_dpi_csum: resb
1 ; Checksum for DPI info
136 ; EBIOS disk address packet
139 dapa: resw
1 ; Packet size
140 .
count: resw
1 ; Block count
141 .
off: resw
1 ; Offset of buffer
142 .
seg: resw
1 ; Segment of buffer
143 .
lba: resd
2 ; LBA (LSW, MSW)
146 ; Spec packet for disk image emulation
149 dspec_packet: resb
1 ; Size of packet
150 dsp_media: resb
1 ; Media type
151 dsp_drive: resb
1 ; Drive number
152 dsp_controller: resb
1 ; Controller index
153 dsp_lba: resd
1 ; LBA for emulated disk image
154 dsp_devspec: resw
1 ; IDE/SCSI information
155 dsp_buffer: resw
1 ; User-provided buffer
156 dsp_loadseg: resw
1 ; Load segment
157 dsp_sectors: resw
1 ; Sector count
158 dsp_chs: resb
3 ; Simulated CHS geometry
159 dsp_dummy: resb
1 ; Scratch, safe to overwrite
163 _spec_len
equ _spec_end
- _spec_start
167 ;; Primary entry point. Because BIOSes are buggy, we only load the first
168 ;; CD-ROM sector (2K) of the file, so the number one priority is actually
172 StackBuf
equ STACK_TOP
-44 ; 44 bytes needed for
173 ; the bootsector chainloading
175 OrigESDI
equ StackBuf
-4 ; The high dword on the stack
176 StackHome
equ OrigESDI
180 _start: ; Far jump makes sure we canonicalize the address
183 times
8-($
-$$
) nop ; Pad to file offset 8
185 ; This table hopefully gets filled in by mkisofs using the
186 ; -boot-info-table option. If not, the values in this
187 ; table are default values that we can use to get us what
188 ; we need, at least under a certain set of assumptions.
191 bi_pvd: dd 16 ; LBA of primary volume descriptor
192 bi_file: dd 0 ; LBA of boot file
193 bi_length: dd 0xdeadbeef ; Length of boot file
194 bi_csum: dd 0xdeadbeef ; Checksum of boot file
195 bi_reserved: times
10 dd 0xdeadbeef ; Reserved
198 ; Custom entry point for the hybrid-mode disk.
199 ; The following values will have been pushed onto the
201 ; - partition offset (qword)
204 ; - DX (including drive number)
210 ; If we had an old isohybrid, the partition offset will
211 ; be missing; we can check for that with sp >= 0x7c00.
212 ; Serious hack alert.
213 %ifndef DEBUG_MESSAGES
215 dd 0x7078c0fb ; An arbitrary number...
219 pop word [cs:bsSecPerTrack
]
220 pop word [cs:bsHeads
]
242 mov [cs:InitStack
],sp ; Save initial stack pointer
243 mov [cs:InitStack
+2],ss
246 mov sp,StackBuf
; Set up stack
247 push es ; Save initial ES:DI -> $PnP pointer
261 mov [GetlinsecPtr
],eax
264 mov si,syslinux_banner
266 %ifdef DEBUG_MESSAGES
274 ; Before modifying any memory, get the checksum of bytes
277 initial_csum: xor edi,edi
279 mov cx,(SECTOR_SIZE
-64) >> 2
283 mov [FirstSecSum
],edi
286 %ifdef DEBUG_MESSAGES
294 ; Initialize spec packet buffers
297 mov cx,_spec_len
>> 2
301 ; Initialize length field of the various packets
302 mov byte [spec_packet
],13h
303 mov byte [drive_params
],30
305 mov byte [dspec_packet
],13h
307 ; Other nonzero fields
308 inc word [dsp_sectors
]
310 ; Are we just pretending to be a CD-ROM?
311 cmp word [BIOSType
],bios_cdrom
312 jne found_drive
; If so, no spec packet...
314 ; Now figure out what we're actually doing
315 ; Note: use passed-in DL value rather than 7Fh because
316 ; at least some BIOSes will get the wrong value otherwise
317 mov ax,4B01h ; Get disk emulation status
321 jc award_hack
; changed for BrokenAwardHack
323 cmp [sp_drive
],dl ; Should contain the drive number
324 jne spec_query_failed
326 %ifdef DEBUG_MESSAGES
329 mov al,byte [sp_drive
]
335 ; Alright, we have found the drive. Now, try to find the
336 ; boot file itself. If we have a boot info table, life is
337 ; good; if not, we have to make some assumptions, and try
338 ; to figure things out ourselves. In particular, the
339 ; assumptions we have to make are:
340 ; - single session only
341 ; - only one boot entry (no menu or other alternatives)
343 cmp dword [bi_file
],0 ; Address of code to load
344 jne found_file
; Boot info table present :)
346 %ifdef DEBUG_MESSAGES
347 mov si,noinfotable_msg
351 ; No such luck. See if the spec packet contained one.
354 jz set_file
; Good enough
356 %ifdef DEBUG_MESSAGES
357 mov si,noinfoinspec_msg
361 ; No such luck. Get the Boot Record Volume, assuming single
362 ; session disk, and that we're the first entry in the chain.
363 mov eax,17 ; Assumed address of BRV
367 mov eax,[trackbuf
+47h] ; Get boot catalog address
369 call getonesec
; Get boot catalog
371 mov eax,[trackbuf
+28h] ; First boot entry
372 ; And hope and pray this is us...
374 ; Some BIOSes apparently have limitations on the size
375 ; that may be loaded (despite the El Torito spec being very
376 ; clear on the fact that it must all be loaded.) Therefore,
377 ; we load it ourselves, and *bleep* the BIOS.
383 ; Set up boot file sizes
385 sub eax,SECTOR_SIZE
-3 ; ... minus sector loaded
386 shr eax,2 ; bytes->dwords
387 mov [ImageDwords
],eax ; boot file dwords
388 add eax,((SECTOR_SIZE
-1) >> 2)
389 shr eax,SECTOR_SHIFT
-2 ; dwords->sectors
390 mov [ImageSectors
],ax ; boot file sectors
392 mov eax,[bi_file
] ; Address of code to load
393 inc eax ; Don't reload bootstrap code
394 %ifdef DEBUG_MESSAGES
401 ; Load the rest of the file. However, just in case there
402 ; are still BIOSes with 64K wraparound problems, we have to
403 ; take some extra precautions. Since the normal load
404 ; address (TEXT_START) is *not* 2K-sector-aligned, we round
405 ; the target address upward to a sector boundary,
406 ; and then move the entire thing down as a unit.
407 MaxLMA
equ 384*1024 ; Reasonable limit (384K)
409 mov bx,((TEXT_START
+2*SECTOR_SIZE
-1) & ~
(SECTOR_SIZE
-1)) >> 4
410 mov bp,[ImageSectors
]
411 push bx ; Load segment address
414 push bx ; Segment address
415 push bp ; Sector count
421 shr cx,SECTOR_SHIFT
- 4
423 mov cx,0x10000 >> SECTOR_SHIFT
; Full 64K segment possible
439 shl cx,SECTOR_SHIFT
- 4
445 ; Move the image into place, and also verify the
447 pop ax ; Load segment address
448 mov bx,(TEXT_START
+ SECTOR_SIZE
) >> 4
449 mov ecx,[ImageDwords
]
450 mov edi,[FirstSecSum
] ; First sector checksum
473 ; Verify the checksum on the loaded image.
482 %ifdef DEBUG_MESSAGES
486 jmp all_read
; Jump to main code
488 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
489 ;; Start of BrokenAwardHack --- 10-nov-2002 Knut_Petersen@t-online.de
490 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
492 ;; There is a problem with certain versions of the AWARD BIOS ...
493 ;; the boot sector will be loaded and executed correctly, but, because the
494 ;; int 13 vector points to the wrong code in the BIOS, every attempt to
495 ;; load the spec packet will fail. We scan for the equivalent of
504 ;; and use <direct far> as the new vector for int 13. The code above is
505 ;; used to load the boot code into ram, and there should be no reason
506 ;; for anybody to change it now or in the future. There are no opcodes
507 ;; that use encodings relativ to IP, so scanning is easy. If we find the
508 ;; code above in the BIOS code we can be pretty sure to run on a machine
509 ;; with an broken AWARD BIOS ...
511 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
513 %ifdef DEBUG_MESSAGES
;;
515 award_notice
db "Trying BrokenAwardHack first ...",CR
,LF
,0 ;;
516 award_not_orig
db "BAH: Original Int 13 vector : ",0 ;;
517 award_not_new
db "BAH: Int 13 vector changed to : ",0 ;;
518 award_not_succ
db "BAH: SUCCESS",CR
,LF
,0 ;;
519 award_not_fail
db "BAH: FAILURE" ;;
520 award_not_crlf
db CR
,LF
,0 ;;
524 award_oldint13
dd 0 ;;
525 award_string
db 0b8h,1,2,0bbh,0,7ch,0b9h,6,0,0bah
,80h,1,09ch,09ah ;;
527 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
528 award_hack: mov si,spec_err_msg
; Moved to this place from
529 call writemsg
; spec_query_failed
531 %ifdef DEBUG_MESSAGES
;
533 mov si,award_notice
; display our plan
535 mov si,award_not_orig
; display original int 13
536 call writemsg
; vector
539 mov [award_oldint13
],eax ;
541 %ifdef DEBUG_MESSAGES
;
544 mov si,award_not_crlf
;
545 call writestr_early
;
548 mov ax,0f000h
; ES = BIOS Seg
551 xor di,di ; start at ES:DI = f000:0
552 award_loop: push di ; save DI
553 mov si,award_string
; scan for award_string
554 mov cx,7 ; length of award_string = 7dw
557 jcxz award_found
; jmp if found
558 inc di ; not found, inc di
561 award_failed: pop es ; No, not this way :-((
564 %ifdef DEBUG_MESSAGES
;
566 mov si,award_not_fail
; display failure ...
569 mov eax,[award_oldint13
] ; restore the original int
570 or eax,eax ; 13 vector if there is one
571 jz spec_query_failed
; and try other workarounds
573 jmp spec_query_failed
;
575 award_found: mov eax,[es:di+0eh
] ; load possible int 13 addr
578 cmp eax,[award_oldint13
] ; give up if this is the
579 jz award_failed
; active int 13 vector,
580 mov [13h*4],eax ; otherwise change 0:13h*4
583 %ifdef DEBUG_MESSAGES
;
585 push eax ; display message and
586 mov si,award_not_new
; new vector address
590 mov si,award_not_crlf
;
591 call writestr_early
;
593 mov ax,4B01h ; try to read the spec packet
594 mov dl,[DriveNumber
] ; now ... it should not fail
595 mov si,spec_packet
; any longer
599 %ifdef DEBUG_MESSAGES
;
601 mov si,award_not_succ
; display our SUCCESS
604 jmp found_drive
; and leave error recovery code
606 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
607 ;; End of BrokenAwardHack ---- 10-nov-2002 Knut_Petersen@t-online.de
608 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
611 ; INT 13h, AX=4B01h, DL=<passed in value> failed.
612 ; Try to scan the entire 80h-FFh from the end.
616 ; some code moved to BrokenAwardHack
622 mov byte [si],13h ; Size of buffer
633 cmp byte [sp_drive
],dl
636 ; Okay, good enough...
639 .
found_drive0: mov [DriveNumber
],dl
640 .
found_drive: jmp found_drive
642 ; Award BIOS 4.51 apparently passes garbage in sp_drive,
643 ; but if this was the drive number originally passed in
644 ; DL then consider it "good enough"
650 ; Intel Classic R+ computer with Adaptec 1542CP BIOS 1.02
651 ; passes garbage in sp_drive, and the drive number originally
652 ; passed in DL does not have 80h bit set.
657 .
still_broken: dec dx
661 ; No spec packet anywhere. Some particularly pathetic
662 ; BIOSes apparently don't even implement function
663 ; 4B01h, so we can't query a spec packet no matter
664 ; what. If we got a drive number in DL, then try to
665 ; use it, and if it works, then well...
667 cmp dl,81h ; Should be 81-FF at least
668 jb fatal_error
; If not, it's hopeless
670 ; Write a warning to indicate we're on *very* thin ice now
678 jmp .found_drive
; Pray that this works...
684 .
norge: jmp short .norge
686 ; Information message (DS:SI) output
687 ; Prefix with "isolinux: "
719 ; Write a character to the screen. There is a more "sophisticated"
720 ; version of this in the subsequent code, so we patch the pointer
736 ; int13: save all the segment registers and call INT 13h.
737 ; Some CD-ROM BIOSes have been found to corrupt segment registers
738 ; and/or disable interrupts.
749 setc [bp+10] ; Propagate CF to the caller
759 ; Get one sector. Convenience entry point.
763 ; Fall through to getlinsec
766 ; Get linear sectors - EBIOS LBA addressing, 2048-byte sectors.
769 ; EAX - Linear sector number
770 ; ES:BX - Target buffer
774 getlinsec: jmp word [cs:GetlinsecPtr
]
776 %ifndef DEBUG_MESSAGES
779 ; First, the variants that we use when actually loading off a disk
780 ; (hybrid mode.) These are adapted versions of the equivalent routines
787 ; getlinsec implementation for floppy/HDD EBIOS (EDD)
792 shl eax,2 ; Convert to HDD sectors
798 push bp ; Sectors left
800 call maxtrans
; Enforce maximum transfer size
801 movzx edi,bp ; Sectors we are about to read
818 mov ah,42h ; Extended Read
822 lea sp,[si+16] ; Remove DAPA
825 add eax,edi ; Advance sector pointer
827 sub bp,di ; Sectors left
828 shl di,9 ; 512-byte sectors
829 add bx,di ; Advance buffer pointer
836 ; Some systems seem to get "stuck" in an error state when
837 ; using EBIOS. Doesn't happen when using CBIOS, which is
838 ; good, since some other systems get timeout failures
839 ; waiting for the floppy disk to spin up.
841 pushad ; Try resetting the device
846 loop .retry
; CX-- and jump if not zero
848 ;shr word [MaxTransfer],1 ; Reduce the transfer size
851 ; Total failure. Try falling back to CBIOS.
852 mov word [GetlinsecPtr
], getlinsec_cbios
853 ;mov byte [MaxTransfer],63 ; Max possibe CBIOS transfer
856 jmp getlinsec_cbios.
loop
861 ; getlinsec implementation for legacy CBIOS
865 shl eax,2 ; Convert to HDD sectors
875 movzx esi,word [bsSecPerTrack
]
876 movzx edi,word [bsHeads
]
878 ; Dividing by sectors to get (track,sector): we may have
879 ; up to 2^18 tracks, so we need to use 32-bit arithmetric.
883 xchg cx,dx ; CX <- sector index (0-based)
886 div edi ; Convert track to head/cyl
888 ; We should test this, but it doesn't fit...
893 ; Now we have AX = cyl, DX = head, CX = sector (0-based),
894 ; BP = sectors to transfer, SI = bsSecPerTrack,
895 ; ES:BX = data target
898 call maxtrans
; Enforce maximum transfer size
900 ; Must not cross track boundaries, so BP <= SI-CX
907 shl ah,6 ; Because IBM was STOOPID
908 ; and thought 8 bits were enough
909 ; then thought 10 bits were enough...
910 inc cx ; Sector numbers are 1-based, sigh
915 xchg ax,bp ; Sector to transfer count
916 mov ah,02h ; Read sectors
924 movzx ecx,al ; ECX <- sectors transferred
925 shl ax,9 ; Convert sectors in AL to bytes in AX
940 xchg ax,bp ; Sectors transferred <- 0
941 shr word [MaxTransfer
],1
946 ; Truncate BP to MaxTransfer
957 ; This is the variant we use for real CD-ROMs:
958 ; LBA, 2K sectors, some special error handling.
961 mov si,dapa
; Load up the DAPA
966 push bp ; Sectors left
967 cmp bp,[MaxTransferCD
]
969 mov bp,[MaxTransferCD
]
974 mov ah,42h ; Extended Read
978 movzx eax,word [si+2] ; Sectors we read
979 add [si+8],eax ; Advance sector pointer
980 sub bp,ax ; Sectors left
981 shl ax,SECTOR_SHIFT
-4 ; 2048-byte sectors -> segment
982 add [si+6],ax ; Advance buffer pointer
985 mov eax,[si+8] ; Next sector
989 xint13: mov byte [RetryCount
],retry_count
993 add sp,byte 8*4 ; Clean up stack
996 mov [DiskError
],ah ; Save error code
998 mov [DiskSys
],ax ; Save system call number
999 dec byte [RetryCount
]
1003 mov ah,[dapa
+2] ; Sector transfer count
1004 cmp al,2 ; Only 2 attempts left
1006 mov ah,1 ; Drop transfer size to 1
1009 cmp al,retry_count
-2
1010 ja .again
; First time, just try again
1011 shr ah,1 ; Otherwise, try to reduce
1012 adc ah,0 ; the max transfer size, but not to 0
1014 mov [MaxTransferCD
],ah
1020 .
real_error: mov si,diskerr_msg
1033 ; Fall through to kaboom
1036 ; kaboom: write a message and bail out. Wait for a user keypress,
1037 ; then do a hard reboot.
1042 RESET_STACK_AND_SEGS
AX
1047 mov word [BIOS_magic
],0 ; Cold reboot
1048 jmp 0F000h:0FFF0h
; Reset vector address
1050 ; -----------------------------------------------------------------------------
1051 ; Common modules needed in the first sector
1052 ; -----------------------------------------------------------------------------
1054 %include "writehex.inc" ; Hexadecimal output
1056 ; -----------------------------------------------------------------------------
1057 ; Data that needs to be in the first sector
1058 ; -----------------------------------------------------------------------------
1060 global syslinux_banner
, copyright_str
1061 syslinux_banner
db CR
, LF
, MY_NAME
, ' ', VERSION_STR
, ' ', DATE_STR
, ' ', 0
1062 copyright_str
db ' Copyright (C) 1994-'
1064 db ' H. Peter Anvin et al', CR
, LF
, 0
1065 isolinux_str
db 'isolinux: ', 0
1066 %ifdef DEBUG_MESSAGES
1067 startup_msg: db 'Starting up, DL = ', 0
1068 spec_ok_msg: db 'Loaded spec packet OK, drive = ', 0
1069 secsize_msg: db 'Sector size ', 0
1070 offset_msg: db 'Main image LBA = ', 0
1071 verify_msg: db 'Image checksum verified.', CR
, LF
, 0
1072 allread_msg
db 'Main image read, jumping to main code...', CR
, LF
, 0
1074 noinfotable_msg
db 'No boot info table, assuming single session disk...', CR
, LF
, 0
1075 noinfoinspec_msg
db 'Spec packet missing LBA information, trying to wing it...', CR
, LF
, 0
1076 spec_err_msg: db 'Loading spec packet failed, trying to wing it...', CR
, LF
, 0
1077 maybe_msg: db 'Found something at drive = ', 0
1078 alright_msg: db 'Looks reasonable, continuing...', CR
, LF
, 0
1079 nospec_msg
db 'Extremely broken BIOS detected, last attempt with drive = ', 0
1080 nothing_msg: db 'Failed to locate CD-ROM device; boot failed.', CR
, LF
1081 trysbm_msg
db 'See http://syslinux.zytor.com/sbm for more information.', CR
, LF
, 0
1082 diskerr_msg: db 'Disk error ', 0
1083 oncall_str: db ', AX = ',0
1084 ondrive_str: db ', drive ', 0
1085 checkerr_msg: db 'Image checksum error, sorry...', CR
, LF
, 0
1087 err_bootfailed
db CR
, LF
, 'Boot failed: press a key to retry...'
1088 bailmsg
equ err_bootfailed
1092 bios_cdrom_str
db 'ETCD', 0
1093 %ifndef DEBUG_MESSAGES
1094 bios_cbios_str
db 'CHDD', 0
1095 bios_ebios_str
db 'EHDD' ,0
1099 bios_cdrom: dw getlinsec_cdrom
, bios_cdrom_str
1100 %ifndef DEBUG_MESSAGES
1101 bios_cbios: dw getlinsec_cbios
, bios_cbios_str
1102 bios_ebios: dw getlinsec_ebios
, bios_ebios_str
1105 ; Maximum transfer size
1106 MaxTransfer
dw 127 ; Hard disk modes
1107 MaxTransferCD
dw 32 ; CD mode
1109 rl_checkpt
equ $
; Must be <= 800h
1111 ; This pads to the end of sector 0 and errors out on
1113 times
2048-($
-$$
) db 0
1115 ; ----------------------------------------------------------------------------
1116 ; End of code and data that have to be in the first sector
1117 ; ----------------------------------------------------------------------------
1128 ; Common initialization code
1132 ; Tell the user we got this far...
1133 %ifndef DEBUG_MESSAGES
; Gets messy with debugging on
1134 mov si,copyright_str
1139 ; Now we're all set to start with our *real* business. First load the
1140 ; configuration file (if any) and parse it.
1142 ; In previous versions I avoided using 32-bit registers because of a
1143 ; rumour some BIOSes clobbered the upper half of 32-bit registers at
1144 ; random. I figure, though, that if there are any of those still left
1145 ; they probably won't be trying to install Linux on them...
1147 ; The code is still ripe with 16-bitisms, though. Not worth the hassle
1148 ; to take'm out. In fact, we may want to put them back if we're going
1149 ; to boot ELKS at some point.
1153 ; Now, we need to sniff out the actual filesystem data structures.
1154 ; mkisofs gave us a pointer to the primary volume descriptor
1155 ; (which will be at 16 only for a single-session disk!); from the PVD
1156 ; we should be able to find the rest of what we need to know.
1161 mov dl,[DriveNumber
]
1162 cmp word [BIOSType
],bios_cdrom
1163 sete dh ; 1 for cdrom, 0 for hybrid mode
1165 movzx ebp,word [MaxTransferCD
]
1168 movzx ebp,word [MaxTransfer
]
1173 mov di,[bsSecPerTrack
]
1178 jmp kaboom
; load_env32() should never return. If
1179 ; it does, then kaboom!
1191 %ifdef DEBUG_TRACERS
1193 ; debug hack to print a character with minimal code impact
1195 debug_tracer: pushad
1198 mov bx,[bp+9*4] ; Get return address
1199 mov al,[cs:bx] ; Get data byte
1200 inc word [bp+9*4] ; Return to after data byte
1205 %endif
; DEBUG_TRACERS
1209 ThisKbdTo resd
1 ; Temporary holder for KbdTimeout
1210 ThisTotalTo resd
1 ; Temporary holder for TotalTimeout
1211 KernelExtPtr resw
1 ; During search, final null pointer
1212 FuncFlag resb
1 ; Escape sequences received from keyboard
1213 KernelType resb
1 ; Kernel type, from vkernel, if known
1215 KernelName resb FILENAME_MAX
; Mangled name for kernel
1217 global IPAppends
, numIPAppends
1221 IPAppends
dw IPOption
1222 numIPAppends
equ ($
-IPAppends
)/2
1230 ; COMBOOT-loading code
1232 %include "comboot.inc"
1233 %include "com32.inc"
1236 ; Boot sector loading code
1240 ; Abort loading code
1244 ; Hardware cleanup common code
1247 %include "localboot.inc"
1249 ; -----------------------------------------------------------------------------
1251 ; -----------------------------------------------------------------------------
1253 %include "common.inc" ; Universal modules
1255 ; -----------------------------------------------------------------------------
1256 ; Begin data section
1257 ; -----------------------------------------------------------------------------
1260 err_disk_image
db 'Cannot load disk image (invalid file)?', CR
, LF
, 0