ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
board_periph_sd_image.c File Reference

Sparse raw-file lifecycle for the modelled SD card. More...

#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "board_periph_sd.h"
#include "board_periph_sd_internal.h"
#include "emu_host_io_internal.h"
Include dependency graph for board_periph_sd_image.c:

Go to the source code of this file.

Macros

#define _GNU_SOURCE
 Request GNU descriptor-relative syscall declarations on Linux.

Enumerations

enum  board_sd_io_const_t : uint32_t { k_sd_io_chunk = 4096U }
 Fixed transfer size for card-image copies and portable zeroing. More...

Functions

static RA8_INTERNAL void internal_close_fd (int *fd)
 Close a descriptor when owned and invalidate the caller's slot.
static RA8_INTERNAL void internal_release_image (void)
 Release the currently attached anonymous working file.
static RA8_INTERNAL bool internal_create_sparse (uint64_t bytes, int *out_fd)
 Create, unlink, and size an anonymous sparse working file.
static RA8_INTERNAL bool internal_copy_bytes (int source_fd, int target_fd, uint64_t bytes)
 Copy a descriptor range with one fixed scratch buffer.
static RA8_INTERNAL void internal_adopt_image (int image_fd, uint64_t bytes)
 Replace the active card with a prepared working file.
static RA8_INTERNAL bool internal_range_valid (uint64_t offset, size_t count)
 Validate a positioned operation against descriptor and card bounds.
bool priv_board_sd_storage_read (uint64_t offset, void *dst, size_t count)
 Read exactly from the current sparse backend at a checked byte offset.
bool priv_board_sd_storage_write (uint64_t offset, const void *src, size_t count)
 Write exactly to the current sparse backend at a checked byte offset.
static RA8_INTERNAL bool internal_write_zeros (uint64_t offset, uint64_t count)
 Portably zero a range with bounded memory when hole punching is unavailable.
bool priv_board_sd_storage_zero (uint64_t offset, uint64_t count)
 Make a checked byte range read as zero while preserving sparse storage.
bool board_sd_attach (const char *path)
 Attach an SD-card image from a host file.
bool board_sd_attached (void)
 Report whether an SD-card image is currently attached.
static RA8_INTERNAL void internal_report_created (uint64_t bytes, uint8_t fat_bits, uint32_t spc)
 Emit the stable blank-card geometry diagnostic.
bool board_sd_attach_blank (uint32_t total_sectors, uint8_t fat_bits, const char *label)
 Create a blank, FAT-formatted sparse SD card and attach it.
bool board_sd_save (const char *path)
 Transactionally publish the current SD-card image to a file.
void board_sd_info (bool *attached, uint64_t *bytes, uint8_t *fat_bits, const char **label)
 Read back the attached card's summary (for the status view / report).

Detailed Description

Sparse raw-file lifecycle for the modelled SD card.

Owns the private anonymous working descriptor used by the SD model. Input images are copied with a fixed transfer buffer so firmware writes never mutate the source. Blank cards remain sparse at their full advertised size, and saves publish through a sibling transaction.

Since
0.1.0

Definition in file board_periph_sd_image.c.

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Request GNU descriptor-relative syscall declarations on Linux.

Definition at line 16 of file board_periph_sd_image.c.

Enumeration Type Documentation

◆ board_sd_io_const_t

enum board_sd_io_const_t : uint32_t

Fixed transfer size for card-image copies and portable zeroing.

Enumerator
k_sd_io_chunk 

Bounded stack scratch; independent of card size.

Definition at line 35 of file board_periph_sd_image.c.

Function Documentation

◆ board_sd_attach()

bool board_sd_attach ( const char * path)

Attach an SD-card image from a host file.

Copies the file into a private anonymous sparse working descriptor with fixed-size transfers, so firmware writes never mutate the source. A second successful call closes and replaces the prior working descriptor.

Parameters
[in]pathHost path to a raw FAT image (512-byte sectors).
Returns
true if the image loaded and the card is armed; false on I/O error.
Return values
falseThe file could not be opened or read.
Precondition
path is non-null.
Called once during ra8_emulator start-up (single-threaded).
Postcondition
On success board_sd_attached returns true.
On failure any previously attached card remains attached.
Note
Not thread-safe.
Since
0.1.0

Definition at line 267 of file board_periph_sd_image.c.

