Files
ViperOS/VKernel/Kernel/drivers/fs/fat32/fat32.py
2026-07-19 12:38:20 +08:00

209 lines
7.6 KiB
Python

from stdint import *
import string
import fat32_types as types
import fat32_time as ftime
import fat32_mkfs as mkfs_mod
import fat32_part as part
import fat32_diskio as diskio
import sched.sched as sched
import t, c
default_fs: types.volinfo = types.volinfo()
_fs_lock: t.CInt = 0
def lock():
global _fs_lock
while True:
c.Asm("cli")
if _fs_lock == 0:
_fs_lock = 1
c.Asm("sti")
return
c.Asm("sti")
sched.Scheduler._yield()
def unlock():
global _fs_lock
_fs_lock = 0
def mount() -> types.FRESULT:
default_fs.pdrv = 0
default_fs.hidden_sectors = 0
buf: t.CArray[t.CUInt8T, 512]
dres: types.DRESULT = diskio.read(0, c.Addr(buf[0]), 0, 1)
if dres == types.DRESULT.RES_OK:
if buf[0] == 0xEB or buf[0] == 0xE9:
default_fs.hidden_sectors = 0
else:
sig: t.CUInt16T = t.CUInt16T(buf[510]) | (t.CUInt16T(buf[511]) << 8)
if sig == 0xAA55:
ptype: t.CUInt8T = buf[450]
if ptype != 0:
slba: t.CUInt32T = t.CUInt32T(buf[454]) | (t.CUInt32T(buf[455]) << 8) | (t.CUInt32T(buf[456]) << 16) | (t.CUInt32T(buf[457]) << 24)
default_fs.hidden_sectors = slba
if default_fs.mounted: return types.FRESULT.FR_OK
dsk_res: types.DRESULT = diskio.status(default_fs.pdrv)
if dsk_res != types.DRESULT.RES_OK:
dsk_res = diskio.init(default_fs.pdrv)
if dsk_res != types.DRESULT.RES_OK: return types.FRESULT.FR_NOT_READY
default_fs.winsect = 0xFFFFFFFFFFFFFFFF
default_fs.fat_winsect = 0xFFFFFFFFFFFFFFFF
wres: types.FRESULT = default_fs.win_read(0)
if wres != types.FRESULT.FR_OK: return types.FRESULT.FR_DISK_ERR
bps: t.CUInt16T = default_fs.win[11] | (t.CUInt16T(default_fs.win[12]) << 8)
spc: t.CUInt8T = default_fs.win[13]
rsc: t.CUInt16T = default_fs.win[14] | (t.CUInt16T(default_fs.win[15]) << 8)
nf: t.CUInt8T = default_fs.win[16]
if bps != 512: return types.FRESULT.FR_NO_FILESYSTEM
if spc == 0 or (spc & (spc - 1)) != 0: return types.FRESULT.FR_NO_FILESYSTEM
if rsc == 0: return types.FRESULT.FR_NO_FILESYSTEM
if nf == 0: return types.FRESULT.FR_NO_FILESYSTEM
root_ent: t.CUInt16T = default_fs.win[17] | (t.CUInt16T(default_fs.win[18]) << 8)
fat16sz: t.CUInt16T = default_fs.win[22] | (t.CUInt16T(default_fs.win[23]) << 8)
tot32: t.CUInt32T = t.CUInt32T(default_fs.win[32]) | (t.CUInt32T(default_fs.win[33]) << 8) | (t.CUInt32T(default_fs.win[34]) << 16) | (t.CUInt32T(default_fs.win[35]) << 24)
fat32sz: t.CUInt32T = t.CUInt32T(default_fs.win[36]) | (t.CUInt32T(default_fs.win[37]) << 8) | (t.CUInt32T(default_fs.win[38]) << 16) | (t.CUInt32T(default_fs.win[39]) << 24)
root_clus: t.CUInt32T = t.CUInt32T(default_fs.win[44]) | (t.CUInt32T(default_fs.win[45]) << 8) | (t.CUInt32T(default_fs.win[46]) << 16) | (t.CUInt32T(default_fs.win[47]) << 24)
if root_ent != 0 or fat16sz != 0: return types.FRESULT.FR_NO_FILESYSTEM
if fat32sz == 0: return types.FRESULT.FR_NO_FILESYSTEM
if tot32 == 0: return types.FRESULT.FR_NO_FILESYSTEM
if default_fs.win[510] != 0x55 or default_fs.win[511] != 0xAA: return types.FRESULT.FR_NO_FILESYSTEM
fsinfo_sec: t.CUInt16T = default_fs.win[48] | (t.CUInt16T(default_fs.win[49]) << 8)
bkboot_sec: t.CUInt16T = default_fs.win[50] | (t.CUInt16T(default_fs.win[51]) << 8)
default_fs.sector_size = 512
default_fs.cluster_sectors = spc
default_fs.cluster_size = t.CUInt32T(spc) * 512
default_fs.num_fats = nf
default_fs.reserved_sectors = rsc
default_fs.fat_size = fat32sz
default_fs.fat_start = t.CUInt64T(rsc)
default_fs.total_sectors = t.CUInt64T(tot32)
default_fs.root_cluster = root_clus
default_fs.fsinfo_sector = fsinfo_sec
default_fs.backup_sector = bkboot_sec
default_fs.vol_id = t.CUInt32T(default_fs.win[67]) | (t.CUInt32T(default_fs.win[68]) << 8) | (t.CUInt32T(default_fs.win[69]) << 16) | (t.CUInt32T(default_fs.win[70]) << 24)
data_sectors: t.CUInt64T = default_fs.total_sectors - t.CUInt64T(rsc) - t.CUInt64T(t.CUInt64T(nf) * t.CUInt64T(fat32sz))
default_fs.total_clusters = t.CUInt32T(data_sectors / t.CUInt64T(spc))
default_fs.data_start = default_fs.fat_start + t.CUInt64T(t.CUInt64T(nf) * t.CUInt64T(fat32sz))
default_fs.last_alloc = 2
default_fs.free_clusters = 0xFFFFFFFF
if fsinfo_sec != 0:
default_fs.fsinfo_read()
default_fs.mounted = 1
return types.FRESULT.FR_OK
def unmount() -> types.FRESULT:
return default_fs.unmount()
def format(sec_per_clus: t.CUInt8T = 0, vol_id: t.CUInt32T = 0) -> types.FRESULT:
return mkfs_mod.mkfs(default_fs.pdrv, sec_per_clus, vol_id)
def open(path: t.CConst | str, mode: t.CUInt8T) -> types.fileobj | t.CPtr:
return default_fs.file_open(path, mode)
def close(fp: types.fileobj | t.CPtr) -> types.FRESULT:
return fp.close()
def read(fp: types.fileobj | t.CPtr, buff: t.CVoid | t.CPtr, btr: t.CUInt32T) -> t.CUInt32T:
br: t.CUInt32T = 0
fp.read(buff, btr, c.Addr(br))
return br
def write(fp: types.fileobj | t.CPtr, buff: t.CConst | t.CVoid | t.CPtr, btw: t.CUInt32T) -> t.CUInt32T:
bw: t.CUInt32T = 0
fp.write(buff, btw, c.Addr(bw))
return bw
def seek(fp: types.fileobj | t.CPtr, offset: t.CUInt32T) -> types.FRESULT:
return fp.seek(offset)
def tell(fp: types.fileobj | t.CPtr) -> t.CUInt32T:
return fp.tell()
def size(fp: types.fileobj | t.CPtr) -> t.CUInt32T:
return fp.size()
def truncate(fp: types.fileobj | t.CPtr) -> types.FRESULT:
return fp.truncate()
def remove(path: t.CConst | str) -> types.FRESULT:
return default_fs.file_delete(path)
def rename(old_path: t.CConst | str, new_path: t.CConst | str) -> types.FRESULT:
return default_fs.file_rename(old_path, new_path)
def move(old_path: t.CConst | str, new_path: t.CConst | str) -> types.FRESULT:
return default_fs.file_rename(old_path, new_path)
def stat(path: t.CConst | str, info: types.fileinfo | t.CPtr) -> types.FRESULT:
return default_fs.file_stat(path, info)
def mkdir(path: t.CConst | str) -> types.FRESULT:
return default_fs.dir_make(path)
def rmdir(path: t.CConst | str) -> types.FRESULT:
return default_fs.dir_remove(path)
def opendir(path: t.CConst | str, dp: types.dirobj | t.CPtr) -> types.FRESULT:
return default_fs.dir_open_path(path, dp)
def readdir(dp: types.dirobj | t.CPtr, info: types.fileinfo | t.CPtr) -> types.FRESULT:
return default_fs.dir_read(dp, info)
def closedir(dp: types.dirobj | t.CPtr):
dp.is_open = 0
def chmod(path: t.CConst | str, attr: t.CUInt8T, mask: t.CUInt8T) -> types.FRESULT:
return default_fs.chmod(path, attr, mask)
def utime(path: t.CConst | str, mtime: t.CUInt16T, mdate: t.CUInt16T) -> types.FRESULT:
return default_fs.utime(path, mtime, mdate)
def get_free() -> t.CUInt32T:
if not default_fs.mounted: return 0
if default_fs.free_clusters == 0xFFFFFFFF:
return default_fs.count_free_clusters()
return default_fs.free_clusters
def get_total() -> t.CUInt32T:
if not default_fs.mounted: return 0
return default_fs.total_clusters
def get_cluster_size() -> t.CUInt32T:
if not default_fs.mounted: return 0
return default_fs.cluster_size
def is_mounted() -> t.CInt:
return default_fs.mounted
def last_error() -> t.CUInt32T:
return default_fs.last_error
def get_fattime() -> t.CUInt32T:
return ftime.get_fattime()
def get_metadata() -> t.CUInt32T:
return default_fs.metadata
def set_metadata(val: t.CUInt32T):
default_fs.metadata = val
def scan_drives() -> types.FRESULT:
return part.scan_drives()
def get_drive_count() -> t.CInt:
return part.get_drive_count()
def get_drive_letter(idx: t.CInt) -> t.CChar:
return part.get_drive_letter(idx)
def set_drive_letter(idx: t.CInt, letter: t.CChar) -> types.FRESULT:
return part.set_drive_letter(idx, letter)
def get_partition_count(letter: t.CChar) -> t.CInt:
return part.get_partition_count(letter)
def is_partition_fat32(letter: t.CChar, part_idx: t.CInt) -> t.CInt:
return part.is_partition_fat32(letter, part_idx)