bootsect.asm
来自「Next BIOS Source code : Extensible Firmw」· 汇编 代码 · 共 277 行
ASM
277 行
;******************************************************************************
;*
;* Copyright (c) 1999 - 2003 Intel Corporation. All rights reserved
;* This software and associated documentation (if any) is furnished
;* under a license and may only be used or copied in accordance
;* with the terms of the license. Except as permitted by such
;* license, no part of this software or documentation may be
;* reproduced, stored in a retrieval system, or transmitted in any
;* form or by any means without the express written consent of
;* Intel Corporation.
;*
;******************************************************************************
;
; $Header$
; $Log$
;
;******************************************************************************
.model small
; .dosseg
.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
org 0h
Ia32Jump:
jmp BootSectorEntryPoint ; JMP inst - 3 bytes
nop
OemId db "INTEL " ; OemId - 8 bytes
SectorSize dw 0200h ; Sector Size - 16 bits
SectorsPerCluster db 01h ; Sector Per Cluster - 8 bits
ReservedSectors dw 01h ; Reserved Sectors - 16 bits
NoFats db 02h ; Number of FATs - 8 bits
RootEntries dw 00e0h ; Root Entries - 16 bits
Sectors dw 0b40h ; Number of Sectors - 16 bits
Media db 0f0h ; Media - 8 bits - ignored
SectorsPerFat dw 0009h ; Sectors Per FAT - 16 bits
SectorsPerTrack dw 0012h ; Sectors Per Track - 16 bits - ignored
Heads dw 0002h ; Heads - 16 bits - ignored
HiddenSectors dd 0000h ; Hidden Sectors - 32 bits - ignored
LargeSectors dd 0000h ; Large Sectors - 32 bits
PhysicalDrive db 00h ; PhysicalDriveNumber - 8 bits - ignored
CurrentHead db 00h ; Current Head - 8 bits
Signature db 29h ; Signature - 8 bits - ignored
Id db " " ; Id - 4 bytes
FatLabel db "EFI FLOPPY " ; Label - 11 bytes
SystemId db "FAT12 " ; SystemId - 8 bytes
BootSectorEntryPoint:
ASSUME ds:@code
ASSUME ss:@code
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 dl,0 ; dl = 0 - Floppy Drive
int 13h ; Get Drive Parameters
xor ax,ax ; ax = 0
mov al,dh ; al = dh
and al,03fh ; MaxHead = (al & 0x3f)
inc al ; MaxHead = (al & 0x3f) + 1
push ax ; 0000:7bfe = MaxHead + 1
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
cmp byte ptr [bp+Ia32Jump],0ebh ; Verify that first byte is a jump inst
jne BadBootSector
cmp word ptr [bp+SectorSize],00200h ; Verify Block Size == 0x200
jne BadBootSector
cmp byte ptr [bp+SectorsPerCluster],000h ; Verify Sectors Per Cluster != 0
je BadBootSector
cmp word ptr [bp+RootEntries],00000h ; Verify Root Entries != 0
je BadBootSector
mov ax, word ptr [bp+ReservedSectors] ; Verify ReservedSectors > Sectors
cmp ax, word ptr [bp+Sectors]
jg BadBootSector
xor cx,cx
lea si,OemId
mov cl,8
call CheckASCII
lea si,FatLabel
mov cl,11
call CheckASCII
cmp word ptr [bp+SystemId],04146h ; Check for "FA"
jne BadBootSector
cmp word ptr [bp+SystemId+2],03154h ; Check for "T1"
jne BadBootSector
mov ax,02020h
cmp word ptr [bp+SystemId+5],ax
jne BadBootSector
cmp word ptr [bp+SystemId+6],ax
jne BadBootSector
cmp byte ptr [bp+SystemId+4],'2'
je Fat12Found
cmp byte ptr [bp+SystemId+4],'6'
je Fat16Found
jmp BadBootSector
Fat12Found:
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 di,0 ; Store directory in es:di = 1000:0000
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
call ReadBlocks ; Read entire Root Directory
add ax,bx ; ax = NoFats * SectorsPerFat + ReservedSectors + RootDirSectors = FirstClusterLBA
mov word ptr [bp],ax ; Save FirstClusterLBA for later use
FindEFILDR:
cmp word ptr [di],04645h ; Compare to "EF"
jne NotMatchingEFILDR
cmp word ptr [di+2],04c49h ; Compare to "IL"
jne NotMatchingEFILDR
cmp word ptr [di+4],05244h ; Compare to "DR"
jne NotMatchingEFILDR
mov ax,02020h ; ax = " "
cmp word ptr [di+6],ax ; Compare to " "
jne NotMatchingEFILDR
cmp word ptr [di+8],ax ; Compare to " "
jne NotMatchingEFILDR
cmp word ptr [di+9],ax ; Compare to " "
jne NotMatchingEFILDR
mov al, byte ptr [di+11]
and al,058h
je FoundEFILDR
NotMatchingEFILDR:
add di,FAT_DIRECTORY_ENTRY_SIZE ; Increment di
sub cx,FAT_DIRECTORY_ENTRY_SIZE ; Decrement cx
jne FindEFILDR
jmp NotFoundEFILDR
FoundEFILDR:
mov cx, word ptr [di+26] ; cx = FileCluster 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
mul bx ; 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
; ****************************************************************************
; 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
mov si,ax ; si = Start LBA
mov cx,bx ; cx = Number of blocks to read
ReadCylinderLoop:
mov bp,07bfch ; bp = 0x7bfc
mov ax,si ; ax = Start LBA
xor dx,dx ; dx = 0
div word ptr [bp] ; ax = StartLBA / MaxSector
inc dx ; dx = (StartLBA % MaxSector) + 1
mov bx,word ptr [bp] ; bx = MaxSector
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 dl,0 ; 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
pop bx
pop cx
add si,bx ; 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
; ****************************************************************************
; CheckASCII - Verifies that a buffer contains only ASCII characters
;
; CX = Number of characters to check
; SS:BP+SI = Buffer to check
; ****************************************************************************
CheckASCII:
cmp byte ptr [bp+si],07fh
jg BadBootSector
cmp byte ptr [bp+si],020h
jl BadBootSector
inc si
loop CheckASCII
ret
; ****************************************************************************
; ERROR Condition:
; ****************************************************************************
BadBootSector:
Fat16Found:
NotFoundEFILDR:
int 3
jmp BadBootSector
; ****************************************************************************
; Sector Signature
; ****************************************************************************
org 01feh
SectorSignature:
dw 0aa55h ; Boot Sector Signature
end
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?