ReactOS @H_502_5@源码分析@H_502_5@ @H_502_5@@H_502_5@
前言@H_502_5@@H_502_5@
ReactOS@H_502_5@是一个开源的免费的操作系统@H_502_5@,@H_502_5@它致力于兼容现在最流行的操作系统@H_502_5@windows,@H_502_5@打破微软垄断的局面@H_502_5@,@H_502_5@这里我们为那些默默无闻的开发者致敬@H_502_5@,@H_502_5@他们开发@H_502_5@reactos@H_502_5@没有工资@H_502_5@,@H_502_5@没有补贴@H_502_5@,@H_502_5@没有@H_502_5@…@H_502_5@只有默默的写代码@H_502_5@…@H_502_5@这是一种精神@H_502_5@@H_502_5@..@H_502_5@@H_502_5@@H_502_5@
代码分析@H_502_5@@H_502_5@
那我们就在最初引导阶段开始分析@H_502_5@.@H_502_5@首先我们假设我们的机器是@H_502_5@i386@H_502_5@机型@H_502_5@. @H_502_5@引导磁盘是@H_502_5@fat32@H_502_5@格式@H_502_5@.@H_502_5@我的@H_502_5@Reactos@H_502_5@代码在@H_502_5@D:/ReactOS/ReactOS_src/@H_502_5@下@H_502_5@,@H_502_5@代码版本@H_502_5@0.39@H_502_5@@H_502_5@@H_502_5@
1. @H_502_5@@H_502_5@系统开始启动@H_502_5@@H_502_5@@H_502_5@
@H_502_5@@H_502_5@首先机器加电自检@H_502_5@,@H_502_5@然后检查启动盘@H_502_5@,@H_502_5@是从光盘还是硬盘启动呢@H_502_5@?@H_502_5@可能大家都知道@H_502_5@,@H_502_5@这是在@H_502_5@BIOS@H_502_5@里面设置的@H_502_5@,@H_502_5@这里我们是研究已经安装好的系统启动过程@H_502_5@,@H_502_5@就磁盘启动啦@H_502_5@,@H_502_5@首先找到启动磁盘@H_502_5@,BIOS@H_502_5@会检查磁盘的@H_502_5@0@H_502_5@面@H_502_5@0@H_502_5@磁道@H_502_5@,1@H_502_5@扇区@H_502_5@,@H_502_5@如果发现其为@H_502_5@55aa@H_502_5@结尾而且小于@H_502_5@512@H_502_5@字节就认为他就是一个合法的引导扇扇区@H_502_5@(BootSector),@H_502_5@然后把这个引导代码加载到@H_502_5@0000:7c000@H_502_5@处@H_502_5@,@H_502_5@然后跳转到这个地方执行@H_502_5@,@H_502_5@现在就把所有的控制权交给引导代码了@H_502_5@,BIOS@H_502_5@里的启动代码是固定在@H_502_5@ROM@H_502_5@里的@H_502_5@,@H_502_5@所以系统启动的代码就是那段引导程序代码@H_502_5@,@H_502_5@前面我们也假设了我们是@H_502_5@fat32@H_502_5@格式的磁盘@H_502_5@.@H_502_5@所以我们就从@H_502_5@fat32.asm@H_502_5@开始吧@H_502_5@@H_502_5@.@H_502_5@@H_502_5@@H_502_5@
2 @H_502_5@f at32.asm@H_502_5@@H_502_5@
@H_502_5@@H_502_5@代码位置@H_502_5@@H_502_5@: D:/ReactOS/ReactOS_src/boot/freeldr/bootsect/fat32.asm@H_502_5@@H_502_5@@H_502_5@
@H_502_5@@H_502_5@代码如下@H_502_5@@H_502_5@:@H_502_5@@H_502_5@@H_502_5@
;@H_502_5@看了吧@H_502_5@,@H_502_5@这里就是把他加载到了@H_502_5@@H_502_5@0000:7c000@H_502_5@@H_502_5@@H_502_5@
segment .text@H_502_5@@H_502_5@
bits 16 @H_502_5@;16@H_502_5@@H_502_5@位程序@H_502_5@@H_502_5@@H_502_5@
@H_502_5@jmp short main@H_502_5@@H_502_5@@H_502_5@
@H_502_5@nop@H_502_5@@H_502_5@@H_502_5@
/*@H_502_5@这里是什么@H_502_5@?@H_502_5@用@H_502_5@winhex@H_502_5@打开磁盘@H_502_5@,@H_502_5@选在结构@H_502_5@fat32@H_502_5@的样式打开就可以看待这些数据了@H_502_5@@H_502_5@,@H_502_5@@H_502_5@@H_502_5@
typedef struct _FAT_BOOTSECTOR@H_502_5@@H_502_5@@H_502_5@
@H_502_5@UCHAR @H_502_5@JumpBoot[3]; @H_502_5@ @H_502_5@// Jump instruction to boot code@H_502_5@@H_502_5@@H_502_5@
@H_502_5@CHAR @H_502_5@OemName[8]; @H_502_5@// "MSWIN4.1" for MS formatted volumes@H_502_5@@H_502_5@@H_502_5@
@H_502_5@USHORT @H_502_5@BytesPerSector; @H_502_5@// Bytes per sector@H_502_5@@H_502_5@@H_502_5@
@H_502_5@UCHAR @H_502_5@SectorsPerCluster; @H_502_5@ @H_502_5@// Number of sectors in a cluster@H_502_5@@H_502_5@@H_502_5@
@H_502_5@USHORT @H_502_5@ReservedSectors; @H_502_5@ @H_502_5@// Reserved sectors,usually 1 (the bootsector)@H_502_5@@H_502_5@@H_502_5@
@H_502_5@UCHAR @H_502_5@NumberOfFats; @H_502_5@// Number of FAT tables@H_502_5@@H_502_5@@H_502_5@
@H_502_5@USHORT @H_502_5@RootDirEntries; @H_502_5@// Number of root directory entries (fat12/16)@H_502_5@@H_502_5@@H_502_5@
@H_502_5@USHORT @H_502_5@TotalSectors; @H_502_5@ @H_502_5@// Number of total sectors on the drive,16-bit@H_502_5@@H_502_5@@H_502_5@
@H_502_5@UCHAR @H_502_5@MediaDescriptor; @H_502_5@ @H_502_5@// Media descriptor byte@H_502_5@@H_502_5@@H_502_5@
@H_502_5@USHORT @H_502_5@SectorsPerFat; @H_502_5@ @H_502_5@// Sectors per FAT table (fat12/16)@H_502_5@@H_502_5@@H_502_5@
@H_502_5@USHORT @H_502_5@SectorsPerTrack; @H_502_5@ @H_502_5@// Number of sectors in a track@H_502_5@@H_502_5@@H_502_5@
@H_502_5@USHORT @H_502_5@NumberOfHeads; @H_502_5@// Number of heads on the disk@H_502_5@@H_502_5@@H_502_5@
@H_502_5@ULONG @H_502_5@HiddenSectors; @H_502_5@// Hidden sectors (sectors before the partition start like the partition table)@H_502_5@@H_502_5@@H_502_5@
@H_502_5@ULONG @H_502_5@TotalSectorsBig; @H_502_5@ @H_502_5@// This field is the new 32-bit total count of sectors on the volume@H_502_5@@H_502_5@@H_502_5@
@H_502_5@UCHAR @H_502_5@DriveNumber; @H_502_5@ @H_502_5@// Int 0x13 drive number (e.g. 0x80)@H_502_5@@H_502_5@@H_502_5@
@H_502_5@UCHAR @H_502_5@Reserved1; @H_502_5@// Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0.@H_502_5@@H_502_5@@H_502_5@
@H_502_5@UCHAR @H_502_5@BootSignature; @H_502_5@// Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present.@H_502_5@@H_502_5@@H_502_5@
@H_502_5@ULONG @H_502_5@VolumeSerialNumber; @H_502_5@// Volume serial number@H_502_5@@H_502_5@@H_502_5@
@H_502_5@CHAR @H_502_5@VolumeLabel[11]; @H_502_5@ @H_502_5@// Volume label. This field matches the 11-byte volume label recorded in the root directory@H_502_5@@H_502_5@@H_502_5@
@H_502_5@CHAR @H_502_5@FileSystemType[8]; @H_502_5@ @H_502_5@// One of the strings "FAT12 @H_502_5@","FAT16 @H_502_5@",or "FAT @H_502_5@"@H_502_5@@H_502_5@@H_502_5@
@H_502_5@UCHAR @H_502_5@BootCodeAndData[448]; @H_502_5@// The remainder of the boot sector@H_502_5@@H_502_5@@H_502_5@
@H_502_5@USHORT @H_502_5@BootSectorMagic; @H_502_5@ @H_502_5@// 0xAA55@H_502_5@@H_502_5@@H_502_5@
} FAT_BOOTSECTOR,*PFAT_BOOTSECTOR;*/@H_502_5@@H_502_5@@H_502_5@
OEMName @H_502_5@db 'FrLdr1.0'@H_502_5@@H_502_5@
BytesPerSector @H_502_5@dw 512@H_502_5@@H_502_5@
SectsPerCluster @H_502_5@db 0@H_502_5@@H_502_5@
ReservedSectors @H_502_5@dw 32@H_502_5@@H_502_5@
….@H_502_5@略@H_502_5@@H_502_5@@H_502_5@
@H_502_5@@H_502_5@;@H_502_5@@H_502_5@初始化@H_502_5@@H_502_5@@H_502_5@
xor ax,ax @H_502_5@; Setup segment registers@H_502_5@@H_502_5@
@H_502_5@mov ds,ax @H_502_5@; Make DS correct@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov es,ax @H_502_5@; Make ES correct@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov ss,ax @H_502_5@ @H_502_5@;Make SS correct@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov bp,7c00h@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov sp,7c00h @H_502_5@; Setup a stack@H_502_5@@H_502_5@@H_502_5@
@H_502_5@cmp BYTE [BYTE bp+BootDrive],BYTE 0xff @H_502_5@; If they have specified a boot drive then use it@H_502_5@@H_502_5@@H_502_5@
@H_502_5@jne CheckSectorsPerFat@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov [BYTE bp+BootDrive],dl @H_502_5@; Save the boot drive@H_502_5@@H_502_5@@H_502_5@
;@H_502_5@下面检查参数是否正确@H_502_5@@H_502_5@@H_502_5@
CheckSectorsPerFat:@H_502_5@@H_502_5@
@H_502_5@cmp @H_502_5@WORD [BYTE bp+SectorsPerFat],byte 0x00 @H_502_5@; Check the old 16-bit value of SectorsPerFat@H_502_5@@H_502_5@@H_502_5@
@H_502_5@jnz CheckFailed @H_502_5@; If it is non-zero then exit with an error@H_502_5@@H_502_5@@H_502_5@
CheckTotalSectors: @H_502_5@; Check the old 16-bit value of TotalSectors & MaxRootEntries@H_502_5@@H_502_5@
@H_502_5@cmp @H_502_5@DWORD [BYTE bp+MaxRootEntries],byte 0x00; by comparing the DWORD at offset MaxRootEntries to zero@H_502_5@@H_502_5@@H_502_5@
@H_502_5@jnz CheckFailed @H_502_5@; If it is non-zero then exit with an error@H_502_5@@H_502_5@@H_502_5@
CheckFileSystemVersion:@H_502_5@@H_502_5@
@H_502_5@cmp WORD [BYTE bp+FSVersion],byte 0x00 @H_502_5@; Check the file system version word@H_502_5@@H_502_5@@H_502_5@
@H_502_5@jna GetDriveParameters @H_502_5@ @H_502_5@; It is zero,so continue@H_502_5@@H_502_5@@H_502_5@
CheckFailed:@H_502_5@@H_502_5@
@H_502_5@jmp PrintFileSystemError @H_502_5@; If it is not zero then exit with an error@H_502_5@@H_502_5@@H_502_5@
;@H_502_5@下面的函数名称都说明了他的作用@H_502_5@@H_502_5@@H_502_5@
GetDriveParameters:@H_502_5@@H_502_5@
….@H_502_5@省略@H_502_5@@H_502_5@@H_502_5@
CalcDriveSize:@H_502_5@@H_502_5@
…@H_502_5@省略@H_502_5@@H_502_5@@H_502_5@
;@H_502_5@计算出来放在@H_502_5@BiosCHSDriveSize@H_502_5@里面@H_502_5@@H_502_5@@H_502_5@
LoadExtraBootCode:@H_502_5@@H_502_5@
; First we have to load our extra boot code at@H_502_5@@H_502_5@@H_502_5@
; sector 14 into memory at [0000:7e00h]@H_502_5@@H_502_5@@H_502_5@
…@H_502_5@略@H_502_5@@H_502_5@@H_502_5@
call ReadSectors@H_502_5@@H_502_5@@H_502_5@
jmp @H_502_5@StartSearch@H_502_5@@H_502_5@@H_502_5@
;==========================================================@H_502_5@@H_502_5@
; Reads logical sectors into [ES:BX]@H_502_5@@H_502_5@@H_502_5@
; EAX has logical sector number to read@H_502_5@@H_502_5@@H_502_5@
; CX has number of sectors to read@H_502_5@@H_502_5@@H_502_5@
ReadSectors:@H_502_5@@H_502_5@
…@H_502_5@略@H_502_5@@H_502_5@ @H_502_5@@H_502_5@@H_502_5@@H_502_5@
;@H_502_5@这里进行的工作是检查是否为@H_502_5@LBA@H_502_5@模式如果是进行@H_502_5@LBA@H_502_5@模式读取@H_502_5@@H_502_5@@H_502_5@
; End of bootsector@H_502_5@@H_502_5@@H_502_5@
; Now starts the extra boot code that we will store@H_502_5@@H_502_5@@H_502_5@
; at sector 14 on a FAT32 volume@H_502_5@@H_502_5@@H_502_5@
; To remain multi-boot compatible with other operating@H_502_5@@H_502_5@@H_502_5@
; systems we must not overwrite anything other than@H_502_5@@H_502_5@@H_502_5@
; the bootsector which means we will have to use@H_502_5@@H_502_5@@H_502_5@
; a different sector like 14 to store our extra boot code@H_502_5@@H_502_5@@H_502_5@
;========================================================@H_502_5@@H_502_5@
;@H_502_5@下面的代码是进行查找@H_502_5@freeldr.sys,@H_502_5@然后进行加载@H_502_5@,@H_502_5@加载到@H_502_5@0000:8000@H_502_5@处@H_502_5@@H_502_5@@H_502_5@
StartSearch:@H_502_5@@H_502_5@
@H_502_5@; Now we must get the first cluster of the root directory@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@eax,DWORD [BYTE bp+RootDirStartCluster]@H_502_5@@H_502_5@@H_502_5@
@H_502_5@cmp @H_502_5@eax,0ffffff8h @H_502_5@; Check to see if this is the last cluster in the chain@H_502_5@@H_502_5@@H_502_5@
@H_502_5@jb @H_502_5@ContinueSearch @H_502_5@; If not continue,if so then we didn't find freeldr.sys@H_502_5@@H_502_5@@H_502_5@
@H_502_5@jmp @H_502_5@PrintFileNotFound@H_502_5@@H_502_5@@H_502_5@
ContinueSearch:@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@bx,2000h@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@es,bx @H_502_5@; Read cluster to [2000:0000h]@H_502_5@@H_502_5@@H_502_5@
@H_502_5@call ReadCluster @H_502_5@; Read the cluster@H_502_5@@H_502_5@@H_502_5@
@H_502_5@; Now we have to find our way through the root directory to@H_502_5@@H_502_5@@H_502_5@
@H_502_5@; The OSLOADER.SYS file@H_502_5@@H_502_5@@H_502_5@
@H_502_5@xor @H_502_5@bx,bx@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@bl,[BYTE bp+SectsPerCluster]@H_502_5@@H_502_5@@H_502_5@
@H_502_5@shl @H_502_5@bx,4 @H_502_5@ @H_502_5@; BX = BX * 512 / 32@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@ax,2000h @H_502_5@; We loaded at 2000:0000@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@es,ax@H_502_5@@H_502_5@@H_502_5@
@H_502_5@@H_502_5@xor @H_502_5@di,di@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@si,filename@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@cx,11@H_502_5@@H_502_5@@H_502_5@
@H_502_5@rep @H_502_5@cmpsb @H_502_5@; Compare filenames@H_502_5@@H_502_5@@H_502_5@
@H_502_5@jz @H_502_5@FoundFile @H_502_5@; If same we found it@H_502_5@@H_502_5@@H_502_5@
@H_502_5@dec @H_502_5@bx@H_502_5@@H_502_5@@H_502_5@
@H_502_5@jnz @H_502_5@FindFile@H_502_5@@H_502_5@@H_502_5@
@H_502_5@jmp @H_502_5@PrintFileNotFound@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@ax,es @H_502_5@; We didn't find it in the prevIoUs dir entry@H_502_5@@H_502_5@@H_502_5@
@H_502_5@add @H_502_5@ax,2 @H_502_5@; So lets move to the next one@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@es,ax @H_502_5@; And search again@H_502_5@@H_502_5@@H_502_5@
@H_502_5@xor @H_502_5@di,filename @H_502_5@@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@cx,11@H_502_5@@H_502_5@@H_502_5@
@H_502_5@@H_502_5@rep @H_502_5@cmpsb @H_502_5@; Compare filenames@H_502_5@@H_502_5@@H_502_5@
@H_502_5@jz @H_502_5@FoundFile @H_502_5@; If same we found it@H_502_5@@H_502_5@@H_502_5@
@H_502_5@dec @H_502_5@bx @H_502_5@; Keep searching till we run out of dir entries@H_502_5@@H_502_5@@H_502_5@
@H_502_5@jnz @H_502_5@FindFile @H_502_5@; Last entry?@H_502_5@@H_502_5@@H_502_5@
@H_502_5@; Get the next root dir cluster and try again until we run out of clusters@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@eax,DWORD [BYTE bp+RootDirStartCluster]@H_502_5@@H_502_5@@H_502_5@
@H_502_5@call GetFatEntry@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@[BYTE bp+RootDirStartCluster],eax@H_502_5@@H_502_5@@H_502_5@
@H_502_5@jmp @H_502_5@StartSearch@H_502_5@@H_502_5@@H_502_5@
@H_502_5@; Display "Loading FreeLoader..." message@H_502_5@@H_502_5@@H_502_5@
@H_502_5@@H_502_5@mov @H_502_5@si,msgLoading @H_502_5@; Loading message@H_502_5@@H_502_5@@H_502_5@
@H_502_5@call PutChars @H_502_5@; Display it@H_502_5@@H_502_5@@H_502_5@
@H_502_5@xor @H_502_5@di,di @H_502_5@; ES:DI has dir entry@H_502_5@@H_502_5@@H_502_5@
@H_502_5@xor @H_502_5@dx,dx@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@ax,WORD [es:di+14h] @H_502_5@; Get start cluster high word@H_502_5@@H_502_5@@H_502_5@
@H_502_5@shl @H_502_5@eax,16@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@ax,WORD [es:di+1ah] @H_502_5@; Get start cluster low word@H_502_5@@H_502_5@@H_502_5@
CheckStartCluster:@H_502_5@@H_502_5@
@H_502_5@cmp @H_502_5@eax,2 @H_502_5@; Check and see if the start cluster starts at cluster 2 or above@H_502_5@@H_502_5@@H_502_5@
@H_502_5@jnb @H_502_5@CheckEndCluster @H_502_5@; If so then continue@H_502_5@@H_502_5@@H_502_5@
@H_502_5@jmp @H_502_5@PrintFileSystemError @H_502_5@; If not exit with error@H_502_5@@H_502_5@@H_502_5@
CheckEndCluster:@H_502_5@@H_502_5@
@H_502_5@cmp @H_502_5@eax,0ffffff8h @H_502_5@; Check and see if the start cluster is and end of cluster chain indicator@H_502_5@@H_502_5@@H_502_5@
@H_502_5@jb @H_502_5@InitializeLoadSegment @H_502_5@; If not then continue@H_502_5@@H_502_5@@H_502_5@
@H_502_5@jmp @H_502_5@PrintFileSystemError @H_502_5@; If so exit with error@H_502_5@@H_502_5@@H_502_5@
InitializeLoadSegment:@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@bx,800h@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@es,bx@H_502_5@@H_502_5@@H_502_5@
@H_502_5@cmp @H_502_5@eax,0ffffff8h @H_502_5@ @H_502_5@; Check to see if this is the last cluster in the chain@H_502_5@@H_502_5@@H_502_5@
@H_502_5@jae @H_502_5@LoadFileDone @H_502_5@; If so continue,if not then read the next one@H_502_5@@H_502_5@@H_502_5@
@H_502_5@push eax@H_502_5@@H_502_5@@H_502_5@
@H_502_5@xor @H_502_5@bx,bx @H_502_5@; Load ROSLDR starting at 0000:8000h@H_502_5@@H_502_5@@H_502_5@
@H_502_5@push es@H_502_5@@H_502_5@@H_502_5@
@H_502_5@call ReadCluster@H_502_5@@H_502_5@@H_502_5@
@H_502_5@pop @H_502_5@es@H_502_5@@H_502_5@@H_502_5@
@H_502_5@xor @H_502_5@bx,5 @H_502_5@ @H_502_5@; BX = BX * 512 / 16@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@ax,es @H_502_5@; Increment the load address by@H_502_5@@H_502_5@@H_502_5@
@H_502_5@add @H_502_5@ax,bx @H_502_5@; The size of a cluster@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@es,ax@H_502_5@@H_502_5@@H_502_5@
@H_502_5@pop @H_502_5@eax@H_502_5@@H_502_5@@H_502_5@
@H_502_5@push es@H_502_5@@H_502_5@@H_502_5@
@H_502_5@call GetFatEntry @H_502_5@; Get the next entry@H_502_5@@H_502_5@@H_502_5@
@H_502_5@pop @H_502_5@es@H_502_5@@H_502_5@@H_502_5@
@H_502_5@jmp @H_502_5@LoadFile @H_502_5@; Load the next cluster (if any)@H_502_5@@H_502_5@@H_502_5@
LoadFileDone:@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@dl,[BYTE bp+BootDrive] @H_502_5@; Load boot drive into DL@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@dh,[BootPartition] @H_502_5@; Load boot partition into DH@H_502_5@@H_502_5@@H_502_5@
@H_502_5@@H_502_5@;@H_502_5@看这里是把@H_502_5@freeldr@H_502_5@加载到@H_502_5@0000:8000@H_502_5@位置然后跳转到此处@H_502_5@@H_502_5@@H_502_5@
xor @H_502_5@ax,ax@H_502_5@@H_502_5@@H_502_5@
@H_502_5@push ax @H_502_5@; We loaded at 0000:8000@H_502_5@@H_502_5@@H_502_5@
@H_502_5@push WORD 8000h @H_502_5@; We will do a far return to 0000:8000h@H_502_5@@H_502_5@@H_502_5@
@H_502_5@retf @H_502_5@; Transfer control to ROSLDR@H_502_5@@H_502_5@@H_502_5@
;@H_502_5@下面是@H_502_5@fat@H_502_5@格式磁盘的解析函数@H_502_5@,@H_502_5@可以玩下@H_502_5@@H_502_5@@H_502_5@
; Returns the FAT entry for a given cluster number@H_502_5@@H_502_5@@H_502_5@
; On entry EAX has cluster number@H_502_5@@H_502_5@@H_502_5@
; On return EAX has FAT entry for that cluster@H_502_5@@H_502_5@@H_502_5@
GetFatEntry:@H_502_5@@H_502_5@
@H_502_5@shl @H_502_5@eax,2 @H_502_5@; EAX = EAX * 4 (since FAT32 entries are 4 bytes)@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@ecx,eax @H_502_5@; Save this for later in ECX@H_502_5@@H_502_5@@H_502_5@
@H_502_5@xor @H_502_5@edx,edx@H_502_5@@H_502_5@@H_502_5@
@H_502_5@movzx ebx,WORD [BYTE bp+BytesPerSector]@H_502_5@@H_502_5@@H_502_5@
@H_502_5@push @H_502_5@ebx@H_502_5@@H_502_5@@H_502_5@
@H_502_5@div @H_502_5@ebx @H_502_5@; FAT Sector Number = EAX / BytesPerSector@H_502_5@@H_502_5@@H_502_5@
@H_502_5@movzx ebx,WORD [BYTE bp+ReservedSectors]@H_502_5@@H_502_5@@H_502_5@
@H_502_5@add @H_502_5@eax,ebx @H_502_5@; FAT Sector Number += ReservedSectors@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@ebx,DWORD [BYTE bp+HiddenSectors]@H_502_5@@H_502_5@@H_502_5@
@H_502_5@add @H_502_5@eax,ebx @H_502_5@; FAT Sector Number += HiddenSectors@H_502_5@@H_502_5@@H_502_5@
@H_502_5@pop @H_502_5@ebx@H_502_5@@H_502_5@@H_502_5@
@H_502_5@dec @H_502_5@ebx@H_502_5@@H_502_5@@H_502_5@
@H_502_5@and @H_502_5@ecx,ebx @H_502_5@; FAT Offset Within Sector = ECX % BytesPerSector@H_502_5@@H_502_5@@H_502_5@
@H_502_5@; EAX holds logical FAT sector number@H_502_5@@H_502_5@@H_502_5@
@H_502_5@; ECX holds FAT entry offset@H_502_5@@H_502_5@@H_502_5@
@H_502_5@; Now we have to check the extended flags@H_502_5@@H_502_5@@H_502_5@
@H_502_5@; to see which FAT is the active one@H_502_5@@H_502_5@@H_502_5@
@H_502_5@; and use it,or if they are mirrored then@H_502_5@@H_502_5@@H_502_5@
@H_502_5@; no worries@H_502_5@@H_502_5@@H_502_5@
@H_502_5@movzx ebx,WORD [BYTE bp+ExtendedFlags] @H_502_5@; Get extended flags and put into ebx@H_502_5@@H_502_5@@H_502_5@
@H_502_5@and @H_502_5@bx,0x0f @H_502_5@; Mask off upper 8 bits,now we have active fat in bl@H_502_5@@H_502_5@@H_502_5@
@H_502_5@jz @H_502_5@LoadFatSector @H_502_5@; If fat is mirrored then skip fat calcs@H_502_5@@H_502_5@@H_502_5@
@H_502_5@cmp @H_502_5@bl,[BYTE bp+NumberOfFats] @H_502_5@; Compare bl to number of fats@H_502_5@@H_502_5@@H_502_5@
@H_502_5@jb @H_502_5@@H_502_5@GetActiveFatOffset@H_502_5@@H_502_5@@H_502_5@
@H_502_5@jmp @H_502_5@PrintFileSystemError @H_502_5@ @H_502_5@; If bl is bigger than numfats exit with error@H_502_5@@H_502_5@@H_502_5@
GetActiveFatOffset:@H_502_5@@H_502_5@
@H_502_5@push @H_502_5@eax @H_502_5@; Save logical FAT sector number@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@eax,[BYTE bp+SectorsPerFatBig] @H_502_5@ @H_502_5@; Get the number of sectors occupied by one fat in eax@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mul @H_502_5@ebx @H_502_5@; Multiplied by the active FAT index we have in ebx@H_502_5@@H_502_5@@H_502_5@
@H_502_5@pop @H_502_5@edx @H_502_5@; Get logical FAT sector number@H_502_5@@H_502_5@@H_502_5@
@H_502_5@add @H_502_5@eax,edx @H_502_5@; Add the current FAT sector offset@H_502_5@@H_502_5@@H_502_5@
LoadFatSector:@H_502_5@@H_502_5@
@H_502_5@push @H_502_5@ecx@H_502_5@@H_502_5@@H_502_5@
@H_502_5@; EAX holds logical FAT sector number@H_502_5@@H_502_5@@H_502_5@
@H_502_5@; Check if we have already loaded it@H_502_5@@H_502_5@@H_502_5@
@H_502_5@cmp @H_502_5@eax,DWORD [FatSectorInCache]@H_502_5@@H_502_5@@H_502_5@
@H_502_5@je @H_502_5@LoadFatSectorAlreadyLoaded@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@DWORD [FatSectorInCache],eax@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@bx,7000h@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@es,bx@H_502_5@@H_502_5@@H_502_5@
@H_502_5@xor @H_502_5@bx,bx @H_502_5@; We will load it to [7000:0000h]@H_502_5@@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@cx,1@H_502_5@@H_502_5@@H_502_5@
@H_502_5@call ReadSectors@H_502_5@@H_502_5@@H_502_5@
LoadFatSectorAlreadyLoaded:@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@bx,bx@H_502_5@@H_502_5@@H_502_5@
@H_502_5@pop @H_502_5@ecx@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@eax,DWORD [es:ecx] @H_502_5@; Get FAT entry@H_502_5@@H_502_5@@H_502_5@@H_502_5@
@H_502_5@and @H_502_5@eax,0fffffffh @H_502_5@ @H_502_5@; Mask off reserved bits@H_502_5@@H_502_5@@H_502_5@@H_502_5@
@H_502_5@ret@H_502_5@@H_502_5@@H_502_5@
FatSectorInCache: @H_502_5@; This variable tells us which sector we currently have in memory@H_502_5@@H_502_5@@H_502_5@@H_502_5@
@H_502_5@dd @H_502_5@0ffffffffh @H_502_5@; There is no need to re-read the same sector if we don't have to@H_502_5@@H_502_5@@H_502_5@@H_502_5@
; Reads cluster number in EAX into [ES:0000]@H_502_5@@H_502_5@
ReadCluster:@H_502_5@@H_502_5@
@H_502_5@; StartSector = ((Cluster - 2) * SectorsPerCluster) + ReservedSectors + HiddenSectors;@H_502_5@@H_502_5@@H_502_5@
….@H_502_5@略@H_502_5@@H_502_5@@H_502_5@
; Displays a file not found error message@H_502_5@@H_502_5@@H_502_5@
; And reboots@H_502_5@@H_502_5@@H_502_5@
PrintFileNotFound:@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@si,msgFreeLdr @H_502_5@; FreeLdr not found message@H_502_5@@H_502_5@@H_502_5@
@H_502_5@call PutChars @H_502_5@; Display it@H_502_5@@H_502_5@@H_502_5@
@H_502_5@mov @H_502_5@si,msgAnyKey @H_502_5@; Press any key message@H_502_5@@H_502_5@@H_502_5@
@H_502_5@call PutChars @H_502_5@; Display it@H_502_5@@H_502_5@@H_502_5@
@H_502_5@jmp @H_502_5@Reboot@H_502_5@@H_502_5@@H_502_5@
msgFreeLdr @H_502_5@db 'freeldr.sys not found',0dh,0ah,0@H_502_5@@H_502_5@
filename @H_502_5@db 'FREELDR SYS'@H_502_5@@H_502_5@
msgLoading @H_502_5@db 'Loading FreeLoader...',0@H_502_5@@H_502_5@
@H_502_5@times 1022-($-$$) db 0 @H_502_5@; Pad to 1022 bytes@H_502_5@@H_502_5@@H_502_5@
@H_502_5@dw 0aa55h @H_502_5@; BootSector signature@H_502_5@@H_502_5@@H_502_5@
好@H_502_5@,@H_502_5@看完代码也有单晕晕乎乎了@H_502_5@,@H_502_5@我们来总结下@H_502_5@fat32.asm@H_502_5@。首先加载到@H_502_5@0000:7c00@H_502_5@处@H_502_5@,@H_502_5@接下来就是那个结构体@H_502_5@,@H_502_5@而上面跳转到@H_502_5@main@H_502_5@函数那了@H_502_5@.@H_502_5@开始当然是对一些寄存器的初始化@H_502_5@,@H_502_5@接着就是检查@H_502_5@BootSector@H_502_5@的参数是否正确@H_502_5@,@H_502_5@接着计算整个磁盘的存储量@H_502_5@,@H_502_5@为什么要计算这个呢@H_502_5@?@H_502_5@为了检查磁盘是否支持@H_502_5@LBA@H_502_5@模式。再下面的工作就是查找@H_502_5@freeldr.sys.@H_502_5@并将其加载到内存@H_502_5@0000:8000@H_502_5@处@H_502_5@,@H_502_5@@H_502_5@@H_502_5@
其中又有@H_502_5@fat@H_502_5@文件格式的操作@H_502_5@….@H_502_5@@H_502_5@@H_502_5@
需要的知识点@H_502_5@:@H_502_5@@H_502_5@@H_502_5@
1,@H_502_5@汇编是必要的@H_502_5@@H_502_5@.@H_502_5@@H_502_5@@H_502_5@
2,bootsector.@H_502_5@@H_502_5@@H_502_5@
3,fat32@H_502_5@文件系统解析@H_502_5@@H_502_5@@H_502_5@
4,@H_502_5@怎么检查是否支持@H_502_5@LBA@H_502_5@模式@H_502_5@@H_502_5@@H_502_5@
5,int 10,int 13 @H_502_5@貌似都会吧@H_502_5@@H_502_5@..@H_502_5@@H_502_5@@H_502_5@
6,@H_502_5@得会使用@H_502_5@nasm@H_502_5@编译呀@H_502_5@@H_502_5@!!@H_502_5@@H_502_5@@H_502_5@
对了@H_502_5@freeldr@H_502_5@目录下有个@H_502_5@note.txt@H_502_5@里面有内存分配表如下@H_502_5@,@H_502_5@大家好好看看@H_502_5@:@H_502_5@@H_502_5@@H_502_5@
Memory layout:@H_502_5@@H_502_5@
0000:0000 - 0000:0FFF: Interrupt vector table & BIOS data@H_502_5@@H_502_5@
0000:1000 - 0000:6FFF: Real mode stack area@H_502_5@@H_502_5@
0000:7000 - 0000:7FFF: Cmdline (multiboot)@H_502_5@@H_502_5@
0000:8000 - xxxx:xxxx: FreeLoader program & data area@H_502_5@@H_502_5@
xxxx:xxxx - 7000:7FFF: Random memory allocation heap@H_502_5@@H_502_5@
7000:8000 - 7000:FFFF: Protected mode stack area@H_502_5@@H_502_5@
8000:0000 - 8000:FFFF: File system read buffer@H_502_5@@H_502_5@
9000:0000 - 9000:FFFF: Disk read buffer for BIOS Int 13h@H_502_5@@H_502_5@