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

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

Make checking for valid LVM-sector use CF instead of ZF [v1.1.1-testing]

Both the checks for LVM Signature and CRC already use CF on return.
Doing the same for complete LVM-sector validation is more consistent.

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