;====================================================================
;FlyingDragon OS Boot Sector FOR NTFS File System
;Author: Jack
;V0.01 2005-9-1 20:58
;Build : nasm -f bin NTFS.ASM -oNTFS.BIN
;====================================================================================
;BIOS在启动中的角色:
;(1) BIOS装载引导驱动器上的0扇区(CHS = 0:0:1)内容到内存线性地址7C00H处;
;(2) BIOS检查所装载的扇区是否有启动标记(510、511字节分别为55H和AAH);
;(3) CPU寄存器DL被设置为分配给引导驱动器的驱动器号,00H为软驱A,80H为硬盘C;
;(4) BIOS跳转到其装载的扇区中的代码(即7C00H处),将控制权转交给引导代码。
;引导代码应该初始化以下寄存器:
;(1) DS:某些BIOS设置其值为0,某些设置其为40H,它应该被设置为(7C00H-BOOT_ORG)/16;
;其中,BOOT_ORG为引导代码的ORG值,该值通常为7C00H(这意味着DS应设置为0);
;(2) SS和SP(堆栈):这两个寄存器的初始值依赖于BIOS;
;(3) CS个IP(通过JMP指令):大多数的BIOS进入启动代码的地址为0000:7C00H,但是某些
;BIOS却跳转到07C0:0000H。由于短跳转和条件跳转是IP相关的,因此如果没有使用
;远跳转或者绝对跳转,则不需要重置CS和IP;然而,DS仍旧必须是正确的值。
;=====================================================================================
;常规内存( 0000 0000H - 000F FFFFH,即0-1MB )在系统启动时的使用情况
;=====================================================================================
;---------------------------------
;| 0000 0000 - 0000 03FF | 1024B IDT read only
;|-------------------------------|
;| 0000 0400 - 0000 04FF | 256B BIOS Data Area , read only
;|-------------------------------|
;| 0000 0500 - 0000 7BFF |* 30464B Free Memory , read/write (29.75KB)
;|------------------------------ |
;| 0000 7C00 - 0000 7DFF | 512B Boot Sector , read/write
;|------------------------------ |
;| 0000 7E00 - 0000 7FFF | 512B Free Memory , read /write
;|------------------------------ |
;| 0000 8000 - 0009 FBFF | 607KB Free Memory , read / write( 32K - 639KB )
;|------------------------------ |
;| 0009 FC00 - 0009 FFFF |** 1KB EBDA extended BIOS data area
;|------------------------------ |
;| 000A 0000 - 000A FFFF | 64KB Video Memory
;|------------------------------ |
;| 000B 0000 - 000B 7FFF | 32KB Mono Video Text Memory
;|------------------------------ |
;| 000B 8000 - 000B FFFF | 32KB Color Video Text Memory
;|------------------------------ |
;| 000C 0000 - 000C 7FFF | 32KB Video BIOS , read only
;|------------------------------ |
;| 000C 8000 - 000E FFFF | 160KB Adapter ROM,read only
;|------------------------------ |
;| 000F 0000 - 000F FFFF | 64KB System BIOS, read only
;|------------------------------ |
;| 0010 0000 - 0010 FFEF |***64KB-16 High Memory Area,read/write ( 1MB开始处 )
;|------------------------------ |
;| 0010 FFF0 - | Free Extended Memory, read/write
;|------------------------------ |
;空闲内存实际并非从 0000 0500处开始,BIOS数据区实际上会利用从0000 0500开始的少量字节,例如
;00000500处保存的是打印屏幕状态,当按下打印屏幕(PrintScreen)键时,低级键盘BIOS初始化打印屏
;幕功能,键盘BIOS触发中断5打印屏幕处理程序。正因为BIOS数据区越过了256B的界限,因此DOS实际
;上是从0000 0522开始装载的。为保险起见,可从0000 0600开始利用空闲内存。(1.5K - 31K 29.5KB)
;有些机器上没有这段BIOS扩展数据区。
;如果没有使用扩展高端内存区域程序(例如Emm386.exe),则从0010 0000 (1MB )开始的内存都是可用的。
;=====================================================================================
BITS 16 ;生成16位代码而不是32位代码
SECTION .TEXT ;代码段
ORG 0800H ;指定程序被装入内存的起始位置
;====================================================================
;NTFS启动扇区代码使用内存的情况:
;0000 0000 - 0000 07FF 2K IDT和BIOS数据
;0000 0800 - 0000 2800 8K 保留给NTFS启动扇区代码,最多8K
;****:**** - 0000 7FFF 22K 堆栈区域
;0000:8000 - ****:**** 480K 装载第二阶段程序FDOSLDR.BIN及数据的空间
;0008 0000 - 0008 FFFF 64K 用于文件系统的缓冲区
;0009 0000 - 0009 FFFF 64K 用于读取数据簇的缓冲区
;====================================================================
;宏和常量定义
;====================================================================
? EQU 0 ;NASM不支持DW ?这样的语法,可以使用这样的定义
;模拟,以使代码的可读性更强
STACK_ADDR EQU 7FD0H ;堆栈栈顶(注意:堆栈大小约为20K左右)
DATA_BUF_SEG EQU 9000H ;用于读取根目录或文件内容的缓冲区(64K) 段地址
DATA_BUF_OFF EQU 0000H ;数据缓冲区偏移
DATA_BUF_ADDR EQU 90000H ;数据缓冲区线性地址
FILE_BUF_SEG EQU 8000H ;文件记录缓冲区段地址
FILE_BUF_OFF EQU 00000H ;文件记录缓冲区偏移
BOOT_SEC_NUM EQU 16 ;NTFS启动扇区代码的总长度(16个扇区=8K)
BOOT_SEC_ADDR EQU 0800H ;NTFS启动扇区的重定位地址
;第二阶段装载程序FDOSLDR.BIN
OSLOADER_ADDR EQU 8000H ;FDOSLDR.BIN放入内存中的起始位置
OSLOADER_SEG EQU 0800H ;起始段地址
;====================================================================
;用堆栈保存若干中间变量( SS = 0 BP = 7C00H )
;====================================================================
DISK_EXT_SUPPORT EQU 1 ;BYTE 磁盘是否支持扩展BIOS
DRIVE_NUMBER EQU 2 ;BYTE 用于保存启动的磁盘驱动器号
BYTES_PER_FILE_RECORD EQU 8 ;DWORD 用于保存NTFS每个文件记录的尺寸
BYTES_PER_INDEX_BLOCK EQU 12 ;DWORD 用于保存默认的索引分配的尺寸
BYTES_PER_CLUSTER EQU 16 ;DWORD 用于保存每簇字节数字节数
;====================================================================
;扩展磁盘服务所使用的地址包
;====================================================================
DAP_SECTOR_HIGH EQU 24 ;起始扇区号的高32位 ( 每次调用需要重置 ) DWORD
DAP_SECTOR_LOW EQU 28 ;起始扇区号的低32位 ( 每次调用需要重置 ) DWORD
DAP_BUFFER_SEG EQU 30 ;缓冲区段地址 ( 每次调用需要重置 ) WORD
DAP_BUFFER_OFF EQU 32 ;缓冲区偏移 ( 每次调用需要重置 ) WORD
DAP_RESERVED2 EQU 33 ;保留字节
DAP_READ_SECTORS EQU 34 ;要处理的扇区数(1 - 127 )
DAP_RESERVED1 EQU 35 ;保留字节
DAP_PACKET_SIZE EQU 36 ;包的大小为16字节
;====================================================================
;NTFS系统常量
;====================================================================
;记录类型
NTFS_RECORD_TYPE_NONE EQU 0 ;未知的类型
NTFS_RECORD_TYPE_FILE EQU 0x454C4946 ;文件记录($MFT)
NTFS_RECORD_TYPE_INDX EQU 0x58444E49 ;索引记录(Index Allocation)
NTFS_RECORD_TYPE_HOLE EQU 0x454C4F48 ;空洞记录
NTFS_RECORD_TYPE_RSTR EQU 0x52545352 ;重启记录($LogFile Restart Page )
NTFS_RECORD_TYPE_RCRD EQU 0x44524352 ;日志记录($LogFile Log Record Page)
NTFS_RECORD_TYPE_CHKD EQU 0x424B4843 ;检查记录($LogFile CHKDSK)
NTFS_RECORD_TYPE_BAAD EQU 0x44414142 ;多扇区数据写入错误(通常是由于系统断电引起)
NTFS_RECORD_TYPE_FREE EQU 0xFFFFFFFF ;记录是空闲的,在使用前必须初始化
;=============================================================
;NTFS系统文件记录编号
;=============================================================
NTFS_SYSTEM_FILE_MFT EQU 0 ;$MFT ( Master File Table )
NTFS_SYSTEM_FILE_MFTMIRR EQU 1 ;$MFTMirr ( 至少前四个MFT记录的拷贝)
NTFS_SYSTEM_FILE_LOGFILE EQU 2 ;$LogFile ( 事务日志)
NTFS_SYSTEM_FILE_VOLUME EQU 3 ;$Volume ( 卷名及卷信息以及文件系统版本 )
NTFS_SYSTEM_FILE_ATTRDEF EQU 4 ;$AttrDef ( 所有支持的属性定义 )
NTFS_SYSTEM_FILE_ROOT EQU 5 ;. ( 根目录 )
NTFS_SYSTEM_FILE_BITMAP EQU 6 ;$Bitmap ( 卷的数据簇分配位图 )
NTFS_SYSTEM_FILE_BOOT EQU 7 ;$Boot ( 卷的引导记录,指向引导扇区 )
NTFS_SYSTEM_FILE_BADCLUS EQU 8 ;$BadClus ( 卷的坏簇列表 )
NTFS_SYSTEM_FILE_SECURE EQU 9 ;$Secure ( 卷使用的安全描述符 )
NTFS_SYSTEM_FILE_UPCASE EQU 10 ;$UpCase ( 64K个UNICODE字符串的大写形式 )
NTFS_SYSTEM_FILE_EXTEND EQU 11 ;$Extend ( 包含其他系统文件的目录 $ObjId $Quota $Reparse $UsnJrnl - NTFS 3.0 )
NTFS_SYSTEM_FILE_RESERVED12 EQU 12 ;保留
NTFS_SYSTEM_FILE_RESERVED13 EQU 13 ;保留
NTFS_SYSTEM_FILE_RESERVED14 EQU 14 ;保留
NTFS_SYSTEM_FILE_RESERVED15 EQU 15 ;保留
NTFS_SYSTEM_FILE_FIRSTUSER EQU 16 ;第一个用户可以使用的文件记录编号
;MFT文件记录属性
NTFS_FILE_RECORD_FLAG_INUSE EQU 0x0001 ;正在使用
NTFS_FILE_RECORD_FLAG_DIRECTORY EQU 0x0002 ;是目录
;==============================================================================
;属性排序规则
;==============================================================================
NTFS_COLLATION_BINARY EQU 0 ;按原始字节依次顺序比较
NTFS_COLLATION_FILE_NAME EQU 1 ;按UNICODE方式比较文件名(不区分大小写?)
NTFS_COLLATION_UNICODE_STRING EQU 2 ;按UNICODE字符串比较(区分大小写?)
NTFS_COLLATION_ULONG EQU 16 ;按32为无符号整数排序
NTFS_COLLATION_SID EQU 17 ;按SID值排序
NTFS_COLLATION_SECURITY_HASH EQU 18 ;首先按哈希值排序,然后按SID排序
NTFS_COLLATION_ULONGS EQU 19 ;按整数序列排序(GUID?)
;==============================================================================
;属性定义标志(用于属性定义结构)
;==============================================================================
NTFS_ATTRDEF_FLAG_INDEXABLE EQU 0x00000002 ;属性可以被索引
NTFS_ATTRDEF_FLAG_MULTIPLE EQU 0x00000004 ;属性可以出现多次
NTFS_ATTRDEF_FLAG_NOT_NULLABLE EQU 0x00000008 ;属性值必须至少包括一个非0字节
NTFS_ATTRDEF_FLAG_INDEXED_UNIQUE EQU 0x00000010 ;属性必须被索引并且必须唯一
NTFS_ATTRDEF_FLAG_NAMED_UNIQUE EQU 0x00000020 ;属性必须被命名并且名称必须唯一
NTFS_ATTRDEF_FLAG_RESIDENT EQU 0x00000040 ;属性必须是驻留的
NTFS_ATTRDEF_FLAG_LOG EQU 0x00000080 ;属性的修改必须记录日志,不管属性
;是否为驻留属性;如果没有该标志,
;则只记录驻留属性的修改日志
;==============================================================================
;属性类型
;==============================================================================
;Type Name Flags IRN MinSize MaxSize
;------------------------------------------------------------------------------
;0x10 $STANDARD_INFORMATION 0x40 R 0x30 0x48
;0x20 $ATTRIBUTE_LIST 0x80 N - -
;0x30 $FILE_NAME 0x42 IR 0x44 0x242
;0x40 $VOLUME_VERSION 0x40 R 0x8 0x8
;0x40 $OBJECT_ID 0x40 R - 0x100
;0x50 $SECURITY_DEOR 0x80 N - -
;0x60 $VOLUME_NAME 0x40 R 0x2 0x100
;0x70 $VOLUME_INFORMATION 0x40 R 0xC 0xC
;0x80 $DATA 0x00 - -
;0x90 $INDEX_ROOT 0x40 R - -
;0xA0 $INDEX_ALLOCATION 0x80 N - -
;0xB0 $BITMAP 0x80 N - -
;0xC0 $SYMBOLIC_LINK 0x80 N - -
;0xC0 $REPARSE_POINT 0x80 N - 0x4000
;0xD0 $EA_INFORMATION 0x40 R 0x8 0x8
;0xE0 $EA 0x00 - 0x10000
;0xF0 $PROPERTY_SET - - - -
;0x100$LOGGED_UTILITY_STREAM 0x80 N - 0x10000
;------------------------------------------------------------------------------
;其中: I - Indexable
;N - NonNullable
;R - Resident
;==============================================================================
NTFS_ATTRIBUTE_TYPE_STANDARD_INFORMATION EQU 0x00000010 ;标准信息
NTFS_ATTRIBUTE_TYPE_ATTRIBUTE_LIST EQU 0x00000020 ;属性列表
NTFS_ATTRIBUTE_TYPE_FILE_NAME EQU 0x00000030 ;文件名
NTFS_ATTRIBUTE_TYPE_VOLUME_VERSION EQU 0x00000040 ;卷版本信息(WINNT)
NTFS_ATTRIBUTE_TYPE_OBJECT_ID EQU 0x00000040 ;对象ID(Win2000/XP)
NTFS_ATTRIBUTE_TYPE_SECURITY_DEOR EQU 0x00000050 ;安全描述符
NTFS_ATTRIBUTE_TYPE_VOLUME_NAME EQU 0x00000060 ;卷名称
NTFS_ATTRIBUTE_TYPE_VOLUME_INFORMATION EQU 0x00000070 ;卷信息
NTFS_ATTRIBUTE_TYPE_DATA EQU 0x00000080 ;数据
NTFS_ATTRIBUTE_TYPE_INDEX_ROOT EQU 0x00000090 ;索引根目录
NTFS_ATTRIBUTE_TYPE_INDEX_ALLOCATION EQU 0x000000A0 ;索引分配缓冲区
NTFS_ATTRIBUTE_TYPE_BITMAP EQU 0x000000B0 ;位图
NTFS_ATTRIBUTE_TYPE_SYMBOLIC_LINK EQU 0x000000C0 ;符号连接(WINNT)
NTFS_ATTRIBUTE_TYPE_REPARSE_POINT EQU 0x000000C0 ;重解析点(WIN2000/XP)
NTFS_ATTRIBUTE_TYPE_EA_INFORMATION EQU 0x000000D0 ;附加信息
NTFS_ATTRIBUTE_TYPE_EA EQU 0x000000E0 ;附加属性
NTFS_ATTRIBUTE_TYPE_PROPERTY_SET EQU 0x000000F0 ;属性集(WIN2000/XP)
NTFS_ATTRIBUTE_TYPE_LOGGED_UTILITY_STREAM EQU 0x00000100 ;事务日志
NTFS_ATTRIBUTE_TYPE_FIRST_USER EQU 0x00001000 ;用户自定义属性起始值
NTFS_ATTRIBUTE_TYPE_END EQU 0xFFFFFFFF ;表明属性结束
;属性名称最大长度
NTFS_ATTRIBUTE_NAME_LENGTH EQU 64 ;UNICODE字符长度
;属性标志
NTFS_ATTRIBUTE_FLAG_COMPRESSED EQU 0x0001 ;压缩标志
NTFS_ATTRIBUTE_FLAG_ENCRYPTED EQU 0x4000 ;加密标志
NTFS_ATTRIBUTE_FLAG_SPARSE EQU 0x8000 ;稀疏文件
NTFS_ATTRIBUTE_RESIDENT_FLAG_INDEXED EQU 0x0001 ;驻留属性被索引
;============================================================
;文件属性
;=============================================================
NTFS_FILE_FLAG_READONLY EQU 0x00000001 ;只读标志
NTFS_FILE_FLAG_HIDDEN EQU 0x00000002 ;隐藏标志
NTFS_FILE_FLAG_SYSTEM EQU 0x00000004 ;系统标志
NTFS_FILE_FLAG_VOLUME EQU 0x00000008 ;卷标标准(NTFS不使用)
NTFS_FILE_FLAG_DIRECTORY EQU 0x00000010 ;目录属性(NTFS不使用)
NTFS_FILE_FLAG_ARCHIVE EQU 0x00000020 ;归档标志
NTFS_FILE_FLAG_DEVICE EQU 0x00000040 ;设备
NTFS_FILE_FLAG_NORMAL EQU 0x00000080 ;普通属性
NTFS_FILE_FLAG_TEMPORARY EQU 0x00000100 ;临时文件
NTFS_FILE_FLAG_SPARSE_FILE EQU 0x00000200 ;稀疏文件
NTFS_FILE_FLAG_REPARSE_POINT EQU 0x00000400 ;重解析点
NTFS_FILE_FLAG_COMPRESSED EQU 0x00000800 ;压缩标志
NTFS_FILE_FLAG_OFFLINE EQU 0x00001000 ;离线
NTFS_FILE_FLAG_NOT_CONTENT_INDEXED EQU 0x00002000 ;内容没有索引
NTFS_FILE_FLAG_ENCRYPTED EQU 0x00004000 ;加密文件
NTFS_FILE_FLAG_INDEX_ROOT_PRESENT EQU 0x10000000 ;拷贝自MFT记录,是否目录(存在IndexRoot)
NTFS_FILE_FLAG_VIEW_INDEX_PRESENT EQU 0x20000000 ;拷贝自MFT记录,是否存在视图索引(ObjId索引、配额索引等)
;==============================================================================
;文件名相关常量
;==============================================================================
;最大允许的文件名长度
NTFS_FILE_NAME_MAXLENGTH EQU 255
;可能的名字空间
;最大的命名空间,大小写敏感,除了'\0'和'/'之外的所有Unicode字符都可以作为文件名;
NTFS_FILE_NAME_POSIX EQU 0
;大小写不敏感,'\0', '"', '*', '/', ':', '<',>', '?', '\' ,'|'都不能用于文件名;
;并且名字不能以句点(.)和空格结尾;
NTFS_FILE_NAME_WIN32 EQU 1
;传统的8.3名字,大写字母
NTFS_FILE_NAME_DOS EQU 2
;兼顾Win32和DOS名字
NTFS_FILE_NAME_WIN32_AND_DOS EQU 3
;==============================================================================
;卷标志
;==============================================================================
NTFS_VOLUME_FLAG_DIRTY EQU 0x0001 ;脏标志
NTFS_VOLUME_FLAG_RESIZE_LOG_FILE EQU 0x0002 ;重设日志文件
NTFS_VOLUME_FLAG_UPGRADE_ON_MOUNT EQU 0x0004 ;装配时升级
NTFS_VOLUME_FLAG_MOUNTED_ON_NT4 EQU 0x0008 ;装配标志
NTFS_VOLUME_FLAG_DELETE_USN_UNDERWAY EQU 0x0010 ;删除USN
NTFS_VOLUME_FLAG_REPAIR_OBJECT_ID EQU 0x0020 ;修复对象ID
NTFS_VOLUME_FLAG_MODIFIED_BY_CHKDSK EQU 0x8000 ;CHKDSK修改标志
;==============================================================================
;索引标志
;==============================================================================
;用于IndexRoot的属性标志
NTFS_INDEX_FLAG_LARGE_INDEX EQU 1 ;索引存在IndexAllocation属性
;用于IndexAllocation的属性标志
;用于IndexEntry的属性标志
NTFS_INDEX_FLAG_INDEX_NODE EQU 1 ;索引节点(存在子节点)
;用于IndexEntry的属性标志
NTFS_INDEX_FLAG_INDEX_END EQU 2 ;指明是最后一个项(结束标志)
;==============================================================================
;MFT文件记录引用
;当需要指向MFT中的一个记录时,就需要使用MFT文件记录引用,这是一个64位的数值,
;由48位的MFT索引号和16位的序列号(用于一致性检查)组成。为了便于报告错误,我
;们将48位的索引号看成是有符号数;而16位的序列号是一个循环计时器(跳过0),指
;明被引用的MFT记录被使用的次数;如果该序列号数值位0,则指明不进行序列号一致性
;检查。
;==============================================================================
;NTFS_MFT_REF_MASK 0x0000FFFFFFFFFFFFULL
;NTFS_MAKE_MFT_REF( I,S ) ( (((ULONGLONG)(S)) << 48 ) | (((ULONGLONG)(I)) & NTFS_MFT_REF_MASK) )
;NTFS_MFT_REF_INDEX( R ) ((ULONGLONG)((R) & NTFS_MFT_REF_MASK ))
;NTFS_MFT_REF_SEQUENCE(R) ((USHORT)(((R) >> 48) & 0xFFFF))
;NTFS_IS_MFT_REF_ERR( R ) (((R) & 0x000080000000ULL ) ? 1:0)
;====================================================================
;结构定义
;====================================================================
;====================================================================
;带Fixup(TornBits)的记录头,包括FileRecord,IndexAllocation,重启日志等
;====================================================================
STRUC NTFS_RECORD_HEADER
.RecordType RESD 01H ;记录类型
.UsaOffset RESW 01H ;更新序列号数组的偏移(相对于记录开始)
.UsaCount RESW 01H ;更新序列号数组的大小
.RecordLsn RESQ 01H ;该记录的日志序列号,每次修改时更新
;
;更新序列号数组( USA: Update Sequence Array )是一个USHORT值数组,该
;值属于每个由该数组保护的更新序列记录所保护的扇区的末尾信息。
;注意:该数组的第一个元素是USN( Update Sequence Number ),一个表示
;记录被写入磁盘的次数的循环计数器。注意值0和-1( 0xFFFF )没有
;被使用。余下的每个扇区对应的值必须与USN相等(在读取时检查),
;在写入时设置。
;
ENDSTRUC
;====================================================================
;MFT文件记录
;====================================================================
STRUC NTFS_FILE_RECORD
;公共记录头
.RecordType RESD 01H ;记录类型
.UsaOffset RESW 01H ;更新序列号数组的偏移(相对于记录开始)
.UsaCount RESW 01H ;更新序列号数组的大小
.RecordLsn RESQ 01H ;该记录的日志序列号,每次修改时更新
;文件记录特有属性
.SequenceNumber RESW 01H ;该记录被使用的序列号(循环计数器,跳过0)
.LinkCount RESW 01H ;硬连接数,及目录中引用该记录的次数,只在MFT基文件记录中使用;
.AttributesOffset RESW 01H ;第一个属性的偏移,相对于记录开始,必须8字节对齐
.RecordFlags RESW 01H ;记录属性 NTFS_FILE_RECORD_FLAG_xxx
.BytesInUse RESD 01H ;记录头和属性的总长度(文件记录的实际长度),8字节对齐
.BytesAllocated RESD 01H ;总共分配给文件记录的长度(应该与BytesPerFileRecord一致)
.BaseFileRecord RESQ 01H ;基本文件记录中的文件索引号(对于基本文件记录,其值为0)
.NextAttributeNumber RESW 01H ;下一个属性ID,注意第一个属性ID为0;每次增1并在重用是复位为0;
;以下两项出现在NTFS 3.1+ ( Windows XP及以上版本 _
.Reserved RESW 01H ;保留字节用于对齐
.FileRecordNumber RESD 01H ;本记录的索引号
;
;当使用MFT记录时,将USA(更新序列号数组)放在这个位置,即在第一个属性开始
;之前的位置。
;
ENDSTRUC
评论