diff --git a/reactos/boot/freeldr/bootsect/ext2.S b/reactos/boot/freeldr/bootsect/ext2.S index 3dd20a2a883..49967883bd4 100644 --- a/reactos/boot/freeldr/bootsect/ext2.S +++ b/reactos/boot/freeldr/bootsect/ext2.S @@ -1,11 +1,11 @@ -; EXT2.ASM -; EXT2 Boot Sector -; Copyright (c) 2002, 2003 Brian Palmer +// EXT2.ASM +// EXT2 Boot Sector +// Copyright (c) 2002, 2003 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 +// [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 @@ -29,20 +29,20 @@ start: nop BootDrive db 0x80 -;BootPartition db 0 ; Moved to end of boot sector to have a standard format across all boot sectors -;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] +//BootPartition db 0 // Moved to end of boot sector to have a standard format across all boot sectors +//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 -Ext2BlockSizeInBytes dd 1024 ; Block size in bytes -Ext2PointersPerBlock dd 256 ; Number of block pointers that can be contained in one block -Ext2GroupDescPerBlock dd 32 ; Number of group descriptors per block -Ext2FirstDataBlock dd 1 ; First data block (1 for 1024-byte blocks, 0 for bigger sizes) -Ext2InodesPerGroup dd 2048 ; Number of inodes per group -Ext2InodesPerBlock dd 8 ; Number of inodes per block +Ext2VolumeStartSector dd 263088 // Start sector of the ext2 volume +Ext2BlockSize dd 2 // Block size in sectors +Ext2BlockSizeInBytes dd 1024 // Block size in bytes +Ext2PointersPerBlock dd 256 // Number of block pointers that can be contained in one block +Ext2GroupDescPerBlock dd 32 // Number of group descriptors per block +Ext2FirstDataBlock dd 1 // First data block (1 for 1024-byte blocks, 0 for bigger sizes) +Ext2InodesPerGroup dd 2048 // Number of inodes per group +Ext2InodesPerBlock dd 8 // Number of inodes per block Ext2ReadEntireFileLoadSegment: dw 0 @@ -54,83 +54,83 @@ Ext2BlocksLeftToRead: dd 0 main: - xor ax,ax ; Setup segment registers - mov ds,ax ; Make DS correct - mov es,ax ; Make ES correct - mov ss,ax ; Make SS correct + xor ax,ax // Setup segment registers + mov ds,ax // Make DS correct + mov es,ax // Make ES correct + mov ss,ax // Make SS correct mov bp,7c00h - mov sp,7b00h ; Setup a stack + mov sp,7b00h // Setup a stack - cmp BYTE [BYTE bp+BootDrive],BYTE 0xff ; If they have specified a boot drive then use it + 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 + mov [BYTE bp+BootDrive],dl // Save the boot drive GetDriveParameters: mov ah,08h - mov dl,[BYTE bp+BootDrive] ; Get boot drive in dl - int 13h ; Request drive parameters from the bios - jnc CalcDriveSize ; If the call succeeded then calculate the drive size + mov dl,[BYTE bp+BootDrive] // Get boot drive in dl + int 13h // Request drive parameters from the bios + jnc CalcDriveSize // If the call succeeded then calculate the drive size - ; If we get here then the call to the BIOS failed - ; so just set CHS equal to the maximum addressable - ; size + // If we get here then the call to the BIOS failed + // so just set CHS equal to the maximum addressable + // size mov cx,0ffffh mov dh,cl 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 - ; 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 - 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] + // 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 + // 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 + 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 + // We now have the total number of sectors as reported + // by the bios in eax, so store it in our variable 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 + // First we have to load our extra boot code at + // sector 1 into memory at [0000:7e00h] + //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] + 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 jmp LoadRootDirectory -; Reads ext2 group descriptor into [7000:8000] -; We read it to this arbitrary location so -; it will not cross a 64k boundary -; EAX has group descriptor number to read +// Reads ext2 group descriptor into [7000:8000] +// We read it to this arbitrary location so +// it will not cross a 64k boundary +// EAX has group descriptor number to read Ext2ReadGroupDesc: - shl eax,5 ; Group = (Group * sizeof(GROUP_DESCRIPTOR) /* 32 */) + shl eax,5 // Group = (Group * sizeof(GROUP_DESCRIPTOR) /* 32 */) xor edx,edx - div DWORD [BYTE bp+Ext2GroupDescPerBlock] ; Group = (Group / Ext2GroupDescPerBlock) - add eax,DWORD [BYTE bp+Ext2FirstDataBlock] ; Group = Group + Ext2FirstDataBlock + 1 - inc eax ; EAX now has the group descriptor block number - ; EDX now has the group descriptor offset in the block + div DWORD [BYTE bp+Ext2GroupDescPerBlock] // Group = (Group / Ext2GroupDescPerBlock) + add eax,DWORD [BYTE bp+Ext2FirstDataBlock] // Group = Group + Ext2FirstDataBlock + 1 + inc eax // EAX now has the group descriptor block number + // EDX now has the group descriptor offset in the block - ; Adjust the read offset so that the - ; group descriptor is read to 7000:8000 + // Adjust the read offset so that the + // group descriptor is read to 7000:8000 mov ebx,78000h sub ebx,edx shr ebx,4 @@ -138,51 +138,51 @@ Ext2ReadGroupDesc: xor bx,bx - ; Everything is now setup to call Ext2ReadBlock - ; Instead of using the call instruction we will - ; just put Ext2ReadBlock right after this routine + // Everything is now setup to call Ext2ReadBlock + // Instead of using the call instruction we will + // just put Ext2ReadBlock right after this routine -; Reads ext2 block into [ES:BX] -; EAX has logical block number to read +// Reads ext2 block into [ES:BX] +// EAX has logical block number to read Ext2ReadBlock: mov ecx,DWORD [BYTE bp+Ext2BlockSize] mul ecx jmp ReadSectors -; Reads ext2 inode into [6000:8000] -; We read it to this arbitrary location so -; it will not cross a 64k boundary -; EAX has inode number to read +// Reads ext2 inode into [6000:8000] +// We read it to this arbitrary location so +// it will not cross a 64k boundary +// EAX has inode number to read Ext2ReadInode: - dec eax ; Inode = Inode - 1 + dec eax // Inode = Inode - 1 xor edx,edx - div DWORD [BYTE bp+Ext2InodesPerGroup] ; Inode = (Inode / Ext2InodesPerGroup) - mov ebx,eax ; EBX now has the inode group number + div DWORD [BYTE bp+Ext2InodesPerGroup] // Inode = (Inode / Ext2InodesPerGroup) + mov ebx,eax // EBX now has the inode group number mov eax,edx xor edx,edx - div DWORD [BYTE bp+Ext2InodesPerBlock] ; Inode = (Inode / Ext2InodesPerBlock) - shl edx,7 ; FIXME: InodeOffset *= 128 (make the array index a byte offset) - ; EAX now has the inode offset block number from inode table - ; EDX now has the inode offset in the block + div DWORD [BYTE bp+Ext2InodesPerBlock] // Inode = (Inode / Ext2InodesPerBlock) + shl edx,7 // FIXME: InodeOffset *= 128 (make the array index a byte offset) + // EAX now has the inode offset block number from inode table + // EDX now has the inode offset in the block - ; Save the inode values and put the group - ; descriptor number in EAX and read it in + // Save the inode values and put the group + // descriptor number in EAX and read it in push edx push eax mov eax,ebx call Ext2ReadGroupDesc - ; Group descriptor has been read, now - ; grab the inode table block number from it + // Group descriptor has been read, now + // grab the inode table block number from it push WORD 7000h pop es mov di,8008h - pop eax ; Restore inode offset block number from stack - add eax,DWORD [es:di] ; Add the inode table start block + pop eax // Restore inode offset block number from stack + add eax,DWORD [es:di] // Add the inode table start block - ; Adjust the read offset so that the - ; inode we want is read to 6000:8000 - pop edx ; Restore inode offset in the block from stack + // Adjust the read offset so that the + // inode we want is read to 6000:8000 + pop edx // Restore inode offset in the block from stack mov ebx,68000h sub ebx,edx shr ebx,4 @@ -193,131 +193,131 @@ Ext2ReadInode: ret -; Reads logical sectors into [ES:BX] -; EAX has logical sector number to read -; CX has number of sectors to read +// Reads logical sectors into [ES:BX] +// EAX has logical sector number to read +// 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-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 + add eax,DWORD [BYTE bp+Ext2VolumeStartSector] // Add the start of the volume + 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 - pushad ; Save logical sector number & sector count + pushad // Save logical sector number & sector count -CheckInt13hExtensions: ; Now check if this computer supports extended reads - mov ah,0x41 ; AH = 41h - mov bx,0x55aa ; BX = 55AAh - mov dl,[BYTE bp+BootDrive] ; DL = drive (80h-FFh) - int 13h ; IBM/MS INT 13 Extensions - INSTALLATION CHECK - jc ReadSectorsCHS ; CF set on error (extensions not supported) - cmp bx,0xaa55 ; BX = AA55h if installed +CheckInt13hExtensions: // Now check if this computer supports extended reads + mov ah,0x41 // AH = 41h + mov bx,0x55aa // BX = 55AAh + mov dl,[BYTE bp+BootDrive] // DL = drive (80h-FFh) + int 13h // IBM/MS INT 13 Extensions - INSTALLATION CHECK + jc ReadSectorsCHS // CF set on error (extensions not supported) + cmp bx,0xaa55 // BX = AA55h if installed jne ReadSectorsCHS - test cl,1 ; CX = API subset support bitmap - jz ReadSectorsCHS ; Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported + test cl,1 // CX = API subset support bitmap + jz ReadSectorsCHS // Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported - popad ; Restore sector count & logical sector number + popad // Restore sector count & logical sector number ReadSectorsLBA: - pushad ; Save logical sector number & sector count + pushad // Save logical sector number & sector count - 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 + 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-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 - push bx ; Put transfer offset on stack - push cx ; Set transfer count - push byte 0x10 ; Set size of packet to 10h - mov si,sp ; Setup disk address packet on stack + push eax // Put 64-bit logical block address on stack + push es // Put transfer segment on stack + push bx // Put transfer offset on stack + push cx // Set transfer count + push byte 0x10 // Set size of packet to 10h + mov si,sp // Setup disk address packet on stack - mov dl,[BYTE bp+BootDrive] ; Drive number - mov ah,42h ; Int 13h, AH = 42h - Extended Read - int 13h ; Call BIOS - jc PrintDiskError ; If the read failed then abort + mov dl,[BYTE bp+BootDrive] // Drive number + mov ah,42h // Int 13h, AH = 42h - Extended Read + int 13h // Call BIOS + jc PrintDiskError // If the read failed then abort - add sp,byte 0x10 ; Remove disk address packet from stack + add sp,byte 0x10 // Remove disk address packet from stack - popad ; Restore sector count & logical sector number + popad // Restore sector count & logical sector number push bx mov ebx,DWORD [BYTE bp-LBA_SECTORS_READ] - add eax,ebx ; Increment sector to read + add eax,ebx // Increment sector to read shl ebx,5 mov dx,es - add dx,bx ; Setup read buffer for next sector + add dx,bx // Setup read buffer for next sector mov es,dx pop bx sub cx,[BYTE bp-LBA_SECTORS_READ] - jnz ReadSectorsLBA ; Read next sector + jnz ReadSectorsLBA // Read next sector ret -; Reads logical sectors into [ES:BX] -; EAX has logical sector number to read -; CX has number of sectors to read +// Reads logical sectors into [ES:BX] +// EAX has logical sector number to read +// CX has number of sectors to read ReadSectorsCHS: - popad ; Get logical sector number & sector count off stack + popad // Get logical sector number & sector count off stack ReadSectorsCHSLoop: pushad xor edx,edx 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 + 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-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 - ror ah,2 ; Low 8 bits of cylinder in CH, high 2 bits - ; in CL shifted to bits 6 & 7 - or cl,ah ; Or with sector number + 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 + ror ah,2 // Low 8 bits of cylinder in CH, high 2 bits + // in CL shifted to bits 6 & 7 + or cl,ah // Or with sector number mov ax,0201h - int 13h ; DISK - READ SECTORS INTO MEMORY - ; AL = number of sectors to read, CH = track, CL = sector - ; DH = head, DL = drive, ES:BX -> buffer to fill - ; Return: CF set on error, AH = status (see AH=01h), AL = number of sectors read + int 13h // DISK - READ SECTORS INTO MEMORY + // AL = number of sectors to read, CH = track, CL = sector + // DH = head, DL = drive, ES:BX -> buffer to fill + // Return: CF set on error, AH = status (see AH=01h), AL = number of sectors read - jc PrintDiskError ; If the read failed then abort + jc PrintDiskError // If the read failed then abort popad - inc eax ; Increment Sector to Read + inc eax // Increment Sector to Read mov dx,es - add dx,byte 20h ; Increment read buffer for next sector + add dx,byte 20h // Increment read buffer for next sector mov es,dx - loop ReadSectorsCHSLoop ; Read next sector + loop ReadSectorsCHSLoop // Read next sector - ret + ret -; Displays a disk error message -; And reboots +// Displays a disk error message +// And reboots PrintDiskError: - mov si,msgDiskError ; Bad boot disk message - call PutChars ; Display it + mov si,msgDiskError // Bad boot disk 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 + mov si,msgAnyKey // Press any key message + call PutChars // Display it + xor ax,ax + int 16h // Wait for a keypress + int 19h // Reboot PutChars: lodsb @@ -340,318 +340,318 @@ Done: msgDiskError db 'Disk error',0 -; Sorry, need the space... -;msgAnyKey db 'Press any key to restart',0 +// Sorry, need the space... +//msgAnyKey db 'Press any key to restart',0 msgAnyKey db 'Press any key',0 - times 509-($-$$) db 0 ; Pad to 509 bytes + times 509-($-$$) db 0 // Pad to 509 bytes BootPartition db 0 - dw 0aa55h ; BootSector signature - + dw 0aa55h // BootSector signature -; End of bootsector -; -; Now starts the extra boot code that we will store -; at sector 1 on a EXT2 volume + +// End of bootsector +// +// Now starts the extra boot code that we will store +// at sector 1 on a EXT2 volume LoadRootDirectory: - mov eax,EXT2_ROOT_INO ; Put the root directory inode number in EAX - call Ext2ReadInode ; Read in the inode + mov eax,EXT2_ROOT_INO // Put the root directory inode number in EAX + call Ext2ReadInode // Read in the inode - ; Point ES:DI to the inode structure at 6000:8000 + // Point ES:DI to the inode structure at 6000:8000 push WORD 6000h pop es mov di,8000h push di - push es ; Save these for later + push es // Save these for later - ; Get root directory size from inode structure + // Get root directory size from inode structure mov eax,DWORD [es:di+4] push eax - ; Now that the inode has been read in load - ; the root directory file data to 0000:8000 + // Now that the inode has been read in load + // the root directory file data to 0000:8000 call Ext2ReadEntireFile - ; Since the root directory was loaded to 0000:8000 - ; then add 8000h to the root directory's size + // Since the root directory was loaded to 0000:8000 + // then add 8000h to the root directory's size pop eax - mov edx,8000h ; Set EDX to the current offset in the root directory - add eax,edx ; Initially add 8000h to the size of the root directory + mov edx,8000h // Set EDX to the current offset in the root directory + add eax,edx // Initially add 8000h to the size of the root directory SearchRootDirectory: - push edx ; Save current offset in root directory - push eax ; Save the size of the root directory + push edx // Save current offset in root directory + push eax // Save the size of the root directory - ; Now we have to convert the current offset - ; in the root directory to a SEGMENT:OFFSET pair + // Now we have to convert the current offset + // in the root directory to a SEGMENT:OFFSET pair mov eax,edx xor edx,edx mov ecx,16 - div ecx ; Now AX:DX has segment & offset + div ecx // Now AX:DX has segment & offset mov es,ax mov di,dx - push di ; Save the start of the directory entry - add di,byte 8 ; Add the offset to the filename + push di // Save the start of the directory entry + add di,byte 8 // Add the offset to the filename mov si,filename mov cl,11 - rep cmpsb ; Compare the file names + rep cmpsb // Compare the file names pop di pop eax pop edx jz FoundFile - ; Nope, didn't find it in this entry, keep looking + // Nope, didn't find it in this entry, keep looking movzx ecx,WORD [es:di+4] add edx,ecx - ; Check to see if we have reached the - ; end of the root directory + // Check to see if we have reached the + // end of the root directory cmp edx,eax jb SearchRootDirectory jmp PrintFileNotFound FoundFile: - mov eax,[es:di] ; Get inode number from directory entry - call Ext2ReadInode ; Read in the inode + mov eax,[es:di] // Get inode number from directory entry + call Ext2ReadInode // Read in the inode - ; Point ES:DI to the inode structure at 6000:8000 + // Point ES:DI to the inode structure at 6000:8000 pop es - pop di ; These were saved earlier + pop di // These were saved earlier - mov cx,[es:di] ; Get the file mode so we can make sure it's a regular file - and ch,EXT2_S_IFMT ; Mask off everything but the file type - cmp ch,EXT2_S_IFREG ; Make sure it's a regular file + mov cx,[es:di] // Get the file mode so we can make sure it's a regular file + and ch,EXT2_S_IFMT // Mask off everything but the file type + cmp ch,EXT2_S_IFREG // Make sure it's a regular file je LoadFreeLoader jmp PrintRegFileError LoadFreeLoader: - mov si,msgLoading ; "Loading FreeLoader..." message - call PutChars ; Display it + mov si,msgLoading // "Loading FreeLoader..." message + call PutChars // Display it - call Ext2ReadEntireFile ; Read freeldr.sys to 0000:8000 + call Ext2ReadEntireFile // Read freeldr.sys to 0000:8000 mov dl,[BYTE bp+BootDrive] mov dh,[BYTE bp+BootPartition] - push 0 ; push segment (0x0000) - mov eax, [0x8000 + 0xA8] ; load the RVA of the EntryPoint into eax - add eax, 0x8000 ; RVA -> VA - push ax ; push offset - retf ; Transfer control to FreeLoader + push 0 // push segment (0x0000) + mov eax, [0x8000 + 0xA8] // load the RVA of the EntryPoint into eax + add eax, 0x8000 // RVA -> VA + push ax // push offset + retf // Transfer control to FreeLoader -; Reads ext2 file data into [0000:8000] -; This function assumes that the file's -; inode has been read in to 6000:8000 *and* -; ES:DI points to 6000:8000 -; This will load all the blocks up to -; and including the double-indirect pointers. -; This should be sufficient because it -; allows for ~64MB which is much bigger -; than we need for a boot loader. +// Reads ext2 file data into [0000:8000] +// This function assumes that the file's +// inode has been read in to 6000:8000 *and* +// ES:DI points to 6000:8000 +// This will load all the blocks up to +// and including the double-indirect pointers. +// This should be sufficient because it +// allows for ~64MB which is much bigger +// than we need for a boot loader. Ext2ReadEntireFile: - ; Reset the load segment + // Reset the load segment mov WORD [BYTE bp+Ext2ReadEntireFileLoadSegment],800h - ; Now we must calculate how - ; many blocks to read in - ; 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 [BYTE bp+Ext2BlockSizeInBytes] ; Get the block size in bytes + // Now we must calculate how + // many blocks to read in + // 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 [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 + dec eax // Ext2BlockSizeInBytes -= 1 + add eax,DWORD [es:di+4] // Add the file size xor edx,edx - pop ecx ; Divide by the block size in bytes - div ecx ; EAX now contains the number of blocks to load + pop ecx // Divide by the block size in bytes + div ecx // EAX now contains the number of blocks to load push eax - ; Make sure the file size isn't zero + // Make sure the file size isn't zero cmp eax,byte 0 jnz Ext2ReadEntireFile2 jmp PrintFileSizeError Ext2ReadEntireFile2: - ; Save the indirect & double indirect pointers - mov edx,DWORD [es:di+0x58] ; Get indirect pointer - mov [BYTE bp+Ext2InodeIndirectPointer],edx ; Save indirect pointer - mov edx,DWORD [es:di+0x5c] ; Get double indirect pointer - mov [BYTE bp+Ext2InodeDoubleIndirectPointer],edx ; Save double indirect pointer + // Save the indirect & double indirect pointers + mov edx,DWORD [es:di+0x58] // Get indirect pointer + mov [BYTE bp+Ext2InodeIndirectPointer],edx // Save indirect pointer + mov edx,DWORD [es:di+0x5c] // Get double indirect pointer + mov [BYTE bp+Ext2InodeDoubleIndirectPointer],edx // Save double indirect pointer - ; Now copy the direct pointers to 7000:0000 - ; so that we can call Ext2ReadDirectBlocks - push ds ; Save DS + // Now copy the direct pointers to 7000:0000 + // so that we can call Ext2ReadDirectBlocks + push ds // Save DS push es push WORD 7000h pop es pop ds mov si,8028h - xor di,di ; DS:SI = 6000:8028 ES:DI = 7000:0000 - mov cx,24 ; Moving 24 words of data + xor di,di // DS:SI = 6000:8028 ES:DI = 7000:0000 + mov cx,24 // Moving 24 words of data rep movsw - pop ds ; Restore DS + pop ds // Restore DS - ; Now we have all the block pointers in the - ; right location so read them in - pop eax ; Restore the total number of blocks in this file - xor ecx,ecx ; Set the max count of blocks to read to 12 - mov cl,12 ; which is the number of direct block pointers in the inode + // Now we have all the block pointers in the + // right location so read them in + pop eax // Restore the total number of blocks in this file + xor ecx,ecx // Set the max count of blocks to read to 12 + mov cl,12 // which is the number of direct block pointers in the inode call Ext2ReadDirectBlockList - ; Check to see if we actually have - ; blocks left to read + // Check to see if we actually have + // blocks left to read 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 [BYTE bp+Ext2InodeIndirectPointer] ; Get the indirect block pointer + // 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 [BYTE bp+Ext2InodeIndirectPointer] // Get the indirect block pointer push WORD 7000h pop es - xor bx,bx ; Set the load address to 7000:0000 - call Ext2ReadBlock ; Read the block + xor bx,bx // Set the load address to 7000:0000 + call Ext2ReadBlock // Read the block - ; 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 [BYTE bp+Ext2PointersPerBlock] ; Get the number of block pointers that one block contains + // 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 [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 + // Check to see if we actually have + // blocks left to read cmp eax,byte 0 jz Ext2ReadEntireFileDone - ; Now we have read all the direct blocks from - ; the inode's indirect block pointer. So now - ; 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 [BYTE bp+Ext2BlocksLeftToRead],eax ; Save the total block count - mov eax,DWORD [BYTE bp+Ext2InodeDoubleIndirectPointer] ; Get the double indirect block pointer + // Now we have read all the direct blocks from + // the inode's indirect block pointer. So now + // 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 [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 - xor bx,bx ; Set the load address to 7000:8000 - call Ext2ReadBlock ; Read the block + push es // Save an extra copy of this value on the stack + xor bx,bx // Set the load address to 7000:8000 + call Ext2ReadBlock // Read the block - pop es ; Put 7800h into ES (saved on the stack already) + pop es // Put 7800h into ES (saved on the stack already) xor di,di Ext2ReadIndirectBlock: - mov eax,DWORD [es:di] ; Get indirect block pointer - add di,BYTE 4 ; Update DI for next array index + mov eax,DWORD [es:di] // Get indirect block pointer + add di,BYTE 4 // Update DI for next array index push es push di push WORD 7000h pop es - xor bx,bx ; Set the load address to 7000:0000 - call Ext2ReadBlock ; Read the indirect block + xor bx,bx // Set the load address to 7000:0000 + call Ext2ReadBlock // Read the indirect block - ; Now we have all the block pointers from the - ; indirect block in the right location so read them in - 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 + // Now we have all the block pointers from the + // indirect block in the right location so read them in + 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 [BYTE 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 + // Check to see if we actually have + // blocks left to read cmp eax,byte 0 jnz Ext2ReadIndirectBlock Ext2ReadEntireFileDone: ret -; Reads a maximum number of blocks -; from an array at 7000:0000 -; and updates the total count -; ECX contains the max number of blocks to read -; EAX contains the number of blocks left to read -; On return: -; EAX contians the new number of blocks left to read +// Reads a maximum number of blocks +// from an array at 7000:0000 +// and updates the total count +// ECX contains the max number of blocks to read +// EAX contains the number of blocks left to read +// On return: +// EAX contians the new number of blocks left to read Ext2ReadDirectBlockList: - cmp eax,ecx ; Compare it to the maximum number of blocks to read - ja CallExt2ReadDirectBlocks ; If it will take more blocks then just read all of the blocks - mov cx,ax ; Otherwise adjust the block count accordingly + cmp eax,ecx // Compare it to the maximum number of blocks to read + ja CallExt2ReadDirectBlocks // If it will take more blocks then just read all of the blocks + mov cx,ax // Otherwise adjust the block count accordingly CallExt2ReadDirectBlocks: - sub eax,ecx ; Subtract the number of blocks being read from the total count - push eax ; Save the new total count + sub eax,ecx // Subtract the number of blocks being read from the total count + push eax // Save the new total count call Ext2ReadDirectBlocks - pop eax ; Restore the total count + pop eax // Restore the total count ret -; Reads a specified number of blocks -; from an array at 7000:0000 -; CX contains the number of blocks to read +// Reads a specified number of blocks +// from an array at 7000:0000 +// CX contains the number of blocks to read Ext2ReadDirectBlocks: push WORD 7000h pop es - xor di,di ; Set ES:DI = 7000:0000 + xor di,di // Set ES:DI = 7000:0000 Ext2ReadDirectBlocksLoop: - mov eax,[es:di] ; Get direct block pointer from array - add di,BYTE 4 ; Update DI for next array index + mov eax,[es:di] // Get direct block pointer from array + add di,BYTE 4 // Update DI for next array index - push cx ; Save number of direct blocks left - push es ; Save array segment - push di ; Save array offset + push cx // Save number of direct blocks left + push es // Save array segment + push di // Save array offset mov es,[BYTE bp+Ext2ReadEntireFileLoadSegment] - xor bx,bx ; Setup load address for next read + xor bx,bx // Setup load address for next read - call Ext2ReadBlock ; Read the block (this updates ES for the next read) + call Ext2ReadBlock // Read the block (this updates ES for the next read) - mov [BYTE bp+Ext2ReadEntireFileLoadSegment],es ; Save updated ES + mov [BYTE bp+Ext2ReadEntireFileLoadSegment],es // Save updated ES - pop di ; Restore the array offset - pop es ; Restore the array segment - pop cx ; Restore the number of blocks left + pop di // Restore the array offset + pop es // Restore the array segment + pop cx // Restore the number of blocks left loop Ext2ReadDirectBlocksLoop - ; At this point all the direct blocks should - ; be loaded and ES (Ext2ReadEntireFileLoadSegment) - ; should be ready for the next read. + // At this point all the direct blocks should + // be loaded and ES (Ext2ReadEntireFileLoadSegment) + // should be ready for the next read. ret -; Displays a file not found error message -; And reboots +// Displays a file not found error message +// And reboots PrintFileNotFound: - mov si,msgFreeLdr ; FreeLdr not found message + mov si,msgFreeLdr // FreeLdr not found message jmp short DisplayItAndReboot -; Displays a file size is 0 error -; And reboots +// Displays a file size is 0 error +// And reboots PrintFileSizeError: - mov si,msgFileSize ; Error message + mov si,msgFileSize // Error message jmp short DisplayItAndReboot -; Displays a file is not a regular file error -; And reboots +// Displays a file is not a regular file error +// And reboots PrintRegFileError: - mov si,msgRegFile ; Error message + mov si,msgRegFile // Error message DisplayItAndReboot: - call PutChars ; Display it + call PutChars // Display it jmp Reboot msgFreeLdr db 'freeldr.sys not found',0 @@ -660,6 +660,6 @@ msgRegFile db 'freeldr.sys isnt a regular file',0 filename db 'freeldr.sys' msgLoading db 'Loading FreeLoader...',0 - times 1022-($-$$) db 0 ; Pad to 1022 bytes + times 1022-($-$$) db 0 // Pad to 1022 bytes - dw 0aa55h ; BootSector signature + dw 0aa55h // BootSector signature