From ea2806e13cf3f1e95147f73b8a9503f715b8ff0f Mon Sep 17 00:00:00 2001 From: Colin Finck Date: Thu, 28 Sep 2017 20:21:45 +0000 Subject: [PATCH] [BOOTSECTORS] Use the new header with SPDX license identifier for the ISO boot sector files I contributed to. Remove the unmaintained .asm files. svn path=/trunk/; revision=75984 --- reactos/boot/freeldr/bootsect/dosmbr.asm | 179 ---- reactos/boot/freeldr/bootsect/ext2.asm | 665 ------------- reactos/boot/freeldr/bootsect/fat.asm | 404 -------- reactos/boot/freeldr/bootsect/fat32.asm | 507 ---------- reactos/boot/freeldr/bootsect/isoboot.S | 37 +- reactos/boot/freeldr/bootsect/isoboot.asm | 1018 -------------------- reactos/boot/freeldr/bootsect/isobtrt.asm | 984 ------------------- reactos/boot/freeldr/bootsect/isombr.S | 5 +- reactos/boot/freeldr/bootsect/win2k.asm | 466 --------- reactos/boot/freeldr/bootsect/wxpfat16.asm | 249 ----- 10 files changed, 13 insertions(+), 4501 deletions(-) delete mode 100644 reactos/boot/freeldr/bootsect/dosmbr.asm delete mode 100644 reactos/boot/freeldr/bootsect/ext2.asm delete mode 100644 reactos/boot/freeldr/bootsect/fat.asm delete mode 100644 reactos/boot/freeldr/bootsect/fat32.asm delete mode 100644 reactos/boot/freeldr/bootsect/isoboot.asm delete mode 100644 reactos/boot/freeldr/bootsect/isobtrt.asm delete mode 100644 reactos/boot/freeldr/bootsect/win2k.asm delete mode 100644 reactos/boot/freeldr/bootsect/wxpfat16.asm diff --git a/reactos/boot/freeldr/bootsect/dosmbr.asm b/reactos/boot/freeldr/bootsect/dosmbr.asm deleted file mode 100644 index 23b6b94e4b6..00000000000 --- a/reactos/boot/freeldr/bootsect/dosmbr.asm +++ /dev/null @@ -1,179 +0,0 @@ -; -; Normal DOS boot sector -; -; Ported to NASM from FreeDOS fdisk 1.2.0 by: -; Casper Hornstrup (chorns@users.sourceforge.net) -; - - align 2, db 0 - - global _bootnormal_code -_bootnormal_code: - -;----------------------------------------------------------------------- -; ENTRY (copied from freedos bootsector) -; -; IN: DL = boot drive -;OUT: DL = boot drive -; -;----------------------------------------------------------------------- - -real_start: cli - cld - xor ax, ax - mov ss, ax ; initialize stack - mov ds, ax - mov bp, 0x7c00 - lea sp, [bp-0x20] - sti - - mov ax, 0x1FE0 - mov es, ax - mov si, bp - mov di, bp - mov cx, 0x0100 - rep movsw - - jmp word 0x1FE0:0x7c00+ cont-real_start - -cont: mov ds, ax - mov ss, ax - xor ax,ax - mov es,ax - - - ; search for active partition - lea di, [bp+0x1be] ; start of partition table -test_next_for_active: - test byte [di],0x80 - jne active_partition_found - add di,0x10 ; next table - cmp di, 07c00h+0x1fe; scanned beyond end of table ?? - jb test_next_for_active - -;***************************************************************** - call print - db 'No active partition found',0 - -WAIT_FOR_REBOOT: - jmp $ - - -;***************************************************************** -trouble_reading_drive: - call print - db 'Read error while reading drive',0 - jmp WAIT_FOR_REBOOT - -;***************************************************************** - -invalid_partition_code: - call print - db 'Partition signature != 55AA',0 - - jmp WAIT_FOR_REBOOT - - -;***************************************************************** - -active_partition_found: -; call print -; db 'Loading active partition',0 - - call read_boot_sector - - jc trouble_reading_drive - - cmp word [es:0x7c00+0x1fe],0xaa55 - jne invalid_partition_code - - jmp word 0x0:0x7c00 ; and jump to boot sector code - - -;***************************** -; read_boot_sector -; -; IN: DI--> partition info -;OUT:CARRY -;***************************** - -read_boot_sector: - ; /* check for LBA support */ - mov bx,0x55aa - mov ah,0x41 - int 0x13 - - jc StandardBios ; if (regs.b.x != 0xaa55 || (regs.flags & 0x01)) - cmp bx,0xaa55 ; goto StandardBios; - jne StandardBios - - ; /* if DAP cannot be used, don't use LBA */ - ; if ((regs.c.x & 1) == 0) - ; goto StandardBios; - test cl,1 - jz StandardBios - - jmp short LBABios - - -_bios_LBA_address_packet: - db 0x10 - db 0 - db 4 ; read four sectors - why not - db 0 - dw 0x7c00 ; fixed boot address for DOS sector - dw 0x0000 -_bios_LBA_low dw 0 -_bios_LBA_high dw 0 - dw 0,0 - - -LBABios: - ; copy start address of partition to DAP - mov ax,[di+8] - mov [0x7c00+ (_bios_LBA_low-real_start)],ax - mov ax,[di+8+2] - mov [0x7c00+ (_bios_LBA_high-real_start)],ax - - mov ax,0x4200 ; regs.a.x = LBA_READ; - mov si,0x7c00+ (_bios_LBA_address_packet-real_start); regs.si = FP_OFF(&dap); - - int 0x13 - ret - -;***************************************************************** -; read disk, using standard BIOS -; -StandardBios: - mov ax,0x0204 ; regs.a.x = 0x0201; - mov bx,0x7c00 ; regs.b.x = FP_OFF(buffer); - mov cx,[di+2] ; regs.c.x = - ; ((chs.Cylinder & 0xff) << 8) + ((chs.Cylinder & 0x300) >> 2) + - ; chs.Sector; - ; that was easy ;-) - mov dh,[di+1] ; regs.d.b.h = chs.Head; - ; regs.es = FP_SEG(buffer); - int 0x13 - ret - - - -;****** PRINT -; prints text after call to this function. - -print_1char: - xor bx, bx ; video page 0 - mov ah, 0x0E ; else print it - int 0x10 ; via TTY mode -print: pop si ; this is the first character -print1: lodsb ; get token - push si ; stack up potential return address - cmp al, 0 ; end of string? - jne print_1char ; until done - ret ; and jump to it - - - - times 0x1fe-$+$$ db 0 - db 0x55,0xaa - diff --git a/reactos/boot/freeldr/bootsect/ext2.asm b/reactos/boot/freeldr/bootsect/ext2.asm deleted file mode 100644 index ed83aee9de0..00000000000 --- a/reactos/boot/freeldr/bootsect/ext2.asm +++ /dev/null @@ -1,665 +0,0 @@ -; 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 - -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 -EXT2_S_IFREG equ 080h - - -org 7c00h - -segment .text - -bits 16 - -start: - jmp short main - 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] - -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 -Ext2InodeIndirectPointer: - dd 0 -Ext2InodeDoubleIndirectPointer: - dd 0 -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 - mov bp,7c00h - mov sp,7b00h ; Setup a stack - - - 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 - - -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 - - ; 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] - - ; 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 - 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 - - 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 -Ext2ReadGroupDesc: - 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 - - ; Adjust the read offset so that the - ; group descriptor is read to 7000:8000 - mov ebx,78000h - sub ebx,edx - shr ebx,4 - mov es,bx - 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 - -; 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 -Ext2ReadInode: - 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 - 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 - - ; 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 - 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 - - ; 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 - mov es,bx - xor bx,bx - - call Ext2ReadBlock - ret - - -; 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 - - 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 - jne ReadSectorsCHS - 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 - -ReadSectorsLBA: - 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 - -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 - - - 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 - - popad ; Restore sector count & logical sector number - - push bx - mov ebx,DWORD [BYTE bp-LBA_SECTORS_READ] - add eax,ebx ; Increment sector to read - shl ebx,5 - mov dx,es - 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 - - ret - - -; 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 - -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 - 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 - 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 - - jc PrintDiskError ; If the read failed then abort - - popad - - inc eax ; Increment Sector to Read - - mov dx,es - add dx,byte 20h ; Increment read buffer for next sector - mov es,dx - - loop ReadSectorsCHSLoop ; Read next sector - - ret - - - - -; Displays a disk error message -; And reboots -PrintDiskError: - 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 - -PutChars: - lodsb - or al,al - jz short Done - call PutCharsCallBios - jmp short PutChars -PutCharsCallBios: - mov ah,0eh - mov bx,07h - int 10h - retn -Done: - mov al,0dh - call PutCharsCallBios - mov al,0ah - call PutCharsCallBios - retn - - - -msgDiskError db 'Disk error',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 - -BootPartition db 0 - - dw 0aa55h ; BootSector signature - - -; 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 - - ; 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 - - ; 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 - call Ext2ReadEntireFile - - ; 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 - -SearchRootDirectory: - 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 - mov eax,edx - xor edx,edx - mov ecx,16 - 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 - mov si,filename - mov cl,11 - rep cmpsb ; Compare the file names - pop di - pop eax - pop edx - jz FoundFile - - ; 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 - cmp edx,eax - jb SearchRootDirectory - jmp PrintFileNotFound - -FoundFile: - 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 - pop es - 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 - je LoadFreeLoader - jmp PrintRegFileError - -LoadFreeLoader: - mov si,msgLoading ; "Loading FreeLoader..." message - call PutChars ; Display it - - 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 - - - - - -; 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 - 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 - push eax - 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 - push eax - - ; 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 - - ; 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 - rep movsw - 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 - call Ext2ReadDirectBlockList - - ; 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 - push WORD 7000h - pop es - 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 - call Ext2ReadDirectBlockList - - ; 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 - 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 - - 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 - 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 - - ; 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 - pop di - pop es - - ; 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 contains 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 - -CallExt2ReadDirectBlocks: - 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 - ret - - -; 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 - -Ext2ReadDirectBlocksLoop: - 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 - mov es,[BYTE bp+Ext2ReadEntireFileLoadSegment] - xor bx,bx ; Setup load address for next read - - call Ext2ReadBlock ; Read the block (this updates ES for the next read) - - 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 - - loop Ext2ReadDirectBlocksLoop - - ; 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 -PrintFileNotFound: - mov si,msgFreeLdr ; FreeLdr not found message - jmp short DisplayItAndReboot - -; Displays a file size is 0 error -; And reboots -PrintFileSizeError: - mov si,msgFileSize ; Error message - jmp short DisplayItAndReboot - -; Displays a file is not a regular file error -; And reboots -PrintRegFileError: - mov si,msgRegFile ; Error message -DisplayItAndReboot: - call PutChars ; Display it - jmp Reboot - -msgFreeLdr db 'freeldr.sys not found',0 -msgFileSize db 'File size is 0',0 -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 - - dw 0aa55h ; BootSector signature diff --git a/reactos/boot/freeldr/bootsect/fat.asm b/reactos/boot/freeldr/bootsect/fat.asm deleted file mode 100644 index 03ab5dda25e..00000000000 --- a/reactos/boot/freeldr/bootsect/fat.asm +++ /dev/null @@ -1,404 +0,0 @@ -; FAT.ASM -; FAT12/16 Boot Sector -; Copyright (c) 1998, 2001, 2002 Brian Palmer - - - -; This is a FAT12/16 file system boot sector -; that searches the entire root directory -; for the file freeldr.sys and loads it into -; memory. -; -; The stack is set to 0000:7BF2 so that the first -; WORD pushed will be placed at 0000:7BF0 -; -; The DWORD at 0000:7BFC or BP-04h is the logical -; sector number of the start of the data area. -; -; The DWORD at 0000:7BF8 or BP-08h is the total -; sector count of the boot drive as reported by -; the computers bios. -; -; The WORD at 0000:7BF6 or BP-0ah is the offset -; of the ReadSectors function in the boot sector. -; -; The WORD at 0000:7BF4 or BP-0ch is the offset -; of the ReadCluster function in the boot sector. -; -; The WORD at 0000:7BF2 or BP-0eh is the offset -; of the PutChars function in the boot sector. -; -; When it locates freeldr.sys on the disk it will -; load the first sector of the file to 0000:F800 -; With the help of this sector we should be able -; to load the entire file off the disk, no matter -; how fragmented it is. -; -; We load the entire FAT table into memory at -; 7000:0000. This improves the speed of floppy disk -; boots dramatically. - - -BootSectorStackTop equ 0x7bf2 -DataAreaStartHigh equ 0x2 -DataAreaStartLow equ 0x4 -BiosCHSDriveSizeHigh equ 0x6 -BiosCHSDriveSizeLow equ 0x8 -BiosCHSDriveSize equ 0x8 -ReadSectorsOffset equ 0xa -ReadClusterOffset equ 0xc -PutCharsOffset equ 0xe - - -org 7c00h - -segment .text - -bits 16 - -start: - jmp short main - nop - -OEMName db 'FrLdr1.0' -BytesPerSector dw 512 -SectsPerCluster db 1 -ReservedSectors dw 1 -NumberOfFats db 2 -MaxRootEntries dw 224 -TotalSectors dw 2880 -MediaDescriptor db 0f0h -SectorsPerFat dw 9 -SectorsPerTrack dw 18 -NumberOfHeads dw 2 -HiddenSectors dd 0 -TotalSectorsBig dd 0 -BootDrive db 0xff -Reserved db 0 -ExtendSig db 29h -SerialNumber dd 00000000h -VolumeLabel db 'NO NAME ' -FileSystem db 'FAT12 ' - -main: - xor ax,ax - mov ss,ax - mov bp,7c00h - mov sp,BootSectorStackTop ; Setup a stack - mov ds,ax ; Make DS correct - 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 - - -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 - - ; 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 - 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 - - - ; Now we must find our way to the first sector of the root directory - xor ax,ax - xor cx,cx - mov al,[BYTE bp+NumberOfFats] ; Number of fats - mul WORD [BYTE bp+SectorsPerFat] ; Times sectors per fat - add ax,WORD [BYTE bp+HiddenSectors] - adc dx,WORD [BYTE bp+HiddenSectors+2] ; Add the number of hidden sectors - add ax,WORD [BYTE bp+ReservedSectors] ; Add the number of reserved sectors - adc dx,cx ; Add carry bit - mov WORD [BYTE bp-DataAreaStartLow],ax ; Save the starting sector of the root directory - mov WORD [BYTE bp-DataAreaStartHigh],dx ; Save it in the first 4 bytes before the boot sector - mov si,WORD [BYTE bp+MaxRootEntries] ; Get number of root dir entries in SI - pusha ; Save 32-bit logical start sector of root dir - ; DX:AX now has the number of the starting sector of the root directory - - ; Now calculate the size of the root directory - xor dx,dx - mov ax,0020h ; Size of dir entry - mul si ; Times the number of entries - mov bx,[BYTE bp+BytesPerSector] - add ax,bx - dec ax - div bx ; Divided by the size of a sector - ; AX now has the number of root directory sectors - - add [BYTE bp-DataAreaStartLow],ax ; Add the number of sectors of the root directory to our other value - adc [BYTE bp-DataAreaStartHigh],cx ; Now the first 4 bytes before the boot sector contain the starting sector of the data area - popa ; Restore root dir logical sector start to DX:AX - -LoadRootDirSector: - mov bx,7e0h ; We will load the root directory sector - mov es,bx ; Right after the boot sector in memory - xor bx,bx ; We will load it to [0000:7e00h] - xor cx,cx ; Zero out CX - inc cx ; Now increment it to 1, we are reading one sector - xor di,di ; Zero out di - push es ; Save ES because it will get incremented by 20h - call ReadSectors ; Read the first sector of the root directory - pop es ; Restore ES (ES:DI = 07E0:0000) - -SearchRootDirSector: - cmp [es:di],ch ; If the first byte of the directory entry is zero then we have - jz ErrBoot ; reached the end of the directory and FREELDR.SYS is not here so reboot - pusha ; Save all registers - mov cl,0xb ; Put 11 in cl (length of filename in directory entry) - mov si,filename ; Put offset of filename string in DS:SI - repe cmpsb ; Compare this directory entry against 'FREELDR SYS' - popa ; Restore all the registers - jz FoundFreeLoader ; If we found it then jump - dec si ; SI holds MaxRootEntries, subtract one - jz ErrBoot ; If we are out of root dir entries then reboot - add di,BYTE +0x20 ; Increment DI by the size of a directory entry - cmp di,0200h ; Compare DI to 512 (DI has offset to next dir entry, make sure we haven't gone over one sector) - jc SearchRootDirSector ; If DI is less than 512 loop again - jmp short LoadRootDirSector ; Didn't find FREELDR.SYS in this directory sector, try again - -FoundFreeLoader: - ; We found freeldr.sys on the disk - ; so we need to load the first 512 - ; bytes of it to 0000:F800 - ; ES:DI has dir entry (ES:DI == 07E0:XXXX) - mov ax,WORD [es:di+1ah] ; Get start cluster - push ax ; Save start cluster - push WORD 0F80h ; FREELDR_BASE / 16 ; Put load segment on the stack and load it - pop es ; Into ES so that we load the cluster at 0000:F800 - call ReadCluster ; Read the cluster - pop ax ; Restore start cluster of FreeLoader - - ; Save the addresses of needed functions so - ; the helper code will know where to call them. - mov WORD [BYTE bp-ReadSectorsOffset],ReadSectors ; Save the address of ReadSectors - mov WORD [BYTE bp-ReadClusterOffset],ReadCluster ; Save the address of ReadCluster - mov WORD [BYTE bp-PutCharsOffset],PutChars ; Save the address of PutChars - - ; Now AX has start cluster of FreeLoader and we - ; have loaded the helper code in the first 512 bytes - ; of FreeLoader to 0000:F800. Now transfer control - ; to the helper code. Skip the first three bytes - ; because they contain a jump instruction to skip - ; over the helper code in the FreeLoader image. - ;ljmp16 0, FREELDR_BASE + 3 - db 0EAh - dw 0F803h - dw 0 - - - - -; Displays an error message -; And reboots -ErrBoot: - mov si,msgFreeLdr ; FreeLdr not found 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 - -PutChars: - lodsb - or al,al - jz short Done - mov ah,0eh - mov bx,07h - int 10h - jmp short PutChars -Done: - retn - -; Displays a bad boot message -; And reboots -BadBoot: - mov si,msgDiskError ; Bad boot disk 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 FREELDR.SYS - xor bx,bx ; We will load it to [ES:0000], ES loaded before function call - ;mov cl,BYTE [BYTE bp+SectsPerCluster]; Sectors per cluster still in CX - ;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: - - ; 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 - ja ReadSectorsLBA ; No - go to the LBA routine - 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: - popa -ReadSectorsLBALoop: - pusha ; Save logical sector number & sector count - - o32 push byte 0 - push dx ; Put 64-bit logical - push ax ; block address on stack - push es ; Put transfer segment on stack - push bx ; Put transfer offset on stack - push byte 1 ; Set transfer count to 1 sector - push byte 0x10 ; Set size of packet to 10h - mov si,sp ; Setup disk address packet on stack - -; We are so totally out of space here that I am forced to -; comment out this very beautifully written piece of code -; It would have been nice to have had this check... -;CheckInt13hExtensions: ; Now make sure 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 PrintDiskError ; CF set on error (extensions not supported) -; cmp bx,0xaa55 ; BX = AA55h if installed -; jne PrintDiskError -; test cl,1 ; CX = API subset support bitmap -; jz PrintDiskError ; Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported - - - ; Good, we're here so the computer supports LBA disk access - ; So finish the extended read - mov dl,[BYTE bp+BootDrive] ; Drive number - mov ah,42h ; Int 13h, AH = 42h - Extended Read - int 13h ; Call BIOS - jc BadBoot ; If the read failed then abort - - add sp,byte 0x10 ; Remove disk address packet from stack - - popa ; Restore sector count & logical sector number - - inc ax ; Increment Sector to Read - adc dx,byte 0 - - push bx - mov bx,es - add bx,byte 20h ; Increment read buffer for next sector - mov es,bx - pop bx - - loop ReadSectorsLBALoop ; Read next sector - - ret - - -; Reads logical sectors into [ES:BX] -; DX:AX has logical sector number to read -; CX has number of sectors to read -; CarryFlag set on error -ReadSectorsCHS: - popa -ReadSectorsCHSLoop: - pusha - xchg ax,cx - xchg ax,dx - xor dx,dx - div WORD [BYTE bp+SectorsPerTrack] - xchg ax,cx - div WORD [BYTE bp+SectorsPerTrack] ; Divide logical by SectorsPerTrack - inc dx ; Sectors numbering starts at 1 not 0 - xchg cx,dx - div WORD [BYTE bp+NumberOfHeads] ; Number of heads - mov dh,dl ; Head to DH, drive to DL - mov dl,[BYTE bp+BootDrive] ; Drive number - 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 - - jc BadBoot - - popa - inc ax ;Increment Sector to Read - jnz NoCarryCHS - inc dx - - -NoCarryCHS: - push bx - mov bx,es - add bx,byte 20h - mov es,bx - pop bx - ; Increment read buffer for next sector - loop ReadSectorsCHSLoop ; Read next sector - - ret - - -msgDiskError db 'Disk error',0dh,0ah,0 -msgFreeLdr db 'Ldr not found',0dh,0ah,0 -; Sorry, need the space... -;msgAnyKey db 'Press any key to restart',0dh,0ah,0 -;msgAnyKey db 'Press a key',0dh,0ah,0 -filename db 'FREELDR SYS' - - times 509-($-$$) db 0 ; Pad to 509 bytes - -BootPartition: - db 0 - -BootSignature: - dw 0aa55h ; BootSector signature diff --git a/reactos/boot/freeldr/bootsect/fat32.asm b/reactos/boot/freeldr/bootsect/fat32.asm deleted file mode 100644 index 00b4ff00138..00000000000 --- a/reactos/boot/freeldr/bootsect/fat32.asm +++ /dev/null @@ -1,507 +0,0 @@ -; FAT32.ASM -; FAT32 Boot Sector -; Copyright (c) 1998, 2000, 2001, 2002 Brian Palmer - -org 7c00h - -segment .text - -bits 16 - -start: - jmp short main - nop - -OEMName db 'FrLdr1.0' -BytesPerSector dw 512 -SectsPerCluster db 0 -ReservedSectors dw 32 -NumberOfFats db 2 -MaxRootEntries dw 0 ; Always zero for FAT32 volumes -TotalSectors dw 0 ; Always zero for FAT32 volumes -MediaDescriptor db 0f8h -SectorsPerFat dw 0 ; Always zero for FAT32 volumes -SectorsPerTrack dw 0 -NumberOfHeads dw 0 -HiddenSectors dd 0 -TotalSectorsBig dd 0 -; FAT32 Inserted Info -SectorsPerFatBig dd 0 -ExtendedFlags dw 0 -FSVersion dw 0 -RootDirStartCluster dd 0 -FSInfoSector dw 0 -BackupBootSector dw 6 -Reserved1 times 12 db 0 -; End FAT32 Inserted Info -BootDrive db 0 -Reserved db 0 -ExtendSig db 29h -SerialNumber dd 00000000h -VolumeLabel db 'NO NAME ' -FileSystem db 'FAT32 ' - -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 - mov bp,7c00h - mov sp,7c00h ; Setup a stack - - - - 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 - jnz CheckFailed ; If it is non-zero then exit with an error -CheckTotalSectors: ; Check the old 16-bit value of TotalSectors & MaxRootEntries - cmp DWORD [BYTE bp+MaxRootEntries],byte 0x00; by comparing the DWORD at offset MaxRootEntries to zero - jnz CheckFailed ; If it is non-zero then exit with an error -CheckFileSystemVersion: - cmp WORD [BYTE bp+FSVersion],byte 0x00 ; Check the file system version word - jna GetDriveParameters ; It is zero, so continue -CheckFailed: - jmp PrintFileSystemError ; If it is not zero then exit with an error - - -GetDriveParameters: - mov ax,0800h - 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 - 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 - 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 [BiosCHSDriveSize],eax - - -LoadExtraBootCode: - ; First we have to load our extra boot code at - ; sector 14 into memory at [0000:7e00h] - mov eax,0eh - add eax,DWORD [BYTE bp+HiddenSectors] ; Add the number of hidden sectors - mov cx,1 - xor bx,bx - mov es,bx ; Read sector to [0000:7e00h] - mov bx,7e00h - call ReadSectors - jmp StartSearch - - - -; Reads logical sectors into [ES:BX] -; EAX has logical sector number to read -; CX has number of sectors to read -ReadSectors: - push es - cmp eax,DWORD [BiosCHSDriveSize] ; 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 - -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 - - popad ; Restore sector count & logical sector number - -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 - 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 [LBASectorsRead],cx - 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 - - - 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 - - popad ; Restore sector count & logical sector number - - push bx - mov ebx,DWORD [LBASectorsRead] - add eax,ebx ; Increment sector to read - shl ebx,5 - mov dx,es - add dx,bx ; Setup read buffer for next sector - mov es,dx - pop bx - - sub cx,[LBASectorsRead] - jnz ReadSectorsLBA ; Read next sector - - pop es - ret - -LBASectorsRead: - dd 0 - - -; 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 - -ReadSectorsCHSLoop: - pushad - xor edx,edx - movzx ecx,WORD [BYTE bp+SectorsPerTrack] - 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 - mov dh,dl ; Head in DH - mov dl,[BYTE bp+BootDrive] ; Drive number in DL - mov ch,al ; Cylinder in CX - ror ah,1 ; Low 8 bits of cylinder in CH, high 2 bits - ror ah,1 ; 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 - - jc PrintDiskError ; If the read failed then abort - - popad - - inc eax ; Increment Sector to Read - - mov dx,es - add dx,byte 20h ; Increment read buffer for next sector - mov es,dx - - loop ReadSectorsCHSLoop ; Read next sector - - ret - - - - -; Displays a disk error message -; And reboots -PrintDiskError: - mov si,msgDiskError ; Bad boot disk message - call PutChars ; Display it - - jmp Reboot - -; Displays a file system error message -; And reboots -PrintFileSystemError: - mov si,msgFileSystemError ; FreeLdr not found 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 - -PutChars: - lodsb - or al,al - jz short Done - mov ah,0eh - mov bx,07h - int 10h - jmp short PutChars -Done: - retn - - - -BiosCHSDriveSize dd 0 - -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 509-($-$$) db 0 ; Pad to 509 bytes - -BootPartition: - db 0 - -BootSignature: - dw 0aa55h ; BootSector signature - - -; End of bootsector -; -; Now starts the extra boot code that we will store -; at sector 14 on a FAT32 volume -; -; To remain multi-boot compatible with other operating -; systems we must not overwrite anything other than -; the bootsector which means we will have to use -; a different sector like 14 to store our extra boot code - - - -StartSearch: - ; Now we must get the first cluster of the root directory - mov eax,DWORD [BYTE bp+RootDirStartCluster] - cmp eax,0ffffff8h ; Check to see if this is the last cluster in the chain - jb ContinueSearch ; If not continue, if so then we didn't find freeldr.sys - jmp PrintFileNotFound -ContinueSearch: - mov bx,2000h - mov es,bx ; Read cluster to [2000:0000h] - call ReadCluster ; Read the cluster - - - ; Now we have to find our way through the root directory to - ; The FREELDR.SYS file - xor bx,bx - mov bl,[BYTE bp+SectsPerCluster] - shl bx,4 ; BX = BX * 512 / 32 - mov ax,2000h ; We loaded at 2000:0000 - mov es,ax - xor di,di - mov si,filename - mov cx,11 - rep cmpsb ; Compare filenames - jz FoundFile ; If same we found it - dec bx - jnz FindFile - jmp PrintFileNotFound - -FindFile: - mov ax,es ; We didn't find it in the previous dir entry - add ax,2 ; So lets move to the next one - mov es,ax ; And search again - xor di,di - mov si,filename - mov cx,11 - rep cmpsb ; Compare filenames - jz FoundFile ; If same we found it - dec bx ; Keep searching till we run out of dir entries - jnz FindFile ; Last entry? - - ; Get the next root dir cluster and try again until we run out of clusters - mov eax,DWORD [BYTE bp+RootDirStartCluster] - call GetFatEntry - mov [BYTE bp+RootDirStartCluster],eax - jmp StartSearch - -FoundFile: - ; Display "Loading FreeLoader..." message - mov si,msgLoading ; Loading message - call PutChars ; Display it - - xor di,di ; ES:DI has dir entry - xor dx,dx - mov ax,WORD [es:di+14h] ; Get start cluster high word - shl eax,16 - mov ax,WORD [es:di+1ah] ; Get start cluster low word - -CheckStartCluster: - cmp eax,2 ; Check and see if the start cluster starts at cluster 2 or above - jnb CheckEndCluster ; If so then continue - jmp PrintFileSystemError ; If not exit with error -CheckEndCluster: - cmp eax,0ffffff8h ; Check and see if the start cluster is and end of cluster chain indicator - jb InitializeLoadSegment ; If not then continue - jmp PrintFileSystemError ; If so exit with error - -InitializeLoadSegment: - mov bx,0F80h ; FREELDR_BASE / 16 - mov es,bx - -LoadFile: - cmp eax,0ffffff8h ; Check to see if this is the last cluster in the chain - jae LoadFileDone ; If so continue, if not then read the next one - push eax - xor bx,bx ; Load ROSLDR starting at 0000:F800h - push es - call ReadCluster - pop es - - xor bx,bx - mov bl,[BYTE bp+SectsPerCluster] - shl bx,5 ; BX = BX * 512 / 16 - mov ax,es ; Increment the load address by - add ax,bx ; The size of a cluster - mov es,ax - - pop eax - push es - call GetFatEntry ; Get the next entry - pop es - - jmp LoadFile ; Load the next cluster (if any) - -LoadFileDone: - mov dl,[BYTE bp+BootDrive] ; Load boot drive into DL - mov dh,[BootPartition] ; Load boot partition into DH - - ; Transfer execution to the bootloader - ;ljmp16 0, FREELDR_BASE - db 0EAh - dw 0F800h - dw 0 - -; Returns the FAT entry for a given cluster number -; On entry EAX has cluster number -; On return EAX has FAT entry for that cluster -GetFatEntry: - - shl eax,2 ; EAX = EAX * 4 (since FAT32 entries are 4 bytes) - mov ecx,eax ; Save this for later in ECX - xor edx,edx - movzx ebx,WORD [BYTE bp+BytesPerSector] - push ebx - div ebx ; FAT Sector Number = EAX / BytesPerSector - movzx ebx,WORD [BYTE bp+ReservedSectors] - add eax,ebx ; FAT Sector Number += ReservedSectors - mov ebx,DWORD [BYTE bp+HiddenSectors] - add eax,ebx ; FAT Sector Number += HiddenSectors - pop ebx - dec ebx - and ecx,ebx ; FAT Offset Within Sector = ECX % BytesPerSector - ; EAX holds logical FAT sector number - ; ECX holds FAT entry offset - - ; Now we have to check the extended flags - ; to see which FAT is the active one - ; and use it, or if they are mirrored then - ; no worries - movzx ebx,WORD [BYTE bp+ExtendedFlags] ; Get extended flags and put into ebx - and bx,0x0f ; Mask off upper 8 bits, now we have active fat in bl - jz LoadFatSector ; If fat is mirrored then skip fat calcs - cmp bl,[BYTE bp+NumberOfFats] ; Compare bl to number of fats - jb GetActiveFatOffset - jmp PrintFileSystemError ; If bl is bigger than numfats exit with error -GetActiveFatOffset: - push eax ; Save logical FAT sector number - mov eax,[BYTE bp+SectorsPerFatBig] ; Get the number of sectors occupied by one fat in eax - mul ebx ; Multiplied by the active FAT index we have in ebx - pop edx ; Get logical FAT sector number - add eax,edx ; Add the current FAT sector offset - -LoadFatSector: - push ecx - - mov bx, 9000h ; We will load it to [9000:0000h] - mov es, bx - - ; EAX holds logical FAT sector number - ; Check if we have already loaded it - cmp eax,DWORD [FatSectorInCache] - je LoadFatSectorAlreadyLoaded - - mov DWORD [FatSectorInCache],eax - xor bx,bx - mov cx,1 - call ReadSectors - -LoadFatSectorAlreadyLoaded: - pop ecx - mov eax,DWORD [es:ecx] ; Get FAT entry - and eax,0fffffffh ; Mask off reserved bits - - ret - -FatSectorInCache: ; This variable tells us which sector we currently have in memory - dd 0ffffffffh ; There is no need to re-read the same sector if we don't have to - - -; Reads cluster number in EAX into [ES:0000] -ReadCluster: - ; StartSector = ((Cluster - 2) * SectorsPerCluster) + ReservedSectors + HiddenSectors; - - dec eax - dec eax - xor edx,edx - movzx ebx,BYTE [BYTE bp+SectsPerCluster] - mul ebx - push eax - xor edx,edx - movzx eax,BYTE [BYTE bp+NumberOfFats] - mul DWORD [BYTE bp+SectorsPerFatBig] - movzx ebx,WORD [BYTE bp+ReservedSectors] - add eax,ebx - add eax,DWORD [BYTE bp+HiddenSectors] - pop ebx - add eax,ebx ; EAX now contains the logical sector number of the cluster - xor bx,bx ; We will load it to [ES:0000], ES loaded before function call - movzx cx,BYTE [BYTE bp+SectsPerCluster] - call ReadSectors - ret - - -; Displays a file not found error message -; And reboots -PrintFileNotFound: - mov si,msgFreeLdr ; FreeLdr not found message - call PutChars ; Display it - mov si,msgAnyKey ; Press any key message - call PutChars ; Display it - - jmp Reboot - -msgFreeLdr db 'freeldr.sys not found',0dh,0ah,0 -filename db 'FREELDR SYS' -msgLoading db 'Loading FreeLoader...',0dh,0ah,0 - - - times 1022-($-$$) db 0 ; Pad to 1022 bytes - - dw 0aa55h ; BootSector signature diff --git a/reactos/boot/freeldr/bootsect/isoboot.S b/reactos/boot/freeldr/bootsect/isoboot.S index c9c3443e66e..76861165dcb 100644 --- a/reactos/boot/freeldr/bootsect/isoboot.S +++ b/reactos/boot/freeldr/bootsect/isoboot.S @@ -1,31 +1,14 @@ /* - * PROJECT: ReactOS Boot Sector for ISO file system (based on ISOLINUX) - * LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation - * PROGRAMMERS: H. Peter Anvin - * Michael K. Ter Louw - * Eric Kohl - * Timo Kreuzer - * Colin Finck - * - ***************************************************************************** - * - * isolinux.asm - * - * A program to boot Linux kernels off a CD-ROM using the El Torito - * boot standard in "no emulation" mode, making the entire filesystem - * available. It is based on the SYSLINUX boot loader for MS-DOS - * floppies. - * - * Copyright 1994-2009 H. Peter Anvin - All Rights Reserved - * Copyright 2009 Intel Corporation *author: H. Peter Anvin - * - * This program is free software *you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, Inc., 53 Temple Place Ste 330, - * Boston MA 02111-1307, USA *either version 2 of the License, or - * (at your option) any later version *incorporated herein by reference. - * - *****************************************************************************/ + * PROJECT: ReactOS Boot Sector for ISO file system (based on ISOLINUX) + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: Booting ReactOS off a CD-ROM using the El Torito boot standard in "no emulation mode" + * COPYRIGHT: Copyright 1994-2009 H. Peter Anvin + * Copyright 2002 Michael K. Ter Louw + * Copyright 2002 Eric Kohl + * Copyright 2009 Intel Corporation *author: H. Peter Anvin + * Copyright 2011 Timo Kreuzer (timo.kreuzer@reactos.org) + * Copyright 2017 Colin Finck (colin@reactos.org) + */ /* INCLUDES ******************************************************************/ #include diff --git a/reactos/boot/freeldr/bootsect/isoboot.asm b/reactos/boot/freeldr/bootsect/isoboot.asm deleted file mode 100644 index 9c0e186e7f0..00000000000 --- a/reactos/boot/freeldr/bootsect/isoboot.asm +++ /dev/null @@ -1,1018 +0,0 @@ -; **************************************************************************** -; -; isolinux.asm -; -; A program to boot Linux kernels off a CD-ROM using the El Torito -; boot standard in "no emulation" mode, making the entire filesystem -; available. It is based on the SYSLINUX boot loader for MS-DOS -; floppies. -; -; Copyright (C) 1994-2001 H. Peter Anvin -; -; This program is free software; you can redistribute it and/or modify -; it under the terms of the GNU General Public License as published by -; the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, -; USA; either version 2 of the License, or (at your option) any later -; version; incorporated herein by reference. -; -; **************************************************************************** -; -; THIS FILE IS A MODIFIED VERSION OF ISOLINUX.ASM -; MODIFICATION DONE BY MICHAEL K TER LOUW -; LAST UPDATED 3-9-2002 -; SEE "COPYING" FOR INFORMATION ABOUT THE LICENSE THAT APPLIES TO THIS RELEASE -; -; **************************************************************************** -; -; This file is a modified version of ISOLINUX.ASM. -; Modification done by Eric Kohl -; Last update 04-25-2002 -; -; **************************************************************************** - -; Note: The Makefile builds one version with DEBUG_MESSAGES automatically. -;%define DEBUG_MESSAGES ; Uncomment to get debugging messages - -%define WAIT_FOR_KEY - - -; --------------------------------------------------------------------------- -; BEGIN THE BIOS/CODE/DATA SEGMENT -; --------------------------------------------------------------------------- - - absolute 0400h -serial_base resw 4 ; Base addresses for 4 serial ports - absolute 0413h -BIOS_fbm resw 1 ; Free Base Memory (kilobytes) - absolute 046Ch -BIOS_timer resw 1 ; Timer ticks - absolute 0472h -BIOS_magic resw 1 ; BIOS reset magic - absolute 0484h -BIOS_vidrows resb 1 ; Number of screen rows - -; -; Memory below this point is reserved for the BIOS and the MBR -; - absolute 1000h -trackbuf resb 8192 ; Track buffer goes here -trackbufsize equ $-trackbuf -; trackbuf ends at 3000h - - struc open_file_t -file_sector resd 1 ; Sector pointer (0 = structure free) -file_left resd 1 ; Number of sectors left - endstruc - - struc dir_t -dir_lba resd 1 ; Directory start (LBA) -dir_len resd 1 ; Length in bytes -dir_clust resd 1 ; Length in clusters - endstruc - - -MAX_OPEN_LG2 equ 2 ; log2(Max number of open files) -MAX_OPEN equ (1 << MAX_OPEN_LG2) -SECTORSIZE_LG2 equ 11 ; 2048 bytes/sector (El Torito requirement) -SECTORSIZE equ (1 << SECTORSIZE_LG2) -CR equ 13 ; Carriage Return -LF equ 10 ; Line Feed -retry_count equ 6 ; How patient are we with the BIOS? - - - - absolute 5000h ; Here we keep our BSS stuff - -DriveNo resb 1 ; CD-ROM BIOS drive number -DiskError resb 1 ; Error code for disk I/O -RetryCount resb 1 ; Used for disk access retries -TimeoutCount resb 1 ; Timeout counter -ISOFlags resb 1 ; Flags for ISO directory search -RootDir resb dir_t_size ; Root directory -CurDir resb dir_t_size ; Current directory -ISOFileName resb 64 ; ISO filename canonicalization buffer -ISOFileNameEnd equ $ - - - alignb open_file_t_size -Files resb MAX_OPEN*open_file_t_size - - - - section .text - org 7000h - -start: - cli ; Disable interrupts - xor ax, ax ; ax = segment zero - mov ss, ax ; Initialize stack segment - mov sp, start ; Set up stack - mov ds, ax ; Initialize other segment registers - mov es, ax - mov fs, ax - mov gs, ax - sti ; Enable interrupts - cld ; Increment pointers - - mov cx, 2048 >> 2 ; Copy the bootsector - mov si, 0x7C00 ; from 0000:7C00 - mov di, 0x7000 ; to 0000:7000 - rep movsd ; copy the program - jmp 0:relocate ; jump into relocated code - -relocate: - ; Display the banner and copyright -%ifdef DEBUG_MESSAGES - mov si, isolinux_banner ; si points to hello message - call writestr ; display the message - mov si,copyright_str - call writestr -%endif - - - ; Make sure the keyboard buffer is empty -%ifdef WAIT_FOR_KEY - call pollchar_and_empty - - ; Check for MBR on harddisk - pusha - mov ax, 0201h - mov dx, 0080h - mov cx, 0001h - mov bx, trackbuf - int 13h - popa - jc .boot_cdrom ; could not read hdd - - push ax - mov ax, word [trackbuf] - cmp ax, 0 - je .boot_cdrom ; no boot sector found (hopefully there are no weird bootsectors which begin with 0) - pop ax - - ; Display the 'Press key' message and wait for a maximum of 5 seconds - call crlf - mov si, presskey_msg ; si points to 'Press key' message - call writestr ; display the message - - mov byte [TimeoutCount], 5 -.next_second: - mov eax, [BIOS_timer] ; load current tick counter - add eax, 19 ; - -.poll_again: - call pollchar_and_empty - jnz .boot_cdrom - - mov ebx, [BIOS_timer] - cmp eax, ebx - jnz .poll_again - - mov si, dot_msg ; print '.' - call writestr - dec byte [TimeoutCount] ; decrement timeout counter - jz .boot_harddisk - jmp .next_second - -.boot_harddisk: - call crlf - - ; Boot first harddisk (drive 0x80) - mov ax, 0201h - mov dx, 0080h - mov cx, 0001h - mov bx, 7C00h - int 13h - jnc .go_hd - jmp kaboom -.go_hd: - mov ax, cs - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov dx, 0080h - - jmp 0:0x7C00 -%endif - -.boot_cdrom: -%ifdef WAIT_FOR_KEY - call crlf - call crlf -%endif - - ; Save and display the boot drive number - mov [DriveNo], dl -%ifdef DEBUG_MESSAGES - mov si, startup_msg - call writemsg - mov al, dl - call writehex2 - call crlf -%endif - - ; Now figure out what we're actually doing - ; Note: use passed-in DL value rather than 7Fh because - ; at least some BIOSes will get the wrong value otherwise - mov ax, 4B01h ; Get disk emulation status - mov dl, [DriveNo] - mov si, spec_packet - int 13h - jc near spec_query_failed ; Shouldn't happen (BIOS bug) - mov dl, [DriveNo] - cmp [sp_drive], dl ; Should contain the drive number - jne near spec_query_failed - -%ifdef DEBUG_MESSAGES - mov si, spec_ok_msg - call writemsg - mov al, byte [sp_drive] - call writehex2 - call crlf -%endif - -found_drive: - ; Get drive information - mov ah, 48h - mov dl, [DriveNo] - mov si, drive_params - int 13h - jnc params_ok - - ; mov si, nosecsize_msg No use in reporting this - ; call writemsg - -params_ok: - ; Check for the sector size (should be 2048, but - ; some BIOSes apparently think we're 512-byte media) - ; - ; FIX: We need to check what the proper behaviour - ; is for getlinsec when the BIOS thinks the sector - ; size is 512!!! For that, we need such a BIOS, though... -%ifdef DEBUG_MESSAGES - mov si, secsize_msg - call writemsg - mov ax, [dp_secsize] - call writehex4 - call crlf -%endif - - - ; - ; Clear Files structures - ; - mov di, Files - mov cx, (MAX_OPEN*open_file_t_size)/4 - xor eax, eax - rep stosd - - ; - ; Now, we need to sniff out the actual filesystem data structures. - ; mkisofs gave us a pointer to the primary volume descriptor - ; (which will be at 16 only for a single-session disk!); from the PVD - ; we should be able to find the rest of what we need to know. - ; -get_fs_structures: - mov eax, 16 ; Primary Volume Descriptor (sector 16) - mov bx, trackbuf - call getonesec - - mov eax, [trackbuf+156+2] - mov [RootDir+dir_lba],eax - mov [CurDir+dir_lba],eax -%ifdef DEBUG_MESSAGES - mov si, rootloc_msg - call writemsg - call writehex8 - call crlf -%endif - - mov eax,[trackbuf+156+10] - mov [RootDir+dir_len],eax - mov [CurDir+dir_len],eax -%ifdef DEBUG_MESSAGES - mov si, rootlen_msg - call writemsg - call writehex8 - call crlf -%endif - add eax,SECTORSIZE-1 - shr eax,SECTORSIZE_LG2 - mov [RootDir+dir_clust],eax - mov [CurDir+dir_clust],eax -%ifdef DEBUG_MESSAGES - mov si, rootsect_msg - call writemsg - call writehex8 - call crlf -%endif - - ; Look for the "REACTOS" directory, and if found, - ; make it the current directory instead of the root - ; directory. - mov di,isolinux_dir - mov al,02h ; Search for a directory - call searchdir_iso - jnz .dir_found - mov si,no_dir_msg - call writemsg - jmp kaboom - -.dir_found: - mov [CurDir+dir_len],eax - mov eax,[si+file_left] - mov [CurDir+dir_clust],eax - xor eax,eax ; Free this file pointer entry - xchg eax,[si+file_sector] - mov [CurDir+dir_lba],eax - - - mov di, isolinux_bin ; di points to Isolinux filename - call searchdir ; look for the file - jnz .isolinux_opened ; got the file - mov si, no_isolinux_msg ; si points to error message - call writemsg ; display the message - jmp kaboom ; fail boot - -.isolinux_opened: - mov di, si ; save file pointer - -%ifdef DEBUG_MESSAGES - mov si, filelen_msg - call writemsg - call writehex8 - call crlf -%endif - - mov ecx, eax ; calculate sector count - shr ecx, 11 - test eax, 0x7FF - jz .full_sector - inc ecx -.full_sector: - -%ifdef DEBUG_MESSAGES - mov eax, ecx - mov si, filesect_msg - call writemsg - call writehex8 - call crlf -%endif - -; use high segment, as some bios can fail, when offset is too big - mov bx, 0x0F80 ; FREELDR_BASE / 16 ; es = load segment - mov es, bx - xor ebx, ebx ; bx = load offset - mov si, di ; restore file pointer - mov cx, 0xFFFF ; load the whole file - call getfssec ; get the whole file - -%ifdef DEBUG_MESSAGES - mov si, startldr_msg - call writemsg - call crlf -%endif - - mov dl, [DriveNo] ; dl = boot drive - mov dh, 0 ; dh = boot partition - - ; Transfer execution to the bootloader - ;ljmp16 0, FREELDR_BASE - db 0xEA - dw 0xF800 - dw 0 - -; -; searchdir: -; -; Open a file -; -; On entry: -; DS:DI = filename -; If successful: -; ZF clear -; SI = file pointer -; DX:AX or EAX = file length in bytes -; If unsuccessful -; ZF set -; - -; -; searchdir_iso is a special entry point for ISOLINUX only. In addition -; to the above, searchdir_iso passes a file flag mask in AL. This is useful -; for searching for directories. -; -alloc_failure: - xor ax,ax ; ZF <- 1 - ret - -searchdir: - xor al,al -searchdir_iso: - mov [ISOFlags],al - call allocate_file ; Temporary file structure for directory - jnz alloc_failure - push es - push ds - pop es ; ES = DS - mov si,CurDir - cmp byte [di],'\' ; If filename begins with slash - jne .not_rooted - inc di ; Skip leading slash - mov si,RootDir ; Reference root directory instead -.not_rooted: - mov eax,[si+dir_clust] - mov [bx+file_left],eax - mov eax,[si+dir_lba] - mov [bx+file_sector],eax - mov edx,[si+dir_len] - -.look_for_slash: - mov ax,di -.scan: - mov cl,[di] - inc di - and cl,cl - jz .isfile - cmp cl,'\' - jne .scan - mov [di-1],byte 0 ; Terminate at directory name - mov cl,02h ; Search for directory - xchg cl,[ISOFlags] - push di - push cx - push word .resume ; Where to "return" to - push es -.isfile: - xchg ax,di - -.getsome: - ; Get a chunk of the directory - mov si,trackbuf - pushad - xchg bx,si - mov cx,1 ; load one sector - call getfssec - popad - -.compare: - movzx eax, byte [si] ; Length of directory entry - cmp al, 33 - jb .next_sector - mov cl, [si+25] - xor cl, [ISOFlags] - test cl, byte 8Eh ; Unwanted file attributes! - jnz .not_file - pusha - movzx cx, byte [si+32] ; File identifier length - add si, byte 33 ; File identifier offset - call iso_compare_names - popa - je .success -.not_file: - sub edx, eax ; Decrease bytes left - jbe .failure - add si, ax ; Advance pointer - -.check_overrun: - ; Did we finish the buffer? - cmp si, trackbuf+trackbufsize - jb .compare ; No, keep going - - jmp short .getsome ; Get some more directory - -.next_sector: - ; Advance to the beginning of next sector - lea ax, [si+SECTORSIZE-1] - and ax, ~(SECTORSIZE-1) - sub ax, si - jmp short .not_file ; We still need to do length checks - -.failure: -%ifdef DEBUG_MESSAGES - mov si, findfail_msg - call writemsg - call crlf -%endif - xor eax, eax ; ZF = 1 - mov [bx+file_sector], eax - pop es - ret - -.success: - mov eax, [si+2] ; Location of extent - mov [bx+file_sector], eax - mov eax, [si+10] ; Data length - push eax - add eax, SECTORSIZE-1 - shr eax, SECTORSIZE_LG2 - mov [bx+file_left], eax - pop eax - mov edx, eax - shr edx, 16 - and bx, bx ; ZF = 0 - mov si, bx - pop es - ret - -.resume: - ; We get here if we were only doing part of a lookup - ; This relies on the fact that .success returns bx == si - xchg edx, eax ; Directory length in edx - pop cx ; Old ISOFlags - pop di ; Next filename pointer - - mov byte [di-1], '\' ; restore the backslash in the filename - - mov [ISOFlags], cl ; Restore the flags - jz .failure ; Did we fail? If so fail for real! - jmp .look_for_slash ; Otherwise, next level - -; -; allocate_file: Allocate a file structure -; -; If successful: -; ZF set -; BX = file pointer -; In unsuccessful: -; ZF clear -; -allocate_file: - push cx - mov bx, Files - mov cx, MAX_OPEN -.check: - cmp dword [bx], byte 0 - je .found - add bx, open_file_t_size ; ZF = 0 - loop .check - ; ZF = 0 if we fell out of the loop -.found: - pop cx - ret - -; -; iso_compare_names: -; Compare the names DS:SI and DS:DI and report if they are -; equal from an ISO 9660 perspective. SI is the name from -; the filesystem; CX indicates its length, and ';' terminates. -; DI is expected to end with a null. -; -; Note: clobbers AX, CX, SI, DI; assumes DS == ES == base segment -; -iso_compare_names: - ; First, terminate and canonicalize input filename - push di - mov di, ISOFileName -.canon_loop: - jcxz .canon_end - lodsb - dec cx - cmp al, ';' - je .canon_end - and al, al - je .canon_end - stosb - cmp di, ISOFileNameEnd-1 ; Guard against buffer overrun - jb .canon_loop -.canon_end: - cmp di, ISOFileName - jbe .canon_done - cmp byte [di-1], '.' ; Remove terminal dots - jne .canon_done - dec di - jmp short .canon_end -.canon_done: - mov [di], byte 0 ; Null-terminate string - pop di - mov si, ISOFileName -.compare: - lodsb - mov ah, [di] - inc di - and ax, ax - jz .success ; End of string for both - and al, al ; Is either one end of string? - jz .failure ; If so, failure - and ah, ah - jz .failure - or ax, 2020h ; Convert to lower case - cmp al, ah - je .compare -.failure: - and ax, ax ; ZF = 0 (at least one will be nonzero) -.success: - ret - - - - - - - -; -; getfssec: Get multiple clusters from a file, given the file pointer. -; -; On entry: -; ES:BX -> Buffer -; SI -> File pointer -; CX -> Cluster count; 0FFFFh = until end of file -; On exit: -; SI -> File pointer (or 0 on EOF) -; CF = 1 -> Hit EOF -; -getfssec: - cmp cx, [si+file_left] - jna .ok_size - mov cx, [si+file_left] - -.ok_size: - mov bp, cx - push cx - push si - mov eax, [si+file_sector] - call getlinsec - xor ecx, ecx - pop si - pop cx - - add [si+file_sector], ecx - sub [si+file_left], ecx - ja .not_eof ; CF = 0 - - xor ecx, ecx - mov [si+file_sector], ecx ; Mark as unused - xor si,si - stc - -.not_eof: - ret - - - -; INT 13h, AX=4B01h, DL= failed. -; Try to scan the entire 80h-FFh from the end. -spec_query_failed: - mov si,spec_err_msg - call writemsg - - mov dl, 0FFh -.test_loop: - pusha - mov ax, 4B01h - mov si, spec_packet - mov byte [si], 13 ; Size of buffer - int 13h - popa - jc .still_broken - - mov si, maybe_msg - call writemsg - mov al, dl - call writehex2 - call crlf - - cmp byte [sp_drive], dl - jne .maybe_broken - - ; Okay, good enough... - mov si, alright_msg - call writemsg - mov [DriveNo], dl -.found_drive: - jmp found_drive - - ; Award BIOS 4.51 apparently passes garbage in sp_drive, - ; but if this was the drive number originally passed in - ; DL then consider it "good enough" -.maybe_broken: - cmp byte [DriveNo], dl - je .found_drive - -.still_broken: - dec dx - cmp dl, 80h - jnb .test_loop - -fatal_error: - mov si, nothing_msg - call writemsg - -.norge: - jmp short .norge - - - - ; Information message (DS:SI) output - ; Prefix with "isolinux: " - ; -writemsg: - push ax - push si - mov si, isolinux_str - call writestr - pop si - call writestr - pop ax - ret - -; -; crlf: Print a newline -; -crlf: - mov si, crlf_msg - ; Fall through - -; -; writestr: write a null-terminated string to the console, saving -; registers on entry. -; -writestr: - pushfd - pushad -.top: - lodsb - and al, al - jz .end - call writechr - jmp short .top -.end: - popad - popfd - ret - - -; -; writehex[248]: Write a hex number in (AL, AX, EAX) to the console -; -writehex2: - pushfd - pushad - shl eax, 24 - mov cx, 2 - jmp short writehex_common -writehex4: - pushfd - pushad - shl eax, 16 - mov cx, 4 - jmp short writehex_common -writehex8: - pushfd - pushad - mov cx, 8 -writehex_common: -.loop: - rol eax, 4 - push eax - and al, 0Fh - cmp al, 10 - jae .high -.low: - add al, '0' - jmp short .ischar -.high: - add al, 'A'-10 -.ischar: - call writechr - pop eax - loop .loop - popad - popfd - ret - -; -; Write a character to the screen. There is a more "sophisticated" -; version of this in the subsequent code, so we patch the pointer -; when appropriate. -; - -writechr: - pushfd - pushad - mov ah, 0Eh - xor bx, bx - int 10h - popad - popfd - ret - -; -; Get one sector. Convenience entry point. -; -getonesec: - mov bp, 1 - ; Fall through to getlinsec - -; -; Get linear sectors - EBIOS LBA addressing, 2048-byte sectors. -; -; Note that we can't always do this as a single request, because at least -; Phoenix BIOSes has a 127-sector limit. To be on the safe side, stick -; to 32 sectors (64K) per request. -; -; Input: -; EAX - Linear sector number -; ES:BX - Target buffer -; BP - Sector count -; -getlinsec: - mov si,dapa ; Load up the DAPA - mov [si+4],bx - mov bx,es - mov [si+6],bx - mov [si+8],eax -.loop2: - push bp ; Sectors left - cmp bp,[MaxTransfer] - jbe .bp_ok - mov bp,[MaxTransfer] -.bp_ok: - mov [si+2],bp - push si - mov dl,[DriveNo] - mov ah,42h ; Extended Read - call xint13 - pop si - pop bp - movzx eax,word [si+2] ; Sectors we read - add [si+8],eax ; Advance sector pointer - sub bp,ax ; Sectors left - shl ax,SECTORSIZE_LG2-4 ; 2048-byte sectors -> segment - add [si+6],ax ; Advance buffer pointer - and bp,bp - jnz .loop2 - mov eax,[si+8] ; Next sector - ret - - ; INT 13h with retry -xint13: - mov byte [RetryCount], retry_count -.try: - pushad - int 13h - jc .error - add sp, byte 8*4 ; Clean up stack - ret -.error: - mov [DiskError], ah ; Save error code - popad - dec byte [RetryCount] - jz .real_error - push ax - mov al,[RetryCount] - mov ah,[dapa+2] ; Sector transfer count - cmp al,2 ; Only 2 attempts left - ja .nodanger - mov ah,1 ; Drop transfer size to 1 - jmp short .setsize -.nodanger: - cmp al,retry_count-2 - ja .again ; First time, just try again - shr ah,1 ; Otherwise, try to reduce - adc ah,0 ; the max transfer size, but not to 0 -.setsize: - mov [MaxTransfer],ah - mov [dapa+2],ah -.again: - pop ax - jmp .try - -.real_error: - mov si, diskerr_msg - call writemsg - mov al, [DiskError] - call writehex2 - mov si, ondrive_str - call writestr - mov al, dl - call writehex2 - call crlf - ; Fall through to kaboom - -; -; kaboom: write a message and bail out. Wait for a user keypress, -; then do a hard reboot. -; -kaboom: - mov ax, cs - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - sti - mov si, err_bootfailed - call writestr - xor ax, ax ; Wait for keypress - int 16h - cli - mov word [BIOS_magic], 0 ; Cold reboot - jmp 0F000h:0FFF0h ; Reset vector address - - -; -; pollchar_and_empty: check if we have an input character pending (ZF = 0) and empty the input buffer afterwards -; -pollchar_and_empty: - pushad - mov ah, 1 ; Did the user press a key? - int 16h - jz .end ; No, then we're done - mov ah, 0 ; Otherwise empty the buffer by reading it - int 16h -.end: - popad - ret - - - -isolinux_banner db CR, LF, 'Loading IsoBoot...', CR, LF, 0 -copyright_str db ' (C) 1994-2002 H. Peter Anvin', CR, LF, 0 -presskey_msg db 'Press any key to boot from CD', 0 -dot_msg db '.',0 - -%ifdef DEBUG_MESSAGES -startup_msg: db 'Startup, DL = ', 0 -spec_ok_msg: db 'packet OK, drive = ', 0 -secsize_msg: db 'size appears to be ', 0 -rootloc_msg: db 'Root dir loc: ', 0 -rootlen_msg: db 'Root dir len: ', 0 -rootsect_msg: db 'Root dir len(sect): ', 0 -fileloc_msg: db 'SETUPLDR loc: ', 0 -filelen_msg: db 'SETUPLDR len: ', 0 -filesect_msg: db 'SETUPLDR len(sect): ', 0 -findfail_msg: db 'Failed to find file!', 0 -startldr_msg: db 'Starting SETUPLDR.SYS', 0 -%endif - -; nosecsize_msg: db 'No sector size, assume 0800', CR, LF, 0 -spec_err_msg: db 'Load spec failed, trying wing ...', CR, LF, 0 -maybe_msg: db 'Found smth at drive = ', 0 -alright_msg: db 'might be ok, continuing...', CR, LF, 0 -nothing_msg: db 'Failed locate CD-ROM; boot failed.', CR, LF, 0 -isolinux_str db 'IsoBoot: ', 0 -crlf_msg db CR, LF, 0 -diskerr_msg: db 'Disk error ', 0 -ondrive_str: db ', drive ', 0 -err_bootfailed db CR, LF, 'failed..', 0 -isolinux_dir db '\LOADER', 0 -no_dir_msg db 'LOADER dir not found.', CR, LF, 0 -isolinux_bin db 'SETUPLDR.SYS', 0 -no_isolinux_msg db 'SETUPLDR not found.', CR, LF, 0 - -; -; El Torito spec packet -; - align 8, db 0 -spec_packet: db 13h ; Size of packet -sp_media: db 0 ; Media type -sp_drive: db 0 ; Drive number -sp_controller: db 0 ; Controller index -sp_lba: dd 0 ; LBA for emulated disk image -sp_devspec: dw 0 ; IDE/SCSI information -sp_buffer: dw 0 ; User-provided buffer -sp_loadseg: dw 0 ; Load segment -sp_sectors: dw 0 ; Sector count -sp_chs: db 0,0,0 ; Simulated CHS geometry -sp_dummy: db 0 ; Scratch, safe to overwrite - -; -; EBIOS drive parameter packet -; - align 8, db 0 -drive_params: dw 30 ; Buffer size -dp_flags: dw 0 ; Information flags -dp_cyl: dd 0 ; Physical cylinders -dp_head: dd 0 ; Physical heads -dp_sec: dd 0 ; Physical sectors/track -dp_totalsec: dd 0,0 ; Total sectors -dp_secsize: dw 0 ; Bytes per sector -dp_dpte: dd 0 ; Device Parameter Table -dp_dpi_key: dw 0 ; 0BEDDh if rest valid -dp_dpi_len: db 0 ; DPI len - db 0 - dw 0 -dp_bus: times 4 db 0 ; Host bus type -dp_interface: times 8 db 0 ; Interface type -db_i_path: dd 0,0 ; Interface path -db_d_path: dd 0,0 ; Device path - db 0 -db_dpi_csum: db 0 ; Checksum for DPI info - -; -; EBIOS disk address packet -; - align 8, db 0 -dapa: dw 16 ; Packet size -.count: dw 0 ; Block count -.off: dw 0 ; Offset of buffer -.seg: dw 0 ; Segment of buffer -.lba: dd 0 ; LBA (LSW) - dd 0 ; LBA (MSW) - - alignb 4, db 0 -MaxTransfer dw 2 ;32 ; Max sectors per transfer - - times 2046-($-$$) db 0 ; Pad to file offset 2046 - dw 0aa55h ; BootSector signature diff --git a/reactos/boot/freeldr/bootsect/isobtrt.asm b/reactos/boot/freeldr/bootsect/isobtrt.asm deleted file mode 100644 index 5191ac8f594..00000000000 --- a/reactos/boot/freeldr/bootsect/isobtrt.asm +++ /dev/null @@ -1,984 +0,0 @@ -; **************************************************************************** -; -; isolinux.asm -; -; A program to boot Linux kernels off a CD-ROM using the El Torito -; boot standard in "no emulation" mode, making the entire filesystem -; available. It is based on the SYSLINUX boot loader for MS-DOS -; floppies. -; -; Copyright (C) 1994-2001 H. Peter Anvin -; -; This program is free software; you can redistribute it and/or modify -; it under the terms of the GNU General Public License as published by -; the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, -; USA; either version 2 of the License, or (at your option) any later -; version; incorporated herein by reference. -; -; **************************************************************************** -; -; THIS FILE IS A MODIFIED VERSION OF ISOLINUX.ASM -; MODIFICATION DONE BY MICHAEL K TER LOUW -; LAST UPDATED 3-9-2002 -; SEE "COPYING" FOR INFORMATION ABOUT THE LICENSE THAT APPLIES TO THIS RELEASE -; -; **************************************************************************** -; -; This file is a modified version of ISOLINUX.ASM. -; Modification done by Eric Kohl -; Last update 04-25-2002 -; -; **************************************************************************** -; -; This file is a modified version of ISOLINUX.ASM. -; (for ReactOS regression testing) -; Modification done by Christoph von Wittich -; Last update 08-27-2006 -; -; **************************************************************************** - - -; Note: The Makefile builds one version with DEBUG_MESSAGES automatically. -;%define DEBUG_MESSAGES ; Uncomment to get debugging messages - - -; --------------------------------------------------------------------------- -; BEGIN THE BIOS/CODE/DATA SEGMENT -; --------------------------------------------------------------------------- - - absolute 0400h -serial_base resw 4 ; Base addresses for 4 serial ports - absolute 0413h -BIOS_fbm resw 1 ; Free Base Memory (kilobytes) - absolute 046Ch -BIOS_timer resw 1 ; Timer ticks - absolute 0472h -BIOS_magic resw 1 ; BIOS reset magic - absolute 0484h -BIOS_vidrows resb 1 ; Number of screen rows - -; -; Memory below this point is reserved for the BIOS and the MBR -; - absolute 1000h -trackbuf resb 8192 ; Track buffer goes here -trackbufsize equ $-trackbuf -; trackbuf ends at 3000h - - struc open_file_t -file_sector resd 1 ; Sector pointer (0 = structure free) -file_left resd 1 ; Number of sectors left - endstruc - - struc dir_t -dir_lba resd 1 ; Directory start (LBA) -dir_len resd 1 ; Length in bytes -dir_clust resd 1 ; Length in clusters - endstruc - - -MAX_OPEN_LG2 equ 2 ; log2(Max number of open files) -MAX_OPEN equ (1 << MAX_OPEN_LG2) -SECTORSIZE_LG2 equ 11 ; 2048 bytes/sector (El Torito requirement) -SECTORSIZE equ (1 << SECTORSIZE_LG2) -CR equ 13 ; Carriage Return -LF equ 10 ; Line Feed -retry_count equ 6 ; How patient are we with the BIOS? - - - - absolute 5000h ; Here we keep our BSS stuff - -DriveNo resb 1 ; CD-ROM BIOS drive number -DiskError resb 1 ; Error code for disk I/O -RetryCount resb 1 ; Used for disk access retries -TimeoutCount resb 1 ; Timeout counter -ISOFlags resb 1 ; Flags for ISO directory search -RootDir resb dir_t_size ; Root directory -CurDir resb dir_t_size ; Current directory -ISOFileName resb 64 ; ISO filename canonicalization buffer -ISOFileNameEnd equ $ - - - alignb open_file_t_size -Files resb MAX_OPEN*open_file_t_size - - - - section .text - org 7000h - -start: - cli ; Disable interrupts - xor ax, ax ; ax = segment zero - mov ss, ax ; Initialize stack segment - mov sp, start ; Set up stack - mov ds, ax ; Initialize other segment registers - mov es, ax - mov fs, ax - mov gs, ax - sti ; Enable interrupts - cld ; Increment pointers - - mov cx, 2048 >> 2 ; Copy the bootsector - mov si, 0x7C00 ; from 0000:7C00 - mov di, 0x7000 ; to 0000:7000 - rep movsd ; copy the program - jmp 0:relocate ; jump into relocated code - -relocate: - ; Display the banner and copyright -%ifdef DEBUG_MESSAGES - mov si, isolinux_banner ; si points to hello message - call writestr ; display the message - mov si,copyright_str - call writestr -%endif - -; check if there is a mbr on the hdd if so boot from it - - pusha - mov ax, 0201h - mov dx, 0080h - mov cx, 0001h - mov bx, trackbuf - int 13h - popa - jc .boot_cdrom ; could not read hdd - - push ax - mov ax, word [trackbuf+510] - cmp ax, 0 - je .boot_cdrom ; no boot sector found (hopefully there are no weird bootsectors which begin with 0) - pop ax - -.boot_harddisk: - call crlf - - ; Boot first harddisk (drive 0x80) - mov ax, 0201h - mov dx, 0080h - mov cx, 0001h - mov bx, 7C00h - int 13h - jnc .go_hd - jmp kaboom -.go_hd: - mov ax, cs - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov dx, 0080h - - jmp 0:0x7C00 - -.boot_cdrom: - ; Save and display the boot drive number - mov [DriveNo], dl -%ifdef DEBUG_MESSAGES - mov si, startup_msg - call writemsg - mov al, dl - call writehex2 - call crlf -%endif - - ; Now figure out what we're actually doing - ; Note: use passed-in DL value rather than 7Fh because - ; at least some BIOSes will get the wrong value otherwise - mov ax, 4B01h ; Get disk emulation status - mov dl, [DriveNo] - mov si, spec_packet - int 13h - jc near spec_query_failed ; Shouldn't happen (BIOS bug) - mov dl, [DriveNo] - cmp [sp_drive], dl ; Should contain the drive number - jne near spec_query_failed - -%ifdef DEBUG_MESSAGES - mov si, spec_ok_msg - call writemsg - mov al, byte [sp_drive] - call writehex2 - call crlf -%endif - -found_drive: - ; Get drive information - mov ah, 48h - mov dl, [DriveNo] - mov si, drive_params - int 13h - jnc params_ok - - ; mov si, nosecsize_msg No use in reporting this - ; call writemsg - -params_ok: - ; Check for the sector size (should be 2048, but - ; some BIOSes apparently think we're 512-byte media) - ; - ; FIX: We need to check what the proper behaviour - ; is for getlinsec when the BIOS thinks the sector - ; size is 512!!! For that, we need such a BIOS, though... -%ifdef DEBUG_MESSAGES - mov si, secsize_msg - call writemsg - mov ax, [dp_secsize] - call writehex4 - call crlf -%endif - - - ; - ; Clear Files structures - ; - mov di, Files - mov cx, (MAX_OPEN*open_file_t_size)/4 - xor eax, eax - rep stosd - - ; - ; Now, we need to sniff out the actual filesystem data structures. - ; mkisofs gave us a pointer to the primary volume descriptor - ; (which will be at 16 only for a single-session disk!); from the PVD - ; we should be able to find the rest of what we need to know. - ; -get_fs_structures: - mov eax, 16 ; Primary Volume Descriptor (sector 16) - mov bx, trackbuf - call getonesec - - mov eax, [trackbuf+156+2] - mov [RootDir+dir_lba],eax - mov [CurDir+dir_lba],eax -%ifdef DEBUG_MESSAGES - mov si, rootloc_msg - call writemsg - call writehex8 - call crlf -%endif - - mov eax,[trackbuf+156+10] - mov [RootDir+dir_len],eax - mov [CurDir+dir_len],eax -%ifdef DEBUG_MESSAGES - mov si, rootlen_msg - call writemsg - call writehex8 - call crlf -%endif - add eax,SECTORSIZE-1 - shr eax,SECTORSIZE_LG2 - mov [RootDir+dir_clust],eax - mov [CurDir+dir_clust],eax -%ifdef DEBUG_MESSAGES - mov si, rootsect_msg - call writemsg - call writehex8 - call crlf -%endif - - ; Look for the "REACTOS" directory, and if found, - ; make it the current directory instead of the root - ; directory. - mov di,isolinux_dir - mov al,02h ; Search for a directory - call searchdir_iso - jnz .dir_found - mov si,no_dir_msg - call writemsg - jmp kaboom - -.dir_found: - mov [CurDir+dir_len],eax - mov eax,[si+file_left] - mov [CurDir+dir_clust],eax - xor eax,eax ; Free this file pointer entry - xchg eax,[si+file_sector] - mov [CurDir+dir_lba],eax - - - mov di, isolinux_bin ; di points to Isolinux filename - call searchdir ; look for the file - jnz .isolinux_opened ; got the file - mov si, no_isolinux_msg ; si points to error message - call writemsg ; display the message - jmp kaboom ; fail boot - -.isolinux_opened: - mov di, si ; save file pointer - -%ifdef DEBUG_MESSAGES - mov si, filelen_msg - call writemsg - call writehex8 - call crlf -%endif - - mov ecx, eax ; calculate sector count - shr ecx, 11 - test eax, 0x7FF - jz .full_sector - inc ecx -.full_sector: - -%ifdef DEBUG_MESSAGES - mov eax, ecx - mov si, filesect_msg - call writemsg - call writehex8 - call crlf -%endif - -; use high segment, as some bios can fail, when offset is too big - mov bx, 0x0F80 ; FREELDR_BASE / 16 ; es = load segment - mov es, bx - xor ebx, ebx ; bx = load offset - mov si, di ; restore file pointer - mov cx, 0xFFFF ; load the whole file - call getfssec ; get the whole file - -%ifdef DEBUG_MESSAGES - mov si, startldr_msg - call writemsg - call crlf -%endif - - mov dl, [DriveNo] ; dl = boot drive - mov dh, 0 ; dh = boot partition - - ; Transfer execution to the bootloader - ;ljmp16 0, FREELDR_BASE - db 0xEA - dw 0xF800 - dw 0 - -; -; searchdir: -; -; Open a file -; -; On entry: -; DS:DI = filename -; If successful: -; ZF clear -; SI = file pointer -; DX:AX or EAX = file length in bytes -; If unsuccessful -; ZF set -; - -; -; searchdir_iso is a special entry point for ISOLINUX only. In addition -; to the above, searchdir_iso passes a file flag mask in AL. This is useful -; for searching for directories. -; -alloc_failure: - xor ax,ax ; ZF <- 1 - ret - -searchdir: - xor al,al -searchdir_iso: - mov [ISOFlags],al - call allocate_file ; Temporary file structure for directory - jnz alloc_failure - push es - push ds - pop es ; ES = DS - mov si,CurDir - cmp byte [di],'\' ; If filename begins with slash - jne .not_rooted - inc di ; Skip leading slash - mov si,RootDir ; Reference root directory instead -.not_rooted: - mov eax,[si+dir_clust] - mov [bx+file_left],eax - mov eax,[si+dir_lba] - mov [bx+file_sector],eax - mov edx,[si+dir_len] - -.look_for_slash: - mov ax,di -.scan: - mov cl,[di] - inc di - and cl,cl - jz .isfile - cmp cl,'\' - jne .scan - mov [di-1],byte 0 ; Terminate at directory name - mov cl,02h ; Search for directory - xchg cl,[ISOFlags] - push di - push cx - push word .resume ; Where to "return" to - push es -.isfile: - xchg ax,di - -.getsome: - ; Get a chunk of the directory - mov si,trackbuf - pushad - xchg bx,si - mov cx,1 ; load one sector - call getfssec - popad - -.compare: - movzx eax, byte [si] ; Length of directory entry - cmp al, 33 - jb .next_sector - mov cl, [si+25] - xor cl, [ISOFlags] - test cl, byte 8Eh ; Unwanted file attributes! - jnz .not_file - pusha - movzx cx, byte [si+32] ; File identifier length - add si, byte 33 ; File identifier offset - call iso_compare_names - popa - je .success -.not_file: - sub edx, eax ; Decrease bytes left - jbe .failure - add si, ax ; Advance pointer - -.check_overrun: - ; Did we finish the buffer? - cmp si, trackbuf+trackbufsize - jb .compare ; No, keep going - - jmp short .getsome ; Get some more directory - -.next_sector: - ; Advance to the beginning of next sector - lea ax, [si+SECTORSIZE-1] - and ax, ~(SECTORSIZE-1) - sub ax, si - jmp short .not_file ; We still need to do length checks - -.failure: -%ifdef DEBUG_MESSAGES - mov si, findfail_msg - call writemsg - call crlf -%endif - xor eax, eax ; ZF = 1 - mov [bx+file_sector], eax - pop es - ret - -.success: - mov eax, [si+2] ; Location of extent - mov [bx+file_sector], eax - mov eax, [si+10] ; Data length - push eax - add eax, SECTORSIZE-1 - shr eax, SECTORSIZE_LG2 - mov [bx+file_left], eax - pop eax - mov edx, eax - shr edx, 16 - and bx, bx ; ZF = 0 - mov si, bx - pop es - ret - -.resume: - ; We get here if we were only doing part of a lookup - ; This relies on the fact that .success returns bx == si - xchg edx, eax ; Directory length in edx - pop cx ; Old ISOFlags - pop di ; Next filename pointer - - mov byte [di-1], '\' ; restore the backslash in the filename - - mov [ISOFlags], cl ; Restore the flags - jz .failure ; Did we fail? If so fail for real! - jmp .look_for_slash ; Otherwise, next level - -; -; allocate_file: Allocate a file structure -; -; If successful: -; ZF set -; BX = file pointer -; In unsuccessful: -; ZF clear -; -allocate_file: - push cx - mov bx, Files - mov cx, MAX_OPEN -.check: - cmp dword [bx], byte 0 - je .found - add bx, open_file_t_size ; ZF = 0 - loop .check - ; ZF = 0 if we fell out of the loop -.found: - pop cx - ret - -; -; iso_compare_names: -; Compare the names DS:SI and DS:DI and report if they are -; equal from an ISO 9660 perspective. SI is the name from -; the filesystem; CX indicates its length, and ';' terminates. -; DI is expected to end with a null. -; -; Note: clobbers AX, CX, SI, DI; assumes DS == ES == base segment -; -iso_compare_names: - ; First, terminate and canonicalize input filename - push di - mov di, ISOFileName -.canon_loop: - jcxz .canon_end - lodsb - dec cx - cmp al, ';' - je .canon_end - and al, al - je .canon_end - stosb - cmp di, ISOFileNameEnd-1 ; Guard against buffer overrun - jb .canon_loop -.canon_end: - cmp di, ISOFileName - jbe .canon_done - cmp byte [di-1], '.' ; Remove terminal dots - jne .canon_done - dec di - jmp short .canon_end -.canon_done: - mov [di], byte 0 ; Null-terminate string - pop di - mov si, ISOFileName -.compare: - lodsb - mov ah, [di] - inc di - and ax, ax - jz .success ; End of string for both - and al, al ; Is either one end of string? - jz .failure ; If so, failure - and ah, ah - jz .failure - or ax, 2020h ; Convert to lower case - cmp al, ah - je .compare -.failure: - and ax, ax ; ZF = 0 (at least one will be nonzero) -.success: - ret - - - - - - - -; -; getfssec: Get multiple clusters from a file, given the file pointer. -; -; On entry: -; ES:BX -> Buffer -; SI -> File pointer -; CX -> Cluster count; 0FFFFh = until end of file -; On exit: -; SI -> File pointer (or 0 on EOF) -; CF = 1 -> Hit EOF -; -getfssec: - cmp cx, [si+file_left] - jna .ok_size - mov cx, [si+file_left] - -.ok_size: - mov bp, cx - push cx - push si - mov eax, [si+file_sector] - call getlinsec - xor ecx, ecx - pop si - pop cx - - add [si+file_sector], ecx - sub [si+file_left], ecx - ja .not_eof ; CF = 0 - - xor ecx, ecx - mov [si+file_sector], ecx ; Mark as unused - xor si,si - stc - -.not_eof: - ret - - - -; INT 13h, AX=4B01h, DL= failed. -; Try to scan the entire 80h-FFh from the end. -spec_query_failed: - mov si,spec_err_msg - call writemsg - - mov dl, 0FFh -.test_loop: - pusha - mov ax, 4B01h - mov si, spec_packet - mov byte [si], 13 ; Size of buffer - int 13h - popa - jc .still_broken - - mov si, maybe_msg - call writemsg - mov al, dl - call writehex2 - call crlf - - cmp byte [sp_drive], dl - jne .maybe_broken - - ; Okay, good enough... - mov si, alright_msg - call writemsg - mov [DriveNo], dl -.found_drive: - jmp found_drive - - ; Award BIOS 4.51 apparently passes garbage in sp_drive, - ; but if this was the drive number originally passed in - ; DL then consider it "good enough" -.maybe_broken: - cmp byte [DriveNo], dl - je .found_drive - -.still_broken: - dec dx - cmp dl, 80h - jnb .test_loop - -fatal_error: - mov si, nothing_msg - call writemsg - -.norge: - jmp short .norge - - - - ; Information message (DS:SI) output - ; Prefix with "isolinux: " - ; -writemsg: - push ax - push si - mov si, isolinux_str - call writestr - pop si - call writestr - pop ax - ret - -; -; crlf: Print a newline -; -crlf: - mov si, crlf_msg - ; Fall through - -; -; writestr: write a null-terminated string to the console, saving -; registers on entry. -; -writestr: - pushfd - pushad -.top: - lodsb - and al, al - jz .end - call writechr - jmp short .top -.end: - popad - popfd - ret - - -; -; writehex[248]: Write a hex number in (AL, AX, EAX) to the console -; -writehex2: - pushfd - pushad - shl eax, 24 - mov cx, 2 - jmp short writehex_common -writehex4: - pushfd - pushad - shl eax, 16 - mov cx, 4 - jmp short writehex_common -writehex8: - pushfd - pushad - mov cx, 8 -writehex_common: -.loop: - rol eax, 4 - push eax - and al, 0Fh - cmp al, 10 - jae .high -.low: - add al, '0' - jmp short .ischar -.high: - add al, 'A'-10 -.ischar: - call writechr - pop eax - loop .loop - popad - popfd - ret - -; -; Write a character to the screen. There is a more "sophisticated" -; version of this in the subsequent code, so we patch the pointer -; when appropriate. -; - -writechr: - pushfd - pushad - mov ah, 0Eh - xor bx, bx - int 10h - popad - popfd - ret - -; -; Get one sector. Convenience entry point. -; -getonesec: - mov bp, 1 - ; Fall through to getlinsec - -; -; Get linear sectors - EBIOS LBA addressing, 2048-byte sectors. -; -; Note that we can't always do this as a single request, because at least -; Phoenix BIOSes has a 127-sector limit. To be on the safe side, stick -; to 32 sectors (64K) per request. -; -; Input: -; EAX - Linear sector number -; ES:BX - Target buffer -; BP - Sector count -; -getlinsec: - mov si,dapa ; Load up the DAPA - mov [si+4],bx - mov bx,es - mov [si+6],bx - mov [si+8],eax -.loop2: - push bp ; Sectors left - cmp bp,[MaxTransfer] - jbe .bp_ok - mov bp,[MaxTransfer] -.bp_ok: - mov [si+2],bp - push si - mov dl,[DriveNo] - mov ah,42h ; Extended Read - call xint13 - pop si - pop bp - movzx eax,word [si+2] ; Sectors we read - add [si+8],eax ; Advance sector pointer - sub bp,ax ; Sectors left - shl ax,SECTORSIZE_LG2-4 ; 2048-byte sectors -> segment - add [si+6],ax ; Advance buffer pointer - and bp,bp - jnz .loop2 - mov eax,[si+8] ; Next sector - ret - - ; INT 13h with retry -xint13: - mov byte [RetryCount], retry_count -.try: - pushad - int 13h - jc .error - add sp, byte 8*4 ; Clean up stack - ret -.error: - mov [DiskError], ah ; Save error code - popad - dec byte [RetryCount] - jz .real_error - push ax - mov al,[RetryCount] - mov ah,[dapa+2] ; Sector transfer count - cmp al,2 ; Only 2 attempts left - ja .nodanger - mov ah,1 ; Drop transfer size to 1 - jmp short .setsize -.nodanger: - cmp al,retry_count-2 - ja .again ; First time, just try again - shr ah,1 ; Otherwise, try to reduce - adc ah,0 ; the max transfer size, but not to 0 -.setsize: - mov [MaxTransfer],ah - mov [dapa+2],ah -.again: - pop ax - jmp .try - -.real_error: - mov si, diskerr_msg - call writemsg - mov al, [DiskError] - call writehex2 - mov si, ondrive_str - call writestr - mov al, dl - call writehex2 - call crlf - ; Fall through to kaboom - -; -; kaboom: write a message and bail out. Wait for a user keypress, -; then do a hard reboot. -; -kaboom: - mov ax, cs - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - sti - mov si, err_bootfailed - call writestr - call getchar - cli - mov word [BIOS_magic], 0 ; Cold reboot - jmp 0F000h:0FFF0h ; Reset vector address - -getchar: -.again: - mov ah, 1 ; Poll keyboard - int 16h - jz .again -.kbd: - xor ax, ax ; Get keyboard input - int 16h -.func_key: - ret - - -isolinux_banner db CR, LF, 'Loading IsoBoot...', CR, LF, 0 -copyright_str db ' (C) 1994-2002 H. Peter Anvin', CR, LF, 0 -presskey_msg db 'Press any key to boot from CD', 0 -dot_msg db '.',0 - -%ifdef DEBUG_MESSAGES -startup_msg: db 'Starting up, DL = ', 0 -spec_ok_msg: db 'Loaded spec packet OK, drive = ', 0 -secsize_msg: db 'Sector size appears to be ', 0 -rootloc_msg: db 'Root directory location: ', 0 -rootlen_msg: db 'Root directory length: ', 0 -rootsect_msg: db 'Root directory length(sectors): ', 0 -fileloc_msg: db 'SETUPLDR.SYS location: ', 0 -filelen_msg: db 'SETUPLDR.SYS length: ', 0 -filesect_msg: db 'SETUPLDR.SYS length(sectors): ', 0 -findfail_msg: db 'Failed to find file!', 0 -startldr_msg: db 'Starting SETUPLDR.SYS', 0 -%endif - -; nosecsize_msg: db 'Failed to get sector size, assuming 0800', CR, LF, 0 -spec_err_msg: db 'Loading spec packet failed, trying to wing it...', CR, LF, 0 -maybe_msg: db 'Found something at drive = ', 0 -alright_msg: db 'Looks like it might be right, continuing...', CR, LF, 0 -nothing_msg: db 'Failed to locate CD-ROM device; boot failed.', CR, LF, 0 -isolinux_str db 'IsoBoot: ', 0 -crlf_msg db CR, LF, 0 -diskerr_msg: db 'Disk error ', 0 -ondrive_str: db ', drive ', 0 -err_bootfailed db CR, LF, 'Boot failed: press a key to retry...' -isolinux_dir db '\LOADER', 0 -no_dir_msg db 'Could not find the LOADER directory.', CR, LF, 0 -isolinux_bin db 'SETUPLDR.SYS', 0 -no_isolinux_msg db 'Could not find SETUPLDR.SYS.', CR, LF, 0 - -; -; El Torito spec packet -; - align 8, db 0 -spec_packet: db 13h ; Size of packet -sp_media: db 0 ; Media type -sp_drive: db 0 ; Drive number -sp_controller: db 0 ; Controller index -sp_lba: dd 0 ; LBA for emulated disk image -sp_devspec: dw 0 ; IDE/SCSI information -sp_buffer: dw 0 ; User-provided buffer -sp_loadseg: dw 0 ; Load segment -sp_sectors: dw 0 ; Sector count -sp_chs: db 0,0,0 ; Simulated CHS geometry -sp_dummy: db 0 ; Scratch, safe to overwrite - -; -; EBIOS drive parameter packet -; - align 8, db 0 -drive_params: dw 30 ; Buffer size -dp_flags: dw 0 ; Information flags -dp_cyl: dd 0 ; Physical cylinders -dp_head: dd 0 ; Physical heads -dp_sec: dd 0 ; Physical sectors/track -dp_totalsec: dd 0,0 ; Total sectors -dp_secsize: dw 0 ; Bytes per sector -dp_dpte: dd 0 ; Device Parameter Table -dp_dpi_key: dw 0 ; 0BEDDh if rest valid -dp_dpi_len: db 0 ; DPI len - db 0 - dw 0 -dp_bus: times 4 db 0 ; Host bus type -dp_interface: times 8 db 0 ; Interface type -db_i_path: dd 0,0 ; Interface path -db_d_path: dd 0,0 ; Device path - db 0 -db_dpi_csum: db 0 ; Checksum for DPI info - -; -; EBIOS disk address packet -; - align 8, db 0 -dapa: dw 16 ; Packet size -.count: dw 0 ; Block count -.off: dw 0 ; Offset of buffer -.seg: dw 0 ; Segment of buffer -.lba: dd 0 ; LBA (LSW) - dd 0 ; LBA (MSW) - - alignb 4, db 0 -MaxTransfer dw 2 ;32 ; Max sectors per transfer - - times 2046-($-$$) db 0 ; Pad to file offset 2046 - dw 0aa55h ; BootSector signature diff --git a/reactos/boot/freeldr/bootsect/isombr.S b/reactos/boot/freeldr/bootsect/isombr.S index 9515278e9bc..bf99cf9bbbe 100644 --- a/reactos/boot/freeldr/bootsect/isombr.S +++ b/reactos/boot/freeldr/bootsect/isombr.S @@ -1,7 +1,8 @@ /* * PROJECT: ReactOS MBR Boot Sector for ISO file system ("isohybrid mode") - * LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation - * COPYRIGHT: Copyright 2017 Colin Finck + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: Providing an MBR Boot Sector that enables an ISO to be booted from a disk + * COPYRIGHT: Copyright 2017 Colin Finck (colin@reactos.org) */ #include diff --git a/reactos/boot/freeldr/bootsect/win2k.asm b/reactos/boot/freeldr/bootsect/win2k.asm deleted file mode 100644 index 9152a4c1724..00000000000 --- a/reactos/boot/freeldr/bootsect/win2k.asm +++ /dev/null @@ -1,466 +0,0 @@ -; -; Win2k FAT32 Boot Sector -; -; Brian Palmer -; - -; -; The BP register is initialized to 0x7c00, the start of -; the boot sector. The SP register is initialized to -; 0x7bf4, leaving 12 bytes of data storage space above -; the stack. -; -; The DWORD that gets stored at 0x7bf4 is 0xffffffff ?? -; -; The DWORD that gets stored at 0x7bf8 is the count of -; total sectors of the volume, calculated from the BPB. -; -; The DWORD that gets stored at 0x7bfc is the logical -; sector number of the start of the data area. -; - -org 7c00h - -segment .text - -bits 16 - -start: - jmp short main - nop - -OEMName db 'MSWIN4.0' -BytesPerSector dw 512 -SectsPerCluster db 1 -ReservedSectors dw 1 -NumberOfFats db 2 -MaxRootEntries dw 0 ;512 - Always zero for FAT32 volumes -TotalSectors dw 0 ;2880 - Always zero for FAT32 volumes -MediaDescriptor db 0f8h -SectorsPerFat dw 0 ;9 - Always zero for FAT32 volumes -SectorsPerTrack dw 18 -NumberOfHeads dw 2 -HiddenSectors dd 0 -TotalSectorsBig dd 0 -; FAT32 Inserted Info -SectorsPerFatBig dd 0 -ExtendedFlags dw 0 -FSVersion dw 0 -RootDirStartCluster dd 0 -FSInfoSector dw 0 -BackupBootSector dw 6 -Reserved1 times 12 db 0 -; End FAT32 Inserted Info -BootDrive db 80h -Reserved db 0 -ExtendSig db 29h -SerialNumber dd 00000000h -VolumeLabel db 'NO NAME ' -FileSystem db 'FAT32 ' - -main: -00007C5A 33C9 xor cx,cx -00007C5C 8ED1 mov ss,cx ; Setup the stack -00007C5E BCF47B mov sp,0x7bf4 ; Give us 12 bytes of space above the stack -00007C61 8EC1 mov es,cx -00007C63 8ED9 mov ds,cx -00007C65 BD007C mov bp,0x7c00 -00007C68 884E02 mov [bp+0x2],cl ; Zero out the nop instruction?? (3rd byte of the boot sector) -00007C6B 8A5640 mov dl,[bp+BootDrive] -00007C6E B408 mov ah,0x8 -00007C70 CD13 int 0x13 ; Int 13, func 8 - Get Drive Parameters -00007C72 7305 jnc drive_param_ok ; If no error jmp - -drive_param_error: -00007C74 B9FFFF mov cx,0xffff ; We couldn't determine the drive parameters -00007C77 8AF1 mov dh,cl ; So just set the CHS to 0xff - -drive_param_ok: -00007C79 660FB6C6 movzx eax,dh ; Store the number of heads in eax -00007C7D 40 inc ax ; Make it one-based because the bios returns it zero-based -00007C7E 660FB6D1 movzx edx,cl ; Store the sectors per track in edx -00007C82 80E23F and dl,0x3f ; Mask off the cylinder bits -00007C85 F7E2 mul dx ; Multiply the sectors per track with the heads, result in dx:ax -00007C87 86CD xchg cl,ch ; Switch the cylinder with the sectors -00007C89 C0ED06 shr ch,0x6 ; Move the top two cylinder bits down where they should be -00007C8C 41 inc cx ; Make it one-based because the bios returns it zero-based -00007C8D 660FB7C9 movzx ecx,cx -00007C91 66F7E1 mul ecx ; Multiply the cylinders with (heads * sectors) [stored in dx:ax already] -00007C94 668946F8 mov [bp-0x8],eax ; This value is the number of total sectors on the disk, so save it for later -00007C98 837E1600 cmp word [bp+TotalSectors],byte +0x0 ; Check the old 16-bit value of TotalSectors -00007C9C 7538 jnz print_ntldr_error_message ; If it is non-zero then exit with an error - -00007C9E 837E2A00 cmp word [bp+FSVersion],byte +0x0 ; Check the file system version word -00007CA2 7732 ja print_ntldr_error_message ; If it is not zero then exit with an error - - - ; - ; We are now ready to load our second sector of boot code - ; But first, a bit of undocumented information about how - ; Win2k stores it's second sector of boot code. - ; - ; The FAT32 filesystem was designed so that you can store - ; multiple sectors of boot code. The boot sector of a FAT32 - ; volume is actually three sectors long. Microsoft extended - ; the BPB so much that you can't fit enough code in the - ; boot sector to make it work. So they extended it. Sector 0 - ; is the traditional boot sector, sector 1 is the FSInfo sector, - ; and sector 2 is used to store extra boot code to make up - ; for the lost space the BPB takes. - ; - ; Now this creates an interesting problem. Suppose for example - ; that the user has Win98 and Win2k installed. The Win2k - ; boot sector is stored at sector 0 and the Win98 boot sector is - ; stored as BOOTSECT.DOS on the file system. Now if Win2k were - ; to store it's second sector of boot code in sector 2 like - ; the fat spec says to do then when you try to dual boot back - ; to Win98 the Win98 boot sector will load Win2k's second - ; sector of boot code. Understand? ;-) - ; - ; To get around this problem Win2k stores it's second sector - ; of boot code elsewhere. This sector is always stored at sector 13 - ; on the file system. Now don't ask me what happens when you don't - ; have enough reserved sectors to store it, but I've never seen a - ; FAT32 volume that didn't have at least 32 reserved sectors. - ; - -00007CA4 668B461C mov eax,[bp+HiddenSectors] ; Get the count of hidden sectors -00007CA8 6683C00C add eax,byte +0xc ; Add 12 to that value so that we are loading the 13th sector of the volume -00007CAC BB0080 mov bx,0x8000 ; Read the sector to address 0x8000 -00007CAF B90100 mov cx,0x1 ; Read just one sector -00007CB2 E82B00 call read_sectors ; Read it -00007CB5 E94803 jmp 0x8000 ; Jump to the next sector of boot code - -print_disk_error_message: -00007CB8 A0FA7D mov al,[DISK_ERR_offset_from_0x7d00] -putchars: -00007CBB B47D mov ah,0x7d -00007CBD 8BF0 mov si,ax -get_another_char: -00007CBF AC lodsb -00007CC0 84C0 test al,al -00007CC2 7417 jz reboot -00007CC4 3CFF cmp al,0xff -00007CC6 7409 jz print_reboot_message -00007CC8 B40E mov ah,0xe -00007CCA BB0700 mov bx,0x7 -00007CCD CD10 int 0x10 -00007CCF EBEE jmp short get_another_char -print_reboot_message: -00007CD1 A0FB7D mov al,[RESTART_ERR_offset_from_0x7d00] -00007CD4 EBE5 jmp short putchars -print_ntldr_error_message: -00007CD6 A0F97D mov al,[NTLDR_ERR_offset_from_0x7d00] -00007CD9 EBE0 jmp short putchars -reboot: -00007CDB 98 cbw -00007CDC CD16 int 0x16 -00007CDE CD19 int 0x19 - -read_sectors: -00007CE0 6660 pushad -00007CE2 663B46F8 cmp eax,[bp-0x8] -00007CE6 0F824A00 jc near 0x7d34 -00007CEA 666A00 o32 push byte +0x0 -00007CED 6650 push eax -00007CEF 06 push es -00007CF0 53 push bx -00007CF1 666810000100 push dword 0x10010 -00007CF7 807E0200 cmp byte [bp+0x2],0x0 -00007CFB 0F852000 jnz near 0x7d1f -00007CFF B441 mov ah,0x41 -00007D01 BBAA55 mov bx,0x55aa -00007D04 8A5640 mov dl,[bp+BootDrive] -00007D07 CD13 int 0x13 -00007D09 0F821C00 jc near 0x7d29 -00007D0D 81FB55AA cmp bx,0xaa55 -00007D11 0F851400 jnz near 0x7d29 -00007D15 F6C101 test cl,0x1 -00007D18 0F840D00 jz near 0x7d29 -00007D1C FE4602 inc byte [bp+0x2] -00007D1F B442 mov ah,0x42 -00007D21 8A5640 mov dl,[bp+BootDrive] -00007D24 8BF4 mov si,sp -00007D26 CD13 int 0x13 -00007D28 B0F9 mov al,0xf9 -00007D2A 6658 pop eax -00007D2C 6658 pop eax -00007D2E 6658 pop eax -00007D30 6658 pop eax -00007D32 EB2A jmp short 0x7d5e -00007D34 6633D2 xor edx,edx -00007D37 660FB74E18 movzx ecx,word [bp+SectorsPerTrack] -00007D3C 66F7F1 div ecx -00007D3F FEC2 inc dl -00007D41 8ACA mov cl,dl -00007D43 668BD0 mov edx,eax -00007D46 66C1EA10 shr edx,0x10 -00007D4A F7761A div word [bp+NumberOfHeads] -00007D4D 86D6 xchg dl,dh -00007D4F 8A5640 mov dl,[bp+BootDrive] -00007D52 8AE8 mov ch,al -00007D54 C0E406 shl ah,0x6 -00007D57 0ACC or cl,ah -00007D59 B80102 mov ax,0x201 -00007D5C CD13 int 0x13 -00007D5E 6661 popad -00007D60 0F8254FF jc near print_disk_error_message -00007D64 81C30002 add bx,0x200 -00007D68 6640 inc eax -00007D6A 49 dec cx -00007D6B 0F8571FF jnz near read_sectors -00007D6F C3 ret - -NTLDR db 'NTLDR ' - -filler times 49 db 0 - -NTLDR_ERR db 0dh,0ah,'NTLDR is missing',0ffh -DISK_ERR db 0dh,0ah,'Disk error',0ffh -RESTART_ERR db 0dh,0ah,'Press any key to restart',0dh,0ah - -more_filler times 16 db 0 - -NTLDR_offset_from_0x7d00 db 0 -NTLDR_ERR_offset_from_0x7d00 db 0ach -DISK_ERR_offset_from_0x7d00 db 0bfh -RESTART_ERR_offset_from_0x7d00 db 0cch - - dw 0 - dw 0aa55h - - - - - - -; -; And that ends the code that makes up the traditional boot sector -; From here on out is a disassembly of the extra sector of boot -; code required for a FAT32 volume. Win2k stores this code at -; sector 13 on the file system. -; - - - - -00008000 660FB64610 movzx eax,byte [bp+NumberOfFats] ; Put the number of fats into eax -00008005 668B4E24 mov ecx,[bp+SectorsPerFatBig] ; Put the count of sectors per fat into ecx -00008009 66F7E1 mul ecx ; Multiply them, edx:eax = (eax * ecx) -0000800C 6603461C add eax,[bp+HiddenSectors] ; Add the hidden sectors to eax -00008010 660FB7560E movzx edx,word [bp+ReservedSectors] ; Put the count of reserved sectors into edx -00008015 6603C2 add eax,edx ; Add it to eax -00008018 668946FC mov [bp-0x4],eax ; eax now contains the start of the data area, so save it for later -0000801C 66C746F4FFFFFFFF mov dword [bp-0xc],0xffffffff ; Save 0xffffffff for later?? -00008024 668B462C mov eax,[bp+RootDirStartCluster] ; Put the starting cluster of the root directory into eax -00008028 6683F802 cmp eax,byte +0x2 ; Check and see if the root directory starts at cluster 2 or above -0000802C 0F82A6FC jc near print_ntldr_error_message ; If not exit with error -00008030 663DF8FFFF0F cmp eax,0xffffff8 ; Check and see if the root directory start cluster is and end of cluster chain indicator -00008036 0F839CFC jnc near print_ntldr_error_message ; If so exit with error - -search_root_directory_cluster: -0000803A 6650 push eax ; Save root directory start cluster on stack -0000803C 6683E802 sub eax,byte +0x2 ; Adjust it because the first two fat entries are unused so the third entry marks the first data area cluster -00008040 660FB65E0D movzx ebx,byte [bp+SectsPerCluster] ; Put the number of sectors per cluster in ebx -00008045 8BF3 mov si,bx ; Now store it also in si register -00008047 66F7E3 mul ebx ; Multiply sectors per cluster with root directory start cluster -0000804A 660346FC add eax,[bp-0x4] ; Add the start sector of the data area - -read_directory_sector: -0000804E BB0082 mov bx,0x8200 ; We now have the start sector of the root directory, so load it to 0x8200 -00008051 8BFB mov di,bx ; Put the address of the root directory sector in di also -00008053 B90100 mov cx,0x1 ; Read one sector -00008056 E887FC call read_sectors ; Perform the read - -check_entry_for_ntldr: -00008059 382D cmp [di],ch ; Check the first byte of the root directory entry for zero -0000805B 741E jz ntldr_not_found ; If so then NTLDR is missing so exit with error -0000805D B10B mov cl,0xb ; Put the value 11 in cl so we can compare an 11-byte filename -0000805F 56 push si ; Save si (which contains the number of sectors per cluster) -00008060 BE707D mov si,NTLDR ;0x7d70 ; Check and see if "NTLDR" is the first file entry -00008063 F3A6 repe cmpsb ; Do the compare -00008065 5E pop si ; Restore sectors per cluster into si -00008066 741B jz ntldr_found ; If we found it then continue, else check next entry -00008068 03F9 add di,cx ; Add 0 to di? the next entry is 0x15 bytes away -0000806A 83C715 add di,byte +0x15 ; Add 0x15 to di -0000806D 3BFB cmp di,bx ; Check to see if we have reached the end of our sector we loaded, read_sectors sets bx = end address of data loaded -0000806F 72E8 jc check_entry_for_ntldr ; If we haven't reached the end then check the next entry -00008071 4E dec si ; decrement si, si holds the number of sectors per cluster -00008072 75DA jnz read_directory_sector ; If it's not zero then search the next sector for NTLDR -00008074 6658 pop eax ; If we got here that means we didn't find NTLDR in the previous root directory cluster, so restore eax with the start cluster -00008076 E86500 call get_fat_entry ; Get the next cluster in the fat chain -00008079 72BF jc search_root_directory_cluster ; If we reached end-of-file marker then don't jump, otherwise continue search - -ntldr_not_found: -0000807B 83C404 add sp,byte +0x4 -0000807E E955FC jmp print_ntldr_error_message - -ntldr_load_segment_address dw 0x2000 - -ntldr_found: -00008083 83C404 add sp,byte +0x4 ; Adjust stack to remove root directory start cluster -00008086 8B7509 mov si,[di+0x9] ; Put start cluster high word in si -00008089 8B7D0F mov di,[di+0xf] ; Put start cluster low word in di -0000808C 8BC6 mov ax,si ; Put high word in ax -0000808E 66C1E010 shl eax,0x10 ; Shift it into position -00008092 8BC7 mov ax,di ; Put low word in ax, now eax contains start cluster of NTLDR -00008094 6683F802 cmp eax,byte +0x2 ; Check and see if the start cluster of NTLDR starts at cluster 2 or above -00008098 0F823AFC jc near print_ntldr_error_message ; If not exit with error -0000809C 663DF8FFFF0F cmp eax,0xffffff8 ; Check and see if the start cluster of NTLDR is and end of cluster chain indicator -000080A2 0F8330FC jnc near print_ntldr_error_message ; If so exit with error - -load_next_ntldr_cluster: -000080A6 6650 push eax ; Save NTLDR start cluster for later -000080A8 6683E802 sub eax,byte +0x2 ; Adjust it because the first two fat entries are unused so the third entry marks the first data area cluster -000080AC 660FB64E0D movzx ecx,byte [bp+SectsPerCluster] ; Put the sectors per cluster into ecx -000080B1 66F7E1 mul ecx ; Multiply sectors per cluster by the start cluster, we now have the logical start sector -000080B4 660346FC add eax,[bp-0x4] ; Add the start of the data area logical sector -000080B8 BB0000 mov bx,0x0 ; Load NTLDR to offset zero -000080BB 06 push es ; Save es -000080BC 8E068180 mov es,[ntldr_load_segment_address] ; Get the segment address to load NTLDR to -000080C0 E81DFC call read_sectors ; Load the first cluster -000080C3 07 pop es ; Restore es -000080C4 6658 pop eax ; Restore eax to NTLDR start cluster -000080C6 C1EB04 shr bx,0x4 ; bx contains the amount of data we transferred, so divide it by 16 -000080C9 011E8180 add [ntldr_load_segment_address],bx ; Add that value to the segment -000080CD E80E00 call get_fat_entry ; Get the next cluster in eax -000080D0 0F830200 jnc near jump_to_ntldr ; If we have reached the end of file then lets get to NTLDR -000080D4 72D0 jc load_next_ntldr_cluster ; If not, then load another cluster - -jump_to_ntldr: -000080D6 8A5640 mov dl,[bp+BootDrive] ; Put the boot drive in dl -000080D9 EA00000020 jmp 0x2000:0x0 ; Jump to NTLDR - -get_fat_entry: -000080DE 66C1E002 shl eax,0x2 ; Multiply cluster by 4 -000080E2 E81100 call load_fat_sector ; Load the fat sector -000080E5 26668B01 mov eax,[es:bx+di] ; Get the fat entry -000080E9 6625FFFFFF0F and eax,0xfffffff ; Mask off the most significant 4 bits -000080EF 663DF8FFFF0F cmp eax,0xffffff8 ; Compare it to end of file marker to set the flags correctly -000080F5 C3 ret ; Return to caller - -load_fat_sector: -000080F6 BF007E mov di,0x7e00 ; We will load the fat sector to 0x7e00 -000080F9 660FB74E0B movzx ecx,word [bp+SectsPerCluster] ; Get the sectors per cluster -000080FE 6633D2 xor edx,edx ; We will divide (cluster * 4) / sectorspercluster -00008101 66F7F1 div ecx ; eax is already set before we get to this routine -00008104 663B46F4 cmp eax,[bp-0xc] ; Compare eax to 0xffffffff (initially, we set this value later) -00008108 743A jz load_fat_sector_end ; If it is the same return -0000810A 668946F4 mov [bp-0xc],eax ; Update that value -0000810E 6603461C add eax,[bp+HiddenSectors] ; Add the hidden sectors -00008112 660FB74E0E movzx ecx,word [bp+ReservedSectors] ; Add the reserved sectors -00008117 6603C1 add eax,ecx ; To the hidden sectors + the value we computed earlier -0000811A 660FB75E28 movzx ebx,word [bp+ExtendedFlags] ; Get extended flags and put into ebx -0000811F 83E30F and bx,byte +0xf ; Mask off upper 8 bits -00008122 7416 jz load_fat_sector_into_memory ; If fat is mirrored then skip fat calcs -00008124 3A5E10 cmp bl,[bp+NumberOfFats] ; Compare bl to number of fats -00008127 0F83ABFB jnc near print_ntldr_error_message ; If bl is bigger than numfats exit with error -0000812B 52 push dx ; Save dx -0000812C 668BC8 mov ecx,eax ; Put the current fat sector offset into ecx -0000812F 668B4624 mov eax,[bp+SectorsPerFatBig] ; Get the number of sectors occupied by one fat -00008133 66F7E3 mul ebx ; Multiplied by the active fat index -00008136 6603C1 add eax,ecx ; Add the current fat sector offset -00008139 5A pop dx ; Restore dx -load_fat_sector_into_memory: -0000813A 52 push dx ; Save dx, what is so important in dx?? -0000813B 8BDF mov bx,di ; Put 0x7e00 in bx -0000813D B90100 mov cx,0x1 ; Load one sector -00008140 E89DFB call read_sectors ; Perform the read -00008143 5A pop dx ; Restore dx -load_fat_sector_end: -00008144 8BDA mov bx,dx ; Put it into bx, what is this value?? -00008146 C3 ret ; Return - - -00008147 0000 add [bx+si],al -00008149 0000 add [bx+si],al -0000814B 0000 add [bx+si],al -0000814D 0000 add [bx+si],al -0000814F 0000 add [bx+si],al -00008151 0000 add [bx+si],al -00008153 0000 add [bx+si],al -00008155 0000 add [bx+si],al -00008157 0000 add [bx+si],al -00008159 0000 add [bx+si],al -0000815B 0000 add [bx+si],al -0000815D 0000 add [bx+si],al -0000815F 0000 add [bx+si],al -00008161 0000 add [bx+si],al -00008163 0000 add [bx+si],al -00008165 0000 add [bx+si],al -00008167 0000 add [bx+si],al -00008169 0000 add [bx+si],al -0000816B 0000 add [bx+si],al -0000816D 0000 add [bx+si],al -0000816F 0000 add [bx+si],al -00008171 0000 add [bx+si],al -00008173 0000 add [bx+si],al -00008175 0000 add [bx+si],al -00008177 0000 add [bx+si],al -00008179 0000 add [bx+si],al -0000817B 0000 add [bx+si],al -0000817D 0000 add [bx+si],al -0000817F 0000 add [bx+si],al -00008181 0000 add [bx+si],al -00008183 0000 add [bx+si],al -00008185 0000 add [bx+si],al -00008187 0000 add [bx+si],al -00008189 0000 add [bx+si],al -0000818B 0000 add [bx+si],al -0000818D 0000 add [bx+si],al -0000818F 0000 add [bx+si],al -00008191 0000 add [bx+si],al -00008193 0000 add [bx+si],al -00008195 0000 add [bx+si],al -00008197 0000 add [bx+si],al -00008199 0000 add [bx+si],al -0000819B 0000 add [bx+si],al -0000819D 0000 add [bx+si],al -0000819F 0000 add [bx+si],al -000081A1 0000 add [bx+si],al -000081A3 0000 add [bx+si],al -000081A5 0000 add [bx+si],al -000081A7 0000 add [bx+si],al -000081A9 0000 add [bx+si],al -000081AB 0000 add [bx+si],al -000081AD 0000 add [bx+si],al -000081AF 0000 add [bx+si],al -000081B1 0000 add [bx+si],al -000081B3 0000 add [bx+si],al -000081B5 0000 add [bx+si],al -000081B7 0000 add [bx+si],al -000081B9 0000 add [bx+si],al -000081BB 0000 add [bx+si],al -000081BD 0000 add [bx+si],al -000081BF 0000 add [bx+si],al -000081C1 0000 add [bx+si],al -000081C3 0000 add [bx+si],al -000081C5 0000 add [bx+si],al -000081C7 0000 add [bx+si],al -000081C9 0000 add [bx+si],al -000081CB 0000 add [bx+si],al -000081CD 0000 add [bx+si],al -000081CF 0000 add [bx+si],al -000081D1 0000 add [bx+si],al -000081D3 0000 add [bx+si],al -000081D5 0000 add [bx+si],al -000081D7 0000 add [bx+si],al -000081D9 0000 add [bx+si],al -000081DB 0000 add [bx+si],al -000081DD 0000 add [bx+si],al -000081DF 0000 add [bx+si],al -000081E1 0000 add [bx+si],al -000081E3 0000 add [bx+si],al -000081E5 0000 add [bx+si],al -000081E7 0000 add [bx+si],al -000081E9 0000 add [bx+si],al -000081EB 0000 add [bx+si],al -000081ED 0000 add [bx+si],al -000081EF 0000 add [bx+si],al -000081F1 0000 add [bx+si],al -000081F3 0000 add [bx+si],al -000081F5 0000 add [bx+si],al -000081F7 0000 add [bx+si],al -000081F9 0000 add [bx+si],al -000081FB 0000 add [bx+si],al -000081FD 0055AA add [di-0x56],dl ; We can't forget the infamous boot signature diff --git a/reactos/boot/freeldr/bootsect/wxpfat16.asm b/reactos/boot/freeldr/bootsect/wxpfat16.asm deleted file mode 100644 index b4e3abd2f92..00000000000 --- a/reactos/boot/freeldr/bootsect/wxpfat16.asm +++ /dev/null @@ -1,249 +0,0 @@ - -; -; The BP register is initialized to 0x7c00, the start of -; the boot sector. The SP register is initialized to -; 0x7bf0, leaving 16 bytes of data storage space above -; the stack. -; -; The DWORD that gets stored at 0x7bfc is the logical -; sector number of the start of the data area. -; -; The DWORD that gets stored at 0x7bf8 is ???????? -; -; The DWORD that gets stored at 0x7bf4 is ???????? -; -; The DWORD that gets stored at 0x7bf0 is ???????? -; - - -org 7c00h - -segment .text - -bits 16 - -start: - jmp short main - nop - -OEMName db 'MSWIN4.0' -BytesPerSector dw 512 -SectsPerCluster db 1 -ReservedSectors dw 1 -NumberOfFats db 2 -MaxRootEntries dw 0 ;512 - Always zero for FAT32 volumes -TotalSectors dw 0 ;2880 - Always zero for FAT32 volumes -MediaDescriptor db 0f8h -SectorsPerFat dw 0 ;9 - Always zero for FAT32 volumes -SectorsPerTrack dw 18 -NumberOfHeads dw 2 -HiddenSectors dd 0 -TotalSectorsBig dd 0 -BootDrive db 80h -Reserved db 0 -ExtendSig db 29h -SerialNumber dd 00000000h -VolumeLabel db 'NO NAME ' -FileSystem db 'FAT16 ' - -main: -00007C3E 33C9 xor cx,cx -00007C40 8ED1 mov ss,cx ; Setup stack -00007C42 BCF07B mov sp,0x7bf0 ; Give us 16 bytes (4 dwords) of space above stack -00007C45 8ED9 mov ds,cx -00007C47 B80020 mov ax,0x2000 -00007C4A 8EC0 mov es,ax ; Setup ES:0000 == 2000:0000 -00007C4C FC cld -00007C4D BD007C mov bp,0x7c00 -00007C50 384E24 cmp [bp+BootDrive],cl ; Compare the boot drive to zero (I think they are testing for a hard disk drive number) -00007C53 7D24 jnl floppy_boot ; Nope, it's a floppy, skip partition table tests -00007C55 8BC1 mov ax,cx ; Move zero to AX -00007C57 99 cwd ; DX:AX now contains zero -00007C58 E83C01 call read_one_sector ; Try to read in the MBR sector -00007C5B 721C jc floppy_boot ; Read failed, continue -00007C5D 83EB3A sub bx,byte +0x3a ; BX comes back with 512, make it equal to 454 (offset of partition table in MBR) -00007C60 66A11C7C mov eax,[HiddenSectors] ; Put HiddenSectors in EAX -find_our_partition: -00007C64 26663B07 cmp eax,[es:bx] ; Compare partition table entry's start sector to HiddenSectors -00007C68 268A57FC mov dl,[es:bx-0x4] ; Get partition type byte for this entry -00007C6C 7506 jnz next_partition_entry ; If partition start sector != HiddenSectors then skip this entry -00007C6E 80CA02 or dl,0x2 ; Set the second bit in partition type?? I guess this makes types 4 & 6 identical -00007C71 885602 mov [bp+0x2],dl ; Save it on top of nop instruction (3rd byte of boot sector) -next_partition_entry: -00007C74 80C310 add bl,0x10 ; Add 16 to bl (offset of next entry in partition table) -00007C77 73EB jnc find_our_partition ; Jump back until we hit the end of the partition table - -; We now have our partition type at 0000:7C02 -; If the type was 4 or 6 then that byte is 6 -; I can't imagine why the boot sector needs to store -; this information, but hopefully I will uncover it -; as I further disassemble this boot sector. - - -floppy_boot: -00007C79 33C9 xor cx,cx ; Zero out CX -00007C7B 8A4610 mov al,[bp+NumberOfFats] ; Get the number of FATs in AL (usually 2) -00007C7E 98 cbw ; Sign extend it into AX (AX == 2) -00007C7F F76616 mul word [bp+NumberOfFats] ; Multiply it with NumberOfFats PLUS the low byte of MaxRootEntries!!?? -00007C82 03461C add ax,[bp+HiddenSectors] ; Result is in DX:AX -00007C85 13561E adc dx,[bp+HiddenSectors+2] ; Add HiddenSectors to DX:AX -00007C88 03460E add ax,[bp+ReservedSectors] ; Add ReservedSectors to DX:AX -00007C8B 13D1 adc dx,cx ; CX still contains zero -00007C8D 8B7611 mov si,[bp+MaxRootEntries] ; Get MaxRootEntries in SI -00007C90 60 pusha ; Save all registers (right now DX:AX has starting sector of root dir) -00007C91 8946FC mov [bp-0x4],ax ; Save the starting sector of the root directory -00007C94 8956FE mov [bp-0x2],dx ; Save it in the first 4 bytes before the boot sector -00007C97 B82000 mov ax,0x20 ; AX == 32 (size of a directory entry) -00007C9A F7E6 mul si ; Multiply it with MaxRootEntries (DX:AX == length in bytes of root directory) -00007C9C 8B5E0B mov bx,[bp+BytesPerSector] ; Get the BytesPerSector in BX -00007C9F 03C3 add ax,bx ; Add it to AX (what if this addition carries? MS should 'adc dx,0' shouldn't they?) -00007CA1 48 dec ax ; Subtract one (basically rounding up) -00007CA2 F7F3 div bx ; Divide DX:AX (length of root dir in bytes) by the size of a sector -00007CA4 0146FC add [bp-0x4],ax ; Add the number of sectors of the root directory to our other value -00007CA7 114EFE adc [bp-0x2],cx ; Now the first 4 bytes before the boot sector contain the starting sector of the data area -00007CAA 61 popa ; Restore all registers (DX:AX has start sector of root dir) -load_root_dir_sector: -00007CAB BF0000 mov di,0x0 ; Zero out di -00007CAE E8E600 call read_one_sector ; Read the first sector of the root directory -00007CB1 7239 jc print_disk_error_message ; Read failed, print disk error and reboot -search_directory: -00007CB3 26382D cmp [es:di],ch ; If the first byte of the directory entry is zero then we have reached the end -00007CB6 7417 jz print_ntldr_error_message; of the directory and NTLDR is not here so reboot -00007CB8 60 pusha ; Save all registers -00007CB9 B10B mov cl,0xb ; Put 11 in cl (length of filename in directory entry) -00007CBB BEA17D mov si,NTLDR ; Put offset of filename string in DS:SI -00007CBE F3A6 repe cmpsb ; Compare this directory entry against 'NTLDR ' -00007CC0 61 popa ; Restore all the registers -00007CC1 7432 jz found_ntldr ; If we found NTLDR then jump -00007CC3 4E dec si ; SI holds MaxRootEntries, subtract one -00007CC4 7409 jz print_ntldr_error_message; If we are out of root dir entries then reboot -00007CC6 83C720 add di,byte +0x20 ; Increment DI by the size of a directory entry -00007CC9 3BFB cmp di,bx ; Compare DI to BX (DI has offset to next dir entry, BX has address of end of directory sector in memory) -00007CCB 72E6 jc search_directory ; If DI is less than BX loop again -00007CCD EBDC jmp short load_root_dir_sector ; Didn't find NTLDR in this directory sector, try again -print_ntldr_error_message: -00007CCF A0FB7D mov al,[NTLDR_ERR_offset_from_0x7d00] -putchars: -00007CD2 B47D mov ah,0x7d -00007CD4 8BF0 mov si,ax -get_another_char: -00007CD6 AC lodsb -00007CD7 98 cbw -00007CD8 40 inc ax -00007CD9 740C jz print_reboot_message -00007CDB 48 dec ax -00007CDC 7413 jz reboot -00007CDE B40E mov ah,0xe -00007CE0 BB0700 mov bx,0x7 -00007CE3 CD10 int 0x10 -00007CE5 EBEF jmp short get_another_char -print_reboot_message: -00007CE7 A0FD7D mov al,[RESTART_ERR_offset_from_0x7d00] -00007CEA EBE6 jmp short putchars -print_disk_error_message: -00007CEC A0FC7D mov al,[DISK_ERR_offset_from_0x7d00] -00007CEF EBE1 jmp short putchars -reboot: -00007CF1 CD16 int 0x16 -00007CF3 CD19 int 0x19 -found_ntldr: -00007CF5 268B551A mov dx,[es:di+0x1a] ; Get NTLDR start cluster in DX -00007CF9 52 push dx ; Save it on the stack -00007CFA B001 mov al,0x1 ; Read 1 cluster? Or is this one sector? -00007CFC BB0000 mov bx,0x0 ; ES:BX is the load address (2000:0000) -00007CFF E83B00 call read_cluster ; Do the read -00007D02 72E8 jc print_disk_error_message ; If it failed then reboot -00007D04 5B pop bx ; Get the start cluster of NTLDR in BX -00007D05 8A5624 mov dl,[bp+BootDrive] ; Get boot drive in DL -00007D08 BE0B7C mov si,0x7c0b -00007D0B 8BFC mov di,sp -00007D0D C746F03D7D mov word [bp-0x10],read_cluster -00007D12 C746F4297D mov word [bp-0xc],0x7d29 -00007D17 8CD9 mov cx,ds -00007D19 894EF2 mov [bp-0xe],cx -00007D1C 894EF6 mov [bp-0xa],cx -00007D1F C606967DCB mov byte [0x7d96],0xcb -00007D24 EA03000020 jmp 0x2000:0x3 -00007D29 0FB6C8 movzx cx,al -00007D2C 668B46F8 mov eax,[bp-0x8] -00007D30 6603461C add eax,[bp+HiddenSectors] -00007D34 668BD0 mov edx,eax -00007D37 66C1EA10 shr edx,0x10 -00007D3B EB5E jmp short 0x7d9b -read_cluster: -00007D3D 0FB6C8 movzx cx,al -00007D40 4A dec dx -00007D41 4A dec dx -00007D42 8A460D mov al,[bp+SectsPerCluster] -00007D45 32E4 xor ah,ah -00007D47 F7E2 mul dx -00007D49 0346FC add ax,[bp-0x4] -00007D4C 1356FE adc dx,[bp-0x2] -00007D4F EB4A jmp short 0x7d9b - -read_sectors: -00007D51 52 push dx -00007D52 50 push ax -00007D53 06 push es -00007D54 53 push bx -00007D55 6A01 push byte +0x1 -00007D57 6A10 push byte +0x10 -00007D59 91 xchg ax,cx -00007D5A 8B4618 mov ax,[bp+SectorsPerTrack] -00007D5D 96 xchg ax,si -00007D5E 92 xchg ax,dx -00007D5F 33D2 xor dx,dx -00007D61 F7F6 div si -00007D63 91 xchg ax,cx -00007D64 F7F6 div si -00007D66 42 inc dx -00007D67 87CA xchg cx,dx -00007D69 F7761A div word [bp+NumberOfHeads] -00007D6C 8AF2 mov dh,dl -00007D6E 8AE8 mov ch,al -00007D70 C0CC02 ror ah,0x2 -00007D73 0ACC or cl,ah -00007D75 B80102 mov ax,0x201 -00007D78 807E020E cmp byte [bp+0x2],0xe -00007D7C 7504 jnz 0x7d82 -00007D7E B442 mov ah,0x42 -00007D80 8BF4 mov si,sp -00007D82 8A5624 mov dl,[bp+BootDrive] -00007D85 CD13 int 0x13 -00007D87 61 popa -00007D88 61 popa -00007D89 720B jc 0x7d96 -00007D8B 40 inc ax -00007D8C 7501 jnz 0x7d8f -00007D8E 42 inc dx -00007D8F 035E0B add bx,[bp+BytesPerSector] -00007D92 49 dec cx -00007D93 7506 jnz 0x7d9b -00007D95 F8 clc -00007D96 C3 ret - -read_one_sector: -00007D97 41 inc cx -00007D98 BB0000 mov bx,0x0 -00007D9B 60 pusha -00007D9C 666A00 o32 push byte +0x0 -00007D9F EBB0 jmp short 0x7d51 - - -NTLDR db 'NTLDR ' - - -NTLDR_ERR db 0dh,0ah,'NTLDR is missing',0ffh -DISK_ERR db 0dh,0ah,'Disk error',0ffh -RESTART_ERR db 0dh,0ah,'Press any key to restart',0dh,0ah - -filler times 18 db 0 - - -NTLDR_offset_from_0x7d00 db 0 -NTLDR_ERR_offset_from_0x7d00 db 0ach -DISK_ERR_offset_from_0x7d00 db 0bfh -RESTART_ERR_offset_from_0x7d00 db 0cch - - dw 0 - dw 0aa55h -- 2.17.1