;/********************** START OF SPECIFICATIONS ************************/
;/* */
;/* SUBROUTINE NAME: ntfsboot */
;/* */
;/* DESCRIPTIVE NAME: Bootstrap loader */
;/* */
;/* FUNCTION: To load NTLDR into memory. */
;/* */
;/* NOTES: ntfsboot is loaded by the ROM BIOS (Int 19H) at */
;/* physical memory location 0000:7C00H. */
;/* ntfsboot runs in real mode. */
;/* This boot record is for NTFS volumes only. */
;/* */
;/* ENTRY POINT: ntfsboot */
;/* LINKAGE: Jump (far) from Int 19H */
;/* */
;/* INPUT: CS:IP = 0000:7C00H */
;/* SS:SP = 0030:00FAH (CBIOS dependent) */
;/* */
;/* EXIT-NORMAL: DL = INT 13 drive number we booted from */
;/* Jmp to main in NTLDR */
;/* */
;/* EXIT-ERROR: None */
;/* */
;/* EFFECTS: NTLDR is loaded into the physical memory */
;/* location 00020000H */
;/* MESSAGES: A disk read error occurred. */
;/* The file NTLDR cannot be found. */
;/* Insert a system diskette and restart the system. */
BootCode segment
assume cs:BootCode,ds:nothing,es:nothing,ss:nothing
org 0
public _ntfsboot
_ntfsboot proc far
jmp start
.errnz ($-_ntfsboot) GT (3),
org 3
; 这是一个参数块的模版 – 任何调用者将引导代码写入磁盘以后都应该保存一个存在的参数块以及NTFS信息或者创建一个新的
Version db \ \ ; Must be 8 characters
BPB label byte
BytesPerSector dw 0 ; Size of a physical sector
SectorsPerCluster db 0 ; Sectors per allocation unit
ReservedSectors dw 0 ; Number of reserved sectors
Fats db 0 ; Number of fats
DirectoryEntries dw 0 ; Number of directory entries
Sectors dw 0 ; No. of sectors - no. of hidden sectors
Media db 0 ; Media byte
FatSectors dw 0 ; Number of fat sectors
SectorsPerTrack dw 0 ; Sectors per track
Heads dw 0 ; Number of surfaces
HiddenSectors dd 0 ; Number of hidden sectors
SectorsLong dd 0 ; Number of sectors iff Sectors = 0
; The following is the rest of the NTFS Sector Zero information.
; The position and order of DriveNumber and CurrentHead are especiallyimportant
; since those two variables are loaded into a single 16-bitregister for the BIOS with one instruction.
DriveNumber db 80h ; Physical drive number (0 or 80h)
CurrentHead db ?; Variable to store current head no.
SectorZeroPad1 dw 0
SectorsOnVolume db (size LARGE_INTEGER) dup (0)
MftStartLcn db (size LARGE_INTEGER) dup (0)
Mft2StartLcn db (size LARGE_INTEGER) dup (0)
ClustersPerFrs dd 0
DefClustersPerBuf dd 0
SerialNumber db (size LARGE_INTEGER) dup (0)
CheckSum dd 0
; The following variables are not part of the Extended BPB; they're justscratch variables for the boot code.
SectorBase dd ? ; next sector to read
CurrentTrack dw ? ; current track
CurrentSector db ? ; current sector
SectorCount dw ? ; number of sectors to read
start:
; 首先设置需要用到的区段(堆栈和数据).
cli
xor ax, ax ; 设置堆栈起点为该代码的前一句,在重定位之后将会被转移
mov ss, ax
mov sp, 7c00h .
Sti
;BIOS把可引导磁盘(磁道0,磁头0,扇区1)的第一个物理扇区映射到内存中物理地址为7C00处
mov ax, Bootseg
mov ds, ax
assume ds:BootCode
; 开始将引导块内容读入内存,然后跳转至新版本的引导块,位于第二扇区开始处
mov SectorBase.lsw, 0 ; 读取扇区0.
mov SectorBase.msw, 0
mov word ptr [SectorCount], 16 ; 读取引导区域代码
mov ax, NewSeg ; 在NewSeg处读取.
mov es, ax
sub bx, bx ; 定位NewSeg:0000.
call DoReadLL ; 调用底层的DoRead例程,该部分读取扇区的代码从略
push NewSeg ; 调整到 NewSeg:0200h.
push offset mainboot ; 压入第二个扇区的地址
ret ; 返回到第二个扇区
_ntfsboot endp
Intel x86 处理器支持实模式和保护模式,在实模式下,处理器的寄存器都是16 位的,而且不支持虚拟地址转译,只能访问物理内存空间中最低的1 MB 内存。计算机系统的BIOS 工作在实模式下,并且,当ntldr 获得控制权时,处理器仍然在实模式下运行。Ntldr文件实际上是由两部分组成的:第一部分是实模式代码,即首先获得控制的代码区;第二部分是一个标准的Windows 可执行二进制文件,在ntldr 中这部分被称为os loader。
; 此处代码摘自NT4代码的\\private\\\\ntos\\boot\\startup\\i386\\su.asm
; _EnableProtectPaging
; 加载386保护模式寄存器
; 启用386保护模式
; 加载分页寄存器
; 启用386分页机制
public _EnableProtectPaging
_EnableProtectPaging proc near
push dword ptr 0
popfd
mov bx,sp
mov dx,[bx+2] ; 检测是否是第一次开启保护模式以及分页机制
xor ax,ax
mov gs,ax
mov es,ax
; 当调用内核的时候FS必须包含PCR的选择字
push PCR_Selector
pop fs