diff --git a/freeldr/bootsect/ext2.asm b/freeldr/bootsect/ext2.asm index 776922ccf1a..6122738c52b 100644 --- a/freeldr/bootsect/ext2.asm +++ b/freeldr/bootsect/ext2.asm @@ -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 diff --git a/freeldr/bootsect/fat.asm b/freeldr/bootsect/fat.asm index 7562e4adc40..5ce48287a7d 100644 --- a/freeldr/bootsect/fat.asm +++ b/freeldr/bootsect/fat.asm @@ -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 diff --git a/freeldr/bootsect/fat32.asm b/freeldr/bootsect/fat32.asm index e8c2113704e..d18a857f137 100644 --- a/freeldr/bootsect/fat32.asm +++ b/freeldr/bootsect/fat32.asm @@ -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 diff --git a/freeldr/bootsect/isoboot.asm b/freeldr/bootsect/isoboot.asm index 3a97edb50fa..d4a0bc06986 100644 --- a/freeldr/bootsect/isoboot.asm +++ b/freeldr/bootsect/isoboot.asm @@ -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 diff --git a/freeldr/freeldr/CHANGELOG b/freeldr/freeldr/CHANGELOG index e6197bb34ac..041f60dc69c 100644 --- a/freeldr/freeldr/CHANGELOG +++ b/freeldr/freeldr/CHANGELOG @@ -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 diff --git a/freeldr/freeldr/arch/i386/arch.S b/freeldr/freeldr/arch/i386/arch.S index 903b47f3d8f..a591ffc6c1e 100644 --- a/freeldr/freeldr/arch/i386/arch.S +++ b/freeldr/freeldr/arch/i386/arch.S @@ -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 diff --git a/freeldr/freeldr/arch/i386/fathelp.asm b/freeldr/freeldr/arch/i386/fathelp.asm index 833092efc81..805b8ad8dbd 100644 --- a/freeldr/freeldr/arch/i386/fathelp.asm +++ b/freeldr/freeldr/arch/i386/fathelp.asm @@ -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 diff --git a/freeldr/freeldr/arch/i386/i386trap.S b/freeldr/freeldr/arch/i386/i386trap.S index 34c1cd5a5a2..e750238b785 100644 --- a/freeldr/freeldr/arch/i386/i386trap.S +++ b/freeldr/freeldr/arch/i386/i386trap.S @@ -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 diff --git a/freeldr/freeldr/disk/disk.c b/freeldr/freeldr/disk/disk.c index 90f0b17b118..a5ed9e83a32 100644 --- a/freeldr/freeldr/disk/disk.c +++ b/freeldr/freeldr/disk/disk.c @@ -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)); diff --git a/freeldr/freeldr/disk/partition.c b/freeldr/freeldr/disk/partition.c index e773806dcf6..11016ff2122 100644 --- a/freeldr/freeldr/disk/partition.c +++ b/freeldr/freeldr/disk/partition.c @@ -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 diff --git a/freeldr/freeldr/freeldr.c b/freeldr/freeldr/freeldr.c index c707ea7fea4..2f7d88a9a3a 100644 --- a/freeldr/freeldr/freeldr.c +++ b/freeldr/freeldr/freeldr.c @@ -25,9 +25,9 @@ #include #include -// 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"); diff --git a/freeldr/freeldr/fs/ext2.c b/freeldr/freeldr/fs/ext2.c index f32fef6ed40..5198bc1b03f 100644 --- a/freeldr/freeldr/fs/ext2.c +++ b/freeldr/freeldr/fs/ext2.c @@ -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 11) - { - break; - } + RtlZeroMemory(BlockList, BlockCount * sizeof(U32)); + CurrentBlockInList = 0; - BlockList[CurrentBlock] = Inode->i_block[CurrentBlock]; + // Copy the direct block pointers + for (CurrentBlock=0; CurrentBlockInListi_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= ((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= ((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= ((Ext2BlockSizeInBytes / sizeof(U32)) - 1)) - { - break; - } } + MmFreeMemory(BlockBuffer); return TRUE; } diff --git a/freeldr/freeldr/fs/ext2.h b/freeldr/freeldr/fs/ext2.h index 936958a1445..7b7329c7f4c 100644 --- a/freeldr/freeldr/fs/ext2.h +++ b/freeldr/freeldr/fs/ext2.h @@ -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 diff --git a/freeldr/freeldr/include/debug.h b/freeldr/freeldr/include/debug.h index 0bbe9b867f9..ec1d7947295 100644 --- a/freeldr/freeldr/include/debug.h +++ b/freeldr/freeldr/include/debug.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_) diff --git a/freeldr/freeldr/include/mm.h b/freeldr/freeldr/include/mm.h index c74e75d0aca..281cee477d1 100644 --- a/freeldr/freeldr/include/mm.h +++ b/freeldr/freeldr/include/mm.h @@ -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; diff --git a/freeldr/freeldr/include/version.h b/freeldr/freeldr/include/version.h index f6a2965ea96..723ab505a2c 100644 --- a/freeldr/freeldr/include/version.h +++ b/freeldr/freeldr/include/version.h @@ -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 " #define AUTHOR_EMAIL "" #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); diff --git a/freeldr/freeldr/inifile/ini.h b/freeldr/freeldr/inifile/ini.h index fd341e59494..6e779035f76 100644 --- a/freeldr/freeldr/inifile/ini.h +++ b/freeldr/freeldr/inifile/ini.h @@ -21,6 +21,7 @@ #define __INI_H #include +#include #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); diff --git a/freeldr/freeldr/inifile/ini_init.c b/freeldr/freeldr/inifile/ini_init.c index f4eade2ef1b..737e1cc402f 100644 --- a/freeldr/freeldr/inifile/ini_init.c +++ b/freeldr/freeldr/inifile/ini_init.c @@ -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; +} diff --git a/freeldr/freeldr/miscboot.c b/freeldr/freeldr/miscboot.c index 25bc4eb9eb0..0b5dee4ca21 100644 --- a/freeldr/freeldr/miscboot.c +++ b/freeldr/freeldr/miscboot.c @@ -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(); } diff --git a/freeldr/freeldr/mm/mem.h b/freeldr/freeldr/mm/mem.h index 534482d51fe..55645ebdcbd 100644 --- a/freeldr/freeldr/mm/mem.h +++ b/freeldr/freeldr/mm/mem.h @@ -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 diff --git a/freeldr/freeldr/mm/meminit.c b/freeldr/freeldr/mm/meminit.c index 5d2846fc048..1c7143c5bfe 100644 --- a/freeldr/freeldr/mm/meminit.c +++ b/freeldr/freeldr/mm/meminit.c @@ -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 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= (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; - } } }