diff options
author | klu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524> | 2008-04-17 05:48:13 +0000 |
---|---|---|
committer | klu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524> | 2008-04-17 05:48:13 +0000 |
commit | c69dd9dfad3eb97d5e21f520f3ba35d102ec4cfa (patch) | |
tree | e6065a748931519b3cf11d9811c0beef9c80d58e /DuetPkg/BootSector/bootsect.asm | |
parent | fcf03596d10de53e45292bd9eb4767a8ddc344ed (diff) | |
download | edk2-platforms-c69dd9dfad3eb97d5e21f520f3ba35d102ec4cfa.tar.xz |
Porting Duet module from EDKI to EDKII
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5076 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'DuetPkg/BootSector/bootsect.asm')
-rw-r--r-- | DuetPkg/BootSector/bootsect.asm | 288 |
1 files changed, 288 insertions, 0 deletions
diff --git a/DuetPkg/BootSector/bootsect.asm b/DuetPkg/BootSector/bootsect.asm new file mode 100644 index 0000000000..972e36e8a1 --- /dev/null +++ b/DuetPkg/BootSector/bootsect.asm @@ -0,0 +1,288 @@ +;------------------------------------------------------------------------------
+;*
+;* Copyright 2006 - 2007, Intel Corporation
+;* All rights reserved. This program and the accompanying materials
+;* are licensed and made available under the terms and conditions of the BSD License
+;* which accompanies this distribution. The full text of the license may be found at
+;* http://opensource.org/licenses/bsd-license.php
+;*
+;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;*
+;* bootsect.asm
+;*
+;* Abstract:
+;*
+;------------------------------------------------------------------------------
+
+ .model small
+ .stack
+ .486p
+ .code
+
+FAT_DIRECTORY_ENTRY_SIZE EQU 020h
+FAT_DIRECTORY_ENTRY_SHIFT EQU 5
+BLOCK_SIZE EQU 0200h
+BLOCK_MASK EQU 01ffh
+BLOCK_SHIFT EQU 9
+ ; "EFILDR_____"
+LOADER_FILENAME_PART1 EQU 04c494645h ; "EFIL"
+LOADER_FILENAME_PART2 EQU 020205244h ; "DR__"
+LOADER_FILENAME_PART3 EQU 020202020h ; "____"
+
+ org 0h
+Ia32Jump:
+ jmp BootSectorEntryPoint ; JMP inst - 3 bytes
+ nop
+
+OemId db "INTEL " ; OemId - 8 bytes
+; BPB data below will be fixed by tool
+SectorSize dw 0 ; Sector Size - 16 bits
+SectorsPerCluster db 0 ; Sector Per Cluster - 8 bits
+ReservedSectors dw 0 ; Reserved Sectors - 16 bits
+NoFats db 0 ; Number of FATs - 8 bits
+RootEntries dw 0 ; Root Entries - 16 bits
+Sectors dw 0 ; Number of Sectors - 16 bits
+Media db 0 ; Media - 8 bits - ignored
+SectorsPerFat dw 0 ; Sectors Per FAT - 16 bits
+SectorsPerTrack dw 0 ; Sectors Per Track - 16 bits - ignored
+Heads dw 0 ; Heads - 16 bits - ignored
+HiddenSectors dd 0 ; Hidden Sectors - 32 bits - ignored
+LargeSectors dd 0 ; Large Sectors - 32 bits
+PhysicalDrive db 0 ; PhysicalDriveNumber - 8 bits - ignored
+CurrentHead db 0 ; Current Head - 8 bits
+Signature db 0 ; Signature - 8 bits - ignored
+Id db " " ; Id - 4 bytes
+FatLabel db " " ; Label - 11 bytes
+SystemId db "FAT12 " ; SystemId - 8 bytes
+
+BootSectorEntryPoint:
+ ASSUME ds:@code
+ ASSUME ss:@code
+
+; ****************************************************************************
+; Start Print
+; ****************************************************************************
+ lea si, cs:[StartString]
+ call PrintString
+
+; ****************************************************************************
+; Print over
+; ****************************************************************************
+
+ mov ax,cs ; ax = 0
+ mov ss,ax ; ss = 0
+ add ax,1000h
+ mov ds,ax
+
+ mov sp,07c00h ; sp = 0x7c00
+ mov bp,sp ; bp = 0x7c00
+
+ mov ah,8 ; ah = 8 - Get Drive Parameters Function
+ mov byte ptr [bp+PhysicalDrive],dl ; BBS defines that BIOS would pass the booting driver number to the loader through DL
+ int 13h ; Get Drive Parameters
+ xor ax,ax ; ax = 0
+ mov al,dh ; al = dh
+ inc al ; MaxHead = al + 1
+ push ax ; 0000:7bfe = MaxHead
+ mov al,cl ; al = cl
+ and al,03fh ; MaxSector = al & 0x3f
+ push ax ; 0000:7bfc = MaxSector
+
+ cmp word ptr [bp+SectorSignature],0aa55h ; Verify Boot Sector Signature
+ jne BadBootSector
+ mov cx,word ptr [bp+RootEntries] ; cx = RootEntries
+ shl cx,FAT_DIRECTORY_ENTRY_SHIFT ; cx = cx * 32 = cx * sizeof(FAT_DIRECTORY_ENTRY) = Size of Root Directory in bytes
+ mov bx,cx ; bx = size of the Root Directory in bytes
+ and bx,BLOCK_MASK ; See if it is an even number of sectors long
+ jne BadBootSector ; If is isn't, then the boot sector is bad.
+ mov bx,cx ; bx = size of the Root Directory in bytes
+ shr bx,BLOCK_SHIFT ; bx = size of Root Directory in sectors
+ mov al,byte ptr [bp+NoFats] ; al = NoFats
+ xor ah,ah ; ah = 0 ==> ax = NoFats
+ mul word ptr [bp+SectorsPerFat] ; ax = NoFats * SectorsPerFat
+ add ax,word ptr [bp+ReservedSectors] ; ax = NoFats * SectorsPerFat + ReservedSectors = RootLBA
+ push ds
+ pop es
+ xor di,di ; Store directory in es:di = 1000:0000
+ call ReadBlocks ; Read entire Root Directory
+ add ax,bx ; ax = NoFats * SectorsPerFat + ReservedSectors + RootDirSectors = FirstClusterLBA (FirstDataSector)
+ mov word ptr [bp],ax ; Save FirstClusterLBA (FirstDataSector) for later use
+
+ ; dx - variable storage (initial value is 0)
+ ; bx - loader (initial value is 0)
+ xor dx, dx
+ xor bx, bx
+
+FindEFILDR:
+ cmp dword ptr [di],LOADER_FILENAME_PART1 ; Compare to "EFIL"
+ jne FindVARSTORE
+ cmp dword ptr [di+4],LOADER_FILENAME_PART2
+ jne FindVARSTORE
+ cmp dword ptr [di+7],LOADER_FILENAME_PART3
+ jne FindVARSTORE
+ mov bx, word ptr [di+26] ; bx = Start Cluster for EFILDR <----------------------------------
+ test dx, dx
+ je FindNext ; Efivar.bin is not loaded
+ jmp FoundAll
+
+FindVARSTORE:
+ ; if the file is not loader file, see if it's "EFIVAR BIN"
+ cmp dword ptr [di], 056494645h ; Compare to "EFIV"
+ jne FindNext
+ cmp dword ptr [di+4], 020205241h ; Compare to "AR "
+ jne FindNext
+ cmp dword ptr [di+7], 04e494220h ; Compare to " BIN"
+ jne FindNext
+ mov dx, di ; dx = Offset of Start Cluster for Efivar.bin <---------------------
+ add dx, 26
+ test bx, bx
+ je FindNext ; Efildr is not loaded
+ jmp FoundAll
+
+FindNext:
+ ; go to next find
+ add di,FAT_DIRECTORY_ENTRY_SIZE ; Increment di
+ sub cx,FAT_DIRECTORY_ENTRY_SIZE ; Decrement cx
+ ; TODO: jump to FindVarStore if ...
+ jne FindEFILDR
+ jmp NotFoundAll
+
+FoundAll:
+FoundEFILDR:
+ mov cx,bx ; cx = Start Cluster for EFILDR <----------------------------------
+ mov ax,cs ; Destination = 2000:0000
+ add ax,2000h
+ mov es,ax
+ xor di,di
+ReadFirstClusterOfEFILDR:
+ mov ax,cx ; ax = StartCluster
+ sub ax,2 ; ax = StartCluster - 2
+ xor bh,bh
+ mov bl,byte ptr [bp+SectorsPerCluster] ; bx = SectorsPerCluster
+ push dx
+ mul bx
+ pop dx ; ax = (StartCluster - 2) * SectorsPerCluster
+ add ax, word ptr [bp] ; ax = FirstClusterLBA + (StartCluster-2)*SectorsPerCluster
+ xor bh,bh
+ mov bl,byte ptr [bp+SectorsPerCluster] ; bx = Number of Sectors in a cluster
+ push es
+ call ReadBlocks
+ pop ax
+JumpIntoFirstSectorOfEFILDR:
+ mov word ptr [bp+JumpSegment],ax
+JumpFarInstruction:
+ db 0eah
+JumpOffset:
+ dw 0000h
+JumpSegment:
+ dw 2000h
+
+
+PrintString:
+ mov ax,0b800h
+ mov es,ax
+ mov ax, 07c0h
+ mov ds, ax
+ mov cx, 7
+ mov di, 160
+ rep movsw
+ ret
+; ****************************************************************************
+; ReadBlocks - Reads a set of blocks from a block device
+;
+; AX = Start LBA
+; BX = Number of Blocks to Read
+; ES:DI = Buffer to store sectors read from disk
+; ****************************************************************************
+
+; cx = Blocks
+; bx = NumberOfBlocks
+; si = StartLBA
+
+ReadBlocks:
+ pusha
+ add eax,dword ptr [bp+LBAOffsetForBootSector] ; Add LBAOffsetForBootSector to Start LBA
+ add eax,dword ptr [bp+HiddenSectors] ; Add HiddenSectors to Start LBA
+ mov esi,eax ; esi = Start LBA
+ mov cx,bx ; cx = Number of blocks to read
+ReadCylinderLoop:
+ mov bp,07bfch ; bp = 0x7bfc
+ mov eax,esi ; eax = Start LBA
+ xor edx,edx ; edx = 0
+ movzx ebx,word ptr [bp] ; bx = MaxSector
+ div ebx ; ax = StartLBA / MaxSector
+ inc dx ; dx = (StartLBA % MaxSector) + 1
+ sub bx,dx ; bx = MaxSector - Sector
+ inc bx ; bx = MaxSector - Sector + 1
+ cmp cx,bx ; Compare (Blocks) to (MaxSector - Sector + 1)
+ jg LimitTransfer
+ mov bx,cx ; bx = Blocks
+LimitTransfer:
+ push cx
+ mov cl,dl ; cl = (StartLBA % MaxSector) + 1 = Sector
+ xor dx,dx ; dx = 0
+ div word ptr [bp+2] ; ax = ax / (MaxHead + 1) = Cylinder
+ ; dx = ax % (MaxHead + 1) = Head
+
+ push bx ; Save number of blocks to transfer
+ mov dh,dl ; dh = Head
+ mov bp,07c00h ; bp = 0x7c00
+ mov dl,byte ptr [bp+PhysicalDrive] ; dl = Drive Number
+ mov ch,al ; ch = Cylinder
+ mov al,bl ; al = Blocks
+ mov ah,2 ; ah = Function 2
+ mov bx,di ; es:bx = Buffer address
+ int 013h
+ jc DiskError
+ pop bx
+ pop cx
+ movzx ebx,bx
+ add esi,ebx ; StartLBA = StartLBA + NumberOfBlocks
+ sub cx,bx ; Blocks = Blocks - NumberOfBlocks
+ mov ax,es
+ shl bx,(BLOCK_SHIFT-4)
+ add ax,bx
+ mov es,ax ; es:di = es:di + NumberOfBlocks*BLOCK_SIZE
+ cmp cx,0
+ jne ReadCylinderLoop
+ popa
+ ret
+
+; ****************************************************************************
+; ERROR Condition:
+; ****************************************************************************
+NotFoundAll:
+ ; if we found EFILDR, continue
+ test bx,bx
+ jne FoundEFILDR
+BadBootSector:
+DiskError:
+ lea si, cs:[ErrorString]
+ call PrintString
+Halt:
+ jmp Halt
+
+StartString:
+ db 'B', 0ch, 'S', 0ch, 't', 0ch, 'a', 0ch, 'r', 0ch, 't', 0ch, '!', 0ch
+ErrorString:
+ db 'B', 0ch, 'E', 0ch, 'r', 0ch, 'r', 0ch, 'o', 0ch, 'r', 0ch, '!', 0ch
+
+; ****************************************************************************
+; LBA Offset for BootSector, need patched by tool for HD boot.
+; ****************************************************************************
+
+ org 01fah
+LBAOffsetForBootSector:
+ dd 0h
+
+; ****************************************************************************
+; Sector Signature
+; ****************************************************************************
+
+ org 01feh
+SectorSignature:
+ dw 0aa55h ; Boot Sector Signature
+
+ end
+
|