Port fat_io_lib, mount atasd0mp1 as sys:

This commit is contained in:
2025-11-19 15:50:00 +01:00
parent 5d77974586
commit 0cc78a7247
35 changed files with 7071 additions and 7 deletions

View File

@ -0,0 +1,225 @@
#include <stdint.h>
#include <stdbool.h>
#include "fs/fatfs/fat_context.h"
#include "fs/fatfs/fat_filelib.h"
#include "sysdefs/fs.h"
#include "vfs/vfs.h"
#include "dlmalloc/malloc.h"
#include "std/string.h"
#include "spinlock/spinlock.h"
#include "util/util.h"
#include "errors.h"
#include "kprintf.h"
// REF: https://github.com/ultraembedded/fat_io_lib/blob/master/examples/sd_card_generic/sd.c
int32_t fatfs_cleanup(struct VfsMountPoint *vmp) {
fl_shutdown(&vmp->fs.fatfs.instance);
return E_OK;
}
void fatfs_vobj_cleanup(struct VfsObj *vobj) {
if (vobj->extra != NULL) {
fl_fclose(&vobj->vmp->fs.fatfs.instance, vobj->extra);
}
dlfree(vobj);
}
int32_t fatfs_vobj_read(struct VfsObj *vobj, uint8_t *const buffer, size_t n, size_t off) {
if (!(vobj->flags & VFS_FLAG_READ)) {
return E_INVALIDOPER;
}
spinlock_acquire(&vobj->spinlock);
int ok = fl_fseek(&vobj->vmp->fs.fatfs.instance, vobj->extra, off, SEEK_SET);
if (ok < 0) {
spinlock_release(&vobj->spinlock);
return E_BADIO;
}
ok = fl_fread(&vobj->vmp->fs.fatfs.instance, buffer, 1, n, vobj->extra);
if (ok < 0) {
spinlock_release(&vobj->spinlock);
return E_BADIO;
}
spinlock_release(&vobj->spinlock);
return E_OK;
}
int32_t fatfs_vobj_write(struct VfsObj *vobj, const uint8_t *const buffer, size_t n, size_t off) {
if (!(vobj->flags & VFS_FLAG_WRITE)) {
return E_INVALIDOPER;
}
spinlock_acquire(&vobj->spinlock);
int ok = fl_fseek(&vobj->vmp->fs.fatfs.instance, vobj->extra, off, SEEK_SET);
if (ok < 0) {
spinlock_release(&vobj->spinlock);
return E_BADIO;
}
ok = fl_fwrite(&vobj->vmp->fs.fatfs.instance, buffer, 1, n, vobj->extra);
if (ok < 0) {
spinlock_release(&vobj->spinlock);
return E_BADIO;
}
spinlock_release(&vobj->spinlock);
return E_OK;
}
struct VfsObj *fatfs_open(struct VfsMountPoint *vmp, const char *path, uint32_t flags) {
VfsObj *vobj = dlmalloc(sizeof(*vobj));
if (vobj == NULL) {
return NULL;
}
memset(vobj, 0, sizeof(*vobj));
spinlock_init(&vobj->spinlock);
char *mods = dlmalloc(4);
memset(mods, 0, 4);
spinlock_acquire(&vmp->spinlock);
FatFs *fs = &vmp->fs.fatfs;
if ((flags & VFS_FLAG_READ) && !(flags & VFS_FLAG_WRITE) && !(flags & VFS_FLAG_MAKE)) {
strcpy(mods, "rb");
} else if (!(flags & VFS_FLAG_READ) && (flags & VFS_FLAG_WRITE) && !(flags & VFS_FLAG_MAKE)) {
strcpy(mods, "wb");
} else if ((flags & VFS_FLAG_READ) && (flags & VFS_FLAG_WRITE) && !(flags & VFS_FLAG_MAKE)) {
strcpy(mods, "rb+");
} else if (!(flags & VFS_FLAG_READ) && (flags & VFS_FLAG_WRITE) && (flags & VFS_FLAG_MAKE)) {
strcpy(mods, "wb");
} else if ((flags & VFS_FLAG_READ) && (flags & VFS_FLAG_WRITE) && (flags & VFS_FLAG_MAKE)) {
strcpy(mods, "wb+");
}
void *f = fl_fopen(&fs->instance, path, mods);
dlfree(mods);
if (f == NULL) {
dlfree(vobj);
spinlock_release(&vmp->spinlock);
return NULL;
}
vobj->flags = flags;
vobj->extra = f;
vobj->vmp = vmp;
vobj->cleanup = &fatfs_vobj_cleanup;
vobj->read = &fatfs_vobj_read;
vobj->write = &fatfs_vobj_write;
spinlock_release(&vmp->spinlock);
return vobj;
}
int32_t fatfs_stat(struct VfsMountPoint *vmp, const char *path, FsStat *statbuf) {
spinlock_acquire(&vmp->spinlock);
if (fl_is_dir(&vmp->fs.fatfs.instance, path)) {
FL_DIR dirstat;
if (fl_opendir(&vmp->fs.fatfs.instance, path, &dirstat) == NULL) {
spinlock_release(&vmp->spinlock);
return E_NOENTRY;
}
statbuf->type = FSSTAT_DIR;
statbuf->size = 0;
fl_dirent dirent;
while (fl_readdir(&vmp->fs.fatfs.instance, &dirstat, &dirent) == 0) {
statbuf->size++;
}
fl_closedir(&vmp->fs.fatfs.instance, &dirstat);
} else {
FL_FILE *f = fl_fopen(&vmp->fs.fatfs.instance, path, "r");
statbuf->type = FSSTAT_FILE;
statbuf->size = f->filelength;
fl_fclose(&vmp->fs.fatfs.instance, f);
}
spinlock_release(&vmp->spinlock);
return E_OK;
}
int32_t fatfs_fetchdirent(struct VfsMountPoint *vmp, const char *path, FsDirent *direntbuf, size_t idx) {
spinlock_acquire(&vmp->spinlock);
FL_DIR dirstat;
FL_DIR *d = fl_opendir(&vmp->fs.fatfs.instance, path, &dirstat);
if (d == NULL) {
spinlock_release(&vmp->spinlock);
return E_BADIO;
}
fl_dirent dirent;
size_t i = 0;
while (fl_readdir(&vmp->fs.fatfs.instance, d, &dirent) == 0) {
if (i == idx) {
direntbuf->stat.type = dirent.is_dir ? FSSTAT_DIR : FSSTAT_FILE;
direntbuf->stat.size = dirent.is_dir ? 0 : dirent.size;
strncpy(direntbuf->name, dirent.filename, sizeof(direntbuf->name));
break;
}
i++;
}
fl_closedir(&vmp->fs.fatfs.instance, d);
spinlock_release(&vmp->spinlock);
return E_OK;
}
int32_t fatfs_mkdir(struct VfsMountPoint *vmp, const char *path) {
spinlock_acquire(&vmp->spinlock);
int err = fl_createdirectory(&vmp->fs.fatfs.instance, path);
spinlock_release(&vmp->spinlock);
return err == 0 ? E_OK : E_BADIO;
}
int32_t fatfs_delete(struct VfsMountPoint *vmp, const char *path) {
spinlock_acquire(&vmp->spinlock);
int err = fl_remove(&vmp->fs.fatfs.instance, path);
spinlock_release(&vmp->spinlock);
return err == 0 ? E_OK : E_BADIO;
}
int portfatfs_diskio_read(struct fat_ctx *ctx, uint32_t sector, uint8_t *buffer, uint32_t sector_count) {
VfsMountPoint *vmp = ctx->extra;
if (sector_count == 0) {
return 0;
}
uint64_t byteaddr = (uint64_t)sector * FAT_SECTOR_SIZE;
ptrdiff_t sector1 = byteaddr / vmp->backingsd->sectorsize;
ptrdiff_t sector_off = byteaddr % vmp->backingsd->sectorsize;
int32_t ret = vmp->backingsd->read(vmp->backingsd, (uint8_t *const)buffer, sector1, sector_off, sector_count * FAT_SECTOR_SIZE);
if (ret != E_OK) {
return 0;
}
return 1;
}
int portfatfs_diskio_write(struct fat_ctx *ctx, uint32_t sector, uint8_t *buffer, uint32_t sector_count) {
VfsMountPoint *vmp = ctx->extra;
if (sector_count == 0) {
return 0;
}
uint64_t byteaddr = (uint64_t)sector * FAT_SECTOR_SIZE;
ptrdiff_t sector1 = byteaddr / vmp->backingsd->sectorsize;
ptrdiff_t sector_off = byteaddr % vmp->backingsd->sectorsize;
int32_t ret = vmp->backingsd->write(vmp->backingsd, (const uint8_t *const)buffer, sector1, sector_off, sector_count * FAT_SECTOR_SIZE);
if (ret != E_OK) {
return 0;
}
return 1;
}

