source: trunk/bootcode/regular/partmain.asm@ 155

Last change on this file since 155 was 155, checked in by Ben Rietbroek, 8 years ago

Updated callers of 'LVM_GetDriveLetter' -- revisit this [v1.1.1-testing]

CAUTION:
This is a testbuild !
AirBoot uses the BIOS to access disks and a small coding error can trash
partition tables or other vital disk structures. You are advised to make
backups of TRACK0 and EBRs before using this testbuild. More info at:
https://rousseaux.github.io/netlabs.air-boot/pdf/AirBoot-v1.1.0-manual.pdf

File size: 79.7 KB
Line 
1; AiR-BOOT (c) Copyright 1998-2008 M. Kiewitz
2;
3; This file is part of AiR-BOOT
4;
5; AiR-BOOT is free software: you can redistribute it and/or modify it under
6; the terms of the GNU General Public License as published by the Free
7; Software Foundation, either version 3 of the License, or (at your option)
8; any later version.
9;
10; AiR-BOOT is distributed in the hope that it will be useful, but WITHOUT ANY
11; WARRANTY: without even the implied warranty of MERCHANTABILITY or FITNESS
12; FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13; details.
14;
15; You should have received a copy of the GNU General Public License along with
16; AiR-BOOT. If not, see <http://www.gnu.org/licenses/>.
17;
18;---------------------------------------------------------------------------
19; AiR-BOOT / PARTiTiON REGULAR ROUTINES
20;---------------------------------------------------------------------------
21
22IFDEF MODULE_NAMES
23DB 'PARTMAIN',0
24ENDIF
25
26PART_FixUpDefaultPartitionValues Proc Near Uses dx si di
27 ; Fix-Up Default and Last Partition - If lost, search for Bootable
28 xor bl, bl
29 mov dl, CFG_PartDefault
30 call PART_FixUpSelectionNumber
31 mov CFG_PartDefault, dl
32 mov dl, CFG_PartLast
33 call PART_FixUpSelectionNumber
34 mov CFG_PartLast, dl
35 mov dl, CFG_PartAutomatic
36 call PART_FixUpSelectionNumber
37 mov CFG_PartAutomatic, dl
38 ret
39PART_FixUpDefaultPartitionValues EndP
40
41; Our resync process for partition number is as specified:
42;==========================================================
43; - If 0FFh -> Partition Disabled, so don't do anything to it...
44; - Try to use GetXref to get the new partition no via X-Ref Table
45; - If failed, increase partition no, till overflow or hit on specific
46; characteristic
47; On overflow -> Resume search from partition no 0
48;
49; Characteristic is a partition id. If this id is 0, then a bootable partition
50; is searched for.
51
52; Fixes a partition number, adjusting it to the new IPT after redetect
53; In: DL - Number of partition
54; BL - Requested Partition ID
55; Out: DL - New number of partition (guessed normally ;)
56PART_FixUpSelectionNumber Proc Near Uses ax cx
57 cmp dl, 080h
58 je PFUPN_SelectionDisabled
59 ja PFUPN_SpecialSelection
60 call PARTSCAN_GetXref ; DL - PartitionNo prev IPT
61 cmp dh, 0FFh ; DH -> Partition No in new IPT
62 je PFUPN_SelectionGone
63 mov dl, dh
64 PFUPN_SelectionDisabled:
65 ret
66
67 PFUPN_SpecialSelection:
68 cmp dl, 0FEh ; Resume-BIOS?
69 ja PFUPN_SpecialSelectionFloppy
70 cmp byte ptr [CFG_ResumeBIOSbootSeq], 0
71 je PFUPN_SelectionGone
72 jmp PFUPN_Found
73 PFUPN_SpecialSelectionFloppy:
74 cmp byte ptr [CFG_IncludeFloppy], 0
75 je PFUPN_SelectionGone
76 jmp PFUPN_Found
77
78 ; Partition is not referenced in New-IPT or Resume-BIOS/Floppy selected, but
79 ; actual media is disabled...so dig for requested partition
80 PFUPN_SelectionGone:
81 mov cl, CFG_Partitions
82 or cl, cl
83 jz PFUPN_NothingFound ; No partitions available -> so fail
84 or bl, bl
85 jz PFUPN_BootableSearchLoop
86 ; Search for Partition ID "BL"
87 PFUPN_PartIDsearchLoop:
88 call PART_GetPartitionPointer ; Gets SI for partition DL
89 cmp bptr ds:[si+LocIPT_SystemID], bl
90 je PFUPN_Found
91 dec cl
92 jz PFUPN_NothingFound
93 inc dl ; Increase
94 cmp CFG_Partitions, dl
95 ja PFUPN_PartIDsearchLoop
96 xor dl, dl
97 jmp PFUPN_PartIDsearchLoop
98
99 ; Search for Partition ID "BL"
100 PFUPN_BootableSearchLoop:
101 call PART_GetPartitionPointer ; Gets SI for partition DL
102 mov al, ds:[si+LocIPT_Flags]
103 and al, Flags_Bootable
104 jnz PFUPN_Found
105 dec cl
106 jz PFUPN_NothingFound
107
108 inc dl ; Increase
109 cmp CFG_Partitions, dl
110 ja PFUPN_PartIDsearchLoop
111 xor dl, dl
112 jmp PFUPN_PartIDsearchLoop
113
114 PFUPN_NothingFound:
115 mov dl, 080h ; Now being Disabled
116 PFUPN_Found:
117 ret
118PART_FixUpSelectionNumber EndP
119
120; ============================================================================
121; In: DS:SI - IPT-Entry of partition
122; DS:PartitionSector - Actual Boot-Record of partition
123; Out: *none* (BootRecordCRC updated)
124; CHECKME: Verify the change (BX points to sector to CRC) is working OK
125PART_UpdateBootRecordCRC Proc Near Uses bx
126 push si
127 ;~ mov si, offset PartitionSector
128 mov si, bx
129 mov bx, 4B4Dh ; Magic: 'MK'
130 call MBR_GetCheckOfSector
131 pop si
132 mov [si+LocIPT_BootRecordCRC], bx
133 ret
134PART_UpdateBootRecordCRC EndP
135
136
137
138; Rousseau:
139; ---------
140; Bug:
141; When ResumeBIOSbootSeq is zero, BX still gets decremented and shifted left.
142; Then when used as an index into ContinueBIOSbootTable to get the address
143; of the device-name, the index is two bytes too low, and SI get's loaded
144; with whatever is before the ContinueBIOSbootTable.
145; Then when SI is used to copy a null-terminated string, it depends on the
146; bogus location SI points to where a null-byte will appear.
147; Since I placed some text before the ContinueBIOSbootTable, the bogus pointer
148; SI obtained pointed to an area where there was no null-byte in sight for
149; more than 11 bytes, causing SI to overwrite the CD-ROM IPT entry with
150; garbage. It took me a while to tackle this one because I was baffled why
151; moving text around in STD_TEXT.ASM, where ContinueBIOSbootTable resides,
152; mattered while the offset of ContinueBIOSbootTable did not change.
153; This bug is also present in v1.06 but never surfaced because STD_TEXT.ASM
154; is kinda static and luck has it that the word preceding ContinueBIOSbootTable
155; presumably pointed to an area where a null byte was near.
156;
157; BOOKMARK: The nasty pointer bug
158
159
160; Copies the device-name to the Resume-BIOS IPT entry
161PART_UpdateResumeBIOSName Proc Near Uses ax bx cx si di
162
163 ; Get BIOS resume indicator.
164 ;movzx bx, CFG_ResumeBIOSbootSeq
165 mov bl,CFG_ResumeBIOSbootSeq
166 mov bh,0
167
168 ; Clear name of IPT-entry.
169 mov di, offset BIOScontIPTentry+LocIPT_Name
170 push di
171 mov cx, 11
172 mov al, ' '
173 rep stosb
174 pop di
175
176 ; If no resume then exit.
177 test bx,bx
178 jz PURBN_NoResumeBootSeq
179
180 ; Convert to index in name-table.
181 dec bx
182 shl bx, 1
183
184 ; Put the pointer to the name in SI.
185 mov si, word ptr [ContinueBIOSbootTable+bx]
186
187 ; Copy the name to the IPT-entry.
188 PURBN_BootDeviceCopyLoop:
189 lodsb
190 or al, al
191 jz PURBN_NoResumeBootSeq
192 stosb
193 jmp PURBN_BootDeviceCopyLoop
194
195 ; We're done.
196 PURBN_NoResumeBootSeq:
197
198 ret
199PART_UpdateResumeBIOSName EndP
200
201
202
203; ============================================================================
204; Partition-Pointer Functions
205; ============================================================================
206
207; Builds Pointer-Table straight (without filtering, w/o Floppy/CD-ROM/Kernels)
208PART_CalculateStraightPartPointers Proc Near
209 mov ax, offset PartitionTable
210 mov bx, offset PartitionPointers
211 mov cx, LocIPT_MaxPartitions
212
213 PCSPP_Loop:
214 mov ds:[bx], ax ; Move address IPT entry to PPT
215 add bx, 2 ; Advance pointer to PPT entry
216 add ax, LocIPT_LenOfIPT ; Advance pointer to IPT entry
217 dec cx ; Decrement counter
218 jnz PCSPP_Loop ; Next iteration
219
220 mov al, ds:[CFG_Partitions] ; Get number of partitions
221 mov ds:[PartitionPointerCount], al ; Update number for PPT
222 ret
223PART_CalculateStraightPartPointers EndP
224
225; This here does PartitionPointers in order for displaying in BootMenu
226; [this means filtering and including Floppy/CD-ROM/Kernels, if wanted]
227PART_CalculateMenuPartPointers Proc Near Uses si
228
229;!
230;! DEBUG_PROBE
231;!
232IFDEF AUX_DEBUGx
233 push 1241h
234 call DEBUG_Probe
235ENDIF
236
237 mov si, offset PartitionTable
238 mov bx, offset PartitionPointers
239 test byte ptr [CFG_IncludeFloppy], 1
240 jz PCMPP_NoFloppyInclude
241 mov ax, offset FloppyIPTentry
242 mov ds:[bx], ax
243 add bx, 2
244 PCMPP_NoFloppyInclude:
245
246 test byte ptr [CFG_ResumeBIOSbootSeq], 0FFh
247 jz PCMPP_NoResumeBootSeqInclude
248 mov ax, offset BIOScontIPTentry
249 mov ds:[bx], ax
250 add bx, 2
251 PCMPP_NoResumeBootSeqInclude:
252
253 ;movzx cx, CFG_Partitions ; LocIPT_MaxPartitions
254 mov cl,CFG_Partitions ; LocIPT_MaxPartitions
255 mov ch,0
256
257 or cx, cx
258 jz PCMPP_NoPartitions
259 PCMPP_Loop:
260 mov al, ds:[si+LocIPT_Flags]
261 and al, Flags_Bootable
262 jz PCMPP_IsNotBootable
263 mov ds:[bx], si
264 add bx, 2
265 PCMPP_IsNotBootable:
266 add si, LocIPT_LenOfIPT
267 dec cx
268 jnz PCMPP_Loop
269 PCMPP_NoPartitions:
270 sub bx, offset PartitionPointers
271 shr bx, 1
272 mov ds:[PartitionPointerCount], bl
273 ret
274PART_CalculateMenuPartPointers EndP
275
276; Gets a pointer to the given partition
277; In: DL - Number of partition
278; Out: SI - Pointer to it
279PART_GetPartitionPointer Proc Near Uses bx
280 cmp dl, 0FEh
281 je PGPP_IsBIOSbootSeq ; FEh -> Resume BIOS boot Sequence
282 ja PGPP_IsFloppy ; FFh -> Floppy
283 ;movzx bx, dl
284 mov bl,dl
285 mov bh,0
286
287 shl bx, 1
288 mov si, word ptr [PartitionPointers+bx]
289 ret
290
291 PGPP_IsBIOSbootSeq:
292;!
293;! DEBUG_PROBE
294;!
295IFDEF AUX_DEBUGx
296 push 1242h
297 call DEBUG_Probe
298ENDIF
299
300 mov si, offset BIOScontIPTentry
301 ret
302
303 PGPP_IsFloppy:
304 mov si, offset FloppyIPTentry ; PartitionTable-LocIPT_LenOfIPT
305 ret
306PART_GetPartitionPointer EndP
307
308; Gets the number of a partition pointer
309; In: SI - Pointer to Partition
310; Out: DL - Number of partition
311PART_GetPartitionNumber Proc Near Uses bx
312 mov dl, ds:[PartitionPointerCount]
313 mov bx, offset PartitionPointers
314 PGPN_SearchLoop:
315 cmp word ptr ds:[bx], si
316 je PGPN_Found
317 add bx, 2
318 dec dl
319 jnz PGPN_SearchLoop
320 mov dl, 0FFh
321 ret
322
323 PGPN_Found:
324 sub dl, ds:[PartitionPointerCount]
325 dec dl
326 not dl
327 ret
328PART_GetPartitionNumber EndP
329
330
331;
332; Following functions are only usable, when Partition-Pointer-View is filtered
333;
334
335; They will convert from and to unfiltered view (used in Boot-Menu)
336; In: DL - Number of partition in filtered view
337; Out: DL - Number of partition in straight view
338;
339; This gets the address of the IPT-entry from the Partition Pointer Table and
340; converts that to an index into the IPT; the straight view.
341;
342PART_ConvertToStraight Proc Near
343 ;movzx bx, dl
344 mov bl,dl ; Partition number to BX
345 mov bh,0
346
347 shl bx, 1 ; Convert to word index
348 mov ax, word ptr cs:[PartitionPointers+bx] ; Get the partition pointer
349 cmp ax, offset FloppyIPTentry ; Check for Floppy
350 jb PCTS_IsBIOSbootSeq ; Nope, is BIOS-bootseq
351 je PCTS_IsFloppy ; Is Floppy
352
353 ;
354 ; Is partition, AX contains pointer to IPT entry
355 ;
356 sub ax, offset PartitionTable ; Make relative
357 mov bl, LocIPT_LenOfIPT ; Length of IPT entry
358 div bl ; Divide with IPTlength
359 mov dl, al ; Index in IPT
360 ret
361
362 PCTS_IsBIOSbootSeq:
363 mov dl, 0FEh
364 ret
365 PCTS_IsFloppy:
366 mov dl, 0FFh
367 ret
368PART_ConvertToStraight EndP
369
370
371
372; In: DL - Number of partition in straight view
373; Out: DL - Number of partition in filtered view
374;
375; This searches for the absolute offset of an IPT-entry in the
376; PartitionPointers table.
377; This table holds the offsets of IPT partition entries that are in the Menu ?
378; If the offset/entry is found it's index, the filtered number, is returned.
379;
380PART_ConvertFromStraight Proc Near Uses es di
381;!
382;! DEBUG_PROBE
383;!
384IFDEF AUX_DEBUGx
385 push 1243h
386 call DEBUG_Probe
387ENDIF
388
389 cmp dl, 0FEh
390 jb PCFS_IsPartition
391 mov ax, offset BIOScontIPTentry
392 je PCFS_DoSearch
393 mov ax, offset FloppyIPTentry
394 jmp PCFS_DoSearch
395
396
397 PCFS_IsPartition:
398 ; First we get Partition-Offset in AX
399 ;movzx ax, dl
400 mov al,dl ; Index in IPT to AX
401 mov ah,0
402 mov bl, LocIPT_LenOfIPT ; Length of an IPT entry
403 mul bl ; Mul to get relative offset
404 add ax, offset PartitionTable ; Add to get absolute offset
405
406 ;
407 ; AX now points to the IPT entry of the partition.
408 ; This address is searched for in the Partition Pointer Table.
409 ;
410
411 PCFS_DoSearch:
412 ; Now search for this offset in our filtered Partition-Pointer-Table
413 push cs
414 pop es
415 mov di, offset PartitionPointers ; Point to table
416 mov cx, LocIPT_MaxPartitions ; Max number of entries to search
417 xor dl, dl ; Reply on Not-Found = Partition==0
418 repne scasw ; Compare-Loop
419 jne PCFS_NotFound
420 sub di, 2 ; One Back, so point to compared value
421 mov dx, di ; Offset in DX
422 sub dx, offset PartitionPointers ; Make relative
423 shr dx, 1 ; Convert to Index
424 ; Adjust for IncludeFloppy/etc. is automatically done, due Pointer-LookUp
425 PCFS_NotFound:
426 ret
427PART_ConvertFromStraight EndP
428
429
430
431; In: AX - Pointer to IPT Entry
432; Out: SI - Pointer to corresponding Size-Element
433; Destroyed: AX
434PART_GetSizeElementPointer Proc Near Uses bx
435 mov si, offset PartitionSizeTable
436 sub ax, offset PartitionTable
437 mov bl, LocIPT_LenOfIPT
438 div bl ; Divide with IPTlength
439 ;movzx bx, al
440 mov bl,al
441 mov bh,0
442
443 shl ax, 1
444 shl bx, 2
445 add ax, bx ; My way of multiplying with 6
446 add si, ax ; SI - Partition Size-Element
447 ret
448PART_GetSizeElementPointer EndP
449
450; In: BX:AX - Sector Size (1=512 Bytes, 2=1024 Bytes, etc.)
451; ES:DI - Pointer to Size-Element (6 bytes)
452; Out: None, Size-Element filled out
453; Destroyed: AX, BX, DI
454PART_FillOutSizeElement Proc Near Uses cx dx
455 add di, 3 ; ES:DI - Last Digit of Size Digits
456 shr bx, 1
457 rcr ax, 1 ; /2 -> Sector Size is now KByte Size
458 xor cl, cl ; 0 - KByte, 1 - MByte, 2 - GByte
459 PFOSE_MakeSmallerLoop:
460 or bx, bx
461 jnz PFOSE_MakeSmaller
462 cmp ax, 9999
463 jbe PFOSE_IsSmallEnough
464 PFOSE_MakeSmaller:
465 mov dx, bx
466 and dx, 1023 ; My crazy way of dividing a 32-bit
467 shr ax, 10 ; value through 1024 using 16-bit
468 shr bx, 10 ; instructions...
469 shl dx, 6
470 or ax, dx
471 inc cl ; Value got smaller...
472 jmp PFOSE_MakeSmallerLoop
473
474 PFOSE_IsSmallEnough:
475 ; First write the type of this Size-Element (KB/MB/GB)
476 mov bx, 'BK'
477 cmp cl, 1
478 jb PFOSE_WriteType
479 je PFOSE_IsMBtype
480 mov bx, 'BG'
481 jmp PFOSE_WriteType
482 PFOSE_IsMBtype:
483 mov bx, 'BM'
484 PFOSE_WriteType:
485 mov word ptr es:[di+1], bx
486 mov bx, 10 ; Digits are 10-Based
487 xor dx, dx
488 PFOSE_DigitLoop:
489 xor dx, dx
490 div bx ; AX - Digit, DX - Remainder
491 add dl, '0' ; Convert digit to ASCII digit
492 mov es:[di], dl
493 or ax, ax
494 jz PFOSE_EndOfDigitLoop
495 dec di ; Go to previous char
496 jmp PFOSE_DigitLoop
497
498 PFOSE_EndOfDigitLoop:
499 ret
500PART_FillOutSizeElement EndP
501
502
503
504
505
506
507
508
509
510
511
512; This routine is called to hide a partition
513; In: DL - Partition to hide
514; Destroyed: None
515PART_HidePartition Proc Near Uses ax bx cx dx si di
516
517IFDEF AUX_DEBUG
518 IF 0
519 DBG_TEXT_OUT_AUX 'PART_HidePartition:'
520 PUSHRF
521 ;~ call DEBUG_DumpRegisters
522 ;~ call AuxIO_DumpParagraph
523 ;~ call AuxIO_TeletypeNL
524 POPRF
525 ENDIF
526ENDIF
527
528 call PART_GetPartitionPointer ; Pointer to partition (DL) -> SI
529
530 ; First load the partition table of that partition...
531 mov ax, wptr [si+LocIPT_AbsolutePartTable+0]
532 mov bx, wptr [si+LocIPT_AbsolutePartTable+2]
533 mov cx, wptr [si+LocIPT_LocationPartTable+1]
534 mov dh, bptr [si+LocIPT_LocationPartTable+0]
535 mov dl, [si+LocIPT_Drive]
536 call DriveIO_LoadPartition
537 ; Partition-Table now LOADED
538 mov di, offset PartitionSector+446 ; ES:DI - 1st partitionentry...
539
540 ; Put our partition's location into registers...
541 mov ax, wptr [si+LocIPT_AbsoluteBegin+0]
542 mov bx, wptr [si+LocIPT_AbsoluteBegin+2]
543 sub ax, wptr [si+LocIPT_AbsolutePartTable+0]
544 sbb bx, wptr [si+LocIPT_AbsolutePartTable+2]
545 ; BX:AX - absolute position of partition relative to partition table
546 ; ...and search for it...
547 PHP_SearchLoop:
548 cmp ax, wptr es:[di+LocBRPT_RelativeBegin]
549 jne PHP_SearchMismatch
550 cmp bx, wptr es:[di+LocBRPT_RelativeBegin+2]
551 jne PHP_SearchMismatch
552 jmp PHP_SearchMatch
553 PHP_SearchMismatch:
554 add di, LocBRPT_LenOfEntry ; 16 Bytes per partition entry
555 cmp di, 500+offset PartitionSector
556 jb PHP_SearchLoop
557 jmp MBR_HaltSystem ; not found, something is wrong here
558
559 ; Found entry...
560 PHP_SearchMatch:
561 mov al, bptr es:[di+LocBRPT_SystemID] ; Partition-ID into AL
562 call PART_SearchFileSysHiddenID ; Put on =STEALTH=
563 mov bptr es:[di+LocBRPT_SystemID], al
564 call DriveIO_SavePartition ; Saves Partition-Table
565 ret
566PART_HidePartition EndP
567
568
569
570
571
572; This here is for marking the first "good" non-hidden partition as being
573; active. It requires the partition table at EXECBASE.
574; Some BIOSes have problems with no primary marked active. Actually this is
575; a buggy implementation, because the MBR-code should normally check,
576; *not* the BIOS. This one *could* cause havoc to some systems, but I can't
577; do anything else.
578PART_MarkFirstGoodPrimary Proc Near Uses ax si di
579
580IFDEF AUX_DEBUG
581 IF 0
582 DBG_TEXT_OUT_AUX 'PART_MarkFirstGoodPrimary:'
583 PUSHRF
584 ;~ call DEBUG_DumpRegisters
585 ;~ call AuxIO_DumpParagraph
586 ;~ call AuxIO_TeletypeNL
587 POPRF
588 ENDIF
589ENDIF
590
591 mov di, offset PartitionSector+446 ; DS:SI - 1st partitionentry
592 ; First action to do: Remove the active flag from every partition
593 push di
594 mov cl, 4
595 PMPP_RemoveActiveFlagLoop:
596 and bptr es:[di+LocBRPT_Flags], 7Fh
597 add di, LocBRPT_LenOfEntry
598 dec cl
599 jnz PMPP_RemoveActiveFlagLoop
600 pop di
601 ; First Search, will hit on any PartitionID that is:
602 ; a) not 0
603 ; b) not hidden
604 ; c) not extended partition (05h or 0Fh)
605 PMPP_Search1Loop:
606 mov al, bptr es:[di+LocBRPT_SystemID]
607 or al, al
608 jz PMPP_Search1NoHit
609 cmp al, 05h
610 je PMPP_Search1NoHit
611 cmp al, 0Fh
612 je PMPP_Search1NoHit
613 mov bl, al ; BL == AL == PartitionID
614 push si
615 call PART_SearchFileSysName
616 pop si ; AL == UnhiddenPartitionID
617 cmp al, bl ; if ID is unhidden...
618 je PMPP_SearchHit
619 PMPP_Search1NoHit:
620 add di, LocBRPT_LenOfEntry ; 16 Bytes per Partition-Entry
621 cmp di, 500+offset PartitionSector
622 jb PMPP_Search1Loop
623
624 mov di, offset PartitionSector+446 ; DS:SI - 1st Partition-Entry
625 ; Second Search, hit on anything that is not an extended partition
626 ; (05 or 0Fh)
627 PMPP_Search2Loop:
628 mov al, bptr es:[di+LocBRPT_SystemID]
629 or al, al
630 jz PMPP_Search2NoHit
631 cmp al, 05h
632 je PMPP_Search2NoHit
633 cmp al, 0Fh
634 jne PMPP_SearchHit
635 PMPP_Search2NoHit:
636 add di, LocBRPT_LenOfEntry ; 16 Bytes per Partition-Entry
637 cmp di, 500+offset PartitionSector
638 jb PMPP_Search2Loop
639 jmp PMPP_SearchFailed
640
641 PMPP_SearchHit:
642 or bptr es:[di], 80h ; SET ACTIVE PARTITION
643 PMPP_SearchFailed:
644 ret
645PART_MarkFirstGoodPrimary EndP
646
647; Searches the Name and Flags to a FileSysID (PartitionID)
648; In: AL - FileSysID
649; Out: AL - Unhidden File-System-ID, AH - Flags for this File-System
650; SI - Pointer to Name (8char)
651; Destroyed: *none*
652PART_SearchFileSysName Proc Near Uses bx dx
653 ;movzx bx, al
654 mov bl,al
655 mov bh,0
656
657 mov si, offset FileSysIDs
658 PSFSN_SearchLoop:
659 lodsw ; AL - NormalID, AH-HiddenID
660 mov dl, ds:[si] ; DL - File-System-Flags
661 inc si
662 cmp al, bl ; Check, if Unhidden-ID matches...
663 je PSFSN_Match
664 cmp ah, bl ; Check, if Hidden-ID matches...
665 je PSFSN_Match
666 mov al, bl ; So Unhidden-ID will be Original-ID
667 cmp ah, 0 ; Unknown (last ID in table)
668 je PSFSN_Match
669 inc bh
670 jmp PSFSN_SearchLoop
671
672 PSFSN_Match:
673 ; AL is already Unhidden-ID
674 mov ah, dl
675 ; AH is now the FileSystem-Flag
676 ;movzx bx, bh
677 mov bl,bh
678 mov bh,0
679
680 shl bx, 3 ; Offsets * 8
681 mov si, offset FileSysNames
682 add si, bx
683 ret
684PART_SearchFileSysName EndP
685
686; Searches the Hidden ID corresponding to a FileSysID (PartitionID)
687; In: AL - FileSysID
688; Out: AL - Hidden File-System-ID
689PART_SearchFileSysHiddenID Proc Near Uses bx
690 ;movzx bx, al
691 mov bl,al
692 mov bh,0
693
694 mov si, offset FileSysIDs
695 PSFSHI_SearchLoop:
696 lodsw ; AL - NormalID, AH-HiddenID
697 inc si
698 cmp al, bl ; Check, if Unhidden-ID matches...
699 je PSFSHI_Match
700 cmp ah, bl ; Check, if Hidden-ID matches...
701 je PSFSHI_Match
702 mov ah, bl ; So Unhidden-ID will get replied...
703 cmp ah, 0 ; Unknown (last ID in table)
704 je PSFSHI_Match
705 inc bh
706 jmp PSFSHI_SearchLoop
707
708 PSFSHI_Match:
709 mov al, ah ; AL = Hidden ID
710 ret
711PART_SearchFileSysHiddenID EndP
712
713; In: DS:SI - Partition-Name, CX - Maximum/Total Length
714; Out: Carry-Flag set, if valid Partition-Name
715; Destroyed: None
716PART_CheckForValidPartName Proc Near Uses ax cx dx si
717 ; Our logic is as follows:
718 ; If all chars are U -> Invalid (due reformated signature)
719 ; If anything below 32, but 0 -> Invalid (due invalid chars)
720 ; If anything above 165 -> Invalid (due invalid chars)
721 ; If anything between 123-128 -> Invalid (due invalid chars)
722 ; DX - holds count of 'U's
723 push cx
724 or cx, cx
725 jz PCFVPN_InvalidName
726 xor dx, dx
727 PCFVPN_CheckLoop:
728 lodsb
729 cmp al, 0
730 je PCFVPN_ValidChar
731 cmp al, 32
732 jb PCFVPN_InvalidName
733 cmp al, 165
734 ja PCFVPN_InvalidName
735 cmp al, 123
736 jb PCFVPN_ValidChar
737 cmp al, 128
738 jbe PCFVPN_InvalidName
739 PCFVPN_ValidChar:
740 cmp al, 'U'
741 jne PCFVPN_NoMagic
742 inc dx
743 PCFVPN_NoMagic:
744 dec cx
745 jnz PCFVPN_CheckLoop
746 pop cx
747 cmp cx, dx
748 clc
749 je PCFVPN_WasMagic
750 stc
751 PCFVPN_WasMagic:
752 ret
753 PCFVPN_InvalidName:
754 pop cx
755 clc
756 ret
757PART_CheckForValidPartName EndP
758
759
760
761; Compare a volume-label in the IPT to the install-volume
762; SI holds pointer to entry in IPT
763; CY set if this entry is also the install-volume
764PART_IsInstallVolume Proc Near Uses ax cx dx si di
765 cld ; Advance upwards with lodsb
766 mov di, offset OS2_InstallVolume ; Address of install-volume label (max. 11 chars)
767
768 mov cx, 11 ; Maximum length of label
769 xor dl, dl ; Not found yet
770
771 ; Compare next character
772 PART_IsInstallVolumeNext:
773 lodsb ; Load byte from SI (IPT-entry)
774 ;cmp al,' ' ; If space then use zero
775 ;jne PART_IsInstallVolume_skip1
776 ;xor al,al
777 PART_IsInstallVolume_skip1:
778 xchg ah,al ; Save char to AH
779 xchg si,di ; Exchange pointers
780 lodsb ; Load byte from SI (install-volume label)
781 ;cmp al,' ' ; If space then use zero
782 ;jne PART_IsInstallVolume_skip2
783 ;xor al,al
784 PART_IsInstallVolume_skip2:
785 xchg si,di ; Reexchange pointers
786 ;~ call AuxIO_Teletype
787 call CONV_ToUpper
788 ;~ call AuxIO_Teletype
789 xchg al,ah
790 ;~ call AuxIO_Teletype
791 call CONV_ToUpper
792 ;~ call AuxIO_Teletype
793 ;~ call AuxIO_TeletypeNL
794
795 ; Are both of them zero ?
796 ; Then the names could be the same, but cx must not equal 11
797 ; because that would indicate a null-string.
798 mov dh,al
799 or dh,ah
800 jz PART_IsInstallVolumeFound
801
802 cmp ah,al ; Are the the same ?
803 jnz PART_IsInstallVolumeNotFound ; Nope, compare ended
804 loop PART_IsInstallVolumeNext ; Yep, Compare next character
805
806 PART_IsInstallVolumeFound:
807 ; If CX is still 11 this was a zero string
808 ; and thus not a valid volume-name.
809 ; This should not occur as this function is only called when the first
810 ; byte is non-zero.
811 cmp cx,11
812 je PART_IsInstallVolumeNotFound
813 ; Found !
814 mov dl,1 ; Found
815 jmp PART_IsInstallVolumeEnd
816
817
818 PART_IsInstallVolumeNotFound:
819 mov dl,0
820 jmp PART_IsInstallVolumeEnd
821
822
823 PART_IsInstallVolumeEnd:
824 ; Set the status in CY
825 mov al,dl
826 add al,'0'
827 ;~ call AuxIO_TeletypeHexByte
828 ;~ call AuxIO_TeletypeNL
829 rcr dl,1 ; Put found-flag in CY
830 ret
831PART_IsInstallVolume EndP
832
833
834
835
836
837
838; If found CY=1, AL=partnum, else CY=0, AL=0FFH
839; BOOKMARK: Setup Phase1
840PART_SetupPhase1 Proc Uses bx cx dx si di
841
842 ;
843 ; Enumberate Bootable Systems by name
844 ; and prepare Phase 1 if active.
845 ;
846 ; This can also be implemented using the
847 ; Installable LVM-flag I think.
848 ; But at the time I had lesser knowledge about LVM...
849 ; So this algorithm may change in the future.
850 ;
851 mov byte ptr [Phase1Active],0 ; Clear phase1 indicator
852 mov si, offset PartitionTable ; Pointer to IPT
853 xor cx,cx
854 mov cl,[CFG_Partitions] ; Partitions in IPT
855
856 ; Process next entry in IPT
857 MBR_Parts:
858 add si, 4
859 ;push si
860 ;push si
861 ;call MBR_TeletypeVolName
862 ;pop si
863 call PART_IsInstallVolume ; Check if this is install-volume
864 jnc MBR_Parts_NI
865
866 ;
867 ; Install Volume found
868 ;
869 mov byte ptr [Phase1Active],1 ; Set phase1 indicator
870
871 mov al,' '
872 mov bl,7
873 mov ah, 0eh
874 int 10h
875
876 mov al,'('
877 mov bl,7
878 mov ah, 0eh
879 int 10h
880
881
882
883 mov al,[CFG_Partitions]
884 sub al,cl
885
886 mov dh,al
887
888
889 mov [CFG_PartAutomatic],al ; Setup entry for install-volume
890 mov [CFG_PartLast],al
891
892 add al,'1'
893 mov bl,7
894 mov ah, 0eh
895 int 10h
896
897 mov al,')'
898 mov bl,7
899 mov ah, 0eh
900 int 10h
901
902 ;mov bx,cx ; ????
903
904 mov al,dh
905 stc
906 jmp PART_SetupPhase1_found
907
908 MBR_Parts_NI:
909 ;xor si,si
910 ;call MBR_TeletypeNL
911 ;pop si
912 add si, 30 ; Add remainder of IPT entry
913 loop MBR_Parts
914
915 mov al,0ffh
916 clc
917
918 PART_SetupPhase1_found:
919
920 ret
921
922PART_SetupPhase1 EndP
923
924
925
926
927;~ PART_GetOldPartitionCount Proc Uses cx dx di
928 ;~ mov di,offset [PartitionXref]
929 ;~ mov dx,LocIPT_MaxPartitions
930 ;~ mov cx,dx
931 ;~ mov al,0ffh
932 ;~ cld
933 ;~ repne scasb
934 ;~ inc cx
935 ;~ sub dx,cx
936 ;~ mov ax,dx
937 ;~ ret
938;~ PART_GetOldPartitionCount EndP
939
940
941
942
943
944;~ HELEMAAL NAKIJKEN !
945;~ DRIVELETTER ASIGNMENT CORRIGEREN
946;~ WORDT TOCH BOOTDRIVE IN BPB GEZET ALS NON-OS/2 SYSTEEM BOOT ?
947
948
949
950; ###################
951; # START PARTITION #
952; ###################
953
954; Starts Partition DL from Internal Partition Table.
955; In: DL - Number of partition (filtered view)
956; Out: No Return...
957; Destroyed: None, due to no return ;-)
958; Logic: - Harddrive: loads partition Table
959; sets partition active
960; saves partition table
961; hides partitions, if needed
962; Linux-Support, if needed
963; load boot sector
964; VIBR checking, if wanted
965; install MBR Protection, if wanted
966; Special Boot Support, if needed (OS/2 Extended partitions)
967; Copy boot-sector to StartBase
968; run boot sector...
969PART_StartPartition Proc Near Uses ax dx es di
970
971IFDEF AUX_DEBUG
972 IF 0
973 DBG_TEXT_OUT_AUX 'PART_StartPartition:'
974 PUSHRF
975 ;~ call DEBUG_DumpRegisters
976 ;~ call AuxIO_DumpParagraph
977 ;~ call AuxIO_TeletypeNL
978 POPRF
979 ENDIF
980ENDIF
981
982 ;
983 ; Local Storage for this much too large function.
984 ;
985 local BootPartNo:byte
986 local PhysDiskBpbIndex:word ; Index into BPB to field of phys-disk
987 local FSType:byte ; The FS used on the loaded BPB
988 ; Only used for FAT/HPFS/JFS
989 local LVMdl:byte ; LVM drive-letter
990 local BPBdl:byte ; BPB boot-drive-letter. (at 25h)
991
992
993 ; Get Partition-Pointer (SI) to Partition-To-Boot (DL).
994 ; DL is filtered partition number and thus uses the PPT.
995 ; Returned is the address of the IPT entry of the partition to boot.
996 call PART_GetPartitionPointer
997
998
999 ;
1000 ; SI now points to the IPT entry for the partition to be booted.
1001 ;
1002
1003
1004 ; This converts DL filered view to straight view, aka index into the IPT.
1005 ; Needed for later.
1006 ; Destroys AX,BX
1007 call PART_ConvertToStraight
1008
1009 ; Save for later use.
1010 mov [BootPartNo], dl
1011 ; Straight - FFh -> Floppy boot
1012 ; FEh -> BIOS continue (CD-ROM, ZIP, etc.)
1013
1014 ; This converts the PPT to have pointers to all the IPT entries.
1015 ; We need straight pointers from now on, so calculate the table...
1016 ; Destroys AX,BX,CX
1017 call PART_CalculateStraightPartPointers
1018
1019
1020
1021 ; SI contains the pointer to the IPT to what partition to boot
1022 ; in this whole routine...it may never get messed up.
1023
1024 ; ------------------------------------------------- PRINT NAME BEING BOOTED
1025
1026 push si
1027 mov dl, [si+LocIPT_Drive] ; Disk where partition resides
1028 mov dh, [si+LocIPT_SystemID] ; AB FileSystem ID (08=NTFS, FC=JFS)
1029 ; Copy Partition-Name to BootingNow area for display purposes
1030 add si, LocIPT_Name ; Advance to AB partition-name
1031 mov cx, 11 ; Max. length of AB name/label
1032 call GetLenOfName ; Returns CX with length of label
1033 mov di, offset TXT_BootingNowPartName
1034 jz PSP_NoName ; Don't copy if zero length label
1035 rep movsb ; Copy label-name to boot
1036 PSP_NoName:
1037 xor al, al ; Null-terminate label-string
1038 stosb ; Ending Zero
1039
1040 ;
1041 ; Display "Booting the system using "
1042 ;
1043 mov si, offset TXT_BootingNow1
1044 call MBR_Teletype
1045
1046 ;~ pusha
1047 ;~ call MBR_Teletype
1048 ;~ mov si,offset TXT_BootingNowPartName
1049 ;~ call MBR_Teletype
1050 ;~ popa
1051
1052
1053 ;
1054 ; DL will be zero for floppy-disk or 80h+ for harddisk.
1055 ; Note thus that DL contains the BIOS disk numer and not the AB value
1056 ; for floppy or cdrom.
1057 ;
1058 or dl, dl
1059 jnz PSP_IsHarddisc
1060
1061 ; When booting floppy/CD-ROM/etc., we got other text to be displayed...
1062 mov si, offset TXT_BootingNowPartName
1063 call MBR_TeletypeVolName
1064 jmp PSP_IsFloppyCDROMetc ; JUMPS BUITEN SI POP !!! AANPASSEN
1065
1066
1067 PSP_IsHarddisc:
1068
1069
1070 ;
1071 ; Save configuration on HDD boots (save CFG_PartLast)
1072 ;
1073 call DriveIO_SaveConfiguration
1074
1075
1076 ;
1077 ; Prints out BootingNow2 including PartitionName
1078 ;
1079 mov si, offset TXT_BootingNowPartName
1080 call MBR_TeletypeVolName
1081 mov si, offset TXT_BootingNowPartition
1082 call MBR_Teletype
1083
1084 ; restores SI (IPT-pointer)
1085 pop si
1086
1087
1088
1089 ;
1090 ; Get the CHS and LBA location of sector containing
1091 ; the partition-table for the partition.
1092 ;
1093 mov ax, wptr [si+LocIPT_AbsolutePartTable+0]
1094 mov bx, wptr [si+LocIPT_AbsolutePartTable+2]
1095 mov cx, wptr [si+LocIPT_LocationPartTable+1]
1096 mov dh, bptr [si+LocIPT_LocationPartTable+0]
1097 mov dl, [si+LocIPT_Drive]
1098
1099IFDEF AUX_DEBUG
1100 IF 1
1101 pushf
1102 pusha
1103 mov si,offset [ptetb]
1104 call AuxIO_Print
1105 call DEBUG_DumpRegisters
1106 call AuxIO_TeletypeNL
1107 mov ax, word ptr [FreeDriveletterMap+00h]
1108 mov dx, word ptr [FreeDriveletterMap+02h]
1109 call AuxIO_TeletypeBinDWord
1110 popa
1111 popf
1112 ENDIF
1113ENDIF
1114
1115
1116 ;
1117 ; This loads the MBR in case of PRI or the EBR in case of LOG partitions.
1118 ;
1119 ; BOOKMARK: PBR/EBR loading
1120 call DriveIO_LoadPartition ; Load Table... [LOAD]
1121
1122
1123 ; -------------------------------------------------- MODIFY PARTITION TABLE
1124
1125 ; Make sure ES is correctly setup.
1126 push cs
1127 pop es
1128
1129 ; ES:DI - First Partitionentry
1130 mov di, offset PartitionSector+446
1131
1132 ; Remove all active-flags for safety reasons, primary partition table will
1133 ; have one partition set active by ScanPartition-routine.
1134 push di
1135 mov cl, 4
1136 PSP_RemoveActiveFlagLoop:
1137 and bptr es:[di+LocBRPT_Flags], 7Fh
1138 add di, LocBRPT_LenOfEntry
1139 dec cl
1140 jnz PSP_RemoveActiveFlagLoop
1141 pop di
1142
1143
1144 ;
1145 ; Put the partition-to-be-booted location into registers...
1146 ;
1147 mov ax, wptr [si+LocIPT_AbsoluteBegin+0]
1148 mov bx, wptr [si+LocIPT_AbsoluteBegin+2]
1149 sub ax, wptr [si+LocIPT_AbsolutePartTable+0]
1150 sbb bx, wptr [si+LocIPT_AbsolutePartTable+2]
1151
1152
1153 ; BX:AX - absolute position of partition relative to partition table
1154 ; ...and search for it...
1155 PSP_SearchLoop:
1156 cmp ax, wptr es:[di+LocBRPT_RelativeBegin]
1157 jne PSP_SearchMismatch
1158 cmp bx, wptr es:[di+LocBRPT_RelativeBegin+2]
1159 jne PSP_SearchMismatch
1160 jmp PSP_SearchMatch
1161 PSP_SearchMismatch:
1162 add di, LocBRPT_LenOfEntry ; 16 Bytes per Partition-Entry
1163 cmp di, 500+offset PartitionSector
1164 jb PSP_SearchLoop
1165
1166 ;
1167 ; Entry not found, Halt System.
1168 ;
1169 jmp MBR_HaltSystem
1170
1171 ; ------------------------------------------------------------- ENTRY FOUND
1172 PSP_SearchMatch:
1173 or byte ptr es:[di+LocBRPT_Flags], 80h ; set ACTIVE partition
1174
1175
1176
1177 ;
1178 ; Save the Partition Table.
1179 ;
1180 call DriveIO_SavePartition ; Saves the Partition-Table [SAVE]
1181
1182
1183
1184 ; --------------------------------------------------------------- OS/2 I13X
1185 ; Now check if the partition to get booted is above 8 GB.
1186 ; If yes, set magic bytes 'I13X' at 3000:0 for boot-loader to recognize.
1187 ; This method is (c) by IBM <g>
1188 ; Rousseau: Booting IBM-BM also requires the LBA address of the IBM-BM
1189 ; partitionafter the 'I13X' signature.
1190 ; Also, FS needs to be set to 3000H.
1191 ; This info was obtained by examining the LVM 2,x MBR-code.
1192 mov ax, wptr [si+LocIPT_AbsoluteBegin+0]
1193 mov bx, wptr [si+LocIPT_AbsoluteBegin+2]
1194 add ax, wptr es:[di+LocBRPT_AbsoluteLength+0] ; Add length to absolute
1195 adc bx, wptr es:[di+LocBRPT_AbsoluteLength+2] ; begin location
1196 ; BX:AX -> Absolute End-Position of Partition
1197
1198
1199 ;
1200 ; Always use INT13X v1.0.8+.
1201 ;
1202 ;~ test byte ptr [CFG_ForceLBAUsage], 1
1203 ;~ jnz PSP_ForceI13X
1204 jmp PSP_ForceI13X
1205
1206 ; LBA-boundary at 16450560 (FB0400h) (16320x16x63)
1207 cmp bx, 00FBh
1208 jb PSP_NoI13X
1209
1210 ;
1211 ; BOOKMARK: Setup 'I13X' signature.
1212 ;
1213 PSP_ForceI13X:
1214 push es
1215 push di
1216 push si
1217
1218 ; Setup ES and FS.
1219 ; FS needs to keep this address.
1220 mov ax, 3000h
1221 mov es, ax
1222 ; mov fs,ax
1223 db 08eh
1224 db 0e0h
1225
1226 ; Insert signature
1227 xor di, di
1228 mov word ptr es:[di+00], '1I'
1229 mov word ptr es:[di+02], 'X3'
1230
1231 ;mov wptr es:[di], 0
1232 ;mov wptr es:[di+2], 0
1233
1234 ; Insert LBA address.
1235 mov ax, [si+LocIPT_AbsoluteBegin+0]
1236 mov es:[di+04], ax
1237 mov ax, [si+LocIPT_AbsoluteBegin+2]
1238 mov es:[di+06], ax
1239
1240 pop si
1241 pop di
1242 pop es
1243
1244
1245
1246 PSP_NoI13X:
1247
1248 ; now check, if we need to hide any partition
1249 test byte ptr [si+LocIPT_Flags], Flags_HideFeature
1250 jz PSP_NoHideFeature
1251
1252 ; ---------------------------------------------------- PARTITION HIDING
1253
1254 ; display "hide active"
1255 push si
1256 mov si, offset TXT_BootingHide
1257 call MBR_Teletype
1258 pop si
1259
1260
1261 ; First, find Hide-Config
1262 mov dl, [BootPartNo] ; EntryNumber is straight view
1263 ;~ mov ax, LocIPT_MaxPartitions
1264 mov ax, LocHPT_LenOfHPT
1265 mul dl
1266 mov di, offset HidePartitionTable
1267 add di, ax ; We got the pointer
1268
1269
1270 ; So process Hide-Config. Read out Bitfield-Entries,
1271 ; each points to a partition.
1272 ; 3Fh is end-marker / maximum entries = CFG_Partitions
1273 mov cl, [CFG_Partitions]
1274 mov ch,0 ; Index in bitfield array.
1275 mov dh,6 ; Bitfield width.
1276 mov bx,di ; Pointer to entry.
1277
1278 PSP_PartitionsHideLoop:
1279 mov dl,ch
1280 call CONV_GetBitfieldValue
1281 mov dl,al
1282
1283 ;~ mov dl, es:[di]
1284 ;~ inc di
1285 ;~ cmp dl, 0FFh
1286 cmp dl,3fh ; Max value for 6-bits field.
1287 je PSP_EndOfHideProcess ; -> End of Hiding
1288 call PART_HidePartition ; Now hide that partition
1289 inc ch ; Next bitfield.
1290 dec cl
1291 jnz PSP_PartitionsHideLoop
1292
1293
1294 PSP_EndOfHideProcess:
1295
1296 ; --- HIDE COMPLETED ---
1297 ; So something got hidden and we have to remark a primary partition,
1298 ; if we are booting something non-primary from the boot-disk.
1299 mov al, [BIOS_BootDisk]
1300 cmp bptr [si+LocIPT_Drive], al
1301 jne PSP_HideAdjustPrimaryMark ; When booting any hdd, but boot-disk
1302 mov ax, wptr [si+LocIPT_AbsolutePartTable]
1303 mov bx, wptr [si+LocIPT_AbsolutePartTable+2]
1304 or ax, ax
1305 jnz PSP_HideAdjustPrimaryMark ; or booting non-primary partition
1306 or bx, bx ; on boot-disk.
1307 jz PSP_NoHideAdjustPrimaryMark
1308
1309 PSP_HideAdjustPrimaryMark:
1310 ; Load Primary Partition Table...
1311 xor ax, ax
1312 xor bx, bx
1313 mov cx, 0001h ; Cylinder 0, Sector 1
1314 xor dh, dh ; Head 0
1315 mov dl, [BIOS_BootDisk] ; Boot Disk
1316
1317 ; This uses the boot-disk and alters 'CurPartition_Location'.
1318 ; CHECKME: How does 81h being the boot-disk influences this ?
1319 call DriveIO_LoadPartition ; Load Primary Partition Table
1320
1321 ; This would only be needed for very old BIOSses
1322 call PART_MarkFirstGoodPrimary
1323
1324 ; CHECKME: Disabled writing back MBR with modified boot flags
1325 ; This is a safety measure now that booting AirBoot from other disks
1326 ; than 80h can occur.
1327 ;~ call DriveIO_SavePartition ; Saves the Partition-Table
1328
1329
1330 PSP_NoHideAdjustPrimaryMark:
1331
1332
1333 PSP_NoHideFeature:
1334 ; Check, if we are supposed to ignore LVM altogether...
1335 test byte ptr [CFG_IgnoreLVM], 1
1336 jnz PSP_NoLVMReassignment
1337
1338 ; ---------------------------------------------------- LVM REASSIGNMENT
1339
1340 ; Driveletter must be set for this partition
1341 test byte ptr [si+LocIPT_Flags], Flags_DriveLetter
1342 jz PSP_NoLVMReassignment
1343 ;movzx bx, BootPartNo ; EntryNumber is straight view
1344 mov bl,[BootPartNo] ; EntryNumber is straight view
1345 mov bh,0
1346
1347 mov al, bptr [DriveLetters+bx]
1348 sub al, 3Dh ; Convert e.g. 80h -> 'C'
1349 cmp al, bptr [PartitionVolumeLetters+bx]
1350
1351
1352 ;~ je PSP_NoLVMReassignment ; If driveletters match -> no change
1353 ; Rousseau:
1354 ; But there can still be other partitions with the same drive-letter.
1355 ; For instance if the user did an advanced installation with multiple
1356 ; eComStation systems using the same boot-drive-letter.
1357 ; So, even if the drive-letter forced is the same as the
1358 ; partition-volume-letter, other partitions still need to be checked
1359 ; and possibly hidden. So we always do the drive-letter reassignment,
1360 ; which is enhanced to keep data-partitions (those -not- in the Menu)
1361 ; visible. So the 'je' instruction above is commented-out.
1362
1363
1364 ;
1365 ; Give partition SI letter AL
1366 ;
1367 call LVM_DoLetterReassignment
1368
1369
1370
1371
1372 PSP_NoLVMReassignment:
1373 push si
1374 ; -------------------------------------------------- -"PLEASE WAIT..."-
1375 PSP_IsFloppyCDROMetc:
1376 mov si, offset TXT_BootingWait
1377 call MBR_Teletype ; display "please wait" ; SI staat nog op stack; aanpassen !!!!
1378 pop si
1379
1380 ; Process Partition Tables, if M$-Hack required (changes Ext Part Type)
1381 call MSHACK_ProcessPartTables
1382
1383 test byte ptr [CFG_BootMenuActive], 0FFh
1384 jz PSP_NoMenuNoSound
1385
1386 ; ---------------------------------------------------------- BOOT-SOUND
1387 call SOUND_ExecuteBoot
1388
1389 PSP_NoMenuNoSound:
1390
1391 ; --------------------------------------------- SPECIAL BOOT PROCESSING
1392 ; Check here, if the Boot shall be done via resume to BIOS...
1393 mov al, byte ptr [si+LocIPT_SystemID]
1394 cmp al, 0FEh ; Via BIOS ? (aka resume BIOS boot sequence)
1395 je PSP_ResumeBIOSbootSeq
1396
1397 jmp PSP_StartNormal
1398
1399 PSP_ResumeBIOSbootSeq:
1400 int 18h ; Give control back to BIOS
1401 db 0EAh ; if return to here -> Reboot
1402 dw 0FFF0h
1403 dw 0F000h
1404
1405
1406 ; =======================================================================
1407 ; FROM THIS POINT ON, ONLY DS and SI REGISTER IS NEEDED TO BE PRESERVED
1408 ; =======================================================================
1409
1410 PSP_StartNormal:
1411 mov ax, wptr [si+LocIPT_AbsoluteBegin+0]
1412 mov bx, wptr [si+LocIPT_AbsoluteBegin+2]
1413 mov cx, [si+LocIPT_LocationBegin+1]
1414 mov dh, [si+LocIPT_LocationBegin+0]
1415 mov dl, [si+LocIPT_Drive]
1416
1417 ; This loads the PBR of the partition.
1418 call DriveIO_LoadPartition ; Loads boot-sector... [PARTBOOTSEC]
1419
1420 ;
1421 ; The JFS PBR-code does not use the passed BPB in memory but uses the BPB
1422 ; on disk. This breaks the drive-letter feature on JFS.
1423 ; So we make a copy of the PBR in memory, and if the partition is JFS
1424 ; we later adjust the physical-disk and boot-drive-letter in this
1425 ; copy and write it back to disk.
1426 ; Then the JFS PBR-code will see the correct boot-drive-letter.
1427 ;
1428 pusha
1429 mov si,offset [PartitionSector]
1430 mov di,offset [PBRSector]
1431 mov cx,100h
1432 cld
1433 rep movsw
1434 popa
1435
1436
1437
1438 ; Check if the disk is a harddisk or a floppy.
1439 mov dl,[si+LocIPT_Drive]
1440 cmp dl, 80h
1441 jae is_harddisk
1442
1443 ;
1444 ; This is a dirty hack to fix booting from a floppy.
1445 ; With all the modifications made since v1.06 this feature was broken
1446 ; because Int13X is used implicitly now, and that does not work
1447 ; for diskette access.
1448 ; This jumps to the code that loads and starts the pbr-code.
1449 ; Note that it also skips virus checking !
1450 ; This will be fixed at a later date.
1451 jmp boot_from_floppy
1452
1453 ;
1454 ; The disk is a harddisk so we need to do various checks and fixes.
1455 ;
1456 is_harddisk:
1457
1458 test byte ptr [CFG_DetectVIBR], 1
1459 jz PSP_NoVIBR
1460 test byte ptr [si+LocIPT_Flags], Flags_VIBR_Detection
1461 jz PSP_NoVIBR
1462
1463
1464 ; ----------------------------------------------------- CHECKS FOR VIBR
1465 ; BOOKMARK: Check for virus in PBR
1466 push si
1467 mov si, offset PartitionSector
1468 mov bx, 4B4Dh ; Magic: 'MK'
1469 call MBR_GetCheckOfSector
1470 pop si
1471
1472 cmp [si+LocIPT_BootRecordCRC], bx
1473 je PSP_NoVIBR
1474 mov bx, [si+LocIPT_BootRecordCRC]
1475 or bx, bx
1476 jz PSP_NoVIBR
1477 ; Oh Oh, got a virus :(
1478 mov si, offset TXT_VirusFoundMain
1479 call MBR_Teletype
1480 mov si, offset TXT_VirusFound2 ; VIBR-Virus
1481 call MBR_Teletype
1482 mov si, offset TXT_VirusFoundEnd
1483 call MBR_Teletype
1484 jmp MBR_HaltSystem
1485
1486 PSP_NoVIBR:
1487 test byte ptr [CFG_ProtectMBR], 1
1488 jz PSP_NoMBRprotect
1489 ; --------------------------------------------- INSTALLS MBR-PROTECTION
1490 ; We need DS:SI later...
1491 push ds
1492 push si
1493
1494 ; First subtract 1024 bytes from Base-Memory...
1495 push ds
1496 mov ax, 40h
1497 mov ds, ax
1498 mov dx, word ptr ds:[13h]
1499 dec dx ; 1 == 1kbyte
1500 mov word ptr ds:[13h], dx
1501 pop ds
1502 shl dx, 6 ; trick, now DX is a segment
1503
1504 ; Now copy in our code (to DX:0)...
1505
1506 mov si, offset MBR_Protection ; DS:SI - Source Image
1507 mov es, dx
1508 xor di, di ; ES:DI - Destination
1509 ;~ mov cx, 512
1510 mov cx, 384
1511 rep movsw ; Move 768 bytes...
1512
1513 ; Now fill in variables...
1514
1515 xor ax, ax
1516 mov ds, ax
1517 mov si, 10h*4
1518 xor di, di ; INT 10h Vector to MBR Protection
1519 ;movsd
1520 movsw
1521 movsw
1522
1523 mov si, 13h*4 ; INT 13h Vector to MBR Protection
1524 ;movsd
1525 movsw
1526 movsw
1527
1528 mov al, CFG_IgnoreWriteToMBR ; Option to MBR Protection
1529 stosb
1530
1531 ; Now switch INT 13h vector to MBR Protection
1532
1533 sub si, 4
1534 mov ax, 9
1535 mov ds:[si], ax
1536 mov ds:[si+2], dx ; Vector hardcoded at DS:0009
1537 ; MBR-Protection now active :)
1538
1539 ; Restore DS:SI
1540 pop si
1541 pop ds
1542
1543
1544
1545 PSP_NoMBRprotect:
1546
1547 ; Display volume-name in bold
1548 ; Just before booting the selected partition
1549 ;pushf
1550 ;pusha
1551 ;push si
1552 ;add si, LocIPT_Name
1553 ;call MBR_TeletypeVolName
1554 ;xor si,si
1555 ;call MBR_TeletypeNL
1556 ;pop si
1557 ;popa
1558 ;popf
1559
1560
1561
1562
1563
1564 ; ------------------------------------------------ SPECIAL PARTITION SUPPORT
1565 ; needed by OS/2 Warp / eComStation
1566
1567
1568 ;cmp byte ptr [si+LocIPT_SystemID],08 ; I hate Microsuck NTFS check
1569 mov di, offset PartitionSector ; ES:DI - Actual Boot-Record
1570
1571 ; Special Support Detection
1572 ;mov ax, word ptr es:[di+18h]
1573 ;cmp ax, 003Fh ; Physical Layout-Sectors... Safety check
1574
1575
1576
1577 ;
1578 ; At this point, SI points to IPT and DI points to the PBR from disk.
1579 ; Depending on the type of BPB used, the physical disk field is at
1580 ; different locations: 24h for old-style (OS/2) BPB's and 40h for
1581 ; FAT32 BPB's.
1582 ; The OS/2 boot-drive-letter is located at 25h in an old-style BPB,
1583 ; while the corresponding field in a FAT32 BPB is located at 41h but
1584 ; used for different purposes.
1585 ; In case of HPFS, using old-style BPB's, the boot-drive-letter needs
1586 ; to be adjusted if it is zero.
1587 ; In that case we trace the LVM-info for that partition and use the
1588 ; drive-letter defined there.
1589 ; This fixes issues #3067 and #3119.
1590 ; Adjusting the physical disk is always done but at different locations
1591 ; depending on the BPB used.
1592 ; Also, the "hidden sectors" field is adjusted to contain the absolute
1593 ; offset from the start of the disk instead of the relative offset to
1594 ; the start of the partition.
1595 ; http://homepage.ntlworld.com./jonathan.deboynepollard/FGA/bios-parameter-block.html
1596 ;
1597
1598
1599 ; Get index of phys-disk field in BX
1600 call PART_GetFieldIndex
1601 mov [PhysDiskBpbIndex],ax
1602 mov bx,ax
1603
1604 ; Locate cursor for output of debug-info
1605 ;~ pusha
1606 ;~ mov ch,7
1607 ;~ mov cl,0
1608 ;~ call VideoIO_Color
1609 ;~ mov ch,6
1610 ;~ mov cl,1
1611 ;~ call VideoIO_Locate
1612 ;~ popa
1613
1614
1615 ; Debug display physdisk, ptype and physdisk offset in BPB
1616 ;~ pusha
1617 ;~ mov ah,[si+LocIPT_Drive]
1618 ;~ mov al,[si+LocIPT_SystemID]
1619 ;~ call VideoIO_PrintHexWord
1620 ;~ mov ax,bx
1621 ;~ call VideoIO_PrintHexWord
1622 ;~ mov ax,[si+LocIPT_AbsolutePartTable+02]
1623 ;~ call VideoIO_PrintHexWord
1624 ;~ mov ax,[si+LocIPT_AbsolutePartTable+00]
1625 ;~ call VideoIO_PrintHexWord
1626 ;~ mov al,[ExtendedAbsPosSet]
1627 ;~ call VideoIO_PrintHexByte
1628 ;~ mov al,'-'
1629 ;~ call VideoIO_PrintSingleChar
1630 ;~ mov al,byte ptr [Menu_EntrySelected]
1631 ;~ call VideoIO_PrintHexByte
1632 ;~ mov al,byte ptr [CFG_PartAutomatic]
1633 ;~ call VideoIO_PrintHexByte
1634 ;~ mov al,byte ptr [Phase1Active]
1635 ;~ call VideoIO_PrintHexByte
1636 ;~ mov al,byte ptr [NewPartitions]
1637 ;~ call VideoIO_PrintHexByte
1638 ;~ mov al, byte ptr [OldPartitionCount]
1639 ;~ call VideoIO_PrintHexByte
1640 ;~ popa
1641
1642
1643 ;
1644 ; If the partition is IBM-BM we skip all the BPB adjustments.
1645 ; IBM-BM does no need them.
1646 ;
1647 cmp byte ptr [si+LocIPT_SystemID], 0ah
1648 jnz no_os2_bm
1649 jmp chainload_ibm_bm
1650
1651
1652 no_os2_bm:
1653
1654 ;
1655 ; Update the phys-disk field
1656 ; DI points to PartitionSector
1657 ; BX holds index to phys-disk field
1658 ;
1659 mov al,byte ptr [si+LocIPT_Drive] ; Moet dit niet later gebeuren ??? (NT/WIN LDR hangs)
1660 mov es:[di+bx],al
1661
1662
1663 ;
1664 ; Legacy systems do not put the correct values in the "hidden sectors"
1665 ; field. Also, this field will be incorrect if a partition is moved on
1666 ; disk by a disktool not accounting for this field.
1667 ; Linux does not have a BPB at all, and does not use this field.
1668 ; So we set the correct value here obtained by the partition scanner.
1669 ; This fixing is done by OS/2 BM as well, according to Martin.
1670 ;
1671
1672 ; BOOKMARK: Fix hidden sectors field
1673 mov ax,[si+LocIPT_AbsoluteBegin]
1674 mov es:[di+1ch], ax ; Low word of 32-bits "hidden sectors"
1675
1676 mov ax,[si+LocIPT_AbsoluteBegin+2]
1677 mov es:[di+1eh], ax ; High word of 32-bits "hidden sectors"
1678
1679 ;
1680 ; Check partitions to see if boot-drive-letter fixing is needed.
1681 ; FAT12/FAT16/HPFS/JFS will have the value at 25h fixed
1682 ; to the LVM-info drive-letter. (+3dh to convert to BIOS notation)
1683 ;
1684
1685
1686 ; Setup partition disk and LBA address
1687 mov dl,byte ptr [si+LocIPT_Drive]
1688 mov cx,[si+LocIPT_AbsoluteBegin+00h]
1689 mov bx,[si+LocIPT_AbsoluteBegin+02h]
1690
1691 ; AL is gonna be used to shift-in CY status.
1692 ; If the type of file-system is one of FAT12/FAT16/HPFS/JFS then
1693 ; AL will be <> 0 and the boot-drive-letter can be tested / fixed.
1694 mov al,0
1695
1696
1697 ;
1698 ; The PBR is already loaded, no need to load it again in the
1699 ; calls below.
1700 ;
1701 ; Better use the already done discovery to determine the system.
1702 ;
1703 ; FIXME: PBR Already loaded
1704
1705 ; When FAT12/FAT16/HPFS/JFS then boot-drive-letter can be tested
1706 ; or adjusted.
1707 call PART_IsJFS
1708 rcl al,1
1709 call PART_IsHPFS
1710 rcl al,1
1711 call PART_IsFAT
1712 rcl al,1
1713 mov ah,al
1714
1715 ; Store for later reference.
1716 mov [FSType],al
1717
1718
1719 ;
1720 ; When the phys-disk byte (80h) is put in this BPB in RAM,
1721 ; Windows will not find it's loader if Windows itself
1722 ; is installed in a logical partition but the loader is on FAT
1723 ; in a primary.
1724 ; This goes for all NT-based versions ?
1725 ;
1726
1727
1728 ;
1729 ; See if phys-disk / boot-drive-letter fix is needed
1730 ; depending on FS used.
1731 ; AL will be 0 for any file-system other than FAT12/FAT16/HPFS/JFS.
1732 ; In that case no fixing of boot-drive-letters is needed.
1733 ;
1734 test al,al
1735 jz bdl_ok
1736
1737
1738 ;
1739 ; We have a partition that potentially can have incorrect values
1740 ; for the boot-drive-letter or incorrect LVM drive-letters.
1741 ;
1742 ; The boot-drive-letter can be zero as the result of copying / moving
1743 ; partitions or restoring a HPFS system from archive.
1744 ; In that case the LVM drive-letter is used if present.
1745 ;
1746 ; Incorrect LVM drive-letters are the result of the drive-letter
1747 ; reassign function when two or more eComStation installations use the
1748 ; same boot-drive-letter.
1749 ; In that case the boot-drive-letter is assigned to the
1750 ; LVM drive-letter.
1751 ;
1752 ; If both are zero there is no way to obtain the correct
1753 ; boot-drive-letter value. The user needs to examine CONFIG.SYS and
1754 ; force that letter for the partition.
1755 ;
1756
1757
1758
1759
1760
1761 ;
1762 ; Get the drive-letter for the partition from the LVM-info.
1763 ; Returns CY=0 if AL contains drive-letter, '*' or 0.
1764 ; Returns CY=1 and AL=0 if no LVM info found.
1765 ; The new 'LVM_GetDriveLetter' directly uses SI, so the loading of
1766 ; DL, CX and BX is not needed. We'll leave it here for now.
1767 ;
1768 mov dl,byte ptr [si+LocIPT_Drive]
1769 mov cx,[si+LocIPT_AbsoluteBegin+00h]
1770 mov bx,[si+LocIPT_AbsoluteBegin+02h]
1771
1772 ; Now uses SI, not DL,CX,BX
1773 call LVM_GetDriveLetter
1774 ;//! CHECKME: No test on LVM info found
1775
1776 ; Save for later use.
1777 mov byte ptr [LVMdl], al
1778
1779 ; See if the drive-letter feature is active.
1780 ; If active, we force the drive-letter from the user.
1781 test byte ptr [si+LocIPT_Flags], Flags_DriveLetter
1782
1783 ; Nope, it's not so we don't force the boot-drive-letter.
1784 jz PSP_NoLogicalSupport
1785
1786 ; Partition index in BX
1787 mov bl,[BootPartNo] ; EntryNumber is straight view
1788 mov bh,0
1789
1790 ; Get the user specified boot-drive-letter.
1791 ; 80h notation.
1792 mov al, bptr [DriveLetters+bx]
1793
1794 ; Safety check for zero value.
1795 test al,al
1796 jz PSP_NoValidUserDriveLetter
1797
1798 ; Convert 80h notation to ASCII.
1799 sub al,3dh ; 80h - 3dh = 43h = 'C', etc.
1800
1801 PSP_NoValidUserDriveLetter:
1802 ; Here we misuse the LVM-dl storage to store the user forced
1803 ; or zero drive-letter.
1804 mov byte ptr [LVMdl], al
1805
1806
1807 PSP_NoLogicalSupport:
1808
1809 ; A possibly valid drive-letter has been obtained from either
1810 ; LVM-info or the drive-letter feature.
1811 ; It's in [LDMdl] local storage.
1812
1813
1814
1815 ;
1816 ; Get the boot-drive-letter from the BPB of the partition.
1817 ;
1818 mov bx, [PhysDiskBpbIndex]
1819 inc bx
1820 mov al,es:[di+bx] ; 80h=C:,81h=D:, etc.
1821 ; Store it for later use
1822 mov byte ptr [BPBdl], al
1823
1824
1825 ; See if both the LVM drive-letter and the BPB drive-letter are zero.
1826 ; If so, then we have a problem.
1827 ; No valid drive-letter can be obtained and the user has to examine
1828 ; CONFIG.SYS and set that letter in the drive-letter feature
1829 ; for the partition.
1830 mov ah,al
1831 mov al, byte ptr [LVMdl]
1832 or al,ah
1833 jz no_valid_boot_drive_letter_found
1834
1835
1836 ; See if both the LVM drive-letter and the BPB drive-letter are
1837 ; the same. In that case we should have a valid situation and no
1838 ; adjustments need to be made.
1839 cmp al,ah
1840 jz PSP_valid_boot_drive
1841
1842
1843 ;
1844 ; Ok, at least one of them is valid.
1845 ;
1846
1847 ; See if the BPB boot-drive-letter is valid
1848 ; This one is supposed not to change since OS/2 cannot be booted
1849 ; from another drive then it was installed on.
1850 test ah,ah
1851 jnz BPB_boot_drive_valid
1852
1853 ; Nope it's not.
1854 ; So we use the LVM drive-letter for the BPB boot-drive-letter.
1855 ; Convert to BIOS notation ('C'+3dh=80h, 'D'->81h, etc.)
1856 ; This is where the user can fix this issue by using the
1857 ; drive-letter feature.
1858 add al,3dh
1859 mov bx,[PhysDiskBpbIndex]
1860 ; Advance to field for drive-letter in BIOS notation (OS/2)
1861 inc bx
1862 ; Fix the boot-drive-letter field in the BPB
1863 mov es:[di+bx],al
1864
1865 jmp PSP_valid_boot_drive
1866
1867 ;
1868 ; OS/2 uses this field to indicate the boot-drive-letter for the system.
1869 ; It is in BIOS notation where 80h='C', 81h='D' ... 97h='Z'.
1870 ; This is the field that get's forced to a specific value when the
1871 ; drive-letter feature of AiR-BOOT is used.
1872 ; Also, this field is the culprit of AiR-BOOT v1.07 not handling it
1873 ; correctly when the system uses HPFS and this byte is zero.
1874 ; This mostly involved booting older OS/2 versions on HPFS.
1875 ; See issues #3067 and #3119 on http://bugs.ecomstation.nl
1876 ;
1877
1878
1879 ;
1880 ; Here we enter when the LVM drive-letter is zero or not the same
1881 ; as the BPB boot-drive-letter.
1882 ; This can be the case when booting a hidden partition, LVM-dl = zero,
1883 ; or the LVM-dl was reassigned because another system with the same
1884 ; drive-letter was booted previously.
1885 ; In any case, we set the LVM drive-letter to the BPB boot-drive-letter
1886 ; so the system can be booted.
1887 ; Driveletters on other partitions have already been reassigned by the
1888 ; reassignement-procedure earlier.
1889 ;
1890 BPB_boot_drive_valid:
1891
1892
1893
1894
1895 ;
1896 ; ALWAYS SET LVM to BPB
1897 ;
1898 ;~ mov dl,byte ptr [si+LocIPT_Drive]
1899 ;~ mov cx,[si+LocIPT_AbsoluteBegin+00h]
1900 ;~ mov bx,[si+LocIPT_AbsoluteBegin+02h]
1901 ;~ mov al,[BPBdl]
1902 ;~ sub al,3dh
1903 ;~ call LVM_SetDriveLetter
1904
1905
1906;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1907 ;
1908 ; ALWAYS SET BPB to LVM
1909 ;
1910 mov dl, byte ptr [si+LocIPT_Drive]
1911 mov cx, [si+LocIPT_AbsoluteBegin+00h]
1912 mov bx, [si+LocIPT_AbsoluteBegin+02h]
1913
1914 ; Now uses SI, not DL,CX,BX
1915 call LVM_GetDriveLetter
1916 ;//! CHECKME: No test on LVM info found
1917
1918 add al, 3dh
1919 mov bx, [PhysDiskBpbIndex]
1920 inc bx
1921 mov es:[di+bx], al
1922
1923
1924 update_PBR:
1925
1926
1927
1928 ;
1929 ; Here both the boot-drive-letter and the LVM drive-letter are zero.
1930 ; So the only way to determine the drive-letter is to examine CONFIG.SYS.
1931 ; Then force that drive-letter in the drive-letter feature.
1932 no_valid_boot_drive_letter_found:
1933 ; HERE SHOULD COME AN ERROR POP-UP ABOUT NO BOOT-DRIVE OR NO LVM-INFO.
1934 ; WE CONTINUE BOOTING BUT OS/2 WILL MOST PROBABLY FAIL TO BOOT.
1935
1936 ; FIXME: Issue some kind of warning
1937
1938 ;mov ah,07h
1939 ;mov si,offset CheckID_MBR
1940 ;call VideoIO_Print
1941
1942 hang:
1943 ;jmp hang
1944
1945
1946
1947
1948 PSP_valid_boot_drive:
1949
1950
1951
1952
1953 ;
1954 ; Boot DriveLetter OK.
1955 ;
1956 bdl_ok:
1957
1958
1959IFDEF AUX_DEBUG
1960 IF 0
1961 pushf
1962 pusha
1963 call AuxIO_TeletypeNL
1964 mov bx, [PhysDiskBpbIndex]
1965 inc bx
1966 mov al, [di+bx]
1967 call AuxIO_TeletypeHexByte
1968 mov bl,[BootPartNo]
1969 mov al, [DriveLetters+bx]
1970 call AuxIO_TeletypeHexByte
1971 mov al, [PartitionVolumeLetters+bx]
1972 add al, 3dh
1973 call AuxIO_TeletypeHexByte
1974 mov al, [LVMdl]
1975 add al, 3dh
1976 call AuxIO_TeletypeHexByte
1977 mov al, [si+LocIPT_SystemID]
1978 call AuxIO_TeletypeHexByte
1979 mov al,[FSType]
1980 call AuxIO_TeletypeHexByte
1981 popa
1982 popf
1983 ENDIF
1984ENDIF
1985
1986 ;
1987 ; If the partition getting booted is a JFS partition then write-back
1988 ; the modified PBR to the disk.
1989 ; Note that it's not the in-memory PBR that get's written back, but
1990 ; a copy of the original where only the phys-disk and boot-drive-letter
1991 ; are adjusted.
1992 ;
1993 pusha
1994 mov al,[FSType]
1995 cmp al,04h ; JFS
1996 je write_back_pbr
1997 cmp al,02h ; HPFS
1998 je write_back_pbr
1999
2000 jmp no_jfs_pbr
2001
2002
2003 write_back_pbr:
2004
2005 ; Save IPT pointer
2006 push si
2007
2008 ; Copy the boot-drive and boot-drive-letter fields.
2009 mov si,offset [PartitionSector]
2010 mov di,offset [PBRSector]
2011 mov al,[si+24h]
2012 mov [di+24h],al
2013 mov al,[si+25h]
2014 mov [di+25h],al
2015
2016 ; Restore IPT pointer
2017 pop si
2018
2019
2020 ; BOOKMARK: Update the CRC of the Partition Boot Record.
2021 mov bx, offset [PBRSector]
2022 call PART_UpdateBootRecordCRC
2023 call DriveIO_SaveConfiguration
2024
2025
2026 ; Setup the registers for the partition location.
2027 mov ax, wptr [si+LocIPT_AbsoluteBegin+0]
2028 mov bx, wptr [si+LocIPT_AbsoluteBegin+2]
2029 mov cx, [si+LocIPT_LocationBegin+1]
2030 mov dh, [si+LocIPT_LocationBegin+0]
2031 mov dl, [si+LocIPT_Drive]
2032
2033
2034 ; BOOKMARK: Write the adjusted HPFS/JFS PBR to disk.
2035 mov si, offset [PBRSector]
2036 call DriveIO_SaveSector
2037
2038 no_jfs_pbr:
2039 popa
2040
2041
2042
2043 ; ----------------------------------------------- LOGICAL PARTITION SUPPORT
2044
2045
2046
2047 ; AiR-BOOT now works around it by using the LVM-info (DLAT) of
2048 ; the partiton if present.
2049 ; Note however that if the drive-letter feature is active,
2050 ; this will override AB's automatic fixing.
2051 ;
2052 ; Test if the drive-letter feature is active for this partition.
2053 ; If so, then the drive that the user defined will be placed at
2054 ; byte 25h (37d) of the in-ram PartitionSector (BPB).
2055 ; (BIOS 80h notation: 80h=C, 81h=D, etc.)
2056 ; This is a remedy for when the corresponding field (25h) in the BPB on
2057 ; disk is zero.
2058 ;
2059
2060
2061
2062 ;
2063 ; Control is transferred to this point if we are booting IBM-BM.
2064 ; IBM-BM does not need the BPB fixes.
2065 ; It does require a other special stuff, which is already taken care of.
2066 ;
2067 chainload_ibm_bm:
2068
2069 ;
2070 ; Control is transferred to this point if we are booting a floppy.
2071 ; Booting from floppy skips all the harddisk related stuff.
2072 ; This is a dirty hack to fix the boot from floppy feature.
2073 ;
2074 boot_from_floppy:
2075
2076
2077
2078
2079 ;
2080 ; Here we copy the prepared boot-record to 0000:7C00h
2081 ; to give it control later on.
2082 ;
2083 push es
2084 push si
2085 mov ax, StartBaseSeg
2086 mov es, ax
2087 mov cx, 256
2088 mov si, offset PartitionSector
2089 mov di, StartBasePtr
2090 cld
2091 rep movsw
2092 pop si
2093 pop es
2094
2095 ; --------------------------------------------------- NOW START BOOT-RECORD
2096
2097
2098
2099
2100IFDEF AUX_DEBUG
2101 IF 1
2102 pushf
2103 pusha
2104 call DEBUG_Dump2
2105 ;~ call DEBUG_DumpBSSSectors
2106 call DEBUG_DumpDriveLetters
2107 call DEBUG_DumpVolumeLetters
2108 call AuxIO_TeletypeNL
2109 popa
2110 popf
2111 ENDIF
2112ENDIF
2113
2114
2115
2116;
2117; ################################## BYE BYE ##################################
2118;
2119
2120 IFNDEF AUX_DEBUG
2121 ; Skip wait-for-key
2122 jmp StartPBR
2123 ENDIF
2124
2125 ;
2126 ; Wait for keypress
2127 ;
2128 xor ax, ax
2129 int 16h
2130
2131 ; Is escape-key ?
2132 cmp al, 1bh
2133
2134 ; Nope, Go activate PBR loader
2135 jne StartPBR
2136
2137 ;push ds
2138 ;pop es
2139
2140 ; Yep, restart AiR-BOOT so simulate load DX:BX with old BIOS SS:SP
2141 jmp AirbootRestart
2142
2143 ; Yep, Reenter bootmenu
2144 ;~ jmp MBR_Main_ReEnterBootMenuPre
2145
2146
2147
2148;
2149; Transfer control to the PBR
2150;
2151StartPBR:
2152
2153 ; Debug display index
2154 ;pusha
2155 ;mov al, cs:[si+LocIPT_Drive] ; Drive Physical No
2156 ;mov ah, cs:[si+LocIPT_SystemID] ; SystemID
2157 ;call VideoIO_PrintHexWord
2158 ;xor ax, ax
2159 ;int 16h
2160 ;popa
2161
2162 ;~ jmp skip_delay
2163
2164
2165 ;
2166 ; Show dot's to indicate something is happening...
2167 ;
2168 call VideoIO_ShowWaitDots
2169
2170 ;
2171 ; Enter here to skip delay.
2172 ;
2173 skip_delay:
2174
2175
2176
2177
2178 ;
2179 ; BYE BYE (prepare some registers? look at other MBR-code)
2180 ;
2181 xor ax, ax
2182 xor bx, bx
2183 xor cx, cx
2184 mov ds, ax
2185 mov es, ax
2186 xor dh, dh
2187 mov dl, cs:[si+LocIPT_Drive] ; Drive Physical No
2188
2189
2190 ; BOOKMARK: JUMP TO PBR CODE
2191 ; ###############################
2192 ; # JUMP TO THE PBR LOADER CODE #
2193 ; ###############################
2194 db 0EAh
2195 dw StartBasePtr
2196 dw StartBaseSeg
2197
2198
2199PART_StartPartition EndP
2200
2201
2202
2203
2204
2205
2206
2207
2208;
2209; ######################################
2210; # Is this a primary partition or not #
2211; ######################################
2212;
2213; In
2214; --
2215; DL = Physical Disk
2216; BX:CX = LBA sector
2217;
2218; Out
2219; ---
2220; AX = Index in PT if found, otherwise -1
2221; CY = Set if Primary, clear if not
2222;
2223PART_IsPrimaryPartition Proc Near Uses bx cx dx si di ds es
2224
2225IFDEF AUX_DEBUG
2226 IF 0
2227 DBG_TEXT_OUT_AUX 'PART_IsPrimaryPartition:'
2228 PUSHRF
2229 ;~ call DEBUG_DumpRegisters
2230 ;~ call AuxIO_DumpParagraph
2231 ;~ call AuxIO_TeletypeNL
2232 POPRF
2233 ENDIF
2234ENDIF
2235
2236 ; Push LBA address of partition
2237 push bx
2238 push cx
2239
2240 ; Load LBA sector 0 from the disk specified in DL
2241 xor bx,bx
2242 xor ax,ax
2243 mov di,ds
2244 mov si,offset [TmpSector]
2245 call DriveIO_ReadSectorLBA
2246
2247 ; Restore partitions LBA address to DI:SI
2248 pop si
2249 pop di
2250
2251 ; Return with index -1 and CY clear if there was an
2252 ; error loading the sector.
2253 mov ax,-1
2254 cmc
2255 jnc PART_IsPrimaryPartition_exit
2256
2257 ; Compare the partition address with each entry in the P-table
2258 mov cx,4 ; Nr. of PT-entries
2259 mov dx,offset [TmpSector]
2260 add dx,01beh+08h ; Point DX to 1st partition address
2261
2262 next_pe:
2263 ; Compute pointer to PE
2264 mov bx,dx ; Point BX to 1st partition address
2265 mov ax,cx ; Get PE-index
2266 dec ax ; Index is zero based so adjust it
2267 shl ax,4 ; PE's are 16 bytes in size
2268 add bx,ax ; Make BX point to the PE
2269
2270 ; Compare LBA address
2271 push si
2272 push di
2273 xor si,[bx+00h] ; Will put 0 in SI if the same
2274 xor di,[bx+02h] ; Will put 0 in DI if the same
2275 or si,di ; Wil set ZF if both zero
2276 pop di
2277 pop si
2278 loopnz next_pe ; Try next entry if non-zero
2279
2280 ; Partition found or counter exhausted
2281 mov ax,-1
2282 clc
2283 ; Not found, so exit with NC and invalid index
2284 jnz PART_IsPrimaryPartition_exit
2285
2286 ; Partition is Primary, set CY and return index
2287 mov ax,cx
2288 stc
2289
2290 PART_IsPrimaryPartition_exit:
2291 ret
2292PART_IsPrimaryPartition Endp
2293
2294
2295
2296;
2297; #############################
2298; # Is this an HPFS partition #
2299; #############################
2300;
2301; In
2302; --
2303; SI = Pointer to IPT entry
2304;
2305; Out
2306; ---
2307; CY = Set if HPFS partition, clear if not
2308;
2309PART_IsHPFS Proc Near Uses ax
2310 mov al, [si+LocIPT_SystemID] ; Get SystemID
2311 cmp al, 07h ; Compare with AiR-BOOT ID for HPFS
2312 stc ; Assume HPFS
2313 je PART_IsHPFS_exit ; Yep
2314 clc ; Nope, clear CY
2315 PART_IsHPFS_exit:
2316 ret
2317PART_IsHPFS Endp
2318
2319
2320;
2321; ###########################
2322; # Is this a JFS partition #
2323; ###########################
2324;
2325; In
2326; --
2327; SI = Pointer to IPT entry
2328;
2329; Out
2330; ---
2331; CY = Set if JFS partition, clear if not
2332;
2333PART_IsJFS Proc Near Uses ax
2334 mov al, [si+LocIPT_SystemID] ; Get SystemID
2335 cmp al, 0fch ; Compare with AiR-BOOT ID for JFS
2336 stc ; Assume JFS
2337 je PART_IsJFS_exit ; Yep
2338 clc ; Nope, clear CY
2339 PART_IsJFS_exit:
2340 ret
2341PART_IsJFS Endp
2342
2343
2344
2345;
2346; #############################
2347; # Is this an NTFS partition #
2348; #############################
2349;
2350; In
2351; --
2352; SI = Pointer to IPT entry
2353;
2354; Out
2355; ---
2356; CY = Set if NTFS partition, clear if not
2357;
2358PART_IsNTFS Proc Near Uses ax
2359 mov al, [si+LocIPT_SystemID] ; Get SystemID
2360 cmp al, 08h ; Compare with AiR-BOOT ID for NTFS
2361 stc ; Assume NTFS
2362 je PART_IsNTFS_exit ; Yep
2363 clc ; Nope, clear CY
2364 PART_IsNTFS_exit:
2365 ret
2366PART_IsNTFS Endp
2367
2368
2369;
2370; ######################################
2371; # Is this a FAT12 or FAT16 partition #
2372; ######################################
2373;
2374; In
2375; --
2376; SI = Pointer to IPT entry
2377;
2378; Out
2379; ---
2380; CY = Set if FAT12 or FAT16 partition, clear if not
2381;
2382PART_IsFAT Proc Near Uses ax
2383 mov al, [si+LocIPT_SystemID] ; Get SystemID
2384 cmp al, 04h ; Is FAT12 ?
2385 stc
2386 je PART_IsFAT_exit ; Yep
2387 cmp al, 06h ; Is FAT16 CHS ?
2388 stc
2389 je PART_IsFAT_exit ; Yep
2390 cmp al, 0eh ; Is FAT16 LBA ?
2391 stc
2392 je PART_IsFAT_exit ; Yep
2393 clc ; Nope
2394 PART_IsFAT_exit:
2395 ret
2396PART_IsFAT Endp
2397
2398
2399;
2400; #############################
2401; # Is this a FAT32 partition #
2402; #############################
2403;
2404; In
2405; --
2406; SI = Pointer to IPT entry
2407;
2408; Out
2409; ---
2410; CY = Set if FAT32 partition, clear if not
2411;
2412PART_IsFAT32 Proc Near Uses ax
2413 mov al, [si+LocIPT_SystemID] ; Get SystemID
2414 cmp al, 0bh ; Is FAT32 CHS ?
2415 stc
2416 je PART_IsFAT32_exit ; Yep
2417 cmp al, 0ch ; Is FAT32 LBA ?
2418 stc
2419 je PART_IsFAT32_exit ; Yep
2420 clc ; Nope
2421 PART_IsFAT32_exit:
2422 ret
2423PART_IsFAT32 Endp
2424
2425
2426
2427;
2428; ##############################################################
2429; # Does this partition have the Windows BootManager installed #
2430; ##############################################################
2431;
2432; In
2433; --
2434; DL = Physical Disk
2435; BX:CX = LBA sector
2436;
2437; Out
2438; ---
2439; CY = Set if BOOTMGR found, clear if not
2440;
2441;PART_IsWinBMGR Proc Near Uses ax bx cx dx si di ds es
2442;
2443; ; Load specified LBA sector (BX:CX) from the disk in DL
2444; mov di,ds
2445; mov si,offset [TmpSector]
2446; mov ax, cx ; LBA low is now in AX
2447; call DriveIO_ReadSectorLBA
2448
2449; ; Point to location of 'BOOTMGR' signature.
2450; add si,169h
2451
2452; ; DL holds equality status
2453; xor dl,dl
2454; cld
2455
2456; ; Load letter into AL, xor with letter will result 0 if the same.
2457; ; Then or to DL.
2458; ; If at the end of the sequence DL is zero, the signature is present.
2459; lodsb
2460; xor al,'B'
2461; or dl,al
2462; lodsb
2463; xor al,'O'
2464; or dl,al
2465; lodsb
2466; xor al,'O'
2467; or dl,al
2468; lodsb
2469; xor al,'T'
2470; or dl,al
2471; lodsb
2472; xor al,'M'
2473; or dl,al
2474; lodsb
2475; xor al,'G'
2476; or dl,al
2477; lodsb
2478; xor al,'R'
2479; or dl,al
2480
2481; ; Assume not present
2482; clc
2483; jnz PART_IsWinBMGR_exit
2484
2485; ; BOOTMGR signature found
2486; stc
2487
2488; PART_IsWinBMGR_exit:
2489; ret
2490;PART_IsWinBMGR Endp
2491
2492
2493;
2494; ##########################################################
2495; # Get the offset of the phys-disk field in the PBR (BPB) #
2496; ##########################################################
2497;
2498; In
2499; --
2500; DS:SI = IPT
2501;
2502; Out
2503; ---
2504; AX = Index in PBR for phys-disk field
2505;
2506PART_GetFieldIndex Proc Near uses bx cx dx
2507 ; Check for FAT32 partition
2508 mov dl,bptr [si+LocIPT_Drive]
2509 mov cx,[si+LocIPT_AbsoluteBegin+00h]
2510 mov bx,[si+LocIPT_AbsoluteBegin+02h]
2511 call PART_IsFAT32
2512 mov ax,24h ; Offset in old-style BPB
2513 jnc PART_GetFieldIndex_exit
2514 mov ax,40h ; Offset in FAT32 BPB
2515 PART_GetFieldIndex_exit:
2516 ret
2517PART_GetFieldIndex EndP
Note: See TracBrowser for help on using the repository browser.