74 const uint64_t denom = ((uint64_t)entry_cap * spc) + (uint32_t)
k_fmt_num_fats;
75 const uint64_t fatsz = (avail + denom - 1U) / denom;
76 *out_fatsz = (uint32_t)fatsz;
78 if (avail <= fat_total) {
81 return (avail - fat_total) / spc;
188 const uint64_t total_512 = total_sectors
202 if (clus_shift <= bps_shift) {
205 return 1U << (clus_shift - bps_shift);
218 bool auto_mode = (spc_hint == 0U);
219 uint32_t spc = spc_hint;
227 for (uint32_t guard = 0U; guard <= (uint32_t)
k_fmt_spc_max; guard++) {
264 static const uint8_t k_oem[
k_filename_base_len] = {
'M',
'S',
'D',
'O',
'S',
'5',
'.',
'0'};
279 static const char k_no_name[] =
"NO NAME";
280 const char* eff = ((label !=
nullptr) && (label[0] !=
'\0')) ? label : k_no_name;
281 bool past_end =
false;
283 if (!past_end && (eff[i] ==
'\0')) {
286 dst[i] = past_end ? (uint8_t)
' ' : (uint8_t)eff[i];
351 static const uint8_t k_t12[
k_filename_base_len] = {
'F',
'A',
'T',
'1',
'2',
' ',
' ',
' '};
352 static const uint8_t k_t16[
k_filename_base_len] = {
'F',
'A',
'T',
'1',
'6',
' ',
' ',
' '};
398 static const uint8_t k_t32[
k_filename_base_len] = {
'F',
'A',
'T',
'3',
'2',
' ',
' ',
' '};
457 while (done < count) {
458 uint32_t chunk = chunk_secs;
459 if ((uint64_t)chunk > (count - done)) {
460 chunk = (uint32_t)(count - done);
565 const uint8_t* boot_sec)
575 const uint32_t free_count =
597 return ((uint32_t)spc & ((uint32_t)spc - 1U)) == 0U;
617 const uint64_t root_span =
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
@ k_ra8_err_invalid_size
Invalid size parameter (too large, too small, or misaligned).
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Minimal FAT12/FAT16/FAT32 filesystem adapter (read + write).
void priv_byte_fill(uint8_t *dst, uint8_t value, uint32_t n)
Fill n bytes of dst with value.
void priv_wr32(uint8_t *p, uint32_t v)
Encode a little-endian uint32_t into a byte buffer.
void priv_byte_copy(uint8_t *dst, const uint8_t *src, uint32_t n)
Length-checked byte copy used in place of memcpy().
void priv_wr16(uint8_t *p, uint16_t v)
Encode a little-endian uint16_t into a byte buffer.
uint8_t * priv_sec_walk(void)
The WALK-role sector buffer (directory scans and entry RMW).
static void internal_fmt_build_bpb_f32(uint8_t *sec, const ra8_fs_fmt_geom_t *g, const char *label)
Build the FAT32 boot sector into the scratch buffer.
static ra8_err_t internal_fmt_write_fsinfo(const ra8_fs_backend_t *backend, const ra8_fs_fmt_geom_t *g, const uint8_t *boot_sec)
Write the FAT32 FSInfo sector (and the backup boot sector copy).
static ra8_err_t internal_fmt_seed_fats(const ra8_fs_backend_t *backend, const ra8_fs_fmt_geom_t *g)
Seed the reserved FAT entries (and FAT32 root-cluster EOC) per copy.
ra8_err_t priv_fmt_emit_volume(const ra8_fs_backend_t *backend, const ra8_fs_fmt_geom_t *g, const char *label)
Lay down the boot sector, FAT seeds, FSInfo, and the empty root.
ra8_err_t priv_fmt_choose_geometry(ra8_fs_fmt_geom_t *g, uint32_t spc_hint)
Pick the cluster size that lands the FAT cluster count in the right band.
static const uint8_t s_fmt_zero_chunk[k_fmt_zero_chunk_bytes]
All-zero source for the chunked FAT/root wipe (read-only, in flash).
static uint32_t internal_fmt_fat32_default_spc(uint64_t total_sectors, uint32_t bps)
Default FAT32 cluster size for a device, per the Microsoft table.
static void internal_fmt_build_bpb_f16(uint8_t *sec, const ra8_fs_fmt_geom_t *g, const char *label)
Build the FAT12/FAT16 boot sector into the scratch buffer.
static uint32_t internal_fmt_log2(uint32_t v)
log2 of a power-of-two value.
static bool internal_fmt_count_in_band(ra8_fs_type_t type, uint64_t count)
Test whether a cluster count is valid for a given FAT type.
static ra8_err_t internal_fmt_zero_run(const ra8_fs_backend_t *backend, uint64_t lba, uint64_t count, uint32_t bps)
Zero a run of sectors on the backend in multi-sector chunks.
ra8_err_t priv_fmt_clear_region(const ra8_fs_backend_t *backend, uint64_t lba, uint64_t count, uint32_t bps)
Clear count blocks at lba to zero – bulk-erase if the backend can.
static void internal_fmt_write_totals(uint8_t *sec, const ra8_fs_fmt_geom_t *g)
Write a totals/FAT-size pair into the BPB, choosing 16- vs 32-bit.
bool priv_fmt_spc_valid(uint8_t spc)
Validate a caller-pinned sectors-per-cluster value.
void priv_fmt_label_field(uint8_t *dst, const char *label)
Pad an ASCII volume label into an 11-byte BS_VolLab / label field.
static uint64_t internal_fmt_clusters_for(const ra8_fs_fmt_geom_t *g, uint32_t spc, uint32_t *out_fatsz)
Compute the cluster count for a trial cluster size.
uint32_t priv_fmt_reserved_for(ra8_fs_type_t type)
Map a requested FAT type to its reserved-sector count.
static void internal_fmt_boot_prologue(uint8_t *sec)
Write the shared boot prologue (jump + OEM) into the scratch sector.
Cross-TU shared declarations for the FAT/exFAT ra8_fs adapter.
uint8_t g_fs_scratch[k_ra8_fs_sector_max]
Single max-sector scratch buffer reused across all I/O.
@ k_fmt_off_f16_volid
FAT12/16 BS_VolID (4 bytes).
@ k_fmt_off_jmp1
Jump-boot byte 1 (offset).
@ k_fmt_off_media
BPB_Media descriptor.
@ k_fmt_fsi_off_free
FSInfo FSI_Free_Count offset.
@ k_fmt_off_f16_drvnum
FAT12/16 BS_DrvNum.
@ k_fmt_off_f32_bkboot
FAT32 BPB_BkBootSec (backup boot).
@ k_fmt_fsi_off_struct
FSInfo FSI_StrucSig offset.
@ k_fmt_off_f32_fsinfo
FAT32 BPB_FSInfo sector number.
@ k_fmt_off_f16_bootsig
FAT12/16 BS_BootSig (0x29).
@ k_fmt_off_oem
OEM name field (8 bytes).
@ k_fmt_fsi_off_nxtfree
FSInfo FSI_Nxt_Free offset.
@ k_fmt_off_f32_fstype
FAT32 BS_FilSysType (8 bytes).
@ k_fmt_off_f32_label
FAT32 BS_VolLab (11 bytes).
@ k_fmt_off_sec_per_trk
BPB_SecPerTrk.
@ k_fmt_off_f16_fstype
FAT12/16 BS_FilSysType (8 bytes).
@ k_fmt_off_num_heads
BPB_NumHeads.
@ k_fmt_off_jmp2
Jump-boot byte 2 (0x90 NOP).
@ k_fmt_off_f32_bootsig
FAT32 BS_BootSig (0x29).
@ k_fmt_off_f32_drvnum
FAT32 BS_DrvNum.
@ k_fmt_off_f32_volid
FAT32 BS_VolID (4 bytes).
@ k_fmt_off_f16_label
FAT12/16 BS_VolLab (11 bytes).
@ k_fmt_fsi_off_lead
FSInfo FSI_LeadSig offset.
@ k_fmt_fsi_off_trail
FSInfo FSI_TrailSig offset.
@ k_fmt_off_jmp0
Jump-boot byte 0 (0xEB).
@ k_bpb_sig_hi
Bpb sig hi.
@ k_bpb_sig_lo
Bpb sig lo.
@ k_fmt_f32_thr_16g
<= 16 GB -> 8 KB clusters.
@ k_fmt_fat16_entry_bytes
Bytes per FAT16 (and FAT12-sizing) entry.
@ k_fmt_f32_clus_512b
log2(512): <= 260 MB cards.
@ k_fmt_f32_thr_260m
<= 260 MB -> 512 B clusters.
@ k_fmt_media_fixed
Media descriptor: non-removable.
@ k_fmt_label_len
Volume-label field width (bytes).
@ k_fmt_num_fats
Two FAT copies, like every mkfs.
@ k_fmt_fsi_lead_sig
FSInfo lead signature "RRaA".
@ k_fmt_resv_f16
FAT12/16 reserved (boot) sectors.
@ k_fmt_sec_per_trk
Conventional CHS sectors/track.
@ k_fmt_f32_clus_8k
log2(8 KB): <= 16 GB cards.
@ k_fmt_num_heads
Conventional CHS heads.
@ k_fmt_fat32_clus_cap
Max FAT32 cluster count we accept.
@ k_fmt_f32_clus_16k
log2(16 KB): <= 32 GB cards.
@ k_fmt_spc_max
Largest sectors-per-cluster we set.
@ k_fmt_fsi_trail_sig
FSInfo trailing signature.
@ k_fmt_jmp_byte1
Jump displacement (to +0x5A).
@ k_fmt_drvnum_hd
BS_DrvNum: first fixed disk.
@ k_fmt_bkboot_sector
FAT32 backup boot sector LBA.
@ k_fmt_fat32_entry_bytes
Bytes per FAT32 FAT entry.
@ k_fmt_volid_base
Arbitrary volume-serial base.
@ k_fmt_root_clus_f32
FAT32 root directory cluster.
@ k_fmt_f32_clus_32k
log2(32 KB): > 32 GB cards.
@ k_fmt_fat32_nxt_free
First allocatable FAT32 cluster.
@ k_fmt_f32_thr_32g
<= 32 GB -> 16 KB clusters.
@ k_fmt_fsi_struct_sig
FSInfo struct signature "rrAa".
@ k_fmt_f32_thr_8g
<= 8 GB -> 4 KB clusters.
@ k_fmt_fsinfo_sector
FAT32 FSInfo sector LBA.
@ k_fmt_resv_f32
FAT32 reserved sectors.
@ k_fmt_jmp_byte2
NOP padding.
@ k_fmt_ext_bootsig
Extended boot signature present.
@ k_fmt_zero_chunk_bytes
Zero-fill bounce buffer size.
@ k_fmt_f32_clus_4k
log2(4 KB): <= 8 GB cards.
@ k_fmt_jmp_byte0
Short jump opcode.
@ k_fmt_fsi_unknown
FSInfo free-count "unknown".
@ k_cluster_eoc_write_fat32
Cluster eoc write fat32.
@ k_cluster_eoc_min_fat32
MS FAT spec sec 4.2 EOC threshold.
@ k_cluster_eoc_min_fat16
MS FAT spec sec 4.1 EOC threshold.
@ k_cluster_eoc_write_fat16
Cluster eoc write fat16.
@ k_cluster_count_fat12_max
MS FAT spec sec 3.5 boundary.
@ k_cluster_count_fat16_max
MS FAT spec sec 3.5 boundary.
@ k_filename_base_len
Filename base length.
@ k_bpb_off_tot_sec_32
MS FAT spec sec 3.1 "BPB_TotSec32".
@ k_bpb_off_root_ent_cnt
MS FAT spec sec 3.1 "BPB_RootEntCnt".
@ k_bpb_off_tot_sec_16
MS FAT spec sec 3.1 "BPB_TotSec16".
@ k_bpb_off_bytes_per_sec
MS FAT spec sec 3.1 "BPB_BytsPerSec".
@ k_bpb_off_signature_lo
Boot sig byte 1 (0x55).
@ k_bpb_off_num_fats
MS FAT spec sec 3.1 "BPB_NumFATs".
@ k_bpb_off_root_clus
MS FAT spec sec 3.5 "BPB_RootClus".
@ k_bpb_off_rsvd_sec_cnt
MS FAT spec sec 3.1 "BPB_RsvdSecCnt".
@ k_bpb_off_fat_sz_32
MS FAT spec sec 3.5 "BPB_FATSz32".
@ k_bpb_off_sec_per_clus
MS FAT spec sec 3.1 "BPB_SecPerClus".
@ k_bpb_off_fat_sz_16
MS FAT spec sec 3.1 "BPB_FATSz16".
@ k_bpb_off_signature_hi
Boot sig byte 2 (0xAA).
ra8_fs_type_t
FAT variant detected from the BPB cluster-count rule.
@ k_ra8_fs_type_fat12
count_of_clusters < 4085.
@ k_ra8_fs_type_fat32
count_of_clusters >= 65525.
@ k_ra8_fs_type_fat16
4085 <= count_of_clusters < 65525.
@ k_ra8_fs_sector_min
Smallest supported sector size.
Block-device interface that ra8_fs runs on top of.
ra8_err_t(* write_block)(void *ctx, uint64_t lba, uint32_t count, const uint8_t *buf)
Write count consecutive blocks starting at lba.
ra8_err_t(* erase_blocks)(void *ctx, uint64_t lba, uint64_t count)
OPTIONAL: bulk-erase count blocks at lba to all-zero bytes.
void * ctx
Caller-owned context passed back into the function pointers.
Computed on-disk geometry for one ra8_fs_format() run.
uint32_t sectors_per_cluster
Chosen cluster size (sectors).
uint32_t bytes_per_sector
Device sector size in bytes.
uint64_t total_sectors
Whole-device sector count.
uint32_t reserved_sectors
Boot + (FAT32) FSInfo/backup region.
uint32_t count_of_clusters
Resulting data-region cluster count.
ra8_fs_type_t type
Resolved FAT variant.
uint32_t root_sectors
FAT12/16 fixed-root sector span.
uint32_t root_entries
FAT12/16 root entries (0 on FAT32).
uint32_t fat_size_sectors
Sectors per FAT copy.