⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat32.asm

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 ASM
📖 第 1 页 / 共 2 页
字号:
        int 19h							; Reboot

PutChars:
        lodsb
        or al,al
        jz short Done
        mov ah,0eh
        mov bx,07h
        int 10h
        jmp short PutChars
Done:
        retn



BiosCHSDriveSize dd 0

msgDiskError		db 'Disk error',0dh,0ah,0
msgFileSystemError	db 'File system error',0dh,0ah,0
msgAnyKey			db 'Press any key to restart',0dh,0ah,0

        times 509-($-$$) db 0   ; Pad to 509 bytes

BootPartition:
		db 0

BootSignature:
        dw 0aa55h       ; BootSector signature
        

; End of bootsector
;
; Now starts the extra boot code that we will store
; at sector 14 on a FAT32 volume
;
; To remain multi-boot compatible with other operating
; systems we must not overwrite anything other than
; the bootsector which means we will have to use
; a different sector like 14 to store our extra boot code



StartSearch:
        ; Now we must get the first cluster of the root directory
		mov  eax,DWORD [BYTE bp+RootDirStartCluster]
		cmp  eax,0ffffff8h		; Check to see if this is the last cluster in the chain
		jb	 ContinueSearch		; If not continue, if so then we didn't find freeldr.sys
		jmp  PrintFileNotFound
ContinueSearch:
        mov  bx,2000h
        mov  es,bx				; Read cluster to [2000:0000h]
        call ReadCluster        ; Read the cluster


        ; Now we have to find our way through the root directory to
        ; The OSLOADER.SYS file
		xor  bx,bx
        mov  bl,[BYTE bp+SectsPerCluster]
		shl  bx,4				; BX = BX * 512 / 32
        mov  ax,2000h            ; We loaded at 2000:0000
        mov  es,ax
        xor  di,di
        mov  si,filename
        mov  cx,11
        rep  cmpsb              ; Compare filenames
        jz   FoundFile          ; If same we found it
        dec  bx
        jnz  FindFile
        jmp  PrintFileNotFound

FindFile:
        mov  ax,es              ; We didn't find it in the previous dir entry
        add  ax,2               ; So lets move to the next one
        mov  es,ax              ; And search again
        xor  di,di
        mov  si,filename        
        mov  cx,11
        rep  cmpsb              ; Compare filenames
        jz   FoundFile          ; If same we found it
        dec  bx                 ; Keep searching till we run out of dir entries
        jnz  FindFile           ; Last entry?

		; Get the next root dir cluster and try again until we run out of clusters
		mov  eax,DWORD [BYTE bp+RootDirStartCluster]
		call GetFatEntry
		mov  [BYTE bp+RootDirStartCluster],eax
        jmp  StartSearch

FoundFile:

										; Display "Loading FreeLoader..." message
        mov  si,msgLoading				; Loading message
        call PutChars					; Display it

        xor  di,di						; ES:DI has dir entry
        xor  dx,dx
        mov  ax,WORD [es:di+14h]        ; Get start cluster high word
		shl  eax,16
        mov  ax,WORD [es:di+1ah]        ; Get start cluster low word

CheckStartCluster:
		cmp  eax,2						; Check and see if the start cluster starts at cluster 2 or above
		jnb  CheckEndCluster			; If so then continue
		jmp  PrintFileSystemError		; If not exit with error
CheckEndCluster:
		cmp  eax,0ffffff8h				; Check and see if the start cluster is and end of cluster chain indicator
		jb   InitializeLoadSegment		; If not then continue
		jmp  PrintFileSystemError		; If so exit with error

InitializeLoadSegment:
        mov  bx,800h
        mov  es,bx

LoadFile:
		cmp  eax,0ffffff8h		; Check to see if this is the last cluster in the chain
		jae	 LoadFileDone		; If so continue, if not then read the next one
		push eax
        xor  bx,bx              ; Load ROSLDR starting at 0000:8000h
		push es
		call ReadCluster
		pop  es

		xor  bx,bx
        mov  bl,[BYTE bp+SectsPerCluster]
		shl  bx,5				; BX = BX * 512 / 16
		mov  ax,es				; Increment the load address by
		add  ax,bx				; The size of a cluster
		mov  es,ax

		pop  eax
		push es
		call GetFatEntry		; Get the next entry
		pop  es

        jmp  LoadFile			; Load the next cluster (if any)

LoadFileDone:
        mov  dl,[BYTE bp+BootDrive]		; Load boot drive into DL
		mov  dh,[BootPartition]			; Load boot partition into DH
        xor  ax,ax
        push ax					; We loaded at 0000:8000
        push WORD 8000h			; We will do a far return to 0000:8000h
        retf                    ; Transfer control to ROSLDR


; Returns the FAT entry for a given cluster number
; On entry EAX has cluster number
; On return EAX has FAT entry for that cluster
GetFatEntry:

		shl   eax,2								; EAX = EAX * 4 (since FAT32 entries are 4 bytes)
		mov   ecx,eax							; Save this for later in ECX
		xor   edx,edx
		movzx ebx,WORD [BYTE bp+BytesPerSector]
		push  ebx
		div   ebx								; FAT Sector Number = EAX / BytesPerSector
		movzx ebx,WORD [BYTE bp+ReservedSectors]
		add   eax,ebx							; FAT Sector Number += ReservedSectors
		mov   ebx,DWORD [BYTE bp+HiddenSectors]
		add   eax,ebx							; FAT Sector Number += HiddenSectors
		pop   ebx
		dec   ebx
		and   ecx,ebx							; FAT Offset Within Sector = ECX % BytesPerSector
												; EAX holds logical FAT sector number
												; ECX holds FAT entry offset

												; Now we have to check the extended flags
												; to see which FAT is the active one
												; and use it, or if they are mirrored then
												; no worries
		movzx ebx,WORD [BYTE bp+ExtendedFlags]	; Get extended flags and put into ebx
		and   bx,0x0f							; Mask off upper 8 bits, now we have active fat in bl
		jz    LoadFatSector						; If fat is mirrored then skip fat calcs
		cmp   bl,[BYTE bp+NumberOfFats]			; Compare bl to number of fats
		jb    GetActiveFatOffset
		jmp   PrintFileSystemError				; If bl is bigger than numfats exit with error
GetActiveFatOffset:
		push  eax								; Save logical FAT sector number
		mov   eax,[BYTE bp+SectorsPerFatBig]	; Get the number of sectors occupied by one fat in eax
		mul   ebx								; Multiplied by the active FAT index we have in ebx
		pop   edx								; Get logical FAT sector number
		add   eax,edx							; Add the current FAT sector offset

LoadFatSector:
		push  ecx
		; EAX holds logical FAT sector number
		; Check if we have already loaded it
		cmp  eax,DWORD [FatSectorInCache]
		je   LoadFatSectorAlreadyLoaded

		mov  DWORD [FatSectorInCache],eax
        mov  bx,7000h
        mov  es,bx
        xor  bx,bx								; We will load it to [7000:0000h]
		mov  cx,1
		call ReadSectors

LoadFatSectorAlreadyLoaded:
        mov  bx,7000h
        mov  es,bx
		pop  ecx
		mov  eax,DWORD [es:ecx]					; Get FAT entry
		and  eax,0fffffffh						; Mask off reserved bits

		ret

FatSectorInCache:								; This variable tells us which sector we currently have in memory
	dd	0ffffffffh								; There is no need to re-read the same sector if we don't have to


; Reads cluster number in EAX into [ES:0000]
ReadCluster:
		; StartSector = ((Cluster - 2) * SectorsPerCluster) + ReservedSectors + HiddenSectors;

		dec   eax
		dec   eax
		xor   edx,edx
		movzx ebx,BYTE [BYTE bp+SectsPerCluster]
		mul   ebx
		push  eax
		xor   edx,edx
		movzx eax,BYTE [BYTE bp+NumberOfFats]
		mul   DWORD [BYTE bp+SectorsPerFatBig]
		movzx ebx,WORD [BYTE bp+ReservedSectors]
		add   eax,ebx
		add   eax,DWORD [BYTE bp+HiddenSectors]
		pop   ebx
		add   eax,ebx			; EAX now contains the logical sector number of the cluster
        xor   bx,bx				; We will load it to [ES:0000], ES loaded before function call
		movzx cx,BYTE [BYTE bp+SectsPerCluster]
		call  ReadSectors
		ret


; Displays a file not found error message
; And reboots
PrintFileNotFound:
        mov  si,msgFreeLdr      ; FreeLdr not found message
        call PutChars           ; Display it
        mov  si,msgAnyKey       ; Press any key message
        call PutChars           ; Display it

		jmp  Reboot

msgFreeLdr   db 'freeldr.sys not found',0dh,0ah,0
filename     db 'FREELDR SYS'
msgLoading   db 'Loading FreeLoader...',0dh,0ah,0


        times 1022-($-$$) db 0   ; Pad to 1022 bytes

        dw 0aa55h       ; BootSector signature

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -