|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
exFAT formatter (mkfs) for the ra8_fs adapter. More...
#include <stddef.h>#include <stdint.h>#include "ra8_attributes.h"#include "ra8_fs.h"#include "ra8_fs_fat_internal.h"Go to the source code of this file.
Data Structures | |
| struct | exfat_geom_t |
| Resolved exFAT volume geometry produced by priv_exfat_geometry. More... | |
Functions | |
| uint32_t | priv_exfat_csum32 (uint32_t cs, const uint8_t *buf, uint32_t len) |
| exFAT 32-bit rotate-right-add checksum (boot region + up-case table). | |
| static uint8_t | internal_exfat_spc_shift (uint64_t total_sectors, uint8_t bps_shift) |
| Return the default SectorsPerClusterShift for an exFAT volume. | |
| static ra8_err_t | internal_exfat_geometry (uint64_t total_sectors, exfat_geom_t *g) |
Resolve the exFAT region geometry for a device of total_sectors. | |
| static void | internal_exfat_build_vbr (uint8_t *sec, const exfat_geom_t *g) |
Build the 512-byte exFAT Main Boot Sector (VBR) into sec. | |
| static ra8_err_t | internal_exfat_wr_dual (const ra8_fs_backend_t *b, uint64_t part_lba, uint32_t lba, const uint8_t *buf) |
| Write a sector to both its primary and backup locations in the exFAT boot region. | |
| static void | internal_exfat_put32 (uint8_t *buf, uint32_t idx, uint32_t val) |
Write a 32-bit little-endian word at slot idx in a sector buffer. | |
| static ra8_err_t | internal_exfat_write_boot_tail (const ra8_fs_backend_t *backend, const exfat_geom_t *g, uint32_t cs) |
| Write exFAT boot sectors 1-11 (ext-boot, OEM, reserved, checksum) to main and backup. | |
| static ra8_err_t | internal_exfat_write_boot (const ra8_fs_backend_t *backend, const exfat_geom_t *g) |
| Write the complete exFAT main and backup boot regions (sectors 0-23). | |
| static ra8_err_t | internal_exfat_write_fat (const ra8_fs_backend_t *backend, const exfat_geom_t *g) |
| Zero the exFAT FAT region, then seed the media, EOC, and chain entries. | |
| static ra8_err_t | internal_exfat_write_bitmap (const ra8_fs_backend_t *backend, const exfat_geom_t *g) |
| Zero the allocation bitmap region, then mark the pre-allocated clusters. | |
| static uint32_t | internal_exfat_label_utf16 (uint8_t *dst, const char *label) |
| Pack an ASCII volume label into a UTF-16LE buffer for the exFAT VolumeLabel entry. | |
| static ra8_err_t | internal_exfat_write_root (const ra8_fs_backend_t *backend, const exfat_geom_t *g, uint32_t upcase_csum, const char *label) |
| Write the exFAT root directory entry set (bitmap, up-case, label). | |
| static void | internal_exfat_lba_to_chs (uint32_t lba, uint8_t *out3) |
| Encode an LBA as legacy CHS bytes using the 255-head / 63-sector geometry. | |
| static ra8_err_t | internal_exfat_write_mbr (const ra8_fs_backend_t *backend, uint32_t bps, uint32_t part_lba, uint32_t part_sectors) |
Write the MBR (LBA 0) with one type-0x07 exFAT partition at part_lba. | |
| static ra8_err_t | internal_exfat_fmt_place (uint64_t total_sectors, uint32_t bps, uint8_t *out_bps_shift, uint32_t *out_part_lba, uint32_t *out_part_sectors) |
| Size and place the exFAT partition on the device, or refuse. | |
| ra8_err_t | priv_exfat_format (const ra8_fs_backend_t *backend, uint64_t total_sectors, uint32_t bps, const char *label) |
| Format the backend as a PC-standard partitioned exFAT volume (#102). | |
exFAT formatter (mkfs) for the ra8_fs adapter.
VBR + checksum construction, FAT/bitmap/up-case seeding, and the root directory writer for a freshly-formatted exFAT volume.
Definition in file ra8_fs_fat_exfat_fmt.c.
|
static |
Build the 512-byte exFAT Main Boot Sector (VBR) into sec.
Zeroes sec, then writes all mandatory exFAT VBR fields: the 3-byte JMP instruction, the "EXFAT " file-system name, PartitionOffset, VolumeLength, FatOffset, FatLength, ClusterHeapOffset, ClusterCount, RootDirectory first cluster, VolumeSerialNumber (XOR of constant and total_sectors), FileSystemRevision (1.00), BytesPerSectorShift, SectorsPerClusterShift, NumberOfFats, PercentInUse, and the 0xAA55 boot signature. All values are written as little-endian fields per the Microsoft exFAT spec.
| [out] | sec | Caller-provided sector buffer to receive the VBR. |
| [in] | g | Resolved exFAT geometry from priv_exfat_geometry(). |
sec is non-NULL and points to at least g->bps writable bytes. g is non-NULL and was filled by a successful priv_exfat_geometry() call. sec holds a spec-compliant exFAT Main Boot Sector. sec have been written (zeroed, then fields set).Definition at line 209 of file ra8_fs_fat_exfat_fmt.c.
References exfat_geom_t::bps, exfat_geom_t::bps_shift, exfat_geom_t::cluster_count, exfat_geom_t::fat_length, exfat_geom_t::fat_offset, exfat_geom_t::heap_offset, k_exfat_fmt_boot_sig, k_exfat_fmt_drive, k_exfat_fmt_fs_rev, k_exfat_fmt_jump0, k_exfat_fmt_jump1, k_exfat_fmt_jump2, k_exfat_fmt_num_fats, k_exfat_fmt_percent, k_exfat_fmt_serial, k_exfat_foff_boot_sig, k_exfat_foff_drive, k_exfat_foff_fs_rev, k_exfat_foff_jump, k_exfat_foff_part_off, k_exfat_foff_percent, k_exfat_foff_serial, k_exfat_foff_vol_len, k_exfat_fsname_len, k_exfat_off_bps_shift, k_exfat_off_clus_count, k_exfat_off_fat_lba, k_exfat_off_fat_len, k_exfat_off_fsname, k_exfat_off_heap_lba, k_exfat_off_num_fats, k_exfat_off_root_clus, k_exfat_off_spc_shift, exfat_geom_t::part_lba, priv_wr16(), priv_wr32(), priv_wr64(), exfat_geom_t::root_cluster, exfat_geom_t::spc_shift, and exfat_geom_t::total_sectors.
Referenced by internal_exfat_write_boot().
|
static |
Size and place the exFAT partition on the device, or refuse.
The preamble of priv_exfat_format, split out so the emit sequence stays inside the function-size gate: derives log2(bps), aligns the partition at 1 MiB, and applies the two size refusals – a device too small for the minimum volume plus the alignment gap, and one whose partition would not fit the MBR's 32-bit fields (past-2-TiB media arrive GPT-partitioned; mounting them is the supported half, #683).
| [in] | total_sectors | Whole-device sector count. |
| [in] | bps | Device sector size (a power of two, 512..4096). |
| [out] | out_bps_shift | Receives log2(bps). |
| [out] | out_part_lba | Receives the partition's first LBA. |
| [out] | out_part_sectors | Receives the partition's sector count. |
| k_ra8_ok | The partition is sized and placed. |
| k_ra8_err_not_supported | Device too small, or past the MBR's fields. |
bps was validated by the format entry point. Definition at line 767 of file ra8_fs_fat_exfat_fmt.c.
References k_exfat_fmt_min_sectors, k_exfat_fmt_part_align, k_ra8_err_not_supported, k_ra8_fs_sector_min, and k_ra8_ok.
Referenced by priv_exfat_format().
|
static |
Resolve the exFAT region geometry for a device of total_sectors.
Picks the cluster size, fixed-points the FAT length against the cluster count (the FAT shrinks the heap which shrinks the count which shrinks the FAT), then lays the allocation bitmap, up-case table, and root directory as the first contiguous clusters of the heap.
| [in] | total_sectors | Partition sector count (device sectors). |
| [out] | g | Receives the resolved geometry (bps / bps_shift already populated by the caller). |
| k_ra8_ok | Geometry resolved. |
| k_ra8_err_invalid_size | Device too small to hold a volume. |
g is non-NULL with bps and bps_shift set. total_sectors is the partition capacity in device sectors (non-zero). g is consistent with the exFAT spec. g may be partially written and must be discarded.Definition at line 141 of file ra8_fs_fat_exfat_fmt.c.
References exfat_geom_t::bitmap_bytes, exfat_geom_t::bitmap_clusters, exfat_geom_t::bps, exfat_geom_t::bps_shift, exfat_geom_t::cluster_count, exfat_geom_t::fat_length, exfat_geom_t::fat_offset, exfat_geom_t::heap_offset, internal_exfat_spc_shift(), k_exfat_fmt_boot_secs, k_exfat_fmt_byte_bits, k_exfat_fmt_first_clus, k_exfat_fmt_geom_iters, k_exfat_fmt_upc_std_bytes, k_ra8_err_invalid_size, k_ra8_ok, exfat_geom_t::root_cluster, exfat_geom_t::spc, exfat_geom_t::spc_shift, exfat_geom_t::total_sectors, exfat_geom_t::upcase_cluster, exfat_geom_t::upcase_clusters, and exfat_geom_t::used_clusters.
Referenced by priv_exfat_format().
|
static |
Pack an ASCII volume label into a UTF-16LE buffer for the exFAT VolumeLabel entry.
Converts up to k_exfat_fmt_label_max ASCII characters of label into UTF-16LE by zero-extending each byte: the low byte of each UTF-16 code-unit receives the ASCII character and the high byte is set to zero. Stops at the NUL terminator or the 11-character limit, whichever comes first. A NULL label writes nothing and returns 0.
| [out] | dst | Destination buffer for the UTF-16LE character array (at least k_exfat_fmt_label_max * 2 bytes). |
| [in] | label | NUL-terminated ASCII label, or NULL for no label. |
dst. | 0 | label is NULL or is an empty string. |
| 11 | label has 11 or more non-NUL characters. |
dst is non-NULL and has at least k_exfat_fmt_label_max * 2 writable bytes. label, if non-NULL, is NUL-terminated and contains only ASCII characters. dst[0 .. (return*2)-1] holds the UTF-16LE label characters. dst is modified.Definition at line 556 of file ra8_fs_fat_exfat_fmt.c.
References k_exfat_fmt_label_max.
Referenced by internal_exfat_write_root().
|
static |
Encode an LBA as legacy CHS bytes using the 255-head / 63-sector geometry.
Fills the three-byte CHS field an MBR partition entry carries. Above k_mbr_fmt_chs_max (the first LBA the 1024-cylinder CHS space cannot address) the universal 0xFE/0xFF/0xFF "beyond CHS, use LBA" sentinel is written, matching what fdisk/sfdisk emit for large disks; below it a real cylinder/head/sector triple is packed (sector in bits[5:0], cylinder bits[9:8] in bits[7:6] of the second byte, cylinder low byte in the third).
| [in] | lba | Logical block address to encode. |
| [out] | out3 | Three-byte CHS field to fill. |
out3 points to at least 3 writable bytes. lba is the sector this CHS field should describe. out3 holds the packed CHS (or the overflow sentinel). out3[0..2] are modified.out3; part of single-threaded format.Definition at line 663 of file ra8_fs_fat_exfat_fmt.c.
References k_byte_mask, k_mbr_fmt_chs_cyl_hi_mask, k_mbr_fmt_chs_cyl_hi_shift, k_mbr_fmt_chs_heads, k_mbr_fmt_chs_max, k_mbr_fmt_chs_ovf_h, k_mbr_fmt_chs_ovf_l, k_mbr_fmt_chs_ovf_m, k_mbr_fmt_chs_sec_mask, and k_mbr_fmt_chs_spt.
Referenced by internal_exfat_write_mbr().
|
static |
Write a 32-bit little-endian word at slot idx in a sector buffer.
Computes the byte offset as idx * 4 and calls priv_wr32() to store val in little-endian order. Used to populate FAT entries and checksum-sector words without repeating the stride arithmetic.
| [in,out] | buf | Sector buffer to write into. |
| [in] | idx | Zero-based 32-bit word index within buf. |
| [in] | val | 32-bit value to store. |
buf is non-NULL and has at least (idx+1)*4 writable bytes. idx does not overflow the sector (caller verifies the range). val in little-endian order. buf.Definition at line 300 of file ra8_fs_fat_exfat_fmt.c.
References priv_wr32().
Referenced by internal_exfat_write_boot_tail(), and internal_exfat_write_fat().
|
static |
Return the default SectorsPerClusterShift for an exFAT volume.
Implements the size-tiered lookup from Microsoft exFAT spec section 12.1, expressed in cluster BYTES so every sector size lands on the same cluster size a 512-byte device of equal capacity gets: up to 256 MB uses 4 kB clusters, up to 32 GB uses 32 kB, up to 256 GB uses 128 kB, and larger devices use 256 kB clusters. The thresholds are counts of 512-byte-equivalent sectors, so the device's count is scaled by bps / 512 first; the returned shift is log2(cluster bytes) - bps_shift, the sectors-per-cluster shift the VBR records.
| [in] | total_sectors | Whole-device sector count (device sectors). |
| [in] | bps_shift | log2 of the device sector size (9..12). |
| 0 | Cluster equals one sector (4 kB clusters on a 4Kn device). |
| 9 | 256 kB clusters on a 512-byte device. |
total_sectors is the actual backend capacity in device sectors. total_sectors is non-zero; bps_shift is 9..12. bps_shift is one of the four cluster tiers. Definition at line 88 of file ra8_fs_fat_exfat_fmt.c.
References k_exfat_bps_shift_min, k_exfat_fmt_clus_128k, k_exfat_fmt_clus_256k, k_exfat_fmt_clus_32k, k_exfat_fmt_clus_4k, k_exfat_fmt_thr_256g, k_exfat_fmt_thr_256m, and k_exfat_fmt_thr_32g.
Referenced by internal_exfat_geometry().
|
static |
Write a sector to both its primary and backup locations in the exFAT boot region.
Calls b->write_block twice: once for the primary copy at lba, and once for the backup copy at lba + k_exfat_fmt_backup_lba (12 sectors later, per the Microsoft exFAT spec). The first write failure aborts; the backup write is skipped to avoid partial state.
| [in] | b | Block-device backend with a non-NULL write_block function. |
| [in] | part_lba | Partition start LBA added to every write (0 = whole-disk). |
| [in] | lba | Partition-relative primary LBA (0 <= lba < k_exfat_fmt_boot_secs). |
| [in] | buf | One whole-sector image to write. |
| k_ra8_ok | Both primary and backup copies written successfully. |
| k_ra8_err_* | The primary or backup write_block call failed. |
b and b->write_block are non-NULL. buf is non-NULL and holds one whole device sector. lba and lba+k_exfat_fmt_backup_lba are identical. Definition at line 265 of file ra8_fs_fat_exfat_fmt.c.
References k_exfat_fmt_backup_lba, and k_ra8_ok.
Referenced by internal_exfat_write_boot(), and internal_exfat_write_boot_tail().
|
static |
Zero the allocation bitmap region, then mark the pre-allocated clusters.
Clears all bitmap sectors via priv_fmt_clear_region(), then builds the first bitmap sector in g_fs_scratch. The g->used_clusters count (bitmap + up-case + root) is marked allocated: full bytes are set to 0xFF and the trailing partial byte gets a mask of the remaining bits. The populated sector is then written to the bitmap's heap LBA.
| [in] | backend | Block-device backend with non-NULL write_block. |
| [in] | g | Resolved exFAT geometry from priv_exfat_geometry(). |
| k_ra8_ok | Bitmap region zeroed and pre-allocated clusters marked. |
| k_ra8_err_* | Backend clear or write failure. |
backend and backend->write_block are non-NULL. g was filled by a successful priv_exfat_geometry() call. Definition at line 507 of file ra8_fs_fat_exfat_fmt.c.
References exfat_geom_t::bitmap_clusters, exfat_geom_t::bps, ra8_fs_backend_t::ctx, g_fs_scratch, exfat_geom_t::heap_offset, k_exfat_fmt_byte_bits, k_exfat_fmt_byte_full, k_ra8_ok, exfat_geom_t::part_lba, priv_fmt_clear_region(), exfat_geom_t::spc, exfat_geom_t::used_clusters, and ra8_fs_backend_t::write_block.
Referenced by priv_exfat_format().
|
static |
Write the complete exFAT main and backup boot regions (sectors 0-23).
Builds the VBR in g_fs_scratch via priv_exfat_build_vbr(), then accumulates the boot checksum over sector 0, skipping the three bytes that the exFAT spec excludes from the checksum: VolumeFlags bytes (offsets 106-107) and PercentInUse (offset 112). The three ranges [0, 106), [108, 112), and [113, 512) are folded via priv_exfat_csum32(). Sector 0 is then written to both main (LBA 0) and backup (LBA 12) by priv_exfat_wr_dual(). The remaining boot sectors 1-11 and their backups are written by priv_exfat_write_boot_tail() using the running checksum.
| [in] | backend | Block-device backend with a non-NULL write_block hook. |
| [in] | g | Resolved exFAT geometry from priv_exfat_geometry(). |
| k_ra8_ok | Both main and backup boot regions (sectors 0-23) written. |
| k_ra8_err_* | Backend write failure; format is aborted. |
backend and backend->write_block are non-NULL. g was filled by a successful priv_exfat_geometry() call. Definition at line 407 of file ra8_fs_fat_exfat_fmt.c.
References exfat_geom_t::bps, g_fs_scratch, internal_exfat_build_vbr(), internal_exfat_wr_dual(), internal_exfat_write_boot_tail(), k_exfat_fmt_csum_skip0, k_exfat_fmt_csum_skip2, k_exfat_off_bps_shift, k_ra8_ok, exfat_geom_t::part_lba, and priv_exfat_csum32().
Referenced by priv_exfat_format().
|
static |
Write exFAT boot sectors 1-11 (ext-boot, OEM, reserved, checksum) to main and backup.
Takes the running boot checksum cs (which already covers sector 0) and completes the boot region. Sectors 1-8 each receive an extended boot sector with only the ExtendedBootSignature (0xAA550000) set; sector 9 (OEM) and sector 10 (reserved) are all-zero. Each sector is folded into cs via priv_exfat_csum32() before being written via priv_exfat_wr_dual() to both the main and backup regions. Sector 11 (checksum) is then filled with k_exfat_fmt_csum_copies copies of the final checksum word and written to both regions. The global g_fs_scratch buffer is used as a scratch pad.
| [in] | backend | Block-device backend with a non-NULL write_block hook. |
| [in] | g | Resolved geometry (partition base + sector size). |
| [in] | cs | Running boot checksum accumulated over sector 0. |
| k_ra8_ok | All sectors written to both main and backup regions. |
| k_ra8_err_* | Backend write_block failure; format is aborted. |
backend and backend->write_block are non-NULL. cs reflects the checksum folded over sector 0 of the VBR. Definition at line 337 of file ra8_fs_fat_exfat_fmt.c.
References exfat_geom_t::bps, g_fs_scratch, internal_exfat_put32(), internal_exfat_wr_dual(), k_exfat_fmt_csum_lba, k_exfat_fmt_ext_count, k_exfat_fmt_ext_first, k_exfat_fmt_ext_sig, k_exfat_fmt_oem_lba, k_exfat_fmt_resv_lba, k_exfat_foff_ext_sig, k_ra8_fs_sector_min, k_ra8_ok, exfat_geom_t::part_lba, priv_exfat_csum32(), and priv_wr32().
Referenced by internal_exfat_write_boot().
|
static |
Zero the exFAT FAT region, then seed the media, EOC, and chain entries.
Clears all FAT sectors via priv_fmt_clear_region(), then builds the first FAT sector in g_fs_scratch. FAT[0] is set to the media byte (k_exfat_fmt_fat_media) and FAT[1] to the end-of-chain sentinel (k_exfat_fmt_fat_eoc). The bitmap and up-case cluster chains are each written as a linked run terminating with EOC (the up-case table may span more than one cluster), and the root directory cluster receives a single EOC entry. Finally, the populated first sector is written to the FAT start LBA (partition-adjusted).
| [in] | backend | Block-device backend with non-NULL write_block. |
| [in] | g | Resolved exFAT geometry from priv_exfat_geometry(). |
| k_ra8_ok | FAT region zeroed and initial entries written. |
| k_ra8_err_* | Backend clear or write failure. |
backend and backend->write_block are non-NULL. g was filled by a successful priv_exfat_geometry() call. Definition at line 455 of file ra8_fs_fat_exfat_fmt.c.
References exfat_geom_t::bitmap_clusters, exfat_geom_t::bps, ra8_fs_backend_t::ctx, exfat_geom_t::fat_length, exfat_geom_t::fat_offset, g_fs_scratch, internal_exfat_put32(), k_exfat_fmt_fat_eoc, k_exfat_fmt_fat_media, k_exfat_fmt_first_clus, k_ra8_ok, exfat_geom_t::part_lba, priv_fmt_clear_region(), exfat_geom_t::root_cluster, exfat_geom_t::upcase_cluster, exfat_geom_t::upcase_clusters, and ra8_fs_backend_t::write_block.
Referenced by priv_exfat_format().
|
static |
Write the MBR (LBA 0) with one type-0x07 exFAT partition at part_lba.
Zeroes the sector, stamps a disk signature at offset 440, lays a single primary partition entry at offset 446 (non-bootable, type 0x07 exFAT/NTFS, packed start/end CHS via priv_exfat_lba_to_chs(), 32-bit start LBA and sector count), and writes the 0x55AA boot signature. A PC then sees standard partitioned removable media rather than a "superfloppy" volume at sector 0.
| [in] | backend | Block-device backend with a non-NULL write_block hook. |
| [in] | bps | Device sector size in bytes. |
| [in] | part_lba | First LBA of the exFAT partition (1 MiB aligned). |
| [in] | part_sectors | Partition length in sectors. |
| k_ra8_ok | MBR written at LBA 0. |
| k_ra8_err_* | Backend write_block failure. |
backend and backend->write_block are non-NULL. part_lba + part_sectors does not exceed the device capacity. Definition at line 712 of file ra8_fs_fat_exfat_fmt.c.
References ra8_fs_backend_t::ctx, g_fs_scratch, internal_exfat_lba_to_chs(), k_exfat_fmt_boot_sig, k_exfat_foff_boot_sig, k_mbr_fmt_boot_none, k_mbr_fmt_disk_sig_base, k_mbr_fmt_disk_sig_off, k_mbr_fmt_part0_off, k_mbr_fmt_pe_boot, k_mbr_fmt_pe_chs_end, k_mbr_fmt_pe_chs_start, k_mbr_fmt_pe_lba, k_mbr_fmt_pe_nsect, k_mbr_fmt_pe_type, k_mbr_fmt_type_exfat, priv_wr16(), priv_wr32(), and ra8_fs_backend_t::write_block.
Referenced by priv_exfat_format().
|
static |
Write the exFAT root directory entry set (bitmap, up-case, label).
Builds the root directory sector in g_fs_scratch and writes it to the root cluster in the heap. The sector contains three directory entries: an Allocation Bitmap entry (0x81) pointing to the first cluster of the bitmap and recording bitmap_bytes as the DataLength; an Up-case Table entry (0x82) with upcase_csum, the up-case cluster, and k_exfat_fmt_upc_std_bytes as the DataLength; and a Volume Label entry (0x83) with the label packed into UTF-16LE via priv_exfat_label_utf16().
| [in] | backend | Block-device backend with non-NULL write_block. |
| [in] | g | Resolved exFAT geometry from priv_exfat_geometry(). |
| [in] | upcase_csum | Rotate-add checksum of the up-case table data. |
| [in] | label | Optional NUL-terminated ASCII volume label, or NULL. |
| k_ra8_ok | Root directory sector written to the root cluster. |
| k_ra8_err_* | Backend write_block failure. |
backend and backend->write_block are non-NULL. g was filled by a successful priv_exfat_geometry() call. label (or zero length if NULL).Definition at line 599 of file ra8_fs_fat_exfat_fmt.c.
References exfat_geom_t::bitmap_bytes, exfat_geom_t::bps, ra8_fs_backend_t::ctx, g_fs_scratch, exfat_geom_t::heap_offset, internal_exfat_label_utf16(), k_exfat_de_data_len, k_exfat_de_first_clus, k_exfat_de_lbl_cnt, k_exfat_de_lbl_name, k_exfat_de_second, k_exfat_de_third, k_exfat_de_upc_csum, k_exfat_entry_bitmap, k_exfat_entry_label, k_exfat_entry_upcase, k_exfat_fmt_first_clus, k_exfat_fmt_upc_std_bytes, k_ra8_ok, exfat_geom_t::part_lba, priv_fmt_clear_region(), priv_wr32(), exfat_geom_t::root_cluster, exfat_geom_t::spc, exfat_geom_t::upcase_cluster, and ra8_fs_backend_t::write_block.
Referenced by priv_exfat_format().
| uint32_t priv_exfat_csum32 | ( | uint32_t | cs, |
| const uint8_t * | buf, | ||
| uint32_t | len ) |
exFAT 32-bit rotate-right-add checksum (boot region + up-case table).
Folds len bytes of buf into the running checksum cs with cs = ror1(cs) + byte per the Microsoft exFAT spec (sections 3.4 and 8.2.2). Shared by the boot-region checksum (which folds surrounding byte ranges to skip the three volatile bytes) and the up-case-table checksum.
| [in] | cs | Running checksum (0 to start). |
| [in] | buf | Bytes to fold in. |
| [in] | len | Number of bytes to fold. |
| 0..UINT32_MAX | The rotate-add fold of cs over buf[0..len-1]. |
buf holds at least len bytes. len is the exact byte count of the span to fold. cs, buf, and len. Definition at line 50 of file ra8_fs_fat_exfat_fmt.c.
References k_exfat_fmt_csum_hibit.
Referenced by internal_exfat_write_boot(), internal_exfat_write_boot_tail(), priv_exfat_upcase_checksum(), and priv_exfat_write_upcase().
| ra8_err_t priv_exfat_format | ( | const ra8_fs_backend_t * | backend, |
| uint64_t | total_sectors, | ||
| uint32_t | bps, | ||
| const char * | label ) |
Format the backend as a PC-standard partitioned exFAT volume (#102).
Writes a DOS/MBR partition table at LBA 0 with a single type-0x07 (exFAT/NTFS) partition aligned at ::k_exfat_fmt_part_lba, then lays a complete exFAT volume INSIDE that partition: main + backup boot regions with boot checksums (VolumeLength = partition length, PartitionOffset = k_exfat_fmt_part_lba), the single FAT (bitmap/up-case/root chains), the allocation bitmap with the system clusters pre-marked, the canonical Microsoft up-case table + its checksum, and the root directory entry set. A PC therefore sees a normal partitioned removable disk and the volume mounts with no repair; ra8_fs_mount follows the MBR back to the partition.
| [in] | backend | Block-device backend. |
| [in] | total_sectors | Device capacity in device sectors. |
| [in] | bps | Device sector size in bytes (a power of two, 512..4096, validated by the format entry point). |
| [in] | label | Optional volume label (<= 11 chars), may be NULL. |
| k_ra8_ok | A mountable partitioned exFAT volume was written. |
| k_ra8_err_invalid_size | Partition too small for an exFAT volume. |
| k_ra8_err_not_supported | Below the exFAT minimum plus the 1 MiB partition alignment, past the MBR's 32-bit fields (2 TiB at 512-byte sectors), or system cluster chains exceed FAT sector 0. |
| k_ra8_err_* | Backend write failure. |
backend and backend->write_block are non-NULL. total_sectors is the actual device capacity reported by the backend. Definition at line 798 of file ra8_fs_fat_exfat_fmt.c.
References exfat_geom_t::heap_offset, internal_exfat_fmt_place(), internal_exfat_geometry(), internal_exfat_write_bitmap(), internal_exfat_write_boot(), internal_exfat_write_fat(), internal_exfat_write_mbr(), internal_exfat_write_root(), k_exfat_fmt_first_clus, k_ra8_err_not_supported, k_ra8_ok, exfat_geom_t::part_lba, priv_exfat_write_upcase(), exfat_geom_t::root_cluster, exfat_geom_t::spc, and exfat_geom_t::upcase_cluster.