References emu_io_file_t::fd, g_board_sd, internal_adopt_image(), internal_close_fd(), internal_copy_bytes(), internal_create_sparse(), k_emu_io_ok, priv_emu_io_close(), priv_emu_io_errf(), priv_emu_io_open_read(), and emu_io_file_t::size.

Referenced by internal_args_try_sd().

◆ board_sd_attach_blank()

bool board_sd_attach_blank ( uint32_t total_sectors,
uint8_t fat_bits,
const char * label )

Create a blank, FAT-formatted sparse SD card and attach it.

Sizes an anonymous sparse raw-file backend, then formats an empty FAT16 or FAT32 volume with fixed one-sector buffers (complete BPB + FAT media / EOC markers, valid to a host fsck_msdos and the firmware's ra8_fs).

Parameters
[in]total_sectorsCard size in 512-byte sectors (>= 64).
[in]fat_bits16 for FAT16, 32 for FAT32 (other values -> FAT16).
[in]labelUp to 11-char volume label (NULL -> blank).
Returns
true on success (a blank card is attached and serving).
Return values
falseSize too small, sparse-file creation failed, or formatting failed.
Precondition
Called once during ra8_emulator start-up (single-threaded).
Postcondition
On success board_sd_attached returns true.
Note
Not thread-safe.
Since
0.1.0
Precondition
The call executes on the emulator's single owning thread.
Postcondition
Ownership of caller-supplied storage is unchanged.

Definition at line 335 of file board_periph_sd_image.c.

References g_board_sd, internal_adopt_image(), internal_close_fd(), internal_create_sparse(), internal_report_created(), k_fat16_bits, k_fat32_bits, k_fmt_label_len, k_fmt_sec_bytes, k_sd_min_sectors, priv_board_sd_format_fat16(), priv_board_sd_format_fat32(), priv_board_sd_label_field(), and priv_emu_io_errf().

Referenced by internal_args_attach_blank_sd().

◆ board_sd_attached()

bool board_sd_attached ( void )

Report whether an SD-card image is currently attached.

Returns
true if a card image is loaded and serving.
Return values
falseNo --sd image was attached.
Precondition
None.
None.
Postcondition
No state is modified.
No state is modified.
Note
Not thread-safe.
Since
0.1.0

Report whether an sd-card image is currently attached; this step is contained within the board periph SD model and uses bounded caller or module-owned storage.

Definition at line 299 of file board_periph_sd_image.c.

References g_board_sd.

Referenced by internal_on_sdmmc_read_block(), internal_sci_reg_write(), and internal_spi_spdr_write().

◆ board_sd_info()

void board_sd_info ( bool * attached,
uint64_t * bytes,
uint8_t * fat_bits,
const char ** label )

Read back the attached card's summary (for the status view / report).

Parameters
[out]attachedReceives whether a card is attached (may be NULL).
[out]bytesReceives the card size in bytes, 64-bit for >4 GB (NULL ok).
[out]fat_bitsReceives 12/16/32 if formatted by –sd-new, else 0 (NULL ok).
[out]labelReceives a pointer to the NUL-terminated label (NULL ok).
Precondition
None.
Postcondition
No card state is modified.
Note
Not thread-safe.
Since
0.1.0

Read back the attached card's summary (for the status view / report); this step is contained within the board periph SD model and uses bounded caller or module-owned storage.

Precondition
The call executes on the emulator's single owning thread.
Postcondition
Ownership of caller-supplied storage is unchanged.

Definition at line 394 of file board_periph_sd_image.c.

References g_board_sd.

Referenced by internal_fill_status_hw(), internal_run_print_sd_summary(), and internal_sdhi_make_csd().

◆ board_sd_save()

bool board_sd_save ( const char * path)

Transactionally publish the current SD-card image to a file.

Copies through a bounded buffer into a same-directory private file, then syncs and renames only after the complete image is present.

Parameters
[in]pathOutput path for the raw card image.
Returns
true on success.
Return values
falseNo card attached, or the file could not be written.
Precondition
A card is attached.
path is non-null, NUL-terminated, and names an accessible parent.
Postcondition
On success the host file atomically holds the current card contents.
On failure an existing target remains unchanged.
Note
Not thread-safe.
Since
0.1.0

Definition at line 366 of file board_periph_sd_image.c.

References emu_io_txn_t::fd, g_board_sd, internal_copy_bytes(), k_emu_io_ok, k_sd_save_max_bytes, k_unit_kib, priv_emu_io_errf(), priv_emu_io_txn_abort(), priv_emu_io_txn_begin(), and priv_emu_io_txn_commit().

Referenced by priv_run_cleanup().

◆ internal_adopt_image()

RA8_INTERNAL void internal_adopt_image ( int image_fd,
uint64_t bytes )
static

Replace the active card with a prepared working file.

Releases prior private state before installing the fully prepared descriptor.

Parameters
[in]image_fdOwned anonymous descriptor to adopt.
[in]bytesExact logical card length.
Precondition
image_fd is open, private, and sized to bytes.
No protocol operation concurrently accesses global SD state.
Postcondition
Prior working descriptor is closed exactly once.
New descriptor, length, and attached state are installed together.
Note
Ownership of image_fd transfers to global SD state.
Since
0.1.0

Definition at line 161 of file board_periph_sd_image.c.

References g_board_sd, internal_release_image(), and RA8_INTERNAL.

Referenced by board_sd_attach(), and board_sd_attach_blank().

◆ internal_close_fd()

RA8_INTERNAL void internal_close_fd ( int * fd)
static

Close a descriptor when owned and invalidate the caller's slot.

Accepts null and already-invalid slots for idempotent unwind paths.

Parameters
[in,out]fdDescriptor slot to release.
Precondition
fd is null or points to caller-owned descriptor state.
No concurrent operation uses a non-negative descriptor in the slot.
Postcondition
A non-null slot contains -1.
Any formerly owned descriptor has been offered to close once.
Note
Close errors are intentionally ignored during best-effort cleanup.
Since
0.1.0

Definition at line 50 of file board_periph_sd_image.c.

References RA8_INTERNAL.

Referenced by board_sd_attach(), board_sd_attach_blank(), internal_create_sparse(), and internal_release_image().

◆ internal_copy_bytes()

RA8_INTERNAL bool internal_copy_bytes ( int source_fd,
int target_fd,
uint64_t bytes )
static

Copy a descriptor range with one fixed scratch buffer.

Performs exact positioned reads and writes in bounded 4 KiB chunks.

Parameters
[in]source_fdOpen source descriptor.
[in]target_fdOpen private target descriptor.
[in]bytesExact byte count to copy from offset zero.
Returns
Whether the complete range was reproduced.
Return values
trueEvery chunk was read and written exactly.
falseFirst exact host I/O operation failed.
Precondition
Both descriptors are open for their respective operations.
Both files span at least bytes and offsets are host-representable.
Postcondition
Success makes target bytes [0,bytes) equal source bytes.
Descriptor stream positions remain unchanged.
Note
Bounded stack use is independent of card size.
Since
0.1.0

Definition at line 126 of file board_periph_sd_image.c.

References k_emu_io_ok, k_sd_io_chunk, priv_emu_io_pread_exact(), priv_emu_io_pwrite_exact(), RA8_INTERNAL, and emu_io_result_t::status.

Referenced by board_sd_attach(), and board_sd_save().

◆ internal_create_sparse()

RA8_INTERNAL bool internal_create_sparse ( uint64_t bytes,
int * out_fd )
static

Create, unlink, and size an anonymous sparse working file.

Uses a private temporary name only until open, then unlinks it and sets the exact logical length without materializing zero-filled card bytes.

Parameters
[in]bytesRequired logical image length.
[out]out_fdReceives the owned anonymous descriptor.
Returns
Whether complete sparse setup succeeded.
Return values
trueCaller owns an unlinked descriptor of exact length.
falseArguments, host creation, unlink-tolerant setup, or truncate failed.
Precondition
out_fd is non-null and writable.
bytes is non-zero and representable by host off_t.
Postcondition
Success initializes out_fd with one owned descriptor.
Failure leaves no descriptor or named temporary owned.
Note
Sparse allocation policy is supplied by the host filesystem.
Since
0.1.0

Definition at line 91 of file board_periph_sd_image.c.

References internal_close_fd(), and RA8_INTERNAL.

Referenced by board_sd_attach(), and board_sd_attach_blank().

◆ internal_range_valid()

RA8_INTERNAL bool internal_range_valid ( uint64_t offset,
size_t count )
static

Validate a positioned operation against descriptor and card bounds.

Uses subtractive range checks after verifying attachment and host offset limits.

Parameters
[in]offsetFirst card byte.
[in]countRequested byte count.
Returns
Whether the complete half-open range is accessible.
Return values
trueAttached descriptor and geometry contain the request.
falseState, offset, or length is invalid.
Precondition
Global SD state is readable and single-thread owned.
count may be zero through any size_t value.
Postcondition
No global or host state changes.
No host I/O is issued.
Note
Not thread-safe with card replacement.
Since
0.1.0

Definition at line 184 of file board_periph_sd_image.c.

References g_board_sd, and RA8_INTERNAL.

Referenced by priv_board_sd_storage_read(), and priv_board_sd_storage_write().

◆ internal_release_image()

RA8_INTERNAL void internal_release_image ( void )
static

Release the currently attached anonymous working file.

Closes the private descriptor and clears observable attachment geometry.

Precondition
Emulator SD state is single-thread owned.
No protocol transfer concurrently uses the working descriptor.
Postcondition
Image descriptor is invalid, length is zero, and attachment is false.
No source or saved host image is changed.
Note
Not thread-safe through global SD state.
Since
0.1.0

Definition at line 68 of file board_periph_sd_image.c.

References g_board_sd, internal_close_fd(), and RA8_INTERNAL.

Referenced by internal_adopt_image().

◆ internal_report_created()

RA8_INTERNAL void internal_report_created ( uint64_t bytes,
uint8_t fat_bits,
uint32_t spc )
static

Emit the stable blank-card geometry diagnostic.

Selects GiB or MiB units while preserving the established CLI spelling.

Parameters
[in]bytesExact logical card length.
[in]fat_bitsSelected FAT width.
[in]spcChosen sectors per cluster.
Precondition
bytes came from a successfully formatted attached image.
fat_bits and spc describe that image geometry.
Postcondition
One best-effort diagnostic line was attempted.
Card image and protocol state are unchanged.
Note
Diagnostic failure does not invalidate the attached card.
Since
0.1.0

Definition at line 317 of file board_periph_sd_image.c.

References k_unit_kib, priv_emu_io_errf(), and RA8_INTERNAL.

Referenced by board_sd_attach_blank().

◆ internal_write_zeros()

RA8_INTERNAL bool internal_write_zeros ( uint64_t offset,
uint64_t count )
static

Portably zero a range with bounded memory when hole punching is unavailable.

Reuses one fixed zero buffer and exact positioned writes for the full range.

Parameters
[in]offsetFirst card byte to clear.
[in]countNumber of bytes to clear.
Returns
Whether every chunk was written.
Return values
trueComplete range now reads as zero.
falseFirst exact storage write failed.
Precondition
Complete range passed the public zero-operation bounds checks.
Working image descriptor remains attached and writable.
Postcondition
Success overwrites exactly [offset, offset + count) with zeroes.
Stack usage is constant independent of count.
Note
Used after unsupported Linux hole punching and on other hosts.
Since
0.1.0

Definition at line 228 of file board_periph_sd_image.c.

References k_sd_io_chunk, priv_board_sd_storage_write(), and RA8_INTERNAL.

Referenced by priv_board_sd_storage_zero().

◆ priv_board_sd_storage_read()

bool priv_board_sd_storage_read ( uint64_t offset,
void * dst,
size_t count )
nodiscard

Read exactly from the current sparse backend at a checked byte offset.

Definition at line 193 of file board_periph_sd_image.c.

References g_board_sd, internal_range_valid(), k_emu_io_ok, priv_emu_io_pread_exact(), and emu_io_result_t::status.

Referenced by internal_board_sd_fill_block().

◆ priv_board_sd_storage_write()

bool priv_board_sd_storage_write ( uint64_t offset,
const void * src,
size_t count )
nodiscard

Write exactly to the current sparse backend at a checked byte offset.

Definition at line 203 of file board_periph_sd_image.c.

References g_board_sd, internal_range_valid(), k_emu_io_ok, priv_emu_io_pwrite_exact(), and emu_io_result_t::status.

Referenced by board_sd_write_block(), internal_sd_write_crc(), and internal_write_zeros().

◆ priv_board_sd_storage_zero()

bool priv_board_sd_storage_zero ( uint64_t offset,
uint64_t count )
nodiscard

Make a checked byte range read as zero while preserving sparse storage.

Definition at line 243 of file board_periph_sd_image.c.

References g_board_sd, and internal_write_zeros().

Referenced by internal_board_sd_cmd_erase().