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
38 ; ---------------------------------------------------------------------------
40 ; ---------------------------------------------------------------------------
43 ; Memory below this point is reserved for the BIOS and the MBR
48 trackbuf resb trackbufsize
; Track buffer goes here
51 ; Some of these are touched before the whole image
52 ; is loaded. DO NOT move this to .bss16/.uibss.
56 FirstSecSum resd
1 ; Checksum of bytes 64-2048
57 ImageDwords resd
1 ; isolinux.bin size, dwords
58 InitStack resd
1 ; Initial stack pointer (SS:SP)
59 DiskSys resw
1 ; Last INT 13h call
60 ImageSectors resw
1 ; isolinux.bin size, sectors
61 ; These following two are accessed as a single dword...
62 GetlinsecPtr resw
1 ; The sector-read pointer
63 BIOSName resw
1 ; Display string for BIOS type
64 %define HAVE_BIOSNAME
1
67 DiskError resb
1 ; Error code for disk I/O
69 DriveNumber resb
1 ; CD-ROM BIOS drive number
70 ISOFlags resb
1 ; Flags for ISO directory search
71 RetryCount resb
1 ; Used for disk access retries
75 Hidden resq
1 ; Used in hybrid mode
76 bsSecPerTrack resw
1 ; Used in hybrid mode
77 bsHeads resw
1 ; Used in hybrid mode
81 ; El Torito spec packet
87 spec_packet: resb
1 ; Size of packet
88 sp_media: resb
1 ; Media type
89 sp_drive: resb
1 ; Drive number
90 sp_controller: resb
1 ; Controller index
91 sp_lba: resd
1 ; LBA for emulated disk image
92 sp_devspec: resw
1 ; IDE/SCSI information
93 sp_buffer: resw
1 ; User-provided buffer
94 sp_loadseg: resw
1 ; Load segment
95 sp_sectors: resw
1 ; Sector count
96 sp_chs: resb
3 ; Simulated CHS geometry
97 sp_dummy: resb
1 ; Scratch, safe to overwrite
100 ; EBIOS drive parameter packet
103 drive_params: resw
1 ; Buffer size
104 dp_flags: resw
1 ; Information flags
105 dp_cyl: resd
1 ; Physical cylinders
106 dp_head: resd
1 ; Physical heads
107 dp_sec: resd
1 ; Physical sectors/track
108 dp_totalsec: resd
2 ; Total sectors
109 dp_secsize: resw
1 ; Bytes per sector
110 dp_dpte: resd
1 ; Device Parameter Table
111 dp_dpi_key: resw
1 ; 0BEDDh if rest valid
112 dp_dpi_len: resb
1 ; DPI len
115 dp_bus: resb
4 ; Host bus type
116 dp_interface: resb
8 ; Interface type
117 db_i_path: resd
2 ; Interface path
118 db_d_path: resd
2 ; Device path
120 db_dpi_csum: resb
1 ; Checksum for DPI info
123 ; EBIOS disk address packet
126 dapa: resw
1 ; Packet size
127 .
count: resw
1 ; Block count
128 .
off: resw
1 ; Offset of buffer
129 .
seg: resw
1 ; Segment of buffer
130 .
lba: resd
2 ; LBA (LSW, MSW)
133 ; Spec packet for disk image emulation
136 dspec_packet: resb
1 ; Size of packet
137 dsp_media: resb
1 ; Media type
138 dsp_drive: resb
1 ; Drive number
139 dsp_controller: resb
1 ; Controller index
140 dsp_lba: resd
1 ; LBA for emulated disk image
141 dsp_devspec: resw
1 ; IDE/SCSI information
142 dsp_buffer: resw
1 ; User-provided buffer
143 dsp_loadseg: resw
1 ; Load segment
144 dsp_sectors: resw
1 ; Sector count
145 dsp_chs: resb
3 ; Simulated CHS geometry
146 dsp_dummy: resb
1 ; Scratch, safe to overwrite
150 _spec_len
equ _spec_end
- _spec_start
154 ;; Primary entry point. Because BIOSes are buggy, we only load the first
155 ;; CD-ROM sector (2K) of the file, so the number one priority is actually
159 StackBuf
equ STACK_TOP
-44 ; 44 bytes needed for
160 ; the bootsector chainloading
163 OrigESDI
equ StackBuf
-4 ; The high dword on the stack
164 StackHome
equ OrigESDI
168 _start: ; Far jump makes sure we canonicalize the address
171 times
8-($
-$$
) nop ; Pad to file offset 8
173 ; This table hopefully gets filled in by mkisofs using the
174 ; -boot-info-table option. If not, the values in this
175 ; table are default values that we can use to get us what
176 ; we need, at least under a certain set of assumptions.
179 bi_pvd: dd 16 ; LBA of primary volume descriptor
180 bi_file: dd 0 ; LBA of boot file
181 bi_length: dd 0xdeadbeef ; Length of boot file
182 bi_csum: dd 0xdeadbeef ; Checksum of boot file
183 bi_reserved: times
10 dd 0xdeadbeef ; Reserved
186 ; Custom entry point for the hybrid-mode disk.
187 ; The following values will have been pushed onto the
189 ; - partition offset (qword)
192 ; - DX (including drive number)
198 ; If we had an old isohybrid, the partition offset will
199 ; be missing; we can check for that with sp >= 0x7c00.
200 ; Serious hack alert.
201 %ifndef DEBUG_MESSAGES
203 dd 0x7078c0fb ; An arbitrary number...
207 pop word [cs:bsSecPerTrack
]
208 pop word [cs:bsHeads
]
230 mov [cs:InitStack
],sp ; Save initial stack pointer
231 mov [cs:InitStack
+2],ss
234 mov sp,StackBuf
; Set up stack
235 push es ; Save initial ES:DI -> $PnP pointer
249 mov [GetlinsecPtr
],eax
252 mov si,syslinux_banner
254 %ifdef DEBUG_MESSAGES
262 ; Before modifying any memory, get the checksum of bytes
265 initial_csum: xor edi,edi
267 mov cx,(SECTOR_SIZE
-64) >> 2
271 mov [FirstSecSum
],edi
274 %ifdef DEBUG_MESSAGES
282 ; Initialize spec packet buffers
285 mov cx,_spec_len
>> 2
289 ; Initialize length field of the various packets
290 mov byte [spec_packet
],13h
291 mov byte [drive_params
],30
293 mov byte [dspec_packet
],13h
295 ; Other nonzero fields
296 inc word [dsp_sectors
]
298 ; Are we just pretending to be a CD-ROM?
299 cmp word [BIOSType
],bios_cdrom
300 jne found_drive
; If so, no spec packet...
302 ; Now figure out what we're actually doing
303 ; Note: use passed-in DL value rather than 7Fh because
304 ; at least some BIOSes will get the wrong value otherwise
305 mov ax,4B01h ; Get disk emulation status
309 jc award_hack
; changed for BrokenAwardHack
311 cmp [sp_drive
],dl ; Should contain the drive number
312 jne spec_query_failed
314 %ifdef DEBUG_MESSAGES
317 mov al,byte [sp_drive
]
323 ; Alright, we have found the drive. Now, try to find the
324 ; boot file itself. If we have a boot info table, life is
325 ; good; if not, we have to make some assumptions, and try
326 ; to figure things out ourselves. In particular, the
327 ; assumptions we have to make are:
328 ; - single session only
329 ; - only one boot entry (no menu or other alternatives)
331 cmp dword [bi_file
],0 ; Address of code to load
332 jne found_file
; Boot info table present :)
334 %ifdef DEBUG_MESSAGES
335 mov si,noinfotable_msg
339 ; No such luck. See if the spec packet contained one.
342 jz set_file
; Good enough
344 %ifdef DEBUG_MESSAGES
345 mov si,noinfoinspec_msg
349 ; No such luck. Get the Boot Record Volume, assuming single
350 ; session disk, and that we're the first entry in the chain.
351 mov eax,17 ; Assumed address of BRV
355 mov eax,[trackbuf
+47h] ; Get boot catalog address
357 call getonesec
; Get boot catalog
359 mov eax,[trackbuf
+28h] ; First boot entry
360 ; And hope and pray this is us...
362 ; Some BIOSes apparently have limitations on the size
363 ; that may be loaded (despite the El Torito spec being very
364 ; clear on the fact that it must all be loaded.) Therefore,
365 ; we load it ourselves, and *bleep* the BIOS.
371 ; Set up boot file sizes
373 sub eax,SECTOR_SIZE
-3 ; ... minus sector loaded
374 shr eax,2 ; bytes->dwords
375 mov [ImageDwords
],eax ; boot file dwords
376 add eax,((SECTOR_SIZE
-1) >> 2)
377 shr eax,SECTOR_SHIFT
-2 ; dwords->sectors
378 mov [ImageSectors
],ax ; boot file sectors
380 mov eax,[bi_file
] ; Address of code to load
381 inc eax ; Don't reload bootstrap code
382 %ifdef DEBUG_MESSAGES
389 ; Load the rest of the file. However, just in case there
390 ; are still BIOSes with 64K wraparound problems, we have to
391 ; take some extra precautions. Since the normal load
392 ; address (TEXT_START) is *not* 2K-sector-aligned, we round
393 ; the target address upward to a sector boundary,
394 ; and then move the entire thing down as a unit.
395 MaxLMA
equ 384*1024 ; Reasonable limit (384K)
397 mov bx,((TEXT_START
+2*SECTOR_SIZE
-1) & ~
(SECTOR_SIZE
-1)) >> 4
398 mov bp,[ImageSectors
]
399 push bx ; Load segment address
402 push bx ; Segment address
403 push bp ; Sector count
409 shr cx,SECTOR_SHIFT
- 4
411 mov cx,0x10000 >> SECTOR_SHIFT
; Full 64K segment possible
427 shl cx,SECTOR_SHIFT
- 4
433 ; Move the image into place, and also verify the
435 pop ax ; Load segment address
436 mov bx,(TEXT_START
+ SECTOR_SIZE
) >> 4
437 mov ecx,[ImageDwords
]
438 mov edi,[FirstSecSum
] ; First sector checksum
461 ; Verify the checksum on the loaded image.
470 %ifdef DEBUG_MESSAGES
474 jmp all_read
; Jump to main code
476 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
477 ;; Start of BrokenAwardHack --- 10-nov-2002 Knut_Petersen@t-online.de
478 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
480 ;; There is a problem with certain versions of the AWARD BIOS ...
481 ;; the boot sector will be loaded and executed correctly, but, because the
482 ;; int 13 vector points to the wrong code in the BIOS, every attempt to
483 ;; load the spec packet will fail. We scan for the equivalent of
492 ;; and use <direct far> as the new vector for int 13. The code above is
493 ;; used to load the boot code into ram, and there should be no reason
494 ;; for anybody to change it now or in the future. There are no opcodes
495 ;; that use encodings relativ to IP, so scanning is easy. If we find the
496 ;; code above in the BIOS code we can be pretty sure to run on a machine
497 ;; with an broken AWARD BIOS ...
499 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
501 %ifdef DEBUG_MESSAGES
;;
503 award_notice
db "Trying BrokenAwardHack first ...",CR
,LF
,0 ;;
504 award_not_orig
db "BAH: Original Int 13 vector : ",0 ;;
505 award_not_new
db "BAH: Int 13 vector changed to : ",0 ;;
506 award_not_succ
db "BAH: SUCCESS",CR
,LF
,0 ;;
507 award_not_fail
db "BAH: FAILURE" ;;
508 award_not_crlf
db CR
,LF
,0 ;;
512 award_oldint13
dd 0 ;;
513 award_string
db 0b8h,1,2,0bbh,0,7ch,0b9h,6,0,0bah
,80h,1,09ch,09ah ;;
515 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
516 award_hack: mov si,spec_err_msg
; Moved to this place from
517 call writemsg
; spec_query_failed
519 %ifdef DEBUG_MESSAGES
;
521 mov si,award_notice
; display our plan
523 mov si,award_not_orig
; display original int 13
524 call writemsg
; vector
527 mov [award_oldint13
],eax ;
529 %ifdef DEBUG_MESSAGES
;
532 mov si,award_not_crlf
;
533 call writestr_early
;
536 mov ax,0f000h
; ES = BIOS Seg
539 xor di,di ; start at ES:DI = f000:0
540 award_loop: push di ; save DI
541 mov si,award_string
; scan for award_string
542 mov cx,7 ; length of award_string = 7dw
545 jcxz award_found
; jmp if found
546 inc di ; not found, inc di
549 award_failed: pop es ; No, not this way :-((
552 %ifdef DEBUG_MESSAGES
;
554 mov si,award_not_fail
; display failure ...
557 mov eax,[award_oldint13
] ; restore the original int
558 or eax,eax ; 13 vector if there is one
559 jz spec_query_failed
; and try other workarounds
561 jmp spec_query_failed
;
563 award_found: mov eax,[es:di+0eh
] ; load possible int 13 addr
566 cmp eax,[award_oldint13
] ; give up if this is the
567 jz award_failed
; active int 13 vector,
568 mov [13h*4],eax ; otherwise change 0:13h*4
571 %ifdef DEBUG_MESSAGES
;
573 push eax ; display message and
574 mov si,award_not_new
; new vector address
578 mov si,award_not_crlf
;
579 call writestr_early
;
581 mov ax,4B01h ; try to read the spec packet
582 mov dl,[DriveNumber
] ; now ... it should not fail
583 mov si,spec_packet
; any longer
587 %ifdef DEBUG_MESSAGES
;
589 mov si,award_not_succ
; display our SUCCESS
592 jmp found_drive
; and leave error recovery code
594 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
595 ;; End of BrokenAwardHack ---- 10-nov-2002 Knut_Petersen@t-online.de
596 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
599 ; INT 13h, AX=4B01h, DL=<passed in value> failed.
600 ; Try to scan the entire 80h-FFh from the end.
604 ; some code moved to BrokenAwardHack
610 mov byte [si],13h ; Size of buffer
621 cmp byte [sp_drive
],dl
624 ; Okay, good enough...
627 .
found_drive0: mov [DriveNumber
],dl
628 .
found_drive: jmp found_drive
630 ; Award BIOS 4.51 apparently passes garbage in sp_drive,
631 ; but if this was the drive number originally passed in
632 ; DL then consider it "good enough"
638 ; Intel Classic R+ computer with Adaptec 1542CP BIOS 1.02
639 ; passes garbage in sp_drive, and the drive number originally
640 ; passed in DL does not have 80h bit set.
645 .
still_broken: dec dx
649 ; No spec packet anywhere. Some particularly pathetic
650 ; BIOSes apparently don't even implement function
651 ; 4B01h, so we can't query a spec packet no matter
652 ; what. If we got a drive number in DL, then try to
653 ; use it, and if it works, then well...
655 cmp dl,81h ; Should be 81-FF at least
656 jb fatal_error
; If not, it's hopeless
658 ; Write a warning to indicate we're on *very* thin ice now
666 jmp .found_drive
; Pray that this works...
672 .
norge: jmp short .norge
674 ; Information message (DS:SI) output
675 ; Prefix with "isolinux: "
707 ; Write a character to the screen. There is a more "sophisticated"
708 ; version of this in the subsequent code, so we patch the pointer
724 ; int13: save all the segment registers and call INT 13h.
725 ; Some CD-ROM BIOSes have been found to corrupt segment registers
726 ; and/or disable interrupts.
737 setc [bp+10] ; Propagate CF to the caller
747 ; Get one sector. Convenience entry point.
751 ; Fall through to getlinsec
754 ; Get linear sectors - EBIOS LBA addressing, 2048-byte sectors.
757 ; EAX - Linear sector number
758 ; ES:BX - Target buffer
762 getlinsec: jmp word [cs:GetlinsecPtr
]
764 %ifndef DEBUG_MESSAGES
767 ; First, the variants that we use when actually loading off a disk
768 ; (hybrid mode.) These are adapted versions of the equivalent routines
775 ; getlinsec implementation for floppy/HDD EBIOS (EDD)
780 shl eax,2 ; Convert to HDD sectors
786 push bp ; Sectors left
788 call maxtrans
; Enforce maximum transfer size
789 movzx edi,bp ; Sectors we are about to read
806 mov ah,42h ; Extended Read
810 lea sp,[si+16] ; Remove DAPA
813 add eax,edi ; Advance sector pointer
815 sub bp,di ; Sectors left
816 shl di,9 ; 512-byte sectors
817 add bx,di ; Advance buffer pointer
824 ; Some systems seem to get "stuck" in an error state when
825 ; using EBIOS. Doesn't happen when using CBIOS, which is
826 ; good, since some other systems get timeout failures
827 ; waiting for the floppy disk to spin up.
829 pushad ; Try resetting the device
834 loop .retry
; CX-- and jump if not zero
836 ;shr word [MaxTransfer],1 ; Reduce the transfer size
839 ; Total failure. Try falling back to CBIOS.
840 mov word [GetlinsecPtr
], getlinsec_cbios
841 ;mov byte [MaxTransfer],63 ; Max possibe CBIOS transfer
844 jmp getlinsec_cbios.
loop
849 ; getlinsec implementation for legacy CBIOS
853 shl eax,2 ; Convert to HDD sectors
863 movzx esi,word [bsSecPerTrack
]
864 movzx edi,word [bsHeads
]
866 ; Dividing by sectors to get (track,sector): we may have
867 ; up to 2^18 tracks, so we need to use 32-bit arithmetric.
871 xchg cx,dx ; CX <- sector index (0-based)
874 div edi ; Convert track to head/cyl
876 ; We should test this, but it doesn't fit...
881 ; Now we have AX = cyl, DX = head, CX = sector (0-based),
882 ; BP = sectors to transfer, SI = bsSecPerTrack,
883 ; ES:BX = data target
886 call maxtrans
; Enforce maximum transfer size
888 ; Must not cross track boundaries, so BP <= SI-CX
895 shl ah,6 ; Because IBM was STOOPID
896 ; and thought 8 bits were enough
897 ; then thought 10 bits were enough...
898 inc cx ; Sector numbers are 1-based, sigh
903 xchg ax,bp ; Sector to transfer count
904 mov ah,02h ; Read sectors
912 movzx ecx,al ; ECX <- sectors transferred
913 shl ax,9 ; Convert sectors in AL to bytes in AX
928 xchg ax,bp ; Sectors transferred <- 0
929 shr word [MaxTransfer
],1
934 ; Truncate BP to MaxTransfer
945 ; This is the variant we use for real CD-ROMs:
946 ; LBA, 2K sectors, some special error handling.
949 mov si,dapa
; Load up the DAPA
954 push bp ; Sectors left
955 cmp bp,[MaxTransferCD
]
957 mov bp,[MaxTransferCD
]
962 mov ah,42h ; Extended Read
966 movzx eax,word [si+2] ; Sectors we read
967 add [si+8],eax ; Advance sector pointer
968 sub bp,ax ; Sectors left
969 shl ax,SECTOR_SHIFT
-4 ; 2048-byte sectors -> segment
970 add [si+6],ax ; Advance buffer pointer
973 mov eax,[si+8] ; Next sector
977 xint13: mov byte [RetryCount
],retry_count
981 add sp,byte 8*4 ; Clean up stack
984 mov [DiskError
],ah ; Save error code
986 mov [DiskSys
],ax ; Save system call number
987 dec byte [RetryCount
]
991 mov ah,[dapa
+2] ; Sector transfer count
992 cmp al,2 ; Only 2 attempts left
994 mov ah,1 ; Drop transfer size to 1
998 ja .again
; First time, just try again
999 shr ah,1 ; Otherwise, try to reduce
1000 adc ah,0 ; the max transfer size, but not to 0
1002 mov [MaxTransferCD
],ah
1008 .
real_error: mov si,diskerr_msg
1021 ; Fall through to kaboom
1024 ; kaboom: write a message and bail out. Wait for a user keypress,
1025 ; then do a hard reboot.
1030 RESET_STACK_AND_SEGS
AX
1035 mov word [BIOS_magic
],0 ; Cold reboot
1036 jmp 0F000h:0FFF0h
; Reset vector address
1038 ; -----------------------------------------------------------------------------
1039 ; Common modules needed in the first sector
1040 ; -----------------------------------------------------------------------------
1042 %include "writehex.inc" ; Hexadecimal output
1044 ; -----------------------------------------------------------------------------
1045 ; Data that needs to be in the first sector
1046 ; -----------------------------------------------------------------------------
1048 global syslinux_banner
, copyright_str
1049 syslinux_banner
db CR
, LF
, MY_NAME
, ' ', VERSION_STR
, ' ', DATE_STR
, ' ', 0
1050 copyright_str
db ' Copyright (C) 1994-'
1052 db ' H. Peter Anvin et al', CR
, LF
, 0
1053 isolinux_str
db 'isolinux: ', 0
1054 %ifdef DEBUG_MESSAGES
1055 startup_msg: db 'Starting up, DL = ', 0
1056 spec_ok_msg: db 'Loaded spec packet OK, drive = ', 0
1057 secsize_msg: db 'Sector size ', 0
1058 offset_msg: db 'Main image LBA = ', 0
1059 verify_msg: db 'Image checksum verified.', CR
, LF
, 0
1060 allread_msg
db 'Main image read, jumping to main code...', CR
, LF
, 0
1062 noinfotable_msg
db 'No boot info table, assuming single session disk...', CR
, LF
, 0
1063 noinfoinspec_msg
db 'Spec packet missing LBA information, trying to wing it...', CR
, LF
, 0
1064 spec_err_msg: db 'Loading spec packet failed, trying to wing it...', CR
, LF
, 0
1065 maybe_msg: db 'Found something at drive = ', 0
1066 alright_msg: db 'Looks reasonable, continuing...', CR
, LF
, 0
1067 nospec_msg
db 'Extremely broken BIOS detected, last attempt with drive = ', 0
1068 nothing_msg: db 'Failed to locate CD-ROM device; boot failed.', CR
, LF
1069 trysbm_msg
db 'See http://syslinux.zytor.com/sbm for more information.', CR
, LF
, 0
1070 diskerr_msg: db 'Disk error ', 0
1071 oncall_str: db ', AX = ',0
1072 ondrive_str: db ', drive ', 0
1073 checkerr_msg: db 'Image checksum error, sorry...', CR
, LF
, 0
1075 err_bootfailed
db CR
, LF
, 'Boot failed: press a key to retry...'
1076 bailmsg
equ err_bootfailed
1080 bios_cdrom_str
db 'ETCD', 0
1081 %ifndef DEBUG_MESSAGES
1082 bios_cbios_str
db 'CHDD', 0
1083 bios_ebios_str
db 'EHDD' ,0
1088 bios_cdrom: dw getlinsec_cdrom
, bios_cdrom_str
1089 %ifndef DEBUG_MESSAGES
1090 bios_cbios: dw getlinsec_cbios
, bios_cbios_str
1091 bios_ebios: dw getlinsec_ebios
, bios_ebios_str
1094 ; Maximum transfer size
1095 MaxTransfer
dw 127 ; Hard disk modes
1096 MaxTransferCD
dw 32 ; CD mode
1098 rl_checkpt
equ $
; Must be <= 800h
1100 ; This pads to the end of sector 0 and errors out on
1102 times
2048-($
-$$
) db 0
1104 ; ----------------------------------------------------------------------------
1105 ; End of code and data that have to be in the first sector
1106 ; ----------------------------------------------------------------------------
1117 ; Common initialization code
1121 ; Tell the user we got this far...
1122 %ifndef DEBUG_MESSAGES
; Gets messy with debugging on
1123 mov si,copyright_str
1128 ; Now we're all set to start with our *real* business. First load the
1129 ; configuration file (if any) and parse it.
1131 ; In previous versions I avoided using 32-bit registers because of a
1132 ; rumour some BIOSes clobbered the upper half of 32-bit registers at
1133 ; random. I figure, though, that if there are any of those still left
1134 ; they probably won't be trying to install Linux on them...
1136 ; The code is still ripe with 16-bitisms, though. Not worth the hassle
1137 ; to take'm out. In fact, we may want to put them back if we're going
1138 ; to boot ELKS at some point.
1142 ; Now, we need to sniff out the actual filesystem data structures.
1143 ; mkisofs gave us a pointer to the primary volume descriptor
1144 ; (which will be at 16 only for a single-session disk!); from the PVD
1145 ; we should be able to find the rest of what we need to know.
1150 mov dl,[DriveNumber
]
1151 cmp word [BIOSType
],bios_cdrom
1152 sete dh ; 1 for cdrom, 0 for hybrid mode
1154 movzx ebp,word [MaxTransferCD
]
1157 movzx ebp,word [MaxTransfer
]
1162 mov di,[bsSecPerTrack
]
1167 jmp kaboom
; load_env32() should never return. If
1168 ; it does, then kaboom!
1180 %ifdef DEBUG_TRACERS
1182 ; debug hack to print a character with minimal code impact
1184 debug_tracer: pushad
1187 mov bx,[bp+9*4] ; Get return address
1188 mov al,[cs:bx] ; Get data byte
1189 inc word [bp+9*4] ; Return to after data byte
1194 %endif
; DEBUG_TRACERS
1198 ThisKbdTo resd
1 ; Temporary holder for KbdTimeout
1199 ThisTotalTo resd
1 ; Temporary holder for TotalTimeout
1200 KernelExtPtr resw
1 ; During search, final null pointer
1201 FuncFlag resb
1 ; Escape sequences received from keyboard
1202 KernelType resb
1 ; Kernel type, from vkernel, if known
1204 KernelName resb FILENAME_MAX
; Mangled name for kernel
1208 ; COMBOOT-loading code
1210 %include "comboot.inc"
1211 %include "com32.inc"
1214 ; Boot sector loading code
1218 ; Abort loading code
1222 ; Hardware cleanup common code
1225 %include "localboot.inc"
1227 ; -----------------------------------------------------------------------------
1229 ; -----------------------------------------------------------------------------
1231 %include "common.inc" ; Universal modules
1233 ; -----------------------------------------------------------------------------
1234 ; Begin data section
1235 ; -----------------------------------------------------------------------------
1238 err_disk_image
db 'Cannot load disk image (invalid file)?', CR
, LF
, 0