View File

@ -0,0 +1,26 @@
#ifndef FS_PORTFATFS_PORTFATFS_H_
#define FS_PORTFATFS_PORTFATFS_H_
#include <stdint.h>
#include <stdbool.h>
#include "fs/fatfs/fat_context.h"
#include "sysdefs/fs.h"
struct VfsMountPoint;
struct VfsObj;
typedef struct {
struct fat_ctx instance;
} FatFs;
int32_t fatfs_cleanup(struct VfsMountPoint *vmp);
struct VfsObj *fatfs_open(struct VfsMountPoint *vmp, const char *path, uint32_t flags);
int32_t fatfs_stat(struct VfsMountPoint *vmp, const char *path, FsStat *statbuf);
int32_t fatfs_fetchdirent(struct VfsMountPoint *vmp, const char *path, FsDirent *direntbuf, size_t idx);
int32_t fatfs_mkdir(struct VfsMountPoint *vmp, const char *path);
int32_t fatfs_delete(struct VfsMountPoint *vmp, const char *path);
int portfatfs_diskio_read(struct fat_ctx *ctx, uint32_t sector, uint8_t *buffer, uint32_t sector_count);
int portfatfs_diskio_write(struct fat_ctx *ctx, uint32_t sector, uint8_t *buffer, uint32_t sector_count);
#endif // FS_PORTFATFS_PORTFATFS_H_