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

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

Changed register interface for LBA read/write sector [v1.1.1-testing]

Changed passing the LBA address from BX:CX to BX:AX, so it corresponds
to the load/save sector functions, which do more checking.

This loses the return-status in AH for reading sectors and specifying
write-verify for writing sectors, but that does not really matter.
Status of the last operation should be available using INT13 function
01h and verification of sectors can be done with function 44h if wanted.
CF indicates success or not, which is enough.

This register combination makes it possible to hold both CHS and LBA
sector addresses in registers if needed:
BX:AX ; LBA32
DX:CX ; CHS10

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.3 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 mov ax, cx ; LBA low is now in AX
323 call DriveIO_ReadSectorLBA
324 pop di
325 pop si
326
327 ; Restore LBA address
328 pop cx
329 pop bx
330
331 ; Restore PRI/LOG partition indicator in DH
332 pop dx
333
334 ; Test PRI or not
335 test dh,dh
336 ; It's not a PRI so we can use the previously loaded LVM sector
337 jz LVM_GetDriveLetter_is_not_pri
338
339 ;
340 ; It's a PRI so we use the special locator function.
341 ; This locator takes care of extended OS/2 geometry should that be used
342 ;
343IF 0
344 ; DH=0 or 1, DL=disk (8?h)
345 pushf
346 pusha
347 mov ax, dx
348 call VideoIO_PrintHexWord
349 mov al,'-'
350 call VideoIO_PrintSingleChar
351 popa
352 popf
353ENDIF
354 ; THIS ONE FAULTERS WHEN DISKS > 1
355 call DriveIO_LoadMasterLVMSector
356
357IF 0
358 ; INVALID LVM SECTOR !!
359 pushf
360 pusha
361 mov ax,0000h
362 rcl al,1
363 call VideoIO_PrintHexWord ; LVMSector
364 mov al,'-'
365 call VideoIO_PrintSingleChar
366 mov si, offset [LVMSector]
367 mov ax, si
368 call VideoIO_PrintHexWord ; LVMSector
369 lodsw
370 call VideoIO_PrintHexWord ; sig
371 lodsw
372 call VideoIO_PrintHexWord ; sig
373 mov al,'-'
374 call VideoIO_PrintSingleChar
375 popa
376 popf
377ENDIF
378
379 LVM_GetDriveLetter_is_not_pri:
380
381
382 ;
383 ; At this stage the LVM-info sector has been loaded at [LVMSector].
384 ; From here we look for an LVM entry for the partition.
385 ; If one is found, based on it's LBA-start, it's driveletter is used
386 ; in case byte 25h in the BPB is zero.
387 ;
388
389
390 ; Search for the partition in the LVM info.
391 ; If found, CY is set and SI points to LVM entry.
392 push si
393 mov ax,cx
394 mov dx,bx ; DL DESTROYED
395 mov si,offset [LVMSector]
396 call LVM_SearchForPartition
397
398IF 0
399 pushf
400 pusha
401 mov ax, 0000h
402 rcl al, 1
403 call VideoIO_PrintHexWord
404 mov ax, si
405 call VideoIO_PrintHexWord
406 popa
407 popf
408ENDIF
409
410IFDEF AUX_DEBUG
411 IF 0
412 pusha
413 push si
414 mov si, offset $+5
415 jmp @F
416 db 10,'LVM_GetDriveLetter:',10,0
417 @@:
418 call AuxIO_Print
419 pop si
420 call DEBUG_DumpRegisters
421 call AuxIO_DumpParagraph
422 call AuxIO_TeletypeNL
423 popa
424 ENDIF
425ENDIF
426
427 mov bx,si ; BX now points to LVM entry
428 mov dx,0
429 pop si
430
431 mov al,0 ; Setup null driveletter
432 ; Oops, no valid LVM record was used so we have a null driveletter.
433 jnc LVM_GetDriveLetter_null_lvm_dl
434
435 ;
436 ; At this point BX points to the LVM-entry related to the
437 ; partition, whether it was a logical or a primary one.
438 ;
439 mov al,[bx+LocLVM_VolumeLetter]
440 ; Test for zero dtive-letter.
441 test al,al
442 ; Preset CY in case drive-letter is zero.
443 clc
444 jz LVM_GetDriveLetter_null_lvm_dl
445
446 ; We have a non-zero drive-letter, so set CY.
447 stc
448
449 LVM_GetDriveLetter_null_lvm_dl:
450 ret
451LVM_GetDriveLetter EndP
452
453
454
455; Sets a drive-letter in the LVM-info of a partition. (if it exists)
456; In: BX:CX - LBA starting sector of partition to be searched
457; DL = Physical Disk in BIOS notation. (80h+)
458; AL = DriveLetter to set (can be zero to hide partition from LVM)
459; Out: CY=1 if LVM-info found, 0 if no LVM-info.
460LVM_SetDriveLetter Proc Near Uses bx cx dx si di ds es
461
462 local disk:byte
463 local drive_letter:byte
464 local pri_ind:byte
465 local lvm_log_high:word
466 local lvm_log_low:word
467 ; For primary partitions this information is stored in the last
468 ; sector of track0; for all four partition entries in case they
469 ; they are all primary ones.
470 ;
471 ; LVM DLAT info for logical partitions is stored in the sector
472 ; preceding the start of the partition.
473 ;
474 ; Because the LVM info of a logical partition is the easiest to find,
475 ; we do that first. The LVM info for primary partitions is located
476 ; dependent on the geometry in use, so we use a special locater
477 ; call for that. Also, since the LVM info for primaries contains
478 ; info on all 4 entries, we need the partition index to obtain the
479 ; correct drive-letter.
480 ;
481
482IFDEF AUX_DEBUG
483 IF 0
484 pushf
485 pusha
486 push si
487 mov si, offset $+5
488 jmp @F
489 db 10,'LVM_SetDriveLetter:',10,0
490 @@:
491 call AuxIO_Print
492 pop si
493 ;~ call DEBUG_DumpRegisters
494 ;~ call AuxIO_DumpParagraph
495 ;~ call AuxIO_TeletypeNL
496 popa
497 popf
498 ENDIF
499ENDIF
500
501 mov [disk], dl
502
503 ; Store the drive-letter for later use
504 mov [drive_letter], al
505
506
507 ; See if this is a primary partition
508 ; CY will be set if it is and AL will contain the 0-based
509 ; index in the P-table.
510 ; If it's a logical partition, CY will be clear and AL
511 ; will be set to 0ffh indicating an invalid index.
512 call PART_IsPrimaryPartition
513 mov al,0
514 rcl al,1 ; CY if primary
515 mov dh,al ; Save PRI or LOG
516 mov [pri_ind],al
517
518 ; Save PRI/LOG indicator for later use
519 push dx
520
521 ; Load *possible* LVM sector
522 ; This load is only valid if the partition is logical, in which case
523 ; the LVM sector is below the start of the partition.
524 ; If primary, the LVM sector is at a location that
525 ; DriveIO_LoadMasterLVMSector will find out.
526
527 ; Push LBA address
528 push bx
529 push cx
530
531 ; Adjust for logical LVM-sector
532 sub cx,1
533 sbb bx,0
534
535 ; Store LBA address of LVM-sector
536 mov [lvm_log_low],cx
537 mov [lvm_log_high],bx
538
539 ; Load the LVM sector
540 push si
541 push di
542 mov si,offset [LVMSector]
543 mov di,ds
544 mov ax, cx ; LBA low is now in AX
545 call DriveIO_ReadSectorLBA
546 pop di
547 pop si
548
549 ; Restore LBA address
550 pop cx
551 pop bx
552
553 ; Restore PRI/LOG partition indicator in DH
554 pop dx
555
556 ; Test PRI or not
557 test dh,dh
558 ; It's not a PRI so we can use the previously loaded LVM sector
559 jz LVM_SetDriveLetter_is_not_pri
560
561 ;
562 ; It's a PRI so we use the special locator function.
563 ; This locator takes care of extended OS/2 geometry should that be used
564 ;
565 call DriveIO_LoadMasterLVMSector
566 jnc LVM_SetDriveLetter_null_lvm_dl
567
568 mov ax, word ptr [MasterLVMLBA] ; ARRAY VAN MAKEN !
569 mov [lvm_log_low], ax
570 mov [lvm_log_high], 0
571
572 LVM_SetDriveLetter_is_not_pri:
573
574 ;
575 ; At this stage the LVM-info sector has been loaded at [LVMSector].
576 ; From here we look for an LVM entry for the partition.
577 ; If one is found, based on it's LBA-start, it's driveletter is used
578 ; in case byte 25h in the BPB is zero.
579 ;
580
581 ; Search for the partition in the LVM info.
582 ; If found, CY is set and SI points to LVM entry.
583 push si
584 mov ax,cx
585 mov dx,bx
586 mov si,offset [LVMSector]
587 call LVM_SearchForPartition
588 mov bx,si ; BX now points to LVM entry
589 pop si
590
591 mov al,0 ; Setup null driveletter
592 ; Oops, no valid LVM record was used so we have a null driveletter.
593 jnc LVM_SetDriveLetter_null_lvm_dl
594
595 ;
596 ; At this point BX points to the LVM-entry related to the
597 ; partition, whether it was a logical or a primary one.
598 ;
599 mov al, [drive_letter]
600 mov [bx+LocLVM_VolumeLetter],al
601
602 mov si, offset [LVMSector]
603 call LVM_UpdateSectorCRC
604
605 mov dl, [disk]
606 mov bx, [lvm_log_high]
607 mov ax, [lvm_log_low]
608
609 call DriveIO_SaveSector
610
611 LVM_SetDriveLetter_null_lvm_dl:
612 ret
613LVM_SetDriveLetter EndP
614
615
616
617; Removes a given drive-letter from the whole LVM information sector
618; In: CH - drive-letter (ascii)
619; DS:SI - LVM-Information-Sector
620; Out: LVM-Information-Sector updated (including LVM CRC)
621; Destroyed: None
622LVM_RemoveVolLetterFromSector Proc Near Uses cx
623
624IFDEF AUX_DEBUG
625 IF 0
626 pushf
627 pusha
628 push si
629 mov si, offset $+5
630 jmp @F
631 db 10,'LVM_RemoveVolLetterFromSector:',10,0
632 @@:
633 call AuxIO_Print
634 pop si
635 ;~ call DEBUG_DumpRegisters
636 ;~ call AuxIO_DumpParagraph
637 ;~ call AuxIO_TeletypeNL
638 popa
639 popf
640 ENDIF
641ENDIF
642
643 cmp bptr [si+LocLVM_SignatureStart], LocLVM_SignatureByte0
644 jne LVMRVLFS_Done ; Quick Check, if LVM sector there
645 push si
646 add si, LocLVM_StartOfEntries
647 mov cl, LocLVM_MaxEntries
648 LVMRVLFS_Loop:
649 cmp ch, [si+LocLVM_VolumeLetter]
650 jne LVMRVLFS_NextEntry
651 ; Reset drive-letter, if matched
652 mov bptr [si+LocLVM_VolumeLetter], 0 ; ASSIGN NEXT FREE HERE... (DOET DUBBEL ALS ZELFDE DL ALS SYS)
653 LVMRVLFS_NextEntry:
654 add si, LocLVM_LenOfEntry
655 dec cl
656 jnz LVMRVLFS_Loop
657 pop si
658 call LVM_UpdateSectorCRC
659 LVMRVLFS_Done:
660 ret
661LVM_RemoveVolLetterFromSector EndP
662
663; Reassigns LVM volume driveletter
664; Will remove the drive-letter from any volume that got it currently
665; and finally change the drive-letter of the given partition
666; In: AL - drive-letter
667; DS:SI - points to partition, that needs that driveletter
668; Out: None
669; Destroyed: AX
670
671LVM_DoLetterReassignment Proc Near Uses bx cx dx si di
672
673IFDEF AUX_DEBUG
674 IF 0
675 pushf
676 pusha
677 push si
678 mov si, offset $+5
679 jmp @F
680 db 10,'LVM_DoLetterReassignment:',10,0
681 @@:
682 call AuxIO_Print
683 pop si
684 ;~ call DEBUG_DumpRegisters
685 ;~ call AuxIO_DumpParagraph
686 ;~ call AuxIO_TeletypeNL
687 popa
688 popf
689 ENDIF
690ENDIF
691
692 mov di, si ; Save SI in DI (Partition-pointer)
693 mov ch, al ; and AL in CH (drive-letter)
694 xor bx, bx
695 mov cl, CFG_Partitions
696 or cl, cl
697 jz LVMDLR_SkipRemove
698
699 LVMDLR_RemoveLoop:
700 cmp bptr [PartitionVolumeLetters+bx], ch
701 jne LVMDLR_NextPartition
702 ; One volume that has our wanted drive-letter, so remove it!
703 mov dl, bl
704 call PART_GetPartitionPointer ; DL - partition -> SI
705 ; Now set CurPartition_Location for the DriveIO-functions to work
706 mov ax, wptr [si+LocIPT_AbsolutePartTable]
707 mov wptr [CurPartition_Location+0], ax
708 mov ax, wptr [si+LocIPT_AbsolutePartTable+2]
709 mov wptr [CurPartition_Location+2], ax
710 mov ax, wptr [si+LocIPT_LocationPartTable+1]
711 mov wptr [CurPartition_Location+6], ax
712 mov ah, bptr [si+LocIPT_LocationPartTable+0]
713 mov al, [si+LocIPT_Drive]
714 mov wptr [CurPartition_Location+4], ax
715 call DriveIO_LoadLVMSector ; SI points now to LVM-Sector
716 call LVM_RemoveVolLetterFromSector
717
718 call DriveIO_SaveLVMSector ; Save sector
719
720 LVMDLR_NextPartition:
721 inc bx
722 dec cl
723 jnz LVMDLR_RemoveLoop
724
725 LVMDLR_SkipRemove:
726 ; Set CurPartition_Location information of destination partition
727 mov ax, wptr [di+LocIPT_AbsolutePartTable]
728 mov wptr [CurPartition_Location+0], ax
729 mov ax, wptr [di+LocIPT_AbsolutePartTable+2]
730 mov wptr [CurPartition_Location+2], ax
731 mov ah, bptr [di+LocIPT_LocationPartTable+0]
732 mov al, [di+LocIPT_Drive]
733 mov wptr [CurPartition_Location+4], ax
734 mov ax, wptr [di+LocIPT_LocationPartTable+1]
735 mov wptr [CurPartition_Location+6], ax
736 call DriveIO_LoadLVMSector ; SI points now to LVM-Sector
737 mov ax, wptr [di+LocIPT_AbsoluteBegin]
738 mov dx, wptr [di+LocIPT_AbsoluteBegin+2]
739 mov di, si ; Save SI in DI
740 call LVM_SearchForPartition
741 jnc LVMDLR_DestPartNotFound
742 ; Set new volume letter
743 mov bptr [si+LocLVM_VolumeLetter], ch
744 mov si, di ; SI - LVM Sector again
745 call LVM_UpdateSectorCRC ; Update LVM-CRC now
746
747 call DriveIO_SaveLVMSector ; Save sector
748
749 LVMDLR_DestPartNotFound:
750 ; This here is done for safety, because we misuse CurPartition_Location
751 xor ax, ax
752 mov di, offset CurPartition_Location
753 mov cx, 4
754 rep stosw ; NUL out CurPartition_Location
755 ret
756LVM_DoLetterReassignment EndP
757
758
759; This walks the IPT and for each partition it obtains the LVM drive-letter
760; if available. This drive-letter is then marked as in-use in the Map.
761; The FreeDriveletterMap is used by the drive-letter reassignment function
762; to assign a new drive to a data-partition when a system-partition is booted
763; with the same drive-letter. The original drive-letter for the data-partition
764; is saved so it can be restored later when a system is booted that does not
765; use the drive-letter. Note that there can be multiple system-partitions
766; using the same drive-letter and data-partitions can become system-partition
767; by making them bootable. (and vice versa)
768LVM_ComposeFreeDriveletterMap Proc
769
770; get nr of partitions in IPT
771; for each partition get LVM drive-letter and reset bit in map.
772
773LVM_ComposeFreeDriveletterMap EndP
774
Note: See TracBrowser for help on using the repository browser.