+++ /dev/null
-;------------------------------------------------------------------------------\r
-;*\r
-;* Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
-;* This program and the accompanying materials \r
-;* are licensed and made available under the terms and conditions of the BSD License \r
-;* which accompanies this distribution. The full text of the license may be found at \r
-;* http://opensource.org/licenses/bsd-license.php \r
-;* \r
-;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-;* \r
-;* bs32.asm\r
-;* \r
-;* Abstract:\r
-;*\r
-;------------------------------------------------------------------------------\r
-\r
- .model small\r
- .stack\r
- .486p\r
- .code\r
-\r
-FAT_DIRECTORY_ENTRY_SIZE EQU 020h\r
-FAT_DIRECTORY_ENTRY_SHIFT EQU 5\r
-BLOCK_SIZE EQU 0200h\r
-BLOCK_MASK EQU 01ffh\r
-BLOCK_SHIFT EQU 9\r
- ; "EFILDR_____"\r
-LOADER_FILENAME_PART1 EQU 04c494645h ; "EFIL"\r
-LOADER_FILENAME_PART2 EQU 030325244h ; "DR20"\r
-LOADER_FILENAME_PART3 EQU 020202030h ; "0___"\r
-\r
- org 0h\r
-Ia32Jump:\r
- jmp BootSectorEntryPoint ; JMP inst - 3 bytes\r
- nop\r
-\r
-OemId db "INTEL " ; OemId - 8 bytes\r
-; BPB data below will be fixed by tool\r
-SectorSize dw 0 ; Sector Size - 16 bits\r
-SectorsPerCluster db 0 ; Sector Per Cluster - 8 bits\r
-ReservedSectors dw 0 ; Reserved Sectors - 16 bits\r
-NoFats db 0 ; Number of FATs - 8 bits\r
-RootEntries dw 0 ; Root Entries - 16 bits\r
-Sectors dw 0 ; Number of Sectors - 16 bits\r
-Media db 0 ; Media - 8 bits - ignored\r
-SectorsPerFat dw 0 ; Sectors Per FAT - 16 bits\r
-SectorsPerTrack dw 0 ; Sectors Per Track - 16 bits - ignored\r
-Heads dw 0 ; Heads - 16 bits - ignored\r
-HiddenSectors dd 0 ; Hidden Sectors - 32 bits - ignored\r
-LargeSectors dd 0 ; Large Sectors - 32 bits \r
-\r
-;******************************************************************************\r
-;\r
-;The structure for FAT32 starting at offset 36 of the boot sector. (At this point, \r
-;the BPB/boot sector for FAT12 and FAT16 differs from the BPB/boot sector for FAT32.)\r
-;\r
-;******************************************************************************\r
-\r
-SectorsPerFat32 dd 0 ; Sectors Per FAT for FAT32 - 4 bytes\r
-ExtFlags dw 0 ; Mirror Flag - 2 bytes\r
-FSVersion dw 0 ; File System Version - 2 bytes\r
-RootCluster dd 0 ; 1st Cluster Number of Root Dir - 4 bytes\r
-FSInfo dw 0 ; Sector Number of FSINFO - 2 bytes\r
-BkBootSector dw 0 ; Sector Number of Bk BootSector - 2 bytes\r
-Reserved db 12 dup(0) ; Reserved Field - 12 bytes\r
-PhysicalDrive db 0 ; Physical Drive Number - 1 byte\r
-Reserved1 db 0 ; Reserved Field - 1 byte\r
-Signature db 0 ; Extended Boot Signature - 1 byte\r
-VolId db " " ; Volume Serial Number - 4 bytes\r
-FatLabel db " " ; Volume Label - 11 bytes\r
-FileSystemType db "FAT32 " ; File System Type - 8 bytes\r
-\r
-BootSectorEntryPoint:\r
- ASSUME ds:@code\r
- ASSUME ss:@code\r
-\r
-; ****************************************************************************\r
-; Start Print\r
-; ****************************************************************************\r
- mov si, offset StartString\r
- call PrintString\r
-\r
-; ****************************************************************************\r
-; Print over\r
-; ****************************************************************************\r
-\r
- mov ax,cs ; ax = 0\r
- mov ss,ax ; ss = 0\r
- add ax,1000h\r
- mov ds,ax\r
-\r
- mov sp,07c00h ; sp = 0x7c00\r
- mov bp,sp ; bp = 0x7c00\r
-\r
- mov ah,8 ; ah = 8 - Get Drive Parameters Function\r
- mov byte ptr [bp+PhysicalDrive],dl ; BBS defines that BIOS would pass the booting driver number to the loader through DL\r
- int 13h ; Get Drive Parameters\r
- xor ax,ax ; ax = 0\r
- mov al,dh ; al = dh\r
- inc al ; MaxHead = al + 1\r
- push ax ; 0000:7bfe = MaxHead\r
- mov al,cl ; al = cl\r
- and al,03fh ; MaxSector = al & 0x3f\r
- push ax ; 0000:7bfc = MaxSector\r
-\r
- cmp word ptr [bp+SectorSignature],0aa55h ; Verify Boot Sector Signature\r
- jne BadBootSector\r
- mov cx,word ptr [bp+RootEntries] ; cx = RootEntries\r
- shl cx,FAT_DIRECTORY_ENTRY_SHIFT ; cx = cx * 32 = cx * sizeof(FAT_DIRECTORY_ENTRY) = Size of Root Directory in bytes\r
- mov bx,cx ; bx = size of the Root Directory in bytes\r
- and bx,BLOCK_MASK ; See if it is an even number of sectors long\r
- jne BadBootSector ; If is isn't, then the boot sector is bad.\r
- mov bx,cx ; bx = size of the Root Directory in bytes\r
- shr bx,BLOCK_SHIFT ; bx = size of Root Directory in sectors\r
- mov al,byte ptr [bp+NoFats] ; al = NoFats\r
- xor ah,ah ; ah = 0 ==> ax = NoFats\r
- mul word ptr [bp+SectorsPerFat32] ; ax = NoFats * SectorsPerFat\r
- add ax,word ptr [bp+ReservedSectors] ; ax = NoFats * SectorsPerFat + ReservedSectors = RootLBA\r
- add ax,bx ; ax = NoFats * SectorsPerFat + ReservedSectors + RootDirSectors = FirstClusterLBA\r
- mov word ptr [bp],ax ; Save FirstClusterLBA for later use\r
- \r
- mov ax,word ptr [bp+RootCluster] ; ax = StartCluster of Root Directory\r
- sub ax,2 ; ax = StartCluster - 2\r
- xor bh,bh \r
- mov bl,byte ptr [bp+SectorsPerCluster]; bx = SectorsPerCluster\r
- mul bx ; ax = (StartCluster - 2) * SectorsPerCluster\r
- add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster\r
- push ds\r
- pop es\r
- xor di,di ; Store directory in es:di = 1000:0000\r
- call ReadBlocks ; Read StartCluster of Root Directory\r
-\r
- ; dx - variable storage (initial value is 0)\r
- ; bx - loader (initial value is 0)\r
- xor dx, dx\r
- xor bx, bx\r
-\r
-FindEFILDR:\r
- cmp dword ptr [di],LOADER_FILENAME_PART1 ; Compare to "EFIL"\r
- jne FindVARSTORE\r
- cmp dword ptr [di+4],LOADER_FILENAME_PART2\r
- jne FindVARSTORE\r
- cmp dword ptr [di+7],LOADER_FILENAME_PART3\r
- jne FindVARSTORE\r
- mov bx, word ptr [di+26] ; bx = Start Cluster for EFILDR <----------------------------------\r
- test dx, dx\r
- je FindNext ; Efivar.bin is not loaded\r
- jmp FoundAll\r
-\r
-FindVARSTORE:\r
- ; if the file is not loader file, see if it's "EFIVAR BIN"\r
- cmp dword ptr [di], 056494645h ; Compare to "EFIV"\r
- jne FindNext\r
- cmp dword ptr [di+4], 020205241h ; Compare to "AR "\r
- jne FindNext\r
- cmp dword ptr [di+7], 04e494220h ; Compare to " BIN"\r
- jne FindNext\r
- mov dx, di ; dx = Offset of Start Cluster for Efivar.bin <---------------------\r
- add dx, 26\r
- test bx, bx\r
- je FindNext ; Efildr is not loaded\r
- jmp FoundAll\r
- \r
-FindNext:\r
- ; go to next find\r
- add di,FAT_DIRECTORY_ENTRY_SIZE ; Increment di\r
- sub cx,FAT_DIRECTORY_ENTRY_SIZE ; Decrement cx\r
- ; TODO: jump to FindVarStore if ...\r
- jne FindEFILDR\r
- jmp NotFoundAll\r
-\r
-FoundAll:\r
-FoundEFILDR:\r
- mov cx,bx ; cx = Start Cluster for EFILDR <----------------------------------\r
- mov ax,cs ; Destination = 2000:0000\r
- add ax,2000h\r
- mov es,ax\r
- xor di,di\r
-ReadFirstClusterOfEFILDR:\r
- mov ax,cx ; ax = StartCluster\r
- sub ax,2 ; ax = StartCluster - 2\r
- xor bh,bh \r
- mov bl,byte ptr [bp+SectorsPerCluster] ; bx = SectorsPerCluster\r
- push dx\r
- mul bx\r
- pop dx ; ax = (StartCluster - 2) * SectorsPerCluster\r
- add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster\r
- xor bh,bh\r
- mov bl,byte ptr [bp+SectorsPerCluster] ; bx = Number of Sectors in a cluster\r
- push es\r
- call ReadBlocks\r
- pop ax\r
-JumpIntoFirstSectorOfEFILDR:\r
- mov word ptr [bp+JumpSegment],ax\r
-JumpFarInstruction:\r
- db 0eah\r
-JumpOffset:\r
- dw 0000h\r
-JumpSegment:\r
- dw 2000h\r
-\r
-\r
-PrintString:\r
- mov ax,0b800h\r
- mov es,ax\r
- mov ax, 07c0h\r
- mov ds, ax\r
- mov cx, 6\r
- mov di, 160\r
- rep movsw\r
- ret\r
-; ****************************************************************************\r
-; ReadBlocks - Reads a set of blocks from a block device\r
-;\r
-; AX = Start LBA\r
-; BX = Number of Blocks to Read\r
-; ES:DI = Buffer to store sectors read from disk\r
-; ****************************************************************************\r
-\r
-; cx = Blocks\r
-; bx = NumberOfBlocks\r
-; si = StartLBA\r
-\r
-ReadBlocks:\r
- pusha\r
- add eax,dword ptr [bp+LBAOffsetForBootSector] ; Add LBAOffsetForBootSector to Start LBA\r
- add eax,dword ptr [bp+HiddenSectors] ; Add HiddenSectors to Start LBA\r
- mov esi,eax ; esi = Start LBA\r
- mov cx,bx ; cx = Number of blocks to read\r
-ReadCylinderLoop:\r
- mov bp,07bfch ; bp = 0x7bfc\r
- mov eax,esi ; eax = Start LBA\r
- xor edx,edx ; edx = 0\r
- movzx ebx,word ptr [bp] ; bx = MaxSector\r
- div ebx ; ax = StartLBA / MaxSector\r
- inc dx ; dx = (StartLBA % MaxSector) + 1\r
- sub bx,dx ; bx = MaxSector - Sector\r
- inc bx ; bx = MaxSector - Sector + 1\r
- cmp cx,bx ; Compare (Blocks) to (MaxSector - Sector + 1)\r
- jg LimitTransfer\r
- mov bx,cx ; bx = Blocks\r
-LimitTransfer:\r
- push cx\r
- mov cl,dl ; cl = (StartLBA % MaxSector) + 1 = Sector\r
- xor dx,dx ; dx = 0\r
- div word ptr [bp+2] ; ax = ax / (MaxHead + 1) = Cylinder \r
- ; dx = ax % (MaxHead + 1) = Head\r
-\r
- push bx ; Save number of blocks to transfer\r
- mov dh,dl ; dh = Head\r
- mov bp,07c00h ; bp = 0x7c00\r
- mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number\r
- mov ch,al ; ch = Cylinder\r
- mov al,bl ; al = Blocks\r
- mov ah,2 ; ah = Function 2\r
- mov bx,di ; es:bx = Buffer address\r
- int 013h\r
- jc DiskError\r
- pop bx\r
- pop cx\r
- movzx ebx,bx\r
- add esi,ebx ; StartLBA = StartLBA + NumberOfBlocks\r
- sub cx,bx ; Blocks = Blocks - NumberOfBlocks\r
- mov ax,es\r
- shl bx,(BLOCK_SHIFT-4)\r
- add ax,bx\r
- mov es,ax ; es:di = es:di + NumberOfBlocks*BLOCK_SIZE\r
- cmp cx,0\r
- jne ReadCylinderLoop\r
- popa\r
- ret\r
-\r
-; ****************************************************************************\r
-; ERROR Condition:\r
-; ****************************************************************************\r
-NotFoundAll:\r
- ; if we found EFILDR, continue\r
- test bx,bx\r
- jne FoundEFILDR\r
-BadBootSector:\r
-DiskError:\r
- mov si, offset ErrorString\r
- call PrintString\r
-Halt:\r
- jmp Halt\r
-\r
-StartString:\r
- db 'B', 0ch, 'S', 0ch, 't', 0ch, 'a', 0ch, 'r', 0ch, 't', 0ch\r
-ErrorString:\r
- db 'B', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch\r
-\r
-; ****************************************************************************\r
-; LBA Offset for BootSector, need patched by tool for HD boot.\r
-; ****************************************************************************\r
-\r
- org 01fah\r
-LBAOffsetForBootSector:\r
- dd 0h\r
-\r
-; ****************************************************************************\r
-; Sector Signature\r
-; ****************************************************************************\r
-\r
- org 01feh\r
-SectorSignature:\r
- dw 0aa55h ; Boot Sector Signature\r
-\r
- end \r
- \r