source: trunk/bootcode/special/lvm.asm@ 111

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

Updated debug hooks (debugging) [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: 25.9 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 / LVM
20;---------------------------------------------------------------------------
21
22IFDEF MODULE_NAMES
23DB 'LVM',0
24ENDIF
25
26LVM_InitCRCTable Proc Near
27 ; Initializes our LVM-CRC-Table
28 xor cl, cl
29 mov di, offset [LVM_CRCTable]
30 LVM_ICRCT_Loop:
31 ;movzx ax, cl
32 mov al,cl
33 mov ah,0
34 xor dx, dx ; DX:AX - CRC-Value
35 mov ch, 8
36 LVM_ICRCT_Loop2:
37 shr dx, 1
38 rcr ax, 1 ; Shift value 1 to the right
39 jnc LVM_ICRCT_NoXOR
40 xor dx, 0EDB8h
41 xor ax, 8320h
42 LVM_ICRCT_NoXOR:
43 dec ch
44 jnz LVM_ICRCT_Loop2
45 mov wptr [di+0], ax
46 mov wptr [di+2], dx
47 add di, 4
48 add cl, 1
49 jnc LVM_ICRCT_Loop
50 ret
51LVM_InitCRCTable EndP
52
53; Calculates an LVM-Sector CRC of a given sector
54; In: DS:SI - Points to Sector...
55; Out: DX:AX - LVM CRC
56; Destroyed: None
57LVM_GetSectorCRC Proc Near Uses bx cx
58
59IFDEF AUX_DEBUG
60 IF 0
61 pushf
62 pusha
63 push si
64 mov si, offset $+5
65 jmp @F
66 db 10,'LVM_GetSectorCRC:',10,0
67 @@:
68 call AuxIO_Print
69 pop si
70 ;~ call DEBUG_DumpRegisters
71 ;~ call AuxIO_DumpParagraph
72 ;~ call AuxIO_TeletypeNL
73 popa
74 popf
75 ENDIF
76ENDIF
77
78 push word ptr [si+LocLVM_CRC+00]
79 push word ptr [si+LocLVM_CRC+02]
80 push si
81 mov word ptr [si+LocLVM_CRC], 0
82 mov word ptr [si+LocLVM_CRC+2], 0
83 mov ax, -1
84 mov dx, -1
85 mov cx, 512
86 LVM_GSCRC_Loop:
87 xor bh, bh
88 mov bl, al ; Save last byte to BL
89 mov al, ah
90 mov ah, dl
91 mov dl, dh
92 xor dh, dh ; SHR DX:AX, 8
93 xor bl, [si]
94 inc si ; XOR last byte with [data]
95 shl bx, 1
96 shl bx, 1
97 xor ax, word ptr [LVM_CRCTable+bx+0]
98 xor dx, word ptr [LVM_CRCTable+bx+2] ; XOR with CRC-Table
99 loop LVM_GSCRC_Loop
100 pop si
101 pop word ptr [si+LocLVM_CRC+2]
102 pop word ptr [si+LocLVM_CRC]
103 ret
104LVM_GetSectorCRC EndP
105
106; Checks ds:[SI], if a valid LVM Signature is found (sets carry in that case)
107; This does not check for valid LVM CRC (which also needs to be done)
108; In: DS:SI - Sector that needs to get checked...
109; Out: Carry set, if valid LVM signature found
110; Destroyed: None
111LVM_CheckSectorSignature Proc Near
112 test byte ptr [CFG_IgnoreLVM], 1 ; We are supposed to ignore LVM, so
113 jnz LVMCSS_InvalidSignature ; any sector is bad!
114 cmp word ptr [si+LocLVM_SignatureStart], 5202h
115 jne LVMCSS_InvalidSignature
116 cmp word ptr [si+LocLVM_SignatureStart+2], 'BM'
117 jne LVMCSS_InvalidSignature
118 cmp word ptr [si+LocLVM_SignatureStart+4], 'MP'
119 jne LVMCSS_InvalidSignature
120 cmp word ptr [si+LocLVM_SignatureStart+6], 'DF'
121 jne LVMCSS_InvalidSignature
122 stc
123 ret
124 LVMCSS_InvalidSignature:
125 clc
126 ret
127LVM_CheckSectorSignature EndP
128
129; Checks Sector for a valid LVM CRC is encountered
130; First one should check for a valid signature and call this later.
131; In: DS:SI - Sector that needs to get checked...
132; Out: Carry set, if LVM CRC valid
133; Destroyed: None
134LVM_CheckSectorCRC Proc Near Uses ax bx dx
135 mov bx, si
136 call IsSectorZero ; Zero sector implies bad CRC
137 jz LVMCSCRC_BadCRC
138 call LVM_GetSectorCRC ; Only use after CRC table is valid
139 cmp ax, word ptr [si+LocLVM_CRC]
140 jne LVMCSCRC_BadCRC
141 cmp dx, word ptr [si+LocLVM_CRC+2]
142 jne LVMCSCRC_BadCRC
143 stc ; Indicate CRC is OK
144 ret
145 LVMCSCRC_BadCRC:
146 clc ; Indicate BAD CRC
147 ret
148LVM_CheckSectorCRC EndP
149
150; Checks if a sector is a valid LVM-sector
151; Sector is considered valid LVM-sector if both signature and CRC are correct.
152; In: DS:SI - Sector that needs to get checked...
153; Out: AL = 1 -> LVM Signature found
154; AH = 1 -> CRC OK
155; ZF = 0 -> Signature found and CRC OK, ZF = 1 -> Invalid LVM sector
156; Note: AL thus indicates a valid signature and AH a valid CRC
157; Destroyed: None
158LVM_ValidateSector Proc Near
159 xor ax, ax ; Start with all zero bits
160 call LVM_CheckSectorSignature ; CF=1 -> Signature OK
161 rcl al, 1 ; Store CF in AL
162 call LVM_CheckSectorCRC ; CF=1 -> Checksum OK
163 rcl ah, 1 ; Store CF in AH
164 test al, ah ; ZF=0 if both AL and AH are 1
165 ret
166LVM_ValidateSector EndP
167
168; Updates Sector with valid LVM CRC
169; This one doesn't check, if it's really an LVM sector, so check before!
170; In: DS:SI - Sector that needs to get checked...
171; Out: None, CRC updated
172; Destroyed: None
173LVM_UpdateSectorCRC Proc Near Uses ax dx
174 call LVM_GetSectorCRC
175 mov word ptr [si+LocLVM_CRC], ax
176 mov word ptr [si+LocLVM_CRC+2], dx
177 ret
178LVM_UpdateSectorCRC EndP
179
180; Searches for a partition in LVM Information Sector and sets SI to point to
181; the LVM-entry. It will also set CARRY then.
182; In: DX:AX - LBA starting sector of partition to be searched
183; DS:SI - Valid (previously checked) LVM-Information-Sector
184; Out: Carry set, if partition found
185; DS:SI - points to LVM information entry
186; Destroyed: None
187
188; INVALID LVM RECORD WHEN STICK INSERTED !
189
190LVM_SearchForPartition Proc Near Uses cx
191
192IFDEF AUX_DEBUG
193 IF 0
194 pushf
195 pusha
196 push si
197 mov si, offset $+5
198 jmp @F
199 db 10,'LVM_SearchForPartition:',10,0
200 @@:
201 call AuxIO_Print
202 pop si
203 ;~ call DEBUG_DumpRegisters
204 ;~ call AuxIO_DumpParagraph
205 ;~ call AuxIO_TeletypeNL
206 popa
207 popf
208 ENDIF
209ENDIF
210
211 cmp byte ptr [si+LocLVM_SignatureStart], LocLVM_SignatureByte0
212 jne LVMSFP_NotFound ; Quick Check, if LVM sector there
213 add si, LocLVM_StartOfEntries
214 mov cl, LocLVM_MaxEntries
215 LVMSFP_Loop:
216 cmp ax, [si+LocLVM_PartitionStart]
217 jne LVMSFP_NextEntry
218 cmp dx, [si+LocLVM_PartitionStart+2]
219 je LVMSFP_FoundIt
220 LVMSFP_NextEntry:
221 add si, LocLVM_LenOfEntry
222 dec cl
223 jnz LVMSFP_Loop
224 LVMSFP_NotFound:
225 clc
226 ret
227 LVMSFP_FoundIt:
228 stc
229 ret
230LVM_SearchForPartition EndP
231
232
233; Gets a drive-letter from the LVM-info of a partition. (if it exists)
234; In: BX:CX - LBA starting sector of partition to be searched
235; DL = Physical Disk in BIOS notation. (80h+)
236; Out: CY=1 if LVM-info found, 0 if no LVM-info.
237; AL - drive-letter from LVM-info or zero if no drive-letter
238; assigned or no LVM-info.
239LVM_GetDriveLetter Proc Near Uses bx cx dx si di ds es
240
241IFDEF AUX_DEBUG
242 IF 0
243 pushf
244 pusha
245 push si
246 mov si, offset $+5
247 jmp @F
248 db 10,'LVM_GetDriveLetter:',10,0
249 @@:
250 call AuxIO_Print
251 pop si
252 ;~ call DEBUG_DumpRegisters
253 ;~ call AuxIO_DumpParagraph
254 ;~ call AuxIO_TeletypeNL
255 popa
256 popf
257 ENDIF
258ENDIF
259
260
261
262 ; For primary partitions this information is stored in the last
263 ; sector of track0; for all four partition entries in case they
264 ; they are all primary ones.
265 ;
266 ; LVM DLAT info for logical partitions is stored in the sector
267 ; preceding the start of the partition.
268 ;
269 ; Because the LVM info of a logical partition is the easiest to find,
270 ; we do that first. The LVM info for primary partitions is located
271 ; dependent on the geometry in use, so we use a special locater
272 ; call for that. Also, since the LVM info for primaries contains
273 ; info on all 4 entries, we need the partition index to obtain the
274 ; correct drive-letter.
275 ;
276
277 ; See if this is a primary partition
278 ; CY will be set if it is and AL will contain the 0-based
279 ; index in the P-table.
280 ; If it's a logical partition, CY will be clear and AL
281 ; will be set to 0ffh indicating an invalid index.
282 call PART_IsPrimaryPartition
283IF 0
284 pushf
285 pusha
286 call VideoIO_PrintHexWord
287 popa
288 popf
289ENDIF
290 mov al,0
291 rcl al,1 ; CY if primary
292 mov dh,al ; Save PRI or LOG
293
294 ; Save PRI/LOG indicator for later use
295 push dx
296
297 ; Load *possible* LVM sector
298 ; This load is only valid if the partition is logical, in which case
299 ; the LVM sector is below the start of the partition.
300 ; If primary, the LVM sector is at a location that
301 ; DriveIO_LoadMasterLVMSector will find out.
302
303 ; Push LBA address
304 push bx
305 push cx
306
307 ; Adjust for logical LVM-sector
308 sub cx,1
309 sbb bx,0
310
311 ; Load the LVM sector
312 push si
313 push di
314 mov si,offset [LVMSector]
315 mov di,ds
316 call DriveIO_ReadSectorLBA
317 pop di
318 pop si
319
320 ; Restore LBA address
321 pop cx
322 pop bx
323
324 ; Restore PRI/LOG partition indicator in DH
325 pop dx
326
327 ; Test PRI or not
328 test dh,dh
329 ; It's not a PRI so we can use the previously loaded LVM sector
330 jz LVM_GetDriveLetter_is_not_pri
331
332 ;
333 ; It's a PRI so we use the special locator function.
334 ; This locator takes care of extended OS/2 geometry should that be used
335 ;
336IF 0
337 ; DH=0 or 1, DL=disk (8?h)
338 pushf
339 pusha
340 mov ax, dx
341 call VideoIO_PrintHexWord
342 mov al,'-'
343 call VideoIO_PrintSingleChar
344 popa
345 popf
346ENDIF
347 ; THIS ONE FAULTERS WHEN DISKS > 1
348 call DriveIO_LoadMasterLVMSector
349
350IF 0
351 ; INVALID LVM SECTOR !!
352 pushf
353 pusha
354 mov ax,0000h
355 rcl al,1
356 call VideoIO_PrintHexWord ; LVMSector
357 mov al,'-'
358 call VideoIO_PrintSingleChar
359 mov si, offset [LVMSector]
360 mov ax, si
361 call VideoIO_PrintHexWord ; LVMSector
362 lodsw
363 call VideoIO_PrintHexWord ; sig
364 lodsw
365 call VideoIO_PrintHexWord ; sig
366 mov al,'-'
367 call VideoIO_PrintSingleChar
368 popa
369 popf
370ENDIF
371
372 LVM_GetDriveLetter_is_not_pri:
373
374
375 ;
376 ; At this stage the LVM-info sector has been loaded at [LVMSector].
377 ; From here we look for an LVM entry for the partition.
378 ; If one is found, based on it's LBA-start, it's driveletter is used
379 ; in case byte 25h in the BPB is zero.
380 ;
381
382
383 ; Search for the partition in the LVM info.
384 ; If found, CY is set and SI points to LVM entry.
385 push si
386 mov ax,cx
387 mov dx,bx ; DL DESTROYED
388 mov si,offset [LVMSector]
389 call LVM_SearchForPartition
390
391IF 0
392 pushf
393 pusha
394 mov ax, 0000h
395 rcl al, 1
396 call VideoIO_PrintHexWord
397 mov ax, si
398 call VideoIO_PrintHexWord
399 popa
400 popf
401ENDIF
402
403IFDEF AUX_DEBUG
404 IF 0
405 pusha
406 push si
407 mov si, offset $+5
408 jmp @F
409 db 10,'LVM_GetDriveLetter:',10,0
410 @@:
411 call AuxIO_Print
412 pop si
413 call DEBUG_DumpRegisters
414 call AuxIO_DumpParagraph
415 call AuxIO_TeletypeNL
416 popa
417 ENDIF
418ENDIF
419
420 mov bx,si ; BX now points to LVM entry
421 mov dx,0
422 pop si
423
424 mov al,0 ; Setup null driveletter
425 ; Oops, no valid LVM record was used so we have a null driveletter.
426 jnc LVM_GetDriveLetter_null_lvm_dl
427
428 ;
429 ; At this point BX points to the LVM-entry related to the
430 ; partition, whether it was a logical or a primary one.
431 ;
432 mov al,[bx+LocLVM_VolumeLetter]
433 ; Test for zero dtive-letter.
434 test al,al
435 ; Preset CY in case drive-letter is zero.
436 clc
437 jz LVM_GetDriveLetter_null_lvm_dl
438
439 ; We have a non-zero drive-letter, so set CY.
440 stc
441
442 LVM_GetDriveLetter_null_lvm_dl:
443 ret
444LVM_GetDriveLetter EndP
445
446
447
448; Sets a drive-letter in the LVM-info of a partition. (if it exists)
449; In: BX:CX - LBA starting sector of partition to be searched
450; DL = Physical Disk in BIOS notation. (80h+)
451; AL = DriveLetter to set (can be zero to hide partition from LVM)
452; Out: CY=1 if LVM-info found, 0 if no LVM-info.
453LVM_SetDriveLetter Proc Near Uses bx cx dx si di ds es
454
455 local disk:byte
456 local drive_letter:byte
457 local pri_ind:byte
458 local lvm_log_high:word
459 local lvm_log_low:word
460 ; For primary partitions this information is stored in the last
461 ; sector of track0; for all four partition entries in case they
462 ; they are all primary ones.
463 ;
464 ; LVM DLAT info for logical partitions is stored in the sector
465 ; preceding the start of the partition.
466 ;
467 ; Because the LVM info of a logical partition is the easiest to find,
468 ; we do that first. The LVM info for primary partitions is located
469 ; dependent on the geometry in use, so we use a special locater
470 ; call for that. Also, since the LVM info for primaries contains
471 ; info on all 4 entries, we need the partition index to obtain the
472 ; correct drive-letter.
473 ;
474
475IFDEF AUX_DEBUG
476 IF 0
477 pushf
478 pusha
479 push si
480 mov si, offset $+5
481 jmp @F
482 db 10,'LVM_SetDriveLetter:',10,0
483 @@:
484 call AuxIO_Print
485 pop si
486 ;~ call DEBUG_DumpRegisters
487 ;~ call AuxIO_DumpParagraph
488 ;~ call AuxIO_TeletypeNL
489 popa
490 popf
491 ENDIF
492ENDIF
493
494 mov [disk], dl
495
496 ; Store the drive-letter for later use
497 mov [drive_letter], al
498
499
500 ; See if this is a primary partition
501 ; CY will be set if it is and AL will contain the 0-based
502 ; index in the P-table.
503 ; If it's a logical partition, CY will be clear and AL
504 ; will be set to 0ffh indicating an invalid index.
505 call PART_IsPrimaryPartition
506 mov al,0
507 rcl al,1 ; CY if primary
508 mov dh,al ; Save PRI or LOG
509 mov [pri_ind],al
510
511 ; Save PRI/LOG indicator for later use
512 push dx
513
514 ; Load *possible* LVM sector
515 ; This load is only valid if the partition is logical, in which case
516 ; the LVM sector is below the start of the partition.
517 ; If primary, the LVM sector is at a location that
518 ; DriveIO_LoadMasterLVMSector will find out.
519
520 ; Push LBA address
521 push bx
522 push cx
523
524 ; Adjust for logical LVM-sector
525 sub cx,1
526 sbb bx,0
527
528 ; Store LBA address of LVM-sector
529 mov [lvm_log_low],cx
530 mov [lvm_log_high],bx
531
532 ; Load the LVM sector
533 push si
534 push di
535 mov si,offset [LVMSector]
536 mov di,ds
537 call DriveIO_ReadSectorLBA
538 pop di
539 pop si
540
541 ; Restore LBA address
542 pop cx
543 pop bx
544
545 ; Restore PRI/LOG partition indicator in DH
546 pop dx
547
548 ; Test PRI or not
549 test dh,dh
550 ; It's not a PRI so we can use the previously loaded LVM sector
551 jz LVM_SetDriveLetter_is_not_pri
552
553 ;
554 ; It's a PRI so we use the special locator function.
555 ; This locator takes care of extended OS/2 geometry should that be used
556 ;
557 call DriveIO_LoadMasterLVMSector
558 jnc LVM_SetDriveLetter_null_lvm_dl
559
560 mov ax, word ptr [MasterLVMLBA] ; ARRAY VAN MAKEN !
561 mov [lvm_log_low], ax
562 mov [lvm_log_high], 0
563
564 LVM_SetDriveLetter_is_not_pri:
565
566 ;
567 ; At this stage the LVM-info sector has been loaded at [LVMSector].
568 ; From here we look for an LVM entry for the partition.
569 ; If one is found, based on it's LBA-start, it's driveletter is used
570 ; in case byte 25h in the BPB is zero.
571 ;
572
573 ; Search for the partition in the LVM info.
574 ; If found, CY is set and SI points to LVM entry.
575 push si
576 mov ax,cx
577 mov dx,bx
578 mov si,offset [LVMSector]
579 call LVM_SearchForPartition
580 mov bx,si ; BX now points to LVM entry
581 pop si
582
583 mov al,0 ; Setup null driveletter
584 ; Oops, no valid LVM record was used so we have a null driveletter.
585 jnc LVM_SetDriveLetter_null_lvm_dl
586
587 ;
588 ; At this point BX points to the LVM-entry related to the
589 ; partition, whether it was a logical or a primary one.
590 ;
591 mov al, [drive_letter]
592 mov [bx+LocLVM_VolumeLetter],al
593
594 mov si, offset [LVMSector]
595 call LVM_UpdateSectorCRC
596
597 mov dl, [disk]
598 mov bx, [lvm_log_high]
599 mov ax, [lvm_log_low]
600
601 call DriveIO_SaveSector
602
603 LVM_SetDriveLetter_null_lvm_dl:
604 ret
605LVM_SetDriveLetter EndP
606
607
608
609; Removes a given drive-letter from the whole LVM information sector
610; In: CH - drive-letter (ascii)
611; DS:SI - LVM-Information-Sector
612; Out: LVM-Information-Sector updated (including LVM CRC)
613; Destroyed: None
614LVM_RemoveVolLetterFromSector Proc Near Uses cx
615
616IFDEF AUX_DEBUG
617 IF 0
618 pushf
619 pusha
620 push si
621 mov si, offset $+5
622 jmp @F
623 db 10,'LVM_RemoveVolLetterFromSector:',10,0
624 @@:
625 call AuxIO_Print
626 pop si
627 ;~ call DEBUG_DumpRegisters
628 ;~ call AuxIO_DumpParagraph
629 ;~ call AuxIO_TeletypeNL
630 popa
631 popf
632 ENDIF
633ENDIF
634
635 cmp bptr [si+LocLVM_SignatureStart], LocLVM_SignatureByte0
636 jne LVMRVLFS_Done ; Quick Check, if LVM sector there
637 push si
638 add si, LocLVM_StartOfEntries
639 mov cl, LocLVM_MaxEntries
640 LVMRVLFS_Loop:
641 cmp ch, [si+LocLVM_VolumeLetter]
642 jne LVMRVLFS_NextEntry
643 ; Reset drive-letter, if matched
644 mov bptr [si+LocLVM_VolumeLetter], 0 ; ASSIGN NEXT FREE HERE... (DOET DUBBEL ALS ZELFDE DL ALS SYS)
645 LVMRVLFS_NextEntry:
646 add si, LocLVM_LenOfEntry
647 dec cl
648 jnz LVMRVLFS_Loop
649 pop si
650 call LVM_UpdateSectorCRC
651 LVMRVLFS_Done:
652 ret
653LVM_RemoveVolLetterFromSector EndP
654
655; Reassigns LVM volume driveletter
656; Will remove the drive-letter from any volume that got it currently
657; and finally change the drive-letter of the given partition
658; In: AL - drive-letter
659; DS:SI - points to partition, that needs that driveletter
660; Out: None
661; Destroyed: AX
662
663LVM_DoLetterReassignment Proc Near Uses bx cx dx si di
664
665IFDEF AUX_DEBUG
666 IF 0
667 pushf
668 pusha
669 push si
670 mov si, offset $+5
671 jmp @F
672 db 10,'LVM_DoLetterReassignment:',10,0
673 @@:
674 call AuxIO_Print
675 pop si
676 ;~ call DEBUG_DumpRegisters
677 ;~ call AuxIO_DumpParagraph
678 ;~ call AuxIO_TeletypeNL
679 popa
680 popf
681 ENDIF
682ENDIF
683
684 mov di, si ; Save SI in DI (Partition-pointer)
685 mov ch, al ; and AL in CH (drive-letter)
686 xor bx, bx
687 mov cl, CFG_Partitions
688 or cl, cl
689 jz LVMDLR_SkipRemove
690
691 LVMDLR_RemoveLoop:
692 cmp bptr [PartitionVolumeLetters+bx], ch
693 jne LVMDLR_NextPartition
694 ; One volume that has our wanted drive-letter, so remove it!
695 mov dl, bl
696 call PART_GetPartitionPointer ; DL - partition -> SI
697 ; Now set CurPartition_Location for the DriveIO-functions to work
698 mov ax, wptr [si+LocIPT_AbsolutePartTable]
699 mov wptr [CurPartition_Location+0], ax
700 mov ax, wptr [si+LocIPT_AbsolutePartTable+2]
701 mov wptr [CurPartition_Location+2], ax
702 mov ax, wptr [si+LocIPT_LocationPartTable+1]
703 mov wptr [CurPartition_Location+6], ax
704 mov ah, bptr [si+LocIPT_LocationPartTable+0]
705 mov al, [si+LocIPT_Drive]
706 mov wptr [CurPartition_Location+4], ax
707 call DriveIO_LoadLVMSector ; SI points now to LVM-Sector
708 call LVM_RemoveVolLetterFromSector
709
710 call DriveIO_SaveLVMSector ; Save sector
711
712 LVMDLR_NextPartition:
713 inc bx
714 dec cl
715 jnz LVMDLR_RemoveLoop
716
717 LVMDLR_SkipRemove:
718 ; Set CurPartition_Location information of destination partition
719 mov ax, wptr [di+LocIPT_AbsolutePartTable]
720 mov wptr [CurPartition_Location+0], ax
721 mov ax, wptr [di+LocIPT_AbsolutePartTable+2]
722 mov wptr [CurPartition_Location+2], ax
723 mov ah, bptr [di+LocIPT_LocationPartTable+0]
724 mov al, [di+LocIPT_Drive]
725 mov wptr [CurPartition_Location+4], ax
726 mov ax, wptr [di+LocIPT_LocationPartTable+1]
727 mov wptr [CurPartition_Location+6], ax
728 call DriveIO_LoadLVMSector ; SI points now to LVM-Sector
729 mov ax, wptr [di+LocIPT_AbsoluteBegin]
730 mov dx, wptr [di+LocIPT_AbsoluteBegin+2]
731 mov di, si ; Save SI in DI
732 call LVM_SearchForPartition
733 jnc LVMDLR_DestPartNotFound
734 ; Set new volume letter
735 mov bptr [si+LocLVM_VolumeLetter], ch
736 mov si, di ; SI - LVM Sector again
737 call LVM_UpdateSectorCRC ; Update LVM-CRC now
738
739 call DriveIO_SaveLVMSector ; Save sector
740
741 LVMDLR_DestPartNotFound:
742 ; This here is done for safety, because we misuse CurPartition_Location
743 xor ax, ax
744 mov di, offset CurPartition_Location
745 mov cx, 4
746 rep stosw ; NUL out CurPartition_Location
747 ret
748LVM_DoLetterReassignment EndP
749
750
751; This walks the IPT and for each partition it obtains the LVM drive-letter
752; if available. This drive-letter is then marked as in-use in the Map.
753; The FreeDriveletterMap is used by the drive-letter reassignment function
754; to assign a new drive to a data-partition when a system-partition is booted
755; with the same drive-letter. The original drive-letter for the data-partition
756; is saved so it can be restored later when a system is booted that does not
757; use the drive-letter. Note that there can be multiple system-partitions
758; using the same drive-letter and data-partitions can become system-partition
759; by making them bootable. (and vice versa)
760LVM_ComposeFreeDriveletterMap Proc
761
762; get nr of partitions in IPT
763; for each partition get LVM drive-letter and reset bit in map.
764
765LVM_ComposeFreeDriveletterMap EndP
766
Note: See TracBrowser for help on using the repository browser.