From 01c414a18004f3998b02e3d8cd5f357f0d6f1189 Mon Sep 17 00:00:00 2001 From: CTCaer Date: Sun, 22 Jun 2025 13:38:56 +0300 Subject: [PATCH] bdk: fatfs: optimize format and fix PrFILE2 SAFE The FAT tables are now always aligned 1MB which can increase the FAT traversing speed. Additionally, always aligning the FAT tables to minimum 16KB fixes a case where PrFILE2 SAFE could be disabled because of unaligned FAT. --- bdk/libs/fatfs/diskio.h | 22 +--------------- bdk/libs/fatfs/ff.c | 58 +++++++++++++++++++++-------------------- 2 files changed, 31 insertions(+), 49 deletions(-) diff --git a/bdk/libs/fatfs/diskio.h b/bdk/libs/fatfs/diskio.h index b5299c65..d4357eb9 100644 --- a/bdk/libs/fatfs/diskio.h +++ b/bdk/libs/fatfs/diskio.h @@ -61,27 +61,7 @@ DRESULT disk_set_info (BYTE pdrv, BYTE cmd, void *buff); #define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */ #define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */ #define SET_SECTOR_OFFSET 5 /* Set media logical offset */ - -/* Generic command (Not used by FatFs) */ -#define CTRL_POWER 5 /* Get/Set power status */ -#define CTRL_LOCK 6 /* Lock/Unlock media removal */ -#define CTRL_EJECT 7 /* Eject media */ -#define CTRL_FORMAT 8 /* Create physical format on the media */ - -/* MMC/SDC specific ioctl command */ -#define MMC_GET_TYPE 10 /* Get card type */ -#define MMC_GET_CSD 11 /* Get CSD */ -#define MMC_GET_CID 12 /* Get CID */ -#define MMC_GET_OCR 13 /* Get OCR */ -#define MMC_GET_SDSTAT 14 /* Get SD status */ -#define ISDIO_READ 55 /* Read data form SD iSDIO register */ -#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */ -#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */ - -/* ATA/CF specific ioctl command */ -#define ATA_GET_REV 20 /* Get F/W revision */ -#define ATA_GET_MODEL 21 /* Get model name */ -#define ATA_GET_SN 22 /* Get serial number */ +#define SET_WRITE_PROTECT 6 /* Lock/Unlock media removal */ #ifdef __cplusplus } diff --git a/bdk/libs/fatfs/ff.c b/bdk/libs/fatfs/ff.c index 109e87b3..81e951da 100644 --- a/bdk/libs/fatfs/ff.c +++ b/bdk/libs/fatfs/ff.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2022 CTCaer + * Copyright (c) 2018-2025 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -39,6 +39,7 @@ #include "ff.h" /* Declarations of FatFs API */ #include "diskio.h" /* Declarations of device I/O functions */ #include +#include #include #define EFSPRINTF(text, ...) print_error(); gfx_printf("%k"text"%k\n", 0xFFFFFF00, 0xFFFFFFFF); @@ -6118,10 +6119,26 @@ FRESULT f_mkfs ( for (i = 0, pau = 1; cst32[i] && cst32[i] <= n; i++, pau <<= 1) ; /* Get from table */ } n_clst = sz_vol / pau; /* Number of clusters */ - sz_fat = (n_clst * 4 + 8 + ss - 1) / ss; /* FAT size [sector] */ - sz_rsv = 32; /* Number of reserved sectors */ - sz_dir = 0; /* No static directory */ - if (n_clst <= MAX_FAT16 || n_clst > MAX_FAT32) LEAVE_MKFS(FR_MKFS_ABORTED); + while (1) { + /* Do not account for reserved/root cluster on FAT size for better alignment. */ + sz_fat = (n_clst * 4 + ss - 1) / ss; /* FAT size [sector]. */ + sz_rsv = 2048; /* Number of reserved sectors. Use 1MB for better performance (for flash memory media) */ + sz_dir = 0; /* No static directory */ + if (n_clst <= MAX_FAT16 || n_clst > MAX_FAT32) LEAVE_MKFS(FR_MKFS_ABORTED); + b_fat = b_vol + sz_rsv; /* FAT base */ + b_data = b_fat + sz_fat * n_fats + sz_dir; /* Data base */ + + /* Align data base to erase block boundary (for flash memory media) */ + n = ((b_data + sz_blk - 1) & ~(sz_blk - 1)) - b_data; /* Next nearest erase block from current data base */ + b_fat += n; /* FAT32: Move FAT base */ + /* Make sure FAT base is aligned to reserved size for performance (PRF2SAFE min cluster alignment) */ + if ((b_fat & (sz_rsv - 1) || (n_fats == 2 && sz_fat & (sz_rsv - 1)))) { + n_clst++; /* FAT size must always be bigger than real free size */ + continue; + } + sz_rsv += n; + break; + } } else { /* FAT volume */ if (pau == 0) { /* au auto-selection */ n = sz_vol / 0x1000; /* Volume size in unit of 4KS */ @@ -6137,17 +6154,13 @@ FRESULT f_mkfs ( sz_fat = (n + ss - 1) / ss; /* FAT size [sector] */ sz_rsv = 1; /* Number of reserved sectors */ sz_dir = (DWORD)n_rootdir * SZDIRE / ss; /* Rootdir size [sector] */ - } - b_fat = b_vol + sz_rsv; /* FAT base */ - b_data = b_fat + sz_fat * n_fats + sz_dir; /* Data base */ + b_fat = b_vol + sz_rsv; /* FAT base */ + b_data = b_fat + sz_fat * n_fats + sz_dir; /* Data base */ - /* Align data base to erase block boundary (for flash memory media) */ - n = ((b_data + sz_blk - 1) & ~(sz_blk - 1)) - b_data; /* Next nearest erase block from current data base */ - if (fmt == FS_FAT32) { /* FAT32: Move FAT base */ - sz_rsv += n; b_fat += n; - } else { /* FAT: Expand FAT size */ + /* Align data base to erase block boundary (for flash memory media) */ + n = ((b_data + sz_blk - 1) & ~(sz_blk - 1)) - b_data; /* Next nearest erase block from current data base */ if (n % n_fats) { /* Adjust fractional error if needed */ - n--; sz_rsv++; b_fat++; + n--; sz_rsv++; b_fat++; /* FAT: Expand FAT size */ } sz_fat += n / n_fats; } @@ -6190,7 +6203,7 @@ FRESULT f_mkfs ( /* Create FAT VBR */ mem_set(buf, 0, ss); /* Boot jump code (x86), OEM name */ - if (!(opt & FM_PRF2)) mem_cpy(buf + BS_JmpBoot, "\xEB\xFE\x90" "NYX1.0.0", 11); + if (!(opt & FM_PRF2)) mem_cpy(buf + BS_JmpBoot, "\xEB\xFE\x90" "NYX1.8.0", 11); else mem_cpy(buf + BS_JmpBoot, "\xEB\xE9\x90\x00\x00\x00\x00\x00\x00\x00\x00", 11); st_word(buf + BPB_BytsPerSec, ss); /* Sector size [byte] */ buf[BPB_SecPerClus] = (BYTE)pau; /* Cluster size [sector] */ @@ -6247,21 +6260,10 @@ FRESULT f_mkfs ( disk_write(pdrv, buf, b_vol + 1, 1); /* Write original FSINFO (VBR + 1) */ } - /* Create PRF2SAFE info */ + /* Clear PRF2SAFE info so PrFILE2 can recreate it and upgrade it if old */ if (fmt == FS_FAT32 && opt & FM_PRF2) { mem_set(buf, 0, ss); - st_dword(buf + 0, 0x32465250); /* Magic PRF2 */ - st_dword(buf + 4, 0x45464153); /* Magic SAFE */ - buf[16] = 0x64; /* Record type */ - st_dword(buf + 32, 0x03); /* Unknown. SYSTEM: 0x3F00. USER: 0x03. Volatile. */ - if (sz_vol < 0x1000000) { - st_dword(buf + 36, 21 + 1); /* 22 Entries. */ - st_dword(buf + 508, 0x90BB2F39); /* Sector CRC32 */ - } else { - st_dword(buf + 36, 21 + 2); /* 23 Entries. */ - st_dword(buf + 508, 0x5EA8AFC8); /* Sector CRC32 */ - } - disk_write(pdrv, buf, b_vol + 3, 1); /* Write PRF2SAFE info (VBR + 3) */ + disk_write(pdrv, buf, b_vol + 3, 1); /* Write PRF2SAFE info (VBR + 3) */ } /* Initialize FAT area */