mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 04:46:37 +00:00
Changes in v1.7.4 (8/20/2002) (brianp)
- Boot sector code now reports to freeldr.sys the partition that it was installed on. This is specified by a byte value in the boot sector code. By default the boot partition is set to zero which indicates the active (bootable) partition, unless the installer sets the value to non-zero. If FreeLoader is installed on a partition other than the active (bootable) partition then the installer must set this byte to that partition number. Otherwise FreeLoader will not be able to find freeldr.ini. - i386trap.S: Added debug macros BREAKPOINT(), INSTRUCTION_BREAKPOINTX(), MEMORY_READWRITE_BREAKPOINTX(), & MEMORY_WRITE_BREAKPOINTX(). - partition.c (DiskGetPartitionEntry): Add the relative offset of the extended partition to the partitions start sector. - ext2.c (Ext2ReadBlockPointerList, Ext2CopyIndirectBlockPointers, Ext2CopyDoubleIndirectBlockPointers, Ext2CopyTripleIndirectBlockPointers): Rewrote the block pointer functions so they actually work. - ini_init.c (IniFileInitialize, IniOpenIniFile): Looks for freeldr.ini on both the active (bootable) partition and the partition passed in from the boot sector code. - meminit.c (MmInitializeMemoryManager, MmFixupSystemMemoryMap, MmGetEndAddressOfAnyMemory, MmGetAddressablePageCountIncludingHoles, MmInitPageLookupTable): Fixed bug that would cause FreeLoader to have an off-by-one error when accessing the last entry in the page lookup table on systems with 4GB of memory (or memory mapped at the end of the address space). svn path=/trunk/; revision=3372
This commit is contained in:
parent
d8bd5ccb4a
commit
367cfa7085
21 changed files with 633 additions and 236 deletions
|
@ -2,6 +2,16 @@
|
|||
; EXT2 Boot Sector
|
||||
; Copyright (c) 2002 Brian Palmer
|
||||
|
||||
; [bp-0x04] Here we will store the number of sectors per track
|
||||
; [bp-0x08] Here we will store the number of heads
|
||||
; [bp-0x0c] Here we will store the size of the disk as the BIOS reports in CHS form
|
||||
; [bp-0x10] Here we will store the number of LBA sectors read
|
||||
|
||||
SECTORS_PER_TRACK equ 0x04
|
||||
NUMBER_OF_HEADS equ 0x08
|
||||
BIOS_CHS_DRIVE_SIZE equ 0x0C
|
||||
LBA_SECTORS_READ equ 0x10
|
||||
|
||||
|
||||
EXT2_ROOT_INO equ 2
|
||||
EXT2_S_IFMT equ 0f0h
|
||||
|
@ -19,10 +29,11 @@ start:
|
|||
nop
|
||||
|
||||
BootDrive db 0x80
|
||||
SectorsPerTrack dw 63
|
||||
NumberOfHeads dw 16
|
||||
BiosCHSDriveSize dd (1024 * 1024 * 63)
|
||||
LBASectorsRead dd 0
|
||||
BootPartition db 0
|
||||
;SectorsPerTrack db 63 ; Moved to [bp-SECTORS_PER_TRACK]
|
||||
;NumberOfHeads dw 16 ; Moved to [bp-NUMBER_OF_HEADS]
|
||||
;BiosCHSDriveSize dd (1024 * 1024 * 63) ; Moved to [bp-BIOS_CHS_DRIVE_SIZE]
|
||||
;LBASectorsRead dd 0 ; Moved to [bp-LBA_SECTORS_READ]
|
||||
|
||||
Ext2VolumeStartSector dd 263088 ; Start sector of the ext2 volume
|
||||
Ext2BlockSize dd 2 ; Block size in sectors
|
||||
|
@ -48,7 +59,7 @@ main:
|
|||
mov es,ax ; Make ES correct
|
||||
mov ss,ax ; Make SS correct
|
||||
mov bp,7c00h
|
||||
mov sp,7c00h ; Setup a stack
|
||||
mov sp,7b00h ; Setup a stack
|
||||
|
||||
|
||||
GetDriveParameters:
|
||||
|
@ -66,29 +77,33 @@ GetDriveParameters:
|
|||
CalcDriveSize:
|
||||
; Now that we have the drive geometry
|
||||
; lets calculate the drive size
|
||||
mov bl,ch ; Put the low 8-bits of the cylinder count into BL
|
||||
mov bh,cl ; Put the high 2-bits in BH
|
||||
shr bh,6 ; Shift them into position, now BX contains the cylinder count
|
||||
and cl,3fh ; Mask off cylinder bits from sector count
|
||||
mov bl,ch ; Put the low 8-bits of the cylinder count into BL
|
||||
mov bh,cl ; Put the high 2-bits in BH
|
||||
shr bh,6 ; Shift them into position, now BX contains the cylinder count
|
||||
and cl,3fh ; Mask off cylinder bits from sector count
|
||||
; CL now contains sectors per track and DH contains head count
|
||||
movzx eax,dh ; Move the heads into EAX
|
||||
movzx ebx,bx ; Move the cylinders into EBX
|
||||
movzx ecx,cl ; Move the sectors per track into ECX
|
||||
inc eax ; Make it one based because the bios returns it zero based
|
||||
inc ebx ; Make the cylinder count one based also
|
||||
mul ecx ; Multiply heads with the sectors per track, result in edx:eax
|
||||
mul ebx ; Multiply the cylinders with (heads * sectors) [stored in edx:eax already]
|
||||
movzx eax,dh ; Move the heads into EAX
|
||||
movzx ebx,bx ; Move the cylinders into EBX
|
||||
movzx ecx,cl ; Move the sectors per track into ECX
|
||||
inc eax ; Make it one based because the bios returns it zero based
|
||||
mov [BYTE bp-NUMBER_OF_HEADS],eax ; Save number of heads
|
||||
mov [BYTE bp-SECTORS_PER_TRACK],ecx ; Save number of sectors per track
|
||||
inc ebx ; Make the cylinder count one based also
|
||||
mul ecx ; Multiply heads with the sectors per track, result in edx:eax
|
||||
mul ebx ; Multiply the cylinders with (heads * sectors) [stored in edx:eax already]
|
||||
|
||||
; We now have the total number of sectors as reported
|
||||
; by the bios in eax, so store it in our variable
|
||||
mov [BYTE bp+BiosCHSDriveSize],eax
|
||||
mov [BYTE bp-BIOS_CHS_DRIVE_SIZE],eax
|
||||
|
||||
|
||||
LoadExtraBootCode:
|
||||
; First we have to load our extra boot code at
|
||||
; sector 1 into memory at [0000:7e00h]
|
||||
mov eax,01h
|
||||
mov cx,1
|
||||
;mov eax,01h
|
||||
xor eax,eax
|
||||
inc eax ; Read logical sector 1, EAX now = 1
|
||||
mov cx,1 ; Read one sector
|
||||
mov bx,7e00h ; Read sector to [0000:7e00h]
|
||||
call ReadSectors
|
||||
|
||||
|
@ -177,7 +192,7 @@ Ext2ReadInode:
|
|||
; CX has number of sectors to read
|
||||
ReadSectors:
|
||||
add eax,DWORD [BYTE bp+Ext2VolumeStartSector] ; Add the start of the volume
|
||||
cmp eax,DWORD [BYTE bp+BiosCHSDriveSize] ; Check if they are reading a sector outside CHS range
|
||||
cmp eax,DWORD [BYTE bp-BIOS_CHS_DRIVE_SIZE] ; Check if they are reading a sector outside CHS range
|
||||
jae ReadSectorsLBA ; Yes - go to the LBA routine
|
||||
; If at all possible we want to use LBA routines because
|
||||
; They are optimized to read more than 1 sector per read
|
||||
|
@ -200,12 +215,13 @@ CheckInt13hExtensions: ; Now check if this computer supports extended read
|
|||
ReadSectorsLBA:
|
||||
pushad ; Save logical sector number & sector count
|
||||
|
||||
cmp cx,64 ; Since the LBA calls only support 0x7F sectors at a time we will limit ourselves to 64
|
||||
cmp cx,byte 64 ; Since the LBA calls only support 0x7F sectors at a time we will limit ourselves to 64
|
||||
jbe ReadSectorsSetupDiskAddressPacket ; If we are reading less than 65 sectors then just do the read
|
||||
mov cx,64 ; Otherwise read only 64 sectors on this loop iteration
|
||||
|
||||
ReadSectorsSetupDiskAddressPacket:
|
||||
mov [BYTE bp+LBASectorsRead],cx
|
||||
mov [BYTE bp-LBA_SECTORS_READ],cx
|
||||
mov WORD [BYTE bp-LBA_SECTORS_READ+2],0
|
||||
o32 push byte 0
|
||||
push eax ; Put 64-bit logical block address on stack
|
||||
push es ; Put transfer segment on stack
|
||||
|
@ -225,7 +241,7 @@ ReadSectorsSetupDiskAddressPacket:
|
|||
popad ; Restore sector count & logical sector number
|
||||
|
||||
push bx
|
||||
mov ebx,DWORD [BYTE bp+LBASectorsRead]
|
||||
mov ebx,DWORD [BYTE bp-LBA_SECTORS_READ]
|
||||
add eax,ebx ; Increment sector to read
|
||||
shl ebx,5
|
||||
mov dx,es
|
||||
|
@ -233,7 +249,7 @@ ReadSectorsSetupDiskAddressPacket:
|
|||
mov es,dx
|
||||
pop bx
|
||||
|
||||
sub cx,[BYTE bp+LBASectorsRead]
|
||||
sub cx,[BYTE bp-LBA_SECTORS_READ]
|
||||
jnz ReadSectorsLBA ; Read next sector
|
||||
|
||||
ret
|
||||
|
@ -248,13 +264,13 @@ ReadSectorsCHS:
|
|||
ReadSectorsCHSLoop:
|
||||
pushad
|
||||
xor edx,edx
|
||||
movzx ecx,WORD [BYTE bp+SectorsPerTrack]
|
||||
mov ecx,DWORD [BYTE bp-SECTORS_PER_TRACK]
|
||||
div ecx ; Divide logical by SectorsPerTrack
|
||||
inc dl ; Sectors numbering starts at 1 not 0
|
||||
mov cl,dl ; Sector in CL
|
||||
mov edx,eax
|
||||
shr edx,16
|
||||
div WORD [BYTE bp+NumberOfHeads] ; Divide logical by number of heads
|
||||
div WORD [BYTE bp-NUMBER_OF_HEADS] ; Divide logical by number of heads
|
||||
mov dh,dl ; Head in DH
|
||||
mov dl,[BYTE bp+BootDrive] ; Drive number in DL
|
||||
mov ch,al ; Cylinder in CX
|
||||
|
@ -410,6 +426,7 @@ LoadFreeLoader:
|
|||
call Ext2ReadEntireFile ; Read freeldr.sys to 0000:8000
|
||||
|
||||
mov dl,[BYTE bp+BootDrive]
|
||||
mov dh,[BYTE bp+BootPartition]
|
||||
push byte 0 ; We loaded at 0000:8000
|
||||
push WORD 8000h ; We will do a far return to 0000:8000h
|
||||
retf ; Transfer control to FreeLoader
|
||||
|
@ -437,7 +454,7 @@ Ext2ReadEntireFile:
|
|||
; We will do this by rounding the
|
||||
; file size up to the next block
|
||||
; size and then dividing by the block size
|
||||
mov eax,DWORD [bp+Ext2BlockSizeInBytes] ; Get the block size in bytes
|
||||
mov eax,DWORD [BYTE bp+Ext2BlockSizeInBytes] ; Get the block size in bytes
|
||||
push eax
|
||||
dec eax ; Ext2BlockSizeInBytes -= 1
|
||||
add eax,DWORD [es:di+4] ; Add the file size
|
||||
|
@ -447,7 +464,7 @@ Ext2ReadEntireFile:
|
|||
push eax
|
||||
|
||||
; Make sure the file size isn't zero
|
||||
cmp eax,0
|
||||
cmp eax,byte 0
|
||||
jnz Ext2ReadEntireFile2
|
||||
jmp PrintFileSizeError
|
||||
|
||||
|
@ -480,14 +497,14 @@ Ext2ReadEntireFile2:
|
|||
|
||||
; Check to see if we actually have
|
||||
; blocks left to read
|
||||
cmp eax,0
|
||||
cmp eax,byte 0
|
||||
jz Ext2ReadEntireFileDone
|
||||
|
||||
; Now we have read all the direct blocks in
|
||||
; the inode. So now we have to read the indirect
|
||||
; block and read all it's direct blocks
|
||||
push eax ; Save the total block count
|
||||
mov eax,DWORD [bp+Ext2InodeIndirectPointer] ; Get the indirect block pointer
|
||||
mov eax,DWORD [BYTE bp+Ext2InodeIndirectPointer] ; Get the indirect block pointer
|
||||
push WORD 7000h
|
||||
pop es
|
||||
xor bx,bx ; Set the load address to 7000:0000
|
||||
|
@ -496,12 +513,12 @@ Ext2ReadEntireFile2:
|
|||
; Now we have all the block pointers from the
|
||||
; indirect block in the right location so read them in
|
||||
pop eax ; Restore the total block count
|
||||
mov ecx,DWORD [bp+Ext2PointersPerBlock] ; Get the number of block pointers that one block contains
|
||||
mov ecx,DWORD [BYTE bp+Ext2PointersPerBlock] ; Get the number of block pointers that one block contains
|
||||
call Ext2ReadDirectBlockList
|
||||
|
||||
; Check to see if we actually have
|
||||
; blocks left to read
|
||||
cmp eax,0
|
||||
cmp eax,byte 0
|
||||
jz Ext2ReadEntireFileDone
|
||||
|
||||
; Now we have read all the direct blocks from
|
||||
|
@ -509,8 +526,8 @@ Ext2ReadEntireFile2:
|
|||
; we have to read the double indirect block
|
||||
; and read all it's indirect blocks
|
||||
; (whew, it's a good thing I don't support triple indirect blocks)
|
||||
mov [bp+Ext2BlocksLeftToRead],eax ; Save the total block count
|
||||
mov eax,DWORD [bp+Ext2InodeDoubleIndirectPointer] ; Get the double indirect block pointer
|
||||
mov [BYTE bp+Ext2BlocksLeftToRead],eax ; Save the total block count
|
||||
mov eax,DWORD [BYTE bp+Ext2InodeDoubleIndirectPointer] ; Get the double indirect block pointer
|
||||
push WORD 7800h
|
||||
pop es
|
||||
push es ; Save an extra copy of this value on the stack
|
||||
|
@ -522,7 +539,7 @@ Ext2ReadEntireFile2:
|
|||
|
||||
Ext2ReadIndirectBlock:
|
||||
mov eax,DWORD [es:di] ; Get indirect block pointer
|
||||
add di,4 ; Update DI for next array index
|
||||
add di,BYTE 4 ; Update DI for next array index
|
||||
push es
|
||||
push di
|
||||
|
||||
|
@ -533,16 +550,16 @@ Ext2ReadIndirectBlock:
|
|||
|
||||
; Now we have all the block pointers from the
|
||||
; indirect block in the right location so read them in
|
||||
mov eax,DWORD [bp+Ext2BlocksLeftToRead] ; Restore the total block count
|
||||
mov ecx,DWORD [bp+Ext2PointersPerBlock] ; Get the number of block pointers that one block contains
|
||||
mov eax,DWORD [BYTE bp+Ext2BlocksLeftToRead] ; Restore the total block count
|
||||
mov ecx,DWORD [BYTE bp+Ext2PointersPerBlock] ; Get the number of block pointers that one block contains
|
||||
call Ext2ReadDirectBlockList
|
||||
mov [bp+Ext2BlocksLeftToRead],eax ; Save the total block count
|
||||
mov [BYTE bp+Ext2BlocksLeftToRead],eax ; Save the total block count
|
||||
pop di
|
||||
pop es
|
||||
|
||||
; Check to see if we actually have
|
||||
; blocks left to read
|
||||
cmp eax,0
|
||||
cmp eax,byte 0
|
||||
jnz Ext2ReadIndirectBlock
|
||||
|
||||
Ext2ReadEntireFileDone:
|
||||
|
@ -579,7 +596,7 @@ Ext2ReadDirectBlocks:
|
|||
|
||||
Ext2ReadDirectBlocksLoop:
|
||||
mov eax,[es:di] ; Get direct block pointer from array
|
||||
add di,4 ; Update DI for next array index
|
||||
add di,BYTE 4 ; Update DI for next array index
|
||||
|
||||
push cx ; Save number of direct blocks left
|
||||
push es ; Save array segment
|
||||
|
|
|
@ -42,9 +42,9 @@
|
|||
BootSectorStackTop equ 0x7bf2
|
||||
DataAreaStartHigh equ 0x2
|
||||
DataAreaStartLow equ 0x4
|
||||
BiosCHSDriveSize equ 0x6
|
||||
BiosCHSDriveSizeHigh equ 0x6
|
||||
BiosCHSDriveSizeLow equ 0x8
|
||||
BiosCHSDriveSize equ 0x8
|
||||
ReadSectorsOffset equ 0xa
|
||||
ReadClusterOffset equ 0xc
|
||||
PutCharsOffset equ 0xe
|
||||
|
@ -89,6 +89,9 @@ main:
|
|||
mov es,ax ; Make ES correct
|
||||
|
||||
|
||||
cmp BYTE [BYTE bp+BootDrive],BYTE 0xff ; If they have specified a boot drive then use it
|
||||
jne GetDriveParameters
|
||||
|
||||
mov [BYTE bp+BootDrive],dl ; Save the boot drive
|
||||
|
||||
|
||||
|
@ -208,22 +211,6 @@ FoundFreeLoader:
|
|||
jmp 8003h
|
||||
|
||||
|
||||
; Reads cluster number in AX into [ES:0000]
|
||||
ReadCluster:
|
||||
; StartSector = ((Cluster - 2) * SectorsPerCluster) + ReservedSectors + HiddenSectors;
|
||||
dec ax ; Adjust start cluster by 2
|
||||
dec ax ; Because the data area starts on cluster 2
|
||||
xor ch,ch
|
||||
mov cl,BYTE [BYTE bp+SectsPerCluster]
|
||||
mul cx ; Times sectors per cluster
|
||||
add ax,[BYTE bp-DataAreaStartLow] ; Add start of data area
|
||||
adc dx,[BYTE bp-DataAreaStartHigh] ; Now we have DX:AX with the logical start sector of OSLOADER.SYS
|
||||
xor bx,bx ; We will load it to [ES:0000], ES loaded before function call
|
||||
mov cl,BYTE [BYTE bp+SectsPerCluster]
|
||||
call ReadSectors
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
; Displays an error message
|
||||
|
@ -231,10 +218,10 @@ ReadCluster:
|
|||
ErrBoot:
|
||||
mov si,msgFreeLdr ; FreeLdr not found message
|
||||
call PutChars ; Display it
|
||||
mov si,msgAnyKey ; Press any key message
|
||||
call PutChars ; Display it
|
||||
|
||||
Reboot:
|
||||
mov si,msgAnyKey ; Press any key message
|
||||
call PutChars ; Display it
|
||||
xor ax,ax
|
||||
int 16h ; Wait for a keypress
|
||||
int 19h ; Reboot
|
||||
|
@ -254,23 +241,49 @@ Done:
|
|||
; And reboots
|
||||
BadBoot:
|
||||
mov si,msgDiskError ; Bad boot disk message
|
||||
call PutChars ; Display it
|
||||
mov si,msgAnyKey ; Press any key message
|
||||
call PutChars ; Display it
|
||||
|
||||
jmp short Reboot
|
||||
|
||||
|
||||
; Reads cluster number in AX into [ES:0000]
|
||||
ReadCluster:
|
||||
; StartSector = ((Cluster - 2) * SectorsPerCluster) + ReservedSectors + HiddenSectors;
|
||||
dec ax ; Adjust start cluster by 2
|
||||
dec ax ; Because the data area starts on cluster 2
|
||||
xor ch,ch
|
||||
mov cl,BYTE [BYTE bp+SectsPerCluster]
|
||||
mul cx ; Times sectors per cluster
|
||||
add ax,[BYTE bp-DataAreaStartLow] ; Add start of data area
|
||||
adc dx,[BYTE bp-DataAreaStartHigh] ; Now we have DX:AX with the logical start sector of OSLOADER.SYS
|
||||
xor bx,bx ; We will load it to [ES:0000], ES loaded before function call
|
||||
mov cl,BYTE [BYTE bp+SectsPerCluster]
|
||||
;call ReadSectors
|
||||
;ret
|
||||
|
||||
|
||||
|
||||
; Reads logical sectors into [ES:BX]
|
||||
; DX:AX has logical sector number to read
|
||||
; CX has number of sectors to read
|
||||
ReadSectors:
|
||||
cmp dx,WORD [BYTE bp-BiosCHSDriveSizeHigh]; Check if they are reading a sector within CHS range
|
||||
jb ReadSectorsCHS ; Yes - go to the old CHS routine
|
||||
cmp ax,WORD [BYTE bp-BiosCHSDriveSizeLow]; Check if they are reading a sector within CHS range
|
||||
jbe ReadSectorsCHS ; Yes - go to the old CHS routine
|
||||
|
||||
; We can't just check if the start sector is
|
||||
; in the BIOS CHS range. We have to check if
|
||||
; the start sector + length is in that range.
|
||||
pusha
|
||||
dec cx
|
||||
add ax,cx
|
||||
adc dx,byte 0
|
||||
|
||||
cmp dx,WORD [BYTE bp-BiosCHSDriveSizeHigh] ; Check if they are reading a sector within CHS range
|
||||
jb ReadSectorsCHS ; Yes - go to the old CHS routine
|
||||
cmp ax,WORD [BYTE bp-BiosCHSDriveSizeLow] ; Check if they are reading a sector within CHS range
|
||||
jbe ReadSectorsCHS ; Yes - go to the old CHS routine
|
||||
|
||||
ReadSectorsLBA:
|
||||
pushad ; Save logical sector number & sector count
|
||||
popa
|
||||
pusha ; Save logical sector number & sector count
|
||||
|
||||
o32 push byte 0
|
||||
push dx ; Put 64-bit logical
|
||||
|
@ -303,16 +316,13 @@ ReadSectorsLBA:
|
|||
int 13h ; Call BIOS
|
||||
jc BadBoot ; If the read failed then abort
|
||||
|
||||
add sp,0x10 ; Remove disk address packet from stack
|
||||
add sp,byte 0x10 ; Remove disk address packet from stack
|
||||
|
||||
popad ; Restore sector count & logical sector number
|
||||
popa ; Restore sector count & logical sector number
|
||||
|
||||
inc ax ; Increment Sector to Read
|
||||
jnz NoCarry
|
||||
inc dx
|
||||
adc dx,byte 0
|
||||
|
||||
|
||||
NoCarry:
|
||||
mov dx,es
|
||||
add dx,byte 20h ; Increment read buffer for next sector
|
||||
mov es,dx
|
||||
|
@ -327,7 +337,8 @@ NoCarry:
|
|||
; CX has number of sectors to read
|
||||
; CarryFlag set on error
|
||||
ReadSectorsCHS:
|
||||
pushad
|
||||
popa
|
||||
pusha
|
||||
xchg ax,cx
|
||||
xchg ax,dx
|
||||
xor dx,dx
|
||||
|
@ -351,7 +362,7 @@ ReadSectorsCHS:
|
|||
|
||||
jc BadBoot
|
||||
|
||||
popad
|
||||
popa
|
||||
inc ax ;Increment Sector to Read
|
||||
jnz NoCarryCHS
|
||||
inc dx
|
||||
|
@ -370,11 +381,16 @@ NoCarryCHS:
|
|||
|
||||
|
||||
msgDiskError db 'Disk error',0dh,0ah,0
|
||||
msgFreeLdr db 'FREELDR.SYS not found',0dh,0ah,0
|
||||
msgFreeLdr db 'freeldr.sys not found',0dh,0ah,0
|
||||
; Sorry, need the space...
|
||||
;msgAnyKey db 'Press any key to restart',0dh,0ah,0
|
||||
msgAnyKey db 'Press any key',0dh,0ah,0
|
||||
filename db 'FREELDR SYS'
|
||||
|
||||
times 510-($-$$) db 0 ; Pad to 510 bytes
|
||||
times 509-($-$$) db 0 ; Pad to 509 bytes
|
||||
|
||||
BootPartition:
|
||||
db 0
|
||||
|
||||
BootSignature:
|
||||
dw 0aa55h ; BootSector signature
|
||||
|
|
|
@ -51,6 +51,12 @@ main:
|
|||
|
||||
|
||||
|
||||
cmp BYTE [BYTE bp+BootDrive],BYTE 0xff ; If they have specified a boot drive then use it
|
||||
jne CheckSectorsPerFat
|
||||
|
||||
mov [BYTE bp+BootDrive],dl ; Save the boot drive
|
||||
|
||||
|
||||
|
||||
CheckSectorsPerFat:
|
||||
cmp WORD [BYTE bp+SectorsPerFat],byte 0x00 ; Check the old 16-bit value of SectorsPerFat
|
||||
|
@ -230,8 +236,6 @@ ReadSectorsCHSLoop:
|
|||
; And reboots
|
||||
PrintDiskError:
|
||||
mov si,msgDiskError ; Bad boot disk message
|
||||
call PutChars ; Display it
|
||||
mov si,msgAnyKey ; Press any key message
|
||||
call PutChars ; Display it
|
||||
|
||||
jmp Reboot
|
||||
|
@ -241,10 +245,10 @@ PrintDiskError:
|
|||
PrintFileSystemError:
|
||||
mov si,msgFileSystemError ; FreeLdr not found message
|
||||
call PutChars ; Display it
|
||||
mov si,msgAnyKey ; Press any key message
|
||||
call PutChars ; Display it
|
||||
|
||||
Reboot:
|
||||
mov si,msgAnyKey ; Press any key message
|
||||
call PutChars ; Display it
|
||||
xor ax,ax
|
||||
int 16h ; Wait for a keypress
|
||||
int 19h ; Reboot
|
||||
|
@ -268,7 +272,12 @@ msgDiskError db 'Disk error',0dh,0ah,0
|
|||
msgFileSystemError db 'File system error',0dh,0ah,0
|
||||
msgAnyKey db 'Press any key to restart',0dh,0ah,0
|
||||
|
||||
times 510-($-$$) db 0 ; Pad to 510 bytes
|
||||
times 509-($-$$) db 0 ; Pad to 510 bytes
|
||||
|
||||
BootPartition:
|
||||
db 0
|
||||
|
||||
BootSignature:
|
||||
dw 0aa55h ; BootSector signature
|
||||
|
||||
|
||||
|
@ -379,7 +388,8 @@ LoadFile:
|
|||
jmp LoadFile ; Load the next cluster (if any)
|
||||
|
||||
LoadFileDone:
|
||||
mov dl,[BYTE bp+BootDrive]
|
||||
mov dl,[BYTE bp+BootDrive] ; Load boot drive into DL
|
||||
mov dh,[BootPartition] ; Load boot partition into DH
|
||||
xor ax,ax
|
||||
push ax ; We loaded at 0000:8000
|
||||
push WORD 8000h ; We will do a far return to 0000:8000h
|
||||
|
@ -485,7 +495,7 @@ PrintFileNotFound:
|
|||
|
||||
jmp Reboot
|
||||
|
||||
msgFreeLdr db 'FREELDR.SYS not found',0dh,0ah,0
|
||||
msgFreeLdr db 'freeldr.sys not found',0dh,0ah,0
|
||||
filename db 'FREELDR SYS'
|
||||
msgLoading db 'Loading FreeLoader...',0dh,0ah,0
|
||||
|
||||
|
|
|
@ -330,6 +330,7 @@ get_fs_structures:
|
|||
mov cx, 0xFFFF ; load the whole file
|
||||
call getfssec ; get the first sector
|
||||
mov dl, [DriveNo] ; dl = boot drive
|
||||
mov dh, 0 ; dh = boot partition
|
||||
jmp 0:0x8000 ; jump into OSLoader
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,32 @@
|
|||
Changes in v1.7.4 (8/20/2002) (brianp)
|
||||
|
||||
- Boot sector code now reports to freeldr.sys the partition
|
||||
that it was installed on. This is specified by a byte
|
||||
value in the boot sector code. By default the boot partition
|
||||
is set to zero which indicates the active (bootable)
|
||||
partition, unless the installer sets the value to non-zero.
|
||||
If FreeLoader is installed on a partition other than
|
||||
the active (bootable) partition then the installer must
|
||||
set this byte to that partition number. Otherwise
|
||||
FreeLoader will not be able to find freeldr.ini.
|
||||
- i386trap.S: Added debug macros BREAKPOINT(),
|
||||
INSTRUCTION_BREAKPOINTX(), MEMORY_READWRITE_BREAKPOINTX(), &
|
||||
MEMORY_WRITE_BREAKPOINTX().
|
||||
- partition.c (DiskGetPartitionEntry): Add the relative offset
|
||||
of the extended partition to the partitions start sector.
|
||||
- ext2.c (Ext2ReadBlockPointerList, Ext2CopyIndirectBlockPointers,
|
||||
Ext2CopyDoubleIndirectBlockPointers, Ext2CopyTripleIndirectBlockPointers):
|
||||
Rewrote the block pointer functions so they actually work.
|
||||
- ini_init.c (IniFileInitialize, IniOpenIniFile): Looks for freeldr.ini
|
||||
on both the active (bootable) partition and the partition
|
||||
passed in from the boot sector code.
|
||||
- meminit.c (MmInitializeMemoryManager, MmFixupSystemMemoryMap,
|
||||
MmGetEndAddressOfAnyMemory, MmGetAddressablePageCountIncludingHoles,
|
||||
MmInitPageLookupTable): Fixed bug that would cause FreeLoader to
|
||||
have an off-by-one error when accessing the last entry in the
|
||||
page lookup table on systems with 4GB of memory (or memory mapped
|
||||
at the end of the address space).
|
||||
|
||||
Changes in v1.7.2 (8/7/2002) (brianp)
|
||||
|
||||
- Fragment size must be equal to the block size
|
||||
|
|
|
@ -48,6 +48,9 @@ EXTERN(RealEntryPoint)
|
|||
/* Store the boot drive */
|
||||
movb %dl,(_BootDrive)
|
||||
|
||||
/* Store the boot partition */
|
||||
movb %dh,(_BootPartition)
|
||||
|
||||
/* GO! */
|
||||
call _BootMain
|
||||
|
||||
|
@ -291,3 +294,6 @@ rmode_idtptr:
|
|||
|
||||
EXTERN(_BootDrive)
|
||||
.long 0
|
||||
|
||||
EXTERN(_BootPartition)
|
||||
.long 0
|
||||
|
|
|
@ -14,9 +14,9 @@ bits 16
|
|||
BootSectorStackTop equ 0x7bf2
|
||||
DataAreaStartHigh equ 0x2
|
||||
DataAreaStartLow equ 0x4
|
||||
BiosCHSDriveSize equ 0x6
|
||||
BiosCHSDriveSizeHigh equ 0x6
|
||||
BiosCHSDriveSizeLow equ 0x8
|
||||
BiosCHSDriveSize equ 0x8
|
||||
ReadSectorsOffset equ 0xa
|
||||
ReadClusterOffset equ 0xc
|
||||
PutCharsOffset equ 0xe
|
||||
|
@ -40,6 +40,8 @@ ExtendSig equ 38
|
|||
SerialNumber equ 39
|
||||
VolumeLabel equ 43
|
||||
FileSystem equ 54
|
||||
|
||||
BootPartition equ 0x7dfd
|
||||
|
||||
|
||||
; This code will be stored in the first 512 bytes
|
||||
|
@ -120,6 +122,7 @@ LoadFile5:
|
|||
|
||||
LoadFile_Done:
|
||||
mov dl,BYTE [BYTE bp+BootDrive] ; Load the boot drive into DL
|
||||
mov dh,[BootPartition] ; Load the boot partition into DH
|
||||
push WORD 0x0000
|
||||
push WORD 0x8000 ; We will do a far return to 0000:8000h
|
||||
retf ; Transfer control to ROSLDR
|
||||
|
|
|
@ -66,6 +66,10 @@
|
|||
movl %eax,i386_DR2
|
||||
movl %dr3,%eax
|
||||
movl %eax,i386_DR3
|
||||
movl %dr6,%eax
|
||||
movl %eax,i386_DR6
|
||||
movl %dr7,%eax
|
||||
movl %eax,i386_DR7
|
||||
sgdt i386_GDTR
|
||||
sidt i386_IDTR
|
||||
sldt i386_LDTR
|
||||
|
@ -115,6 +119,10 @@
|
|||
movl %eax,i386_DR2
|
||||
movl %dr3,%eax
|
||||
movl %eax,i386_DR3
|
||||
movl %dr6,%eax
|
||||
movl %eax,i386_DR6
|
||||
movl %dr7,%eax
|
||||
movl %eax,i386_DR7
|
||||
sgdt i386_GDTR
|
||||
sidt i386_IDTR
|
||||
sldt i386_LDTR
|
||||
|
@ -214,6 +222,10 @@ i386_DR2_Text:
|
|||
.asciz " DR2: "
|
||||
i386_DR3_Text:
|
||||
.asciz " DR3: "
|
||||
i386_DR6_Text:
|
||||
.asciz " DR6: "
|
||||
i386_DR7_Text:
|
||||
.asciz " DR7: "
|
||||
i386_GDTR_Text:
|
||||
.asciz " GDTR Base: "
|
||||
i386_IDTR_Text:
|
||||
|
@ -280,6 +292,10 @@ i386_DR2:
|
|||
.long 0
|
||||
i386_DR3:
|
||||
.long 0
|
||||
i386_DR6:
|
||||
.long 0
|
||||
i386_DR7:
|
||||
.long 0
|
||||
i386_GDTR:
|
||||
.word 0
|
||||
.long 0
|
||||
|
@ -379,6 +395,18 @@ i386CommonExceptionHandler:
|
|||
call i386PrintText
|
||||
movl i386_DR3,%eax
|
||||
call i386PrintHexDword // Display DR3
|
||||
incl i386_ScreenPosY
|
||||
movl $55,i386_ScreenPosX
|
||||
movl $i386_DR6_Text,%esi
|
||||
call i386PrintText
|
||||
movl i386_DR6,%eax
|
||||
call i386PrintHexDword // Display DR6
|
||||
incl i386_ScreenPosY
|
||||
movl $55,i386_ScreenPosX
|
||||
movl $i386_DR7_Text,%esi
|
||||
call i386PrintText
|
||||
movl i386_DR7,%eax
|
||||
call i386PrintHexDword // Display DR7
|
||||
movl $0,i386_ScreenPosX
|
||||
incl i386_ScreenPosY
|
||||
incl i386_ScreenPosY
|
||||
|
@ -759,3 +787,210 @@ EXTERN(i386MachineCheck)
|
|||
|
||||
movl $i386MachineCheckText,i386ExceptionDescriptionText
|
||||
jmp i386CommonExceptionHandler
|
||||
|
||||
/************************************************************************
|
||||
* DEBUGGING SUPPORT FUNCTIONS
|
||||
************************************************************************/
|
||||
EXTERN(_INSTRUCTION_BREAKPOINT1)
|
||||
.code32
|
||||
|
||||
pushl %eax
|
||||
|
||||
movl 8(%esp),%eax
|
||||
|
||||
movl %eax,%dr0
|
||||
movl %dr7,%eax
|
||||
andl $0xfff0ffff,%eax
|
||||
orl $0x00000303,%eax
|
||||
movl %eax,%dr7
|
||||
|
||||
popl %eax
|
||||
|
||||
ret
|
||||
|
||||
EXTERN(_MEMORY_READWRITE_BREAKPOINT1)
|
||||
.code32
|
||||
|
||||
pushl %eax
|
||||
|
||||
movl 8(%esp),%eax
|
||||
|
||||
movl %eax,%dr0
|
||||
movl %dr7,%eax
|
||||
andl $0xfff0ffff,%eax
|
||||
orl $0x00030303,%eax
|
||||
movl %eax,%dr7
|
||||
|
||||
popl %eax
|
||||
|
||||
ret
|
||||
|
||||
EXTERN(_MEMORY_WRITE_BREAKPOINT1)
|
||||
.code32
|
||||
|
||||
pushl %eax
|
||||
|
||||
movl 8(%esp),%eax
|
||||
|
||||
movl %eax,%dr0
|
||||
movl %dr7,%eax
|
||||
andl $0xfff0ffff,%eax
|
||||
orl $0x00010303,%eax
|
||||
movl %eax,%dr7
|
||||
|
||||
popl %eax
|
||||
|
||||
ret
|
||||
|
||||
EXTERN(_INSTRUCTION_BREAKPOINT2)
|
||||
.code32
|
||||
|
||||
pushl %eax
|
||||
|
||||
movl 8(%esp),%eax
|
||||
|
||||
movl %eax,%dr1
|
||||
movl %dr7,%eax
|
||||
andl $0xff0fffff,%eax
|
||||
orl $0x0000030c,%eax
|
||||
movl %eax,%dr7
|
||||
|
||||
popl %eax
|
||||
|
||||
ret
|
||||
|
||||
EXTERN(_MEMORY_READWRITE_BREAKPOINT2)
|
||||
.code32
|
||||
|
||||
pushl %eax
|
||||
|
||||
movl 8(%esp),%eax
|
||||
|
||||
movl %eax,%dr1
|
||||
movl %dr7,%eax
|
||||
andl $0xff0fffff,%eax
|
||||
orl $0x0030030c,%eax
|
||||
movl %eax,%dr7
|
||||
|
||||
popl %eax
|
||||
|
||||
ret
|
||||
|
||||
EXTERN(_MEMORY_WRITE_BREAKPOINT2)
|
||||
.code32
|
||||
|
||||
pushl %eax
|
||||
|
||||
movl 8(%esp),%eax
|
||||
|
||||
movl %eax,%dr1
|
||||
movl %dr7,%eax
|
||||
andl $0xff0fffff,%eax
|
||||
orl $0x0010030c,%eax
|
||||
movl %eax,%dr7
|
||||
|
||||
popl %eax
|
||||
|
||||
ret
|
||||
|
||||
EXTERN(_INSTRUCTION_BREAKPOINT3)
|
||||
.code32
|
||||
|
||||
pushl %eax
|
||||
|
||||
movl 8(%esp),%eax
|
||||
|
||||
movl %eax,%dr2
|
||||
movl %dr7,%eax
|
||||
andl $0xf0ffffff,%eax
|
||||
orl $0x00000330,%eax
|
||||
movl %eax,%dr7
|
||||
|
||||
popl %eax
|
||||
|
||||
ret
|
||||
|
||||
EXTERN(_MEMORY_READWRITE_BREAKPOINT3)
|
||||
.code32
|
||||
|
||||
pushl %eax
|
||||
|
||||
movl 8(%esp),%eax
|
||||
|
||||
movl %eax,%dr2
|
||||
movl %dr7,%eax
|
||||
andl $0xf0ffffff,%eax
|
||||
orl $0x03000330,%eax
|
||||
movl %eax,%dr7
|
||||
|
||||
popl %eax
|
||||
|
||||
ret
|
||||
|
||||
EXTERN(_MEMORY_WRITE_BREAKPOINT3)
|
||||
.code32
|
||||
|
||||
pushl %eax
|
||||
|
||||
movl 8(%esp),%eax
|
||||
|
||||
movl %eax,%dr2
|
||||
movl %dr7,%eax
|
||||
andl $0xf0ffffff,%eax
|
||||
orl $0x01000330,%eax
|
||||
movl %eax,%dr7
|
||||
|
||||
popl %eax
|
||||
|
||||
ret
|
||||
|
||||
EXTERN(_INSTRUCTION_BREAKPOINT4)
|
||||
.code32
|
||||
|
||||
pushl %eax
|
||||
|
||||
movl 8(%esp),%eax
|
||||
|
||||
movl %eax,%dr3
|
||||
movl %dr7,%eax
|
||||
andl $0x0fffffff,%eax
|
||||
orl $0x000003c0,%eax
|
||||
movl %eax,%dr7
|
||||
|
||||
popl %eax
|
||||
|
||||
ret
|
||||
|
||||
EXTERN(_MEMORY_READWRITE_BREAKPOINT4)
|
||||
.code32
|
||||
|
||||
pushl %eax
|
||||
|
||||
movl 8(%esp),%eax
|
||||
|
||||
movl %eax,%dr3
|
||||
movl %dr7,%eax
|
||||
andl $0x0fffffff,%eax
|
||||
orl $0x300003c0,%eax
|
||||
movl %eax,%dr7
|
||||
|
||||
popl %eax
|
||||
|
||||
ret
|
||||
|
||||
EXTERN(_MEMORY_WRITE_BREAKPOINT4)
|
||||
.code32
|
||||
|
||||
pushl %eax
|
||||
|
||||
movl 8(%esp),%eax
|
||||
|
||||
movl %eax,%dr3
|
||||
movl %dr7,%eax
|
||||
andl $0x0fffffff,%eax
|
||||
orl $0x100003c0,%eax
|
||||
movl %eax,%dr7
|
||||
|
||||
popl %eax
|
||||
|
||||
ret
|
||||
|
|
|
@ -34,7 +34,7 @@ VOID DiskError(PUCHAR ErrorString)
|
|||
{
|
||||
UCHAR ErrorCodeString[80];
|
||||
|
||||
sprintf(ErrorCodeString, "%s\nError Code: 0x%lx", ErrorString, BiosInt13GetLastErrorCode());
|
||||
sprintf(ErrorCodeString, "%s\nError Code: 0x%x", ErrorString, BiosInt13GetLastErrorCode());
|
||||
|
||||
DbgPrint((DPRINT_DISK, "%s\n", ErrorCodeString));
|
||||
|
||||
|
|
|
@ -130,6 +130,7 @@ BOOL DiskGetPartitionEntry(U32 DriveNumber, U32 PartitionNumber, PPARTITION_TABL
|
|||
MASTER_BOOT_RECORD MasterBootRecord;
|
||||
PARTITION_TABLE_ENTRY ExtendedPartitionTableEntry;
|
||||
U32 ExtendedPartitionNumber;
|
||||
U32 ExtendedPartitionRelativeOffset;
|
||||
U32 Index;
|
||||
|
||||
// Read master boot record
|
||||
|
@ -158,6 +159,11 @@ BOOL DiskGetPartitionEntry(U32 DriveNumber, U32 PartitionNumber, PPARTITION_TABL
|
|||
|
||||
ExtendedPartitionNumber = PartitionNumber - 5;
|
||||
|
||||
// Set the initial relative starting sector to 0
|
||||
// This is because extended partition starting
|
||||
// sectors a numbered relative to their parent
|
||||
ExtendedPartitionRelativeOffset = 0;
|
||||
|
||||
for (Index=0; Index<=ExtendedPartitionNumber; Index++)
|
||||
{
|
||||
// Get the extended partition table entry
|
||||
|
@ -166,8 +172,11 @@ BOOL DiskGetPartitionEntry(U32 DriveNumber, U32 PartitionNumber, PPARTITION_TABL
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
// Adjust the relative starting sector of the partition
|
||||
ExtendedPartitionRelativeOffset += ExtendedPartitionTableEntry.SectorCountBeforePartition;
|
||||
|
||||
// Read the partition boot record
|
||||
if (!DiskReadBootRecord(DriveNumber, ExtendedPartitionTableEntry.SectorCountBeforePartition, &MasterBootRecord))
|
||||
if (!DiskReadBootRecord(DriveNumber, ExtendedPartitionRelativeOffset, &MasterBootRecord))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -177,6 +186,9 @@ BOOL DiskGetPartitionEntry(U32 DriveNumber, U32 PartitionNumber, PPARTITION_TABL
|
|||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Now correct the start sector of the partition
|
||||
PartitionTableEntry->SectorCountBeforePartition += ExtendedPartitionRelativeOffset;
|
||||
}
|
||||
|
||||
// When we get here we should have the correct entry
|
||||
|
|
|
@ -25,9 +25,9 @@
|
|||
#include <bootmgr.h>
|
||||
#include <fs.h>
|
||||
|
||||
// Variable BootDrive moved to asmcode.S
|
||||
// Variables BootDrive & BootPartition moved to asmcode.S
|
||||
//U32 BootDrive = 0; // BIOS boot drive, 0-A:, 1-B:, 0x80-C:, 0x81-D:, etc.
|
||||
U32 BootPartition = 0; // Boot Partition, 1-4
|
||||
//U32 BootPartition = 0; // Boot Partition, 1-4
|
||||
|
||||
VOID BootMain(VOID)
|
||||
{
|
||||
|
@ -38,6 +38,8 @@ VOID BootMain(VOID)
|
|||
DebugInit();
|
||||
#endif
|
||||
|
||||
DbgPrint((DPRINT_WARNING, "BootMain() called. BootDrive = 0x%x BootPartition = %d\n", BootDrive, BootPartition));
|
||||
|
||||
if (!MmInitializeMemoryManager())
|
||||
{
|
||||
printf("Press any key to reboot.\n");
|
||||
|
|
|
@ -149,7 +149,7 @@ FILE* Ext2OpenFile(PUCHAR FileName)
|
|||
FullPath[Index] = '\0';
|
||||
|
||||
// Concatenate the symbolic link
|
||||
strcat(FullPath, "/");
|
||||
strcat(FullPath, Index == 0 ? "" : "/");
|
||||
strcat(FullPath, SymLinkPath);
|
||||
}
|
||||
|
||||
|
@ -353,7 +353,7 @@ BOOL Ext2ReadFile(FILE *FileHandle, U64 BytesToRead, U64* BytesRead, PVOID Buffe
|
|||
U32 LengthInBlock;
|
||||
U32 NumberOfBlocks;
|
||||
|
||||
DbgPrint((DPRINT_FILESYSTEM, "Ext2ReadFile() BytesToRead = %d Buffer = 0x%x\n", BytesToRead, Buffer));
|
||||
DbgPrint((DPRINT_FILESYSTEM, "Ext2ReadFile() BytesToRead = %d Buffer = 0x%x\n", (U32)BytesToRead, Buffer));
|
||||
|
||||
if (BytesRead != NULL)
|
||||
{
|
||||
|
@ -843,13 +843,23 @@ BOOL Ext2ReadBlock(U32 BlockNumber, PVOID Buffer)
|
|||
DbgPrint((DPRINT_FILESYSTEM, "Ext2ReadBlock() BlockNumber = %d Buffer = 0x%x\n", BlockNumber, Buffer));
|
||||
|
||||
// Make sure its a valid block
|
||||
if ((BlockNumber < 1) || (BlockNumber > Ext2SuperBlock->s_blocks_count))
|
||||
if (BlockNumber > Ext2SuperBlock->s_blocks_count)
|
||||
{
|
||||
sprintf(ErrorString, "Error reading block %d - block out of range.", BlockNumber);
|
||||
FileSystemError(ErrorString);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Check to see if this is a sparse block
|
||||
if (BlockNumber == 0)
|
||||
{
|
||||
DbgPrint((DPRINT_FILESYSTEM, "Block is part of a sparse file. Zeroing input buffer.\n"));
|
||||
|
||||
RtlZeroMemory(Buffer, Ext2BlockSizeInBytes);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return Ext2ReadVolumeSectors(Ext2DriveNumber, (U64)BlockNumber * Ext2BlockSizeInSectors, Ext2BlockSizeInSectors, Buffer);
|
||||
}
|
||||
|
||||
|
@ -996,16 +1006,20 @@ U32* Ext2ReadBlockPointerList(PEXT2_INODE Inode)
|
|||
U64 FileSize;
|
||||
U32 BlockCount;
|
||||
U32* BlockList;
|
||||
U32 CurrentBlockInList;
|
||||
U32 CurrentBlock;
|
||||
|
||||
DbgPrint((DPRINT_FILESYSTEM, "Ext2ReadBlockPointerList()\n"));
|
||||
|
||||
// Get the file size and round it up
|
||||
// Get the number of blocks this file occupies
|
||||
// I would just use Inode->i_blocks but it
|
||||
// doesn't seem to be the number of blocks
|
||||
// the file size corresponds to, but instead
|
||||
// it is much bigger.
|
||||
//BlockCount = Inode->i_blocks;
|
||||
FileSize = Ext2GetInodeFileSize(Inode);
|
||||
FileSize = ROUND_UP(FileSize, Ext2BlockSizeInBytes);
|
||||
|
||||
// Calculate the number of blocks this file occupies
|
||||
BlockCount = FileSize / Ext2BlockSizeInBytes;
|
||||
BlockCount = (FileSize / Ext2BlockSizeInBytes);
|
||||
|
||||
// Allocate the memory for the block list
|
||||
BlockList = MmAllocateMemory(BlockCount * sizeof(U32));
|
||||
|
@ -1014,75 +1028,43 @@ U32* Ext2ReadBlockPointerList(PEXT2_INODE Inode)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// Copy the direct blocks
|
||||
for (CurrentBlock=0; CurrentBlock<BlockCount; CurrentBlock++)
|
||||
{
|
||||
if (CurrentBlock > 11)
|
||||
{
|
||||
break;
|
||||
}
|
||||
RtlZeroMemory(BlockList, BlockCount * sizeof(U32));
|
||||
CurrentBlockInList = 0;
|
||||
|
||||
BlockList[CurrentBlock] = Inode->i_block[CurrentBlock];
|
||||
// Copy the direct block pointers
|
||||
for (CurrentBlock=0; CurrentBlockInList<BlockCount && CurrentBlock<EXT3_NDIR_BLOCKS; CurrentBlock++)
|
||||
{
|
||||
BlockList[CurrentBlockInList] = Inode->i_block[CurrentBlock];
|
||||
CurrentBlockInList++;
|
||||
}
|
||||
BlockCount -= CurrentBlock;
|
||||
|
||||
// Copy the indirect blocks
|
||||
if (BlockCount > 0)
|
||||
// Copy the indirect block pointers
|
||||
if (CurrentBlockInList < BlockCount)
|
||||
{
|
||||
if (!Ext2CopyIndirectBlockPointers(Inode->i_block[12], BlockCount, &BlockList[CurrentBlock]))
|
||||
if (!Ext2CopyIndirectBlockPointers(BlockList, &CurrentBlockInList, BlockCount, Inode->i_block[EXT3_IND_BLOCK]))
|
||||
{
|
||||
MmFreeMemory(BlockList);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CurrentBlock += (Ext2BlockSizeInBytes / sizeof(U32));
|
||||
if (BlockCount >= (Ext2BlockSizeInBytes / sizeof(U32)))
|
||||
{
|
||||
BlockCount -= (Ext2BlockSizeInBytes / sizeof(U32));
|
||||
}
|
||||
else
|
||||
{
|
||||
BlockCount = 0;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the double-indirect blocks
|
||||
if (BlockCount > 0)
|
||||
// Copy the double indirect block pointers
|
||||
if (CurrentBlockInList < BlockCount)
|
||||
{
|
||||
if (!Ext2CopyIndirectBlockPointers(Inode->i_block[12], BlockCount, &BlockList[CurrentBlock]))
|
||||
if (!Ext2CopyDoubleIndirectBlockPointers(BlockList, &CurrentBlockInList, BlockCount, Inode->i_block[EXT3_DIND_BLOCK]))
|
||||
{
|
||||
MmFreeMemory(BlockList);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CurrentBlock += (Ext2BlockSizeInBytes / sizeof(U32)) * (Ext2BlockSizeInBytes / sizeof(U32));
|
||||
if (BlockCount >= (Ext2BlockSizeInBytes / sizeof(U32)) * (Ext2BlockSizeInBytes / sizeof(U32)))
|
||||
{
|
||||
BlockCount -= (Ext2BlockSizeInBytes / sizeof(U32)) * (Ext2BlockSizeInBytes / sizeof(U32));
|
||||
}
|
||||
else
|
||||
{
|
||||
BlockCount = 0;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the triple-indirect blocks
|
||||
if (BlockCount > 0)
|
||||
// Copy the triple indirect block pointers
|
||||
if (CurrentBlockInList < BlockCount)
|
||||
{
|
||||
if (!Ext2CopyIndirectBlockPointers(Inode->i_block[12], BlockCount, &BlockList[CurrentBlock]))
|
||||
if (!Ext2CopyTripleIndirectBlockPointers(BlockList, &CurrentBlockInList, BlockCount, Inode->i_block[EXT3_TIND_BLOCK]))
|
||||
{
|
||||
MmFreeMemory(BlockList);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CurrentBlock += (Ext2BlockSizeInBytes / sizeof(U32)) * (Ext2BlockSizeInBytes / sizeof(U32)) * (Ext2BlockSizeInBytes / sizeof(U32));
|
||||
if (BlockCount >= (Ext2BlockSizeInBytes / sizeof(U32)) * (Ext2BlockSizeInBytes / sizeof(U32)) * (Ext2BlockSizeInBytes / sizeof(U32)))
|
||||
{
|
||||
BlockCount -= (Ext2BlockSizeInBytes / sizeof(U32)) * (Ext2BlockSizeInBytes / sizeof(U32)) * (Ext2BlockSizeInBytes / sizeof(U32));
|
||||
}
|
||||
else
|
||||
{
|
||||
BlockCount = 0;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1101,91 +1083,96 @@ U64 Ext2GetInodeFileSize(PEXT2_INODE Inode)
|
|||
}
|
||||
}
|
||||
|
||||
BOOL Ext2CopyIndirectBlockPointers(U32 IndirectBlock, U32 BlockCount, U32* BlockList)
|
||||
BOOL Ext2CopyIndirectBlockPointers(U32* BlockList, U32* CurrentBlockInList, U32 BlockCount, U32 IndirectBlock)
|
||||
{
|
||||
U32* BlockBuffer = (U32*)FILESYSBUFFER;
|
||||
U32 CurrentBlock;
|
||||
U32 BlockPointersPerBlock;
|
||||
|
||||
DbgPrint((DPRINT_FILESYSTEM, "Ext2CopyIndirectBlockPointers()\n"));
|
||||
DbgPrint((DPRINT_FILESYSTEM, "Ext2CopyIndirectBlockPointers() BlockCount = %d\n", BlockCount));
|
||||
|
||||
BlockPointersPerBlock = Ext2BlockSizeInBytes / sizeof(U32);
|
||||
|
||||
if (!Ext2ReadBlock(IndirectBlock, BlockBuffer))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (CurrentBlock=0; CurrentBlock<BlockCount; CurrentBlock++)
|
||||
for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
|
||||
{
|
||||
BlockList[CurrentBlock] = BlockBuffer[CurrentBlock];
|
||||
|
||||
if (CurrentBlock >= ((Ext2BlockSizeInBytes / sizeof(U32)) - 1))
|
||||
{
|
||||
break;
|
||||
}
|
||||
BlockList[(*CurrentBlockInList)] = BlockBuffer[CurrentBlock];
|
||||
(*CurrentBlockInList)++;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL Ext2CopyDoubleIndirectBlockPointers(U32 DoubleIndirectBlock, U32 BlockCount, U32* BlockList)
|
||||
BOOL Ext2CopyDoubleIndirectBlockPointers(U32* BlockList, U32* CurrentBlockInList, U32 BlockCount, U32 DoubleIndirectBlock)
|
||||
{
|
||||
U32* BlockBuffer = (U32*)FILESYSBUFFER;
|
||||
U32 CurrentIndirectBlock;
|
||||
U32* BlockBuffer;
|
||||
U32 CurrentBlock;
|
||||
U32 BlockPointersPerBlock;
|
||||
|
||||
DbgPrint((DPRINT_FILESYSTEM, "Ext2CopyDoubleIndirectBlockPointers()\n"));
|
||||
DbgPrint((DPRINT_FILESYSTEM, "Ext2CopyDoubleIndirectBlockPointers() BlockCount = %d\n", BlockCount));
|
||||
|
||||
BlockPointersPerBlock = Ext2BlockSizeInBytes / sizeof(U32);
|
||||
|
||||
BlockBuffer = (U32*)MmAllocateMemory(Ext2BlockSizeInBytes);
|
||||
if (BlockBuffer == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!Ext2ReadBlock(DoubleIndirectBlock, BlockBuffer))
|
||||
{
|
||||
MmFreeMemory(BlockBuffer);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (CurrentIndirectBlock=0,CurrentBlock=0; CurrentBlock<BlockCount; CurrentIndirectBlock++)
|
||||
for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
|
||||
{
|
||||
if (!Ext2CopyIndirectBlockPointers(BlockBuffer[CurrentIndirectBlock], BlockCount, &BlockList[CurrentBlock]))
|
||||
if (!Ext2CopyIndirectBlockPointers(BlockList, CurrentBlockInList, BlockCount, BlockBuffer[CurrentBlock]))
|
||||
{
|
||||
MmFreeMemory(BlockBuffer);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CurrentBlock += (Ext2BlockSizeInBytes / sizeof(U32));
|
||||
BlockCount -= (Ext2BlockSizeInBytes / sizeof(U32));
|
||||
|
||||
if (CurrentIndirectBlock >= ((Ext2BlockSizeInBytes / sizeof(U32)) - 1))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MmFreeMemory(BlockBuffer);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL Ext2CopyTripleIndirectBlockPointers(U32 TripleIndirectBlock, U32 BlockCount, U32* BlockList)
|
||||
BOOL Ext2CopyTripleIndirectBlockPointers(U32* BlockList, U32* CurrentBlockInList, U32 BlockCount, U32 TripleIndirectBlock)
|
||||
{
|
||||
U32* BlockBuffer = (U32*)FILESYSBUFFER;
|
||||
U32 CurrentIndirectBlock;
|
||||
U32* BlockBuffer;
|
||||
U32 CurrentBlock;
|
||||
U32 BlockPointersPerBlock;
|
||||
|
||||
DbgPrint((DPRINT_FILESYSTEM, "Ext2CopyTripleIndirectBlockPointers()\n"));
|
||||
DbgPrint((DPRINT_FILESYSTEM, "Ext2CopyTripleIndirectBlockPointers() BlockCount = %d\n", BlockCount));
|
||||
|
||||
BlockPointersPerBlock = Ext2BlockSizeInBytes / sizeof(U32);
|
||||
|
||||
BlockBuffer = (U32*)MmAllocateMemory(Ext2BlockSizeInBytes);
|
||||
if (BlockBuffer == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!Ext2ReadBlock(TripleIndirectBlock, BlockBuffer))
|
||||
{
|
||||
MmFreeMemory(BlockBuffer);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (CurrentIndirectBlock=0,CurrentBlock=0; CurrentBlock<BlockCount; CurrentIndirectBlock++)
|
||||
for (CurrentBlock=0; (*CurrentBlockInList)<BlockCount && CurrentBlock<BlockPointersPerBlock; CurrentBlock++)
|
||||
{
|
||||
if (!Ext2CopyDoubleIndirectBlockPointers(BlockBuffer[CurrentIndirectBlock], BlockCount, &BlockList[CurrentBlock]))
|
||||
if (!Ext2CopyDoubleIndirectBlockPointers(BlockList, CurrentBlockInList, BlockCount, BlockBuffer[CurrentBlock]))
|
||||
{
|
||||
MmFreeMemory(BlockBuffer);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CurrentBlock += (Ext2BlockSizeInBytes / sizeof(U32)) * (Ext2BlockSizeInBytes / sizeof(U32));
|
||||
BlockCount -= (Ext2BlockSizeInBytes / sizeof(U32)) * (Ext2BlockSizeInBytes / sizeof(U32));
|
||||
|
||||
if (CurrentIndirectBlock >= ((Ext2BlockSizeInBytes / sizeof(U32)) - 1))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MmFreeMemory(BlockBuffer);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -653,7 +653,7 @@ typedef struct ext3_dir_entry_2 EXT2_DIR_ENTRY, *PEXT2_DIR_ENTRY;
|
|||
#define EXT2_S_IFLNK 0xA000 // Symbolic link
|
||||
#define EXT2_S_IFSOCK 0xC000 // Socket
|
||||
|
||||
#define FAST_SYMLINK_MAX_NAME_SIZE 60
|
||||
#define FAST_SYMLINK_MAX_NAME_SIZE (EXT3_N_BLOCKS * sizeof(U32)) /* 60 bytes */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -690,8 +690,8 @@ BOOL Ext2ReadInode(U32 Inode, PEXT2_INODE InodeBuffer);
|
|||
BOOL Ext2ReadGroupDescriptor(U32 Group, PEXT2_GROUP_DESC GroupBuffer);
|
||||
U32* Ext2ReadBlockPointerList(PEXT2_INODE Inode);
|
||||
U64 Ext2GetInodeFileSize(PEXT2_INODE Inode);
|
||||
BOOL Ext2CopyIndirectBlockPointers(U32 IndirectBlock, U32 BlockCount, U32* BlockList);
|
||||
BOOL Ext2CopyDoubleIndirectBlockPointers(U32 DoubleIndirectBlock, U32 BlockCount, U32* BlockList);
|
||||
BOOL Ext2CopyTripleIndirectBlockPointers(U32 TripleIndirectBlock, U32 BlockCount, U32* BlockList);
|
||||
BOOL Ext2CopyIndirectBlockPointers(U32* BlockList, U32* CurrentBlockInList, U32 BlockCount, U32 IndirectBlock);
|
||||
BOOL Ext2CopyDoubleIndirectBlockPointers(U32* BlockList, U32* CurrentBlockInList, U32 BlockCount, U32 DoubleIndirectBlock);
|
||||
BOOL Ext2CopyTripleIndirectBlockPointers(U32* BlockList, U32* CurrentBlockInList, U32 BlockCount, U32 TripleIndirectBlock);
|
||||
|
||||
#endif // #defined __EXT2_H
|
||||
|
|
|
@ -43,6 +43,33 @@
|
|||
#define BugCheck(_x_) { DebugPrint(DPRINT_WARNING, "Fatal Error: %s:%d(%s)\n", __FILE__, __LINE__, __FUNCTION__); DebugPrint _x_ ; for (;;); }
|
||||
#define DbgDumpBuffer(_x_, _y_, _z_) DebugDumpBuffer(_x_, _y_, _z_)
|
||||
|
||||
#ifdef __i386__
|
||||
|
||||
// Debugging support functions:
|
||||
//
|
||||
// BREAKPOINT() - Inserts an "int 3" instruction
|
||||
// INSTRUCTION_BREAKPOINTX(x) - Enters exception handler right before instruction at address "x" is executed
|
||||
// MEMORY_READWRITE_BREAKPOINTX(x) - Enters exception handler when a read or write occurs at address "x"
|
||||
// MEMORY_WRITE_BREAKPOINTX(x) - Enters exception handler when a write occurs at address "x"
|
||||
//
|
||||
// You may have as many BREAKPOINT()'s as you like but you may only
|
||||
// have up to four of any of the others.
|
||||
#define BREAKPOINT() __asm__ ("int $3");
|
||||
void INSTRUCTION_BREAKPOINT1(unsigned long addr);
|
||||
void MEMORY_READWRITE_BREAKPOINT1(unsigned long addr);
|
||||
void MEMORY_WRITE_BREAKPOINT1(unsigned long addr);
|
||||
void INSTRUCTION_BREAKPOINT2(unsigned long addr);
|
||||
void MEMORY_READWRITE_BREAKPOINT2(unsigned long addr);
|
||||
void MEMORY_WRITE_BREAKPOINT2(unsigned long addr);
|
||||
void INSTRUCTION_BREAKPOINT3(unsigned long addr);
|
||||
void MEMORY_READWRITE_BREAKPOINT3(unsigned long addr);
|
||||
void MEMORY_WRITE_BREAKPOINT3(unsigned long addr);
|
||||
void INSTRUCTION_BREAKPOINT4(unsigned long addr);
|
||||
void MEMORY_READWRITE_BREAKPOINT4(unsigned long addr);
|
||||
void MEMORY_WRITE_BREAKPOINT4(unsigned long addr);
|
||||
|
||||
#endif // defined __i386__
|
||||
|
||||
#else
|
||||
|
||||
#define DbgPrint(_x_)
|
||||
|
|
|
@ -29,10 +29,8 @@
|
|||
|
||||
typedef struct
|
||||
{
|
||||
U32 BaseAddressLow;
|
||||
U32 BaseAddressHigh;
|
||||
U32 LengthLow;
|
||||
U32 LengthHigh;
|
||||
U64 BaseAddress;
|
||||
U64 Length;
|
||||
U32 Type;
|
||||
U32 Reserved;
|
||||
} PACKED BIOS_MEMORY_MAP, *PBIOS_MEMORY_MAP;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
|
||||
/* just some stuff */
|
||||
#define VERSION "FreeLoader v1.7.2"
|
||||
#define VERSION "FreeLoader v1.7.4"
|
||||
#define COPYRIGHT "Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>"
|
||||
#define AUTHOR_EMAIL "<brianp@sginet.com>"
|
||||
#define BY_AUTHOR "by Brian Palmer"
|
||||
|
@ -36,7 +36,7 @@
|
|||
//
|
||||
#define FREELOADER_MAJOR_VERSION 1
|
||||
#define FREELOADER_MINOR_VERSION 7
|
||||
#define FREELOADER_PATCH_VERSION 2
|
||||
#define FREELOADER_PATCH_VERSION 4
|
||||
|
||||
|
||||
PUCHAR GetFreeLoaderVersionString(VOID);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#define __INI_H
|
||||
|
||||
#include <rtl.h>
|
||||
#include <fs.h>
|
||||
|
||||
|
||||
#define INI_FILE_COMMENT_CHAR ';'
|
||||
|
@ -55,6 +56,8 @@ typedef struct
|
|||
extern PINI_SECTION IniFileSectionListHead;
|
||||
extern U32 IniFileSectionListCount;
|
||||
|
||||
PFILE IniOpenIniFile(U8 BootDriveNumber, U8 BootPartitionNumber);
|
||||
|
||||
BOOL IniParseFile(PUCHAR IniFileData, U32 IniFileSize);
|
||||
U32 IniGetNextLineSize(PUCHAR IniFileData, U32 IniFileSize, U32 CurrentOffset);
|
||||
U32 IniGetNextLine(PUCHAR IniFileData, U32 IniFileSize, PUCHAR Buffer, U32 BufferSize, U32 CurrentOffset);
|
||||
|
|
|
@ -32,18 +32,28 @@ BOOL IniFileInitialize(VOID)
|
|||
U32 FreeLoaderIniFileSize;
|
||||
BOOL Success;
|
||||
|
||||
// Open the boot drive for file access
|
||||
if (!OpenDiskDrive(BootDrive, 0))
|
||||
// Open freeldr.ini
|
||||
// BootDrive & BootPartition are passed
|
||||
// in from the boot sector code in the
|
||||
// DL & DH registers.
|
||||
Freeldr_Ini = IniOpenIniFile(BootDrive, BootPartition);
|
||||
|
||||
// If we couldn't open freeldr.ini on the partition
|
||||
// they specified in the boot sector then try
|
||||
// opening the active (boot) partition.
|
||||
if ((Freeldr_Ini == NULL) && (BootPartition != 0))
|
||||
{
|
||||
printf("Error opening boot drive for file access.\n");
|
||||
BootPartition = 0;
|
||||
|
||||
Freeldr_Ini = IniOpenIniFile(BootDrive, BootPartition);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Try to open freeldr.ini or fail
|
||||
Freeldr_Ini = OpenFile("freeldr.ini");
|
||||
if (Freeldr_Ini == NULL)
|
||||
{
|
||||
printf("FREELDR.INI not found.\nYou need to re-install FreeLoader.\n");
|
||||
printf("Error opening freeldr.ini or file not found.\n");
|
||||
printf("You need to re-install FreeLoader.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -54,7 +64,7 @@ BOOL IniFileInitialize(VOID)
|
|||
// If we are out of memory then return FALSE
|
||||
if (FreeLoaderIniFileData == NULL)
|
||||
{
|
||||
printf("Out of memory while loading FREELDR.INI.\n");
|
||||
printf("Out of memory while loading freeldr.ini.\n");
|
||||
CloseFile(Freeldr_Ini);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -76,3 +86,27 @@ BOOL IniFileInitialize(VOID)
|
|||
|
||||
return Success;
|
||||
}
|
||||
|
||||
PFILE IniOpenIniFile(U8 BootDriveNumber, U8 BootPartitionNumber)
|
||||
{
|
||||
PFILE IniFileHandle; // File handle for freeldr.ini
|
||||
|
||||
if (!OpenDiskDrive(BootDriveNumber, BootPartitionNumber))
|
||||
{
|
||||
if (BootPartitionNumber == 0)
|
||||
{
|
||||
printf("Error opening active (bootable) partition on boot drive 0x%x for file access.\n", BootDriveNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error opening partition %d on boot drive 0x%x for file access.\n", BootPartitionNumber, BootDriveNumber);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Try to open freeldr.ini
|
||||
IniFileHandle = OpenFile("freeldr.ini");
|
||||
|
||||
return IniFileHandle;
|
||||
}
|
||||
|
|
|
@ -105,6 +105,7 @@ VOID LoadAndBootBootSector(PUCHAR OperatingSystemName)
|
|||
// still think the motor is on and this will
|
||||
// result in a read error.
|
||||
//StopFloppyMotor();
|
||||
//DisableA20();
|
||||
ChainLoadBiosBootSectorCode();
|
||||
}
|
||||
|
||||
|
@ -174,6 +175,7 @@ VOID LoadAndBootPartition(PUCHAR OperatingSystemName)
|
|||
// still think the motor is on and this will
|
||||
// result in a read error.
|
||||
//StopFloppyMotor();
|
||||
//DisableA20();
|
||||
ChainLoadBiosBootSectorCode();
|
||||
}
|
||||
|
||||
|
@ -226,5 +228,6 @@ VOID LoadAndBootDrive(PUCHAR OperatingSystemName)
|
|||
// still think the motor is on and this will
|
||||
// result in a read error.
|
||||
//StopFloppyMotor();
|
||||
//DisableA20();
|
||||
ChainLoadBiosBootSectorCode();
|
||||
}
|
||||
|
|
|
@ -22,13 +22,17 @@
|
|||
#define __MEM_H
|
||||
|
||||
|
||||
#ifdef __i386__
|
||||
|
||||
#define MM_PAGE_SIZE 4096
|
||||
|
||||
#endif // defined __i386__
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U32 PageAllocated; // Zero = free, non-zero = allocated
|
||||
U32 PageAllocationLength; // Number of pages allocated (or zero if this isn't the first page in the chain)
|
||||
} PAGE_LOOKUP_TABLE_ITEM, *PPAGE_LOOKUP_TABLE_ITEM;
|
||||
} PACKED PAGE_LOOKUP_TABLE_ITEM, *PPAGE_LOOKUP_TABLE_ITEM;
|
||||
|
||||
//
|
||||
// Define this to 1 if you want the entire contents
|
||||
|
|
|
@ -67,12 +67,6 @@ BOOL MmInitializeMemoryManager(VOID)
|
|||
ExtendedMemorySize = GetExtendedMemorySize();
|
||||
ConventionalMemorySize = GetConventionalMemorySize();
|
||||
|
||||
// If we got the system memory map then fixup invalid entries
|
||||
if (BiosMemoryMapEntryCount != 0)
|
||||
{
|
||||
MmFixupSystemMemoryMap(BiosMemoryMap, &BiosMemoryMapEntryCount);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// Dump the system memory map
|
||||
if (BiosMemoryMapEntryCount != 0)
|
||||
|
@ -80,17 +74,23 @@ BOOL MmInitializeMemoryManager(VOID)
|
|||
DbgPrint((DPRINT_MEMORY, "System Memory Map (Base Address, Length, Type):\n"));
|
||||
for (Index=0; Index<BiosMemoryMapEntryCount; Index++)
|
||||
{
|
||||
DbgPrint((DPRINT_MEMORY, "%x%x\t %x%x\t %s\n", BiosMemoryMap[Index].BaseAddressHigh, BiosMemoryMap[Index].BaseAddressLow, BiosMemoryMap[Index].LengthHigh, BiosMemoryMap[Index].LengthLow, MmGetSystemMemoryMapTypeString(BiosMemoryMap[Index].Type)));
|
||||
DbgPrint((DPRINT_MEMORY, "%x%x\t %x%x\t %s\n", BiosMemoryMap[Index].BaseAddress, BiosMemoryMap[Index].Length, MmGetSystemMemoryMapTypeString(BiosMemoryMap[Index].Type)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgPrint((DPRINT_MEMORY, "GetBiosMemoryMap() not supported.\n"));
|
||||
}
|
||||
#endif
|
||||
|
||||
DbgPrint((DPRINT_MEMORY, "Extended memory size: %d KB\n", ExtendedMemorySize));
|
||||
DbgPrint((DPRINT_MEMORY, "Conventional memory size: %d KB\n", ConventionalMemorySize));
|
||||
#endif
|
||||
|
||||
// If we got the system memory map then fixup invalid entries
|
||||
if (BiosMemoryMapEntryCount != 0)
|
||||
{
|
||||
MmFixupSystemMemoryMap(BiosMemoryMap, &BiosMemoryMapEntryCount);
|
||||
}
|
||||
|
||||
// Since I don't feel like writing two sets of routines
|
||||
// one to handle the BiosMemoryMap structure and another
|
||||
|
@ -99,10 +99,8 @@ BOOL MmInitializeMemoryManager(VOID)
|
|||
// extended memory size if GetBiosMemoryMap() fails.
|
||||
if (BiosMemoryMapEntryCount == 0)
|
||||
{
|
||||
BiosMemoryMap[0].BaseAddressLow = 0x100000; // Start at 1MB
|
||||
BiosMemoryMap[0].BaseAddressHigh = 0;
|
||||
BiosMemoryMap[0].LengthLow = ExtendedMemorySize * 1024;
|
||||
BiosMemoryMap[0].LengthHigh = 0;
|
||||
BiosMemoryMap[0].BaseAddress = 0x100000; // Start at 1MB
|
||||
BiosMemoryMap[0].Length = ExtendedMemorySize * 1024;
|
||||
BiosMemoryMap[0].Type = MEMTYPE_USABLE;
|
||||
BiosMemoryMapEntryCount = 1;
|
||||
}
|
||||
|
@ -153,18 +151,18 @@ U32 MmGetPageNumberFromAddress(PVOID Address)
|
|||
|
||||
PVOID MmGetEndAddressOfAnyMemory(BIOS_MEMORY_MAP BiosMemoryMap[32], U32 MapCount)
|
||||
{
|
||||
U32 MaxStartAddressSoFar;
|
||||
U64 EndAddressOfMemory;
|
||||
U64 MaxStartAddressSoFar;
|
||||
U64 EndAddressOfMemory;
|
||||
U32 Index;
|
||||
|
||||
MaxStartAddressSoFar = 0;
|
||||
EndAddressOfMemory = 0;
|
||||
for (Index=0; Index<MapCount; Index++)
|
||||
{
|
||||
if (MaxStartAddressSoFar < BiosMemoryMap[Index].BaseAddressLow)
|
||||
if (MaxStartAddressSoFar < BiosMemoryMap[Index].BaseAddress)
|
||||
{
|
||||
MaxStartAddressSoFar = BiosMemoryMap[Index].BaseAddressLow;
|
||||
EndAddressOfMemory = ((U64)MaxStartAddressSoFar + (U64)BiosMemoryMap[Index].LengthLow);
|
||||
MaxStartAddressSoFar = BiosMemoryMap[Index].BaseAddress;
|
||||
EndAddressOfMemory = (MaxStartAddressSoFar + BiosMemoryMap[Index].Length);
|
||||
if (EndAddressOfMemory > 0xFFFFFFFF)
|
||||
{
|
||||
EndAddressOfMemory = 0xFFFFFFFF;
|
||||
|
@ -180,8 +178,23 @@ PVOID MmGetEndAddressOfAnyMemory(BIOS_MEMORY_MAP BiosMemoryMap[32], U32 MapCount
|
|||
U32 MmGetAddressablePageCountIncludingHoles(BIOS_MEMORY_MAP BiosMemoryMap[32], U32 MapCount)
|
||||
{
|
||||
U32 PageCount;
|
||||
U64 EndAddress;
|
||||
|
||||
PageCount = MmGetPageNumberFromAddress(MmGetEndAddressOfAnyMemory(BiosMemoryMap, MapCount));
|
||||
EndAddress = (U64)(U32)MmGetEndAddressOfAnyMemory(BiosMemoryMap, MapCount);
|
||||
|
||||
// Since MmGetEndAddressOfAnyMemory() won't
|
||||
// return addresses higher than 0xFFFFFFFF
|
||||
// then we need to adjust the end address
|
||||
// to 0x100000000 so we don't get an
|
||||
// off-by-one error
|
||||
if (EndAddress >= 0xFFFFFFFF)
|
||||
{
|
||||
EndAddress = 0x100000000;
|
||||
|
||||
DbgPrint((DPRINT_MEMORY, "MmGetEndAddressOfAnyMemory() returned 0xFFFFFFFF, correcting to be 0x100000000.\n"));
|
||||
}
|
||||
|
||||
PageCount = (EndAddress / MM_PAGE_SIZE);
|
||||
|
||||
DbgPrint((DPRINT_MEMORY, "MmGetAddressablePageCountIncludingHoles() returning %d\n", PageCount));
|
||||
|
||||
|
@ -207,9 +220,9 @@ PVOID MmFindLocationForPageLookupTable(BIOS_MEMORY_MAP BiosMemoryMap[32], U32 Ma
|
|||
{
|
||||
// If this is usable memory with a big enough length
|
||||
// then we'll put our page lookup table here
|
||||
if (TempBiosMemoryMap[Index].Type == MEMTYPE_USABLE && TempBiosMemoryMap[Index].LengthLow >= PageLookupTableSize)
|
||||
if (TempBiosMemoryMap[Index].Type == MEMTYPE_USABLE && TempBiosMemoryMap[Index].Length >= PageLookupTableSize)
|
||||
{
|
||||
PageLookupTableAddress = (PVOID)(TempBiosMemoryMap[Index].BaseAddressLow + (TempBiosMemoryMap[Index].LengthLow - PageLookupTableSize));
|
||||
PageLookupTableAddress = (PVOID)(U32)(TempBiosMemoryMap[Index].BaseAddress + (TempBiosMemoryMap[Index].Length - PageLookupTableSize));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -231,7 +244,7 @@ VOID MmSortBiosMemoryMap(BIOS_MEMORY_MAP BiosMemoryMap[32], U32 MapCount)
|
|||
{
|
||||
for (Index=0; Index<(MapCount-1); Index++)
|
||||
{
|
||||
if (BiosMemoryMap[Index].BaseAddressLow > BiosMemoryMap[Index+1].BaseAddressLow)
|
||||
if (BiosMemoryMap[Index].BaseAddress > BiosMemoryMap[Index+1].BaseAddress)
|
||||
{
|
||||
TempMapItem = BiosMemoryMap[Index];
|
||||
BiosMemoryMap[Index] = BiosMemoryMap[Index+1];
|
||||
|
@ -260,8 +273,8 @@ VOID MmInitPageLookupTable(PVOID PageLookupTable, U32 TotalPageCount, BIOS_MEMOR
|
|||
|
||||
for (Index=0; Index<MapCount; Index++)
|
||||
{
|
||||
MemoryMapStartPage = MmGetPageNumberFromAddress((PVOID)BiosMemoryMap[Index].BaseAddressLow);
|
||||
MemoryMapEndPage = MmGetPageNumberFromAddress((PVOID)(BiosMemoryMap[Index].BaseAddressLow + BiosMemoryMap[Index].LengthLow - 1));
|
||||
MemoryMapStartPage = MmGetPageNumberFromAddress((PVOID)(U32)BiosMemoryMap[Index].BaseAddress);
|
||||
MemoryMapEndPage = MmGetPageNumberFromAddress((PVOID)(U32)(BiosMemoryMap[Index].BaseAddress + BiosMemoryMap[Index].Length - 1));
|
||||
MemoryMapPageCount = (MemoryMapEndPage - MemoryMapStartPage) + 1;
|
||||
MemoryMapPageAllocated = (BiosMemoryMap[Index].Type == MEMTYPE_USABLE) ? 0 : BiosMemoryMap[Index].Type;
|
||||
DbgPrint((DPRINT_MEMORY, "Marking pages as type %d: StartPage: %d PageCount: %d\n", MemoryMapPageAllocated, MemoryMapStartPage, MemoryMapPageCount));
|
||||
|
@ -286,9 +299,14 @@ VOID MmMarkPagesInLookupTable(PVOID PageLookupTable, U32 StartPage, U32 PageCoun
|
|||
|
||||
for (Index=StartPage; Index<(StartPage+PageCount); Index++)
|
||||
{
|
||||
if ((Index <= (StartPage + 16)) || (Index >= (StartPage+PageCount-16)))
|
||||
{
|
||||
DbgPrint((DPRINT_MEMORY, "Index = %d StartPage = %d PageCount = %d\n", Index, StartPage, PageCount));
|
||||
}
|
||||
RealPageLookupTable[Index].PageAllocated = PageAllocated;
|
||||
RealPageLookupTable[Index].PageAllocationLength = PageAllocated ? 1 : 0;
|
||||
}
|
||||
DbgPrint((DPRINT_MEMORY, "MmMarkPagesInLookupTable() Done\n"));
|
||||
}
|
||||
|
||||
VOID MmAllocatePagesInLookupTable(PVOID PageLookupTable, U32 StartPage, U32 PageCount)
|
||||
|
@ -360,14 +378,14 @@ VOID MmFixupSystemMemoryMap(BIOS_MEMORY_MAP BiosMemoryMap[32], U32* MapCount)
|
|||
{
|
||||
int Index;
|
||||
int Index2;
|
||||
U64 RealLength;
|
||||
|
||||
// Loop through each entry in the array
|
||||
for (Index=0; Index<*MapCount; Index++)
|
||||
{
|
||||
// If the base address for this entry starts at
|
||||
// or above 4G then remove this entry
|
||||
if (BiosMemoryMap[Index].BaseAddressHigh != 0)
|
||||
// If the entry type isn't usable then remove
|
||||
// it from the memory map (this will help reduce
|
||||
// the size of our lookup table)
|
||||
if (BiosMemoryMap[Index].Type != 0)
|
||||
{
|
||||
// Slide every entry after this down one
|
||||
for (Index2=Index; Index2<(*MapCount - 1); Index2++)
|
||||
|
@ -377,14 +395,6 @@ VOID MmFixupSystemMemoryMap(BIOS_MEMORY_MAP BiosMemoryMap[32], U32* MapCount)
|
|||
(*MapCount)--;
|
||||
Index--;
|
||||
}
|
||||
|
||||
// If the base address plus the length for this entry
|
||||
// extends beyond 4G then truncate this entry
|
||||
RealLength = BiosMemoryMap[Index].BaseAddressLow + BiosMemoryMap[Index].LengthLow;
|
||||
if ((BiosMemoryMap[Index].LengthHigh != 0) || (RealLength > 0xFFFFFFFF))
|
||||
{
|
||||
BiosMemoryMap[Index].LengthLow = 0xFFFFFFFF - BiosMemoryMap[Index].BaseAddressLow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue