move old fat32 system to fat32/old
This commit is contained in:
320
include/fat32/old/FAT32_SYS.old.inc
Normal file
320
include/fat32/old/FAT32_SYS.old.inc
Normal file
@@ -0,0 +1,320 @@
|
||||
; Copyright (C) 2025 Elaina Claus
|
||||
;
|
||||
; This program is free software: you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation, either version 3 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
%ifndef __INC_FAT32_SYS
|
||||
|
||||
%include "partition_table.inc"
|
||||
%include "fat32/bpb_offset_bx.inc"
|
||||
%include "fat32/fat32_structures.inc"
|
||||
|
||||
; Clobbers: eax, edx
|
||||
; returns: none
|
||||
ALIGN 4, db 0x90
|
||||
InitFATDriver:
|
||||
__CDECL16_PROC_ENTRY
|
||||
.func:
|
||||
|
||||
__CDECL16_CALL_ARGS fat32_state, 0x0000, FAT32_State_t_size
|
||||
__CDECL16_CALL kmemset, 3
|
||||
|
||||
.calc_active_part:
|
||||
mov ax, word [partition_offset]
|
||||
mov di, fat32_state
|
||||
|
||||
mov dx, partition_table
|
||||
add dx, ax ; dx points to the partition that was booted from
|
||||
mov bx, dx ; set bx, should point at our partition
|
||||
|
||||
mov eax, dword [bx + PartEntry_t.lba_start]
|
||||
mov dword [di + FAT32_State_t.curr_drive_lba_32], eax
|
||||
|
||||
mov si, fat32_bpb
|
||||
mov bx, fat32_ebpb
|
||||
.calc_first_fat:
|
||||
movzx eax, word [si + FAT32_bpb_t.reserved_sectors_word] ; first fat from start of partition
|
||||
add eax, dword [di + FAT32_State_t.curr_drive_lba_32] ; calculate offset from start of drive
|
||||
jc InitFATDriver.error
|
||||
|
||||
mov dword [di + FAT32_State_t.first_fat_sector_32], eax
|
||||
.calc_total_fat:
|
||||
mov edx, dword [bx + FAT32_ebpb_t.FATSz_dword]
|
||||
movzx eax, byte [si + FAT32_bpb_t.fat_count_byte]
|
||||
mul edx ; result in EDX:EAX, CF set on > 32bit return value
|
||||
jc InitFATDriver.error ; as a catch for unhandled overflow, just error if value is greater than 32bits
|
||||
|
||||
mov dword [di + FAT32_State_t.fat_size_32], eax
|
||||
.calc_first_data:
|
||||
mov edx, dword [di + FAT32_State_t.first_fat_sector_32]
|
||||
add eax, edx
|
||||
jc InitFATDriver.error
|
||||
|
||||
mov dword [di + FAT32_State_t.first_data_sector_32], eax
|
||||
.set_first_dir:
|
||||
mov eax, dword [bx + FAT32_ebpb_t.root_clus_dword]
|
||||
mov dword [di + FAT32_State_t.curr_dir_cluster_32], eax
|
||||
.endp:
|
||||
__CDECL16_PROC_EXIT
|
||||
ret
|
||||
.error:
|
||||
ERROR STAGE2_FAT32_INIT_CF
|
||||
|
||||
ALIGN 4, db 0x90
|
||||
FSInfoPrinter:
|
||||
__CDECL16_PROC_ENTRY
|
||||
.func:
|
||||
;info we want to print to validate we are loading stuff from the disk correctly
|
||||
; boot_drive # (i.e 0x80)
|
||||
; active/bootable partition info (lba_start, lba_length, part_type)
|
||||
; BPB Info: BS_OEMName = ident_8, BPB_BytsPerSec = bytes_per_sector_16, BPB_SecPerClus = sectors_per_cluster_8
|
||||
; eBPB info: FATSz_dword, volid, vol label
|
||||
;
|
||||
; print entire FAT32 state
|
||||
;
|
||||
.endp:
|
||||
__CDECL16_PROC_EXIT
|
||||
ret
|
||||
.error:
|
||||
ERROR STAGE2_ERROR_INFOPRINTER
|
||||
|
||||
; this involves using the low memory buffer for the bios call and moving the file sector by sector to high memory
|
||||
;
|
||||
; SFN is a 8.3 file name, all uppercase, and padded with spaces
|
||||
; do not add a null byte to the end of the string
|
||||
; eg. kernel.bin == "KERNEL BIN"
|
||||
;
|
||||
; returns first cluster of file if found
|
||||
; halts/errors if file is not found
|
||||
; uint32_t SearchFATDIR(uint8_t* SFN);
|
||||
ALIGN 4, db 0x90
|
||||
SearchFATDIR:
|
||||
__CDECL16_PROC_ENTRY
|
||||
.file_lookup:
|
||||
__CDECL16_CALL_ARGS SearchFATDIR_info
|
||||
__CDECL16_CALL PrintString, 1
|
||||
|
||||
mov bx, fat32_state
|
||||
.load_first_dir:
|
||||
|
||||
; uint8_t ReadFATCluster(uint16_t seg, uint16_t offset, uint32_t cluster)
|
||||
push dword [bx + FAT32_State_t.curr_dir_cluster_32] ; cluster
|
||||
push dir_buffer ; offset
|
||||
push 0x0000 ; segment
|
||||
call ReadFATCluster
|
||||
add sp, 0x8
|
||||
|
||||
mov si, dir_buffer
|
||||
jmp SearchFATDIR.empty_dir_entry
|
||||
|
||||
.load_next_dir:
|
||||
; if eax >= 0x0FFFFFF8 then there are no more clusters (end of chain)
|
||||
; if eax == 0x0FFFFFF7 then this is a cluster that is marked as bad
|
||||
|
||||
; uint32_t NextCluster(uint32_t active_cluster);
|
||||
push dword [bx + FAT32_State_t.curr_dir_cluster_32]
|
||||
call NextCluster
|
||||
add sp, 0x4
|
||||
|
||||
cmp eax, 0x0fff_fff7
|
||||
;je SearchFATDIR.bad_cluster ; TODO: Implement Bad cluster checks
|
||||
jb SearchFATDIR.load_next_dir_next_OK
|
||||
ERROR STAGE2_FAT32_END_OF_CHAIN
|
||||
|
||||
.load_next_dir_next_OK:
|
||||
; load 512 bytes of directory entries from data sector
|
||||
|
||||
; uint8_t ReadFATCluster(uint16_t seg, uint16_t offset, uint32_t cluster)
|
||||
push dword [bx + FAT32_State_t.curr_dir_cluster_32] ; cluster
|
||||
push dir_buffer ; offset
|
||||
push 0x0000 ; segment
|
||||
call ReadFATCluster
|
||||
add sp, 0x8
|
||||
|
||||
.empty_dir_entry:
|
||||
; check for 0x0 in first byte, if true then there are no more files
|
||||
; if true we did not find the file, we should error here
|
||||
cmp byte [si], 0
|
||||
jne SearchFATDIR.unused_dir_entry
|
||||
ERROR STAGE2_FAT32_NO_FILE
|
||||
|
||||
.unused_dir_entry:
|
||||
; check for 0xe5 and 0x05 in first byte, if true then this entry is unused, but it is not the last entry.
|
||||
cmp byte [si], 0xe5
|
||||
je SearchFATDIR.next_entry
|
||||
|
||||
cmp byte [si], 0x05
|
||||
je SearchFATDIR.next_entry
|
||||
jmp SearchFATDIR.parse_dir
|
||||
|
||||
.next_entry:
|
||||
; increment offset by 32 bytes to read the next entry in this set of dir entries
|
||||
; if we are at the end of the buffer, then load the next buffer
|
||||
add si, 0x20 ; 32 bytes
|
||||
|
||||
mov ax, dir_buffer
|
||||
add ax, 0x1FF ; 512 - 1 bytes
|
||||
cmp si, ax
|
||||
jae SearchFATDIR.load_next_dir
|
||||
jmp SearchFATDIR.empty_dir_entry
|
||||
|
||||
; TODO: move this to a seperate string search function
|
||||
.parse_dir:
|
||||
__CDECL16_CALL_ARGS MaybeFound_Boot_info
|
||||
__CDECL16_CALL PrintString, 1
|
||||
|
||||
.lfn_check:
|
||||
; check for ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID (0x0F) in offset 11
|
||||
; TODO: going to skip LFN for now, since all valid volumes will have SFN's
|
||||
cmp byte [si+11], 0x0F
|
||||
je SearchFATDIR.next_entry
|
||||
.sfn_file_name_check:
|
||||
push si
|
||||
push di
|
||||
|
||||
mov cx, 0xA ; max of 11 filename length of 11 characters
|
||||
; si points to the start of the current directory entry
|
||||
mov di, BootTarget ; current memory location (8.3 name is at offset 0)
|
||||
repe cmpsb ; compare the strings
|
||||
|
||||
pop di
|
||||
pop si
|
||||
jne SearchFATDIR.next_entry
|
||||
|
||||
.sfn_entry_found:
|
||||
mov ax, [si + FAT32_SFN_t.cluster_16_high]
|
||||
shl eax, 16
|
||||
mov ax, [si + FAT32_SFN_t.cluster_16_low]
|
||||
; eax == first cluster of file
|
||||
.endp:
|
||||
__CDECL16_PROC_EXIT
|
||||
ret
|
||||
|
||||
; BUG: this function needs review
|
||||
; uint32_t NextCluster(uint32_t active_cluster);
|
||||
; if eax >= 0x0FFFFFF8 then there are no more clusters (end of chain)
|
||||
; if eax == 0x0FFFFFF7 then this is a cluster that is marked as bad
|
||||
ALIGN 4, db 0x90
|
||||
NextCluster:
|
||||
__CDECL16_PROC_ENTRY
|
||||
.func:
|
||||
__CDECL16_CALL_ARGS NextFATCluster_info
|
||||
__CDECL16_CALL PrintString, 1
|
||||
|
||||
__CDECL16_CALL_ARGS fat32_nc_data, 0x0000, FAT32_NextClusterData_t_size
|
||||
__CDECL16_CALL kmemset, 3
|
||||
|
||||
mov edx, dword [bp + 4] ; active_cluster
|
||||
mov si, fat32_nc_data ; instead of push/pop and moving the data back
|
||||
mov di, fat32_bpb ; load si & di then use xchg
|
||||
mov bx, fat32_state
|
||||
.calc_offset:
|
||||
; fat_offset = active_cluster * 4
|
||||
mov eax, 4
|
||||
mul edx
|
||||
jc NextCluster.error_cfdivz
|
||||
mov dword [si + FAT32_NextClusterData_t.fat_offset], eax ; move lower 32 bits to fat offset
|
||||
.calc_fat_sector:
|
||||
; fat_sector = first_fat_sector + (fat_offset / sector_size)
|
||||
; entry_offset = fat_offset % sector_size
|
||||
xor edx, edx
|
||||
movzx ecx, word [di + FAT32_bpb_t.bytes_per_sector_word]
|
||||
cmp eax, 0
|
||||
je NextCluster.error_cfdivz
|
||||
div ecx ; eDX:eAX / eCX = fat_sector - first_fat_sector in eAX
|
||||
; eDX = remainder (fat_offset mod sector_size)
|
||||
|
||||
mov dword [si + FAT32_NextClusterData_t.entry_offset], edx
|
||||
mov ecx, dword [bx + FAT32_State_t.first_fat_sector_32]
|
||||
add eax, ecx ; fat_sector + first_fat_sector
|
||||
mov dword [si + FAT32_NextClusterData_t.fat_sector], eax
|
||||
.load_fat_table:
|
||||
xor ax, ax
|
||||
mov al, byte [boot_drive]
|
||||
push ax
|
||||
|
||||
mov ax, 0x1
|
||||
push ax
|
||||
|
||||
; load correct fat
|
||||
mov eax, dword [si + FAT32_NextClusterData_t.fat_sector]
|
||||
push dword eax
|
||||
|
||||
mov ax, fat_buffer
|
||||
push ax
|
||||
|
||||
xor ax, ax
|
||||
push ax
|
||||
call read_disk_raw
|
||||
add sp, 0xC
|
||||
; uint8_t read_stage2_raw(uint16_t buf_segment, uint16_t buf_offset,
|
||||
; uint32_t lba,
|
||||
; uint16_t count, uint16_t drive_num)
|
||||
.read_cluster:
|
||||
; next_cluster = fat_buffer[entry_offset]
|
||||
mov ebx, dword [si + FAT32_NextClusterData_t.entry_offset]
|
||||
mov si, fat_buffer
|
||||
mov eax, dword [bx+si+0]
|
||||
; BUG: ???
|
||||
.endp:
|
||||
__CDECL16_PROC_EXIT
|
||||
ret
|
||||
.error_cfdivz:
|
||||
ERROR STAGE2_FAT32_NCLUS_CFDIVZ
|
||||
|
||||
; uint8_t ReadFATCluster(uint16_t seg, uint16_t offset, uint32_t cluster)
|
||||
ALIGN 4, db 0x90
|
||||
ReadFATCluster:
|
||||
__CDECL16_PROC_ENTRY
|
||||
.func:
|
||||
__CDECL16_CALL_ARGS ReadFATCluster_info
|
||||
__CDECL16_CALL PrintString, 1
|
||||
|
||||
mov bx, fat32_bpb
|
||||
mov si, fat32_ebpb
|
||||
|
||||
xor ax, ax
|
||||
mov al, byte [boot_drive]
|
||||
push ax
|
||||
|
||||
mov ax, 0x1 ; count = 1
|
||||
push ax
|
||||
|
||||
mov eax, dword [bp + 8] ; cluster
|
||||
sub eax, 2
|
||||
movzx edx, byte [bx + FAT32_bpb_t.sectors_per_cluster_byte]
|
||||
mul edx ; result in eax, error on carry
|
||||
jc ReadFATCluster.error
|
||||
add eax, dword [si + FAT32_State_t.first_data_sector_32]
|
||||
jc ReadFATCluster.error
|
||||
; eax contains the LBA now
|
||||
push dword eax ; lba = ClusterToLBA(..)
|
||||
|
||||
mov ax, word [bp + 6] ; offset
|
||||
push ax
|
||||
|
||||
mov ax, word [bp + 4]
|
||||
push ax
|
||||
; uint8_t read_disk_raw(uint16_t buf_segment, uint16_t buf_offset,
|
||||
; uint32_t lba,
|
||||
; uint16_t count, uint16_t drive_num)
|
||||
call read_disk_raw
|
||||
add sp, 0xC
|
||||
.endp:
|
||||
__CDECL16_PROC_EXIT
|
||||
ret
|
||||
.error:
|
||||
ERROR STAGE2_FAT32_CLS2LBA_CF
|
||||
|
||||
%endif
|
||||
%define __INC_FAT32_SYS
|
||||
Reference in New Issue
Block a user