Skip to content

Commit

Permalink
bis_storage: add QoL improvements
Browse files Browse the repository at this point in the history
The BIS storage interface is now initialized by utilsInitializeResources() via bisStorageInitialize(). It takes care of mounting all eMMC FAT partitions in read-only mode, making it possible for the rest of the code to interact with them at any time without having to manually mount them beforehand.

Other changes include:

* bis_storage: add bisStorageExit().
* bis_storage: add bisStorageGetGptPartitionNameByBisPartitionId(), bisStorageGetSystemInitializerPartitionNameByBisPartitionId() and bisStorageGetMountNameByBisPartitionId() helpers.
* bis_storage: change bisStorageMountPartition(), bisStorageUnmountPartition() and bisStorageUnmountAllPartitions() to static functions.
* bis_storage: mount FAT partitions with FatFs by using drive numbers instead of arbitrary strings.

* cert: update code to reflect BIS storage interface changes.

* defines: add BIS_FAT_PARTITION_COUNT macro.

* fatfs/ffconf: use BIS_FAT_PARTITION_COUNT macro as the value for the FF_VOLUMES macro.
* fatfs/ffconf: disable arbitrary string support for volume IDs.

* nxdt_devoptab: increase concurrent mounted device count to 8.

* nxdt_utils: add missing underscores to anonymous variables in SCOPED_LOCK and SCOPED_TRY_LOCK macros.
* nxdt_utils: take care of BIS storage interface (de)initialization.

* poc: update code to reflect BIS storage interface changes.

* tik: update code to reflect BIS storage interface changes.
  • Loading branch information
DarkMatterCore committed Nov 1, 2024
1 parent 4589614 commit 94f0312
Show file tree
Hide file tree
Showing 10 changed files with 177 additions and 146 deletions.
11 changes: 1 addition & 10 deletions code_templates/nxdt_rw_poc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3730,19 +3730,12 @@ static bool browseEmmcPartition(void *userdata)

bool success = false;

if (bis_partition_id < FsBisPartitionId_CalibrationFile || bis_partition_id > FsBisPartitionId_System)
if (bis_partition_id < FsBisPartitionId_CalibrationFile || bis_partition_id > FsBisPartitionId_System || !(mount_name = bisStorageGetMountNameByBisPartitionId(bis_partition_id)))
{
consolePrint("invalid bis partition id! (%u)\n", bis_partition_id);
goto end;
}

/* Mount BIS partition. */
if (!bisStorageMountPartition(bis_partition_id, &mount_name))
{
consolePrint("failed to mount bis partition %u!\n", bis_partition_id);
goto end;
}

/* Generate output base path. */
base_out_path = generateOutputGameCardFileName(utilsGetAtmosphereEmummcStatus() ? "emuMMC" : "sysMMC", mount_name, false);
if (!base_out_path) goto end;
Expand All @@ -3754,8 +3747,6 @@ static bool browseEmmcPartition(void *userdata)
/* Free data. */
if (base_out_path) free(base_out_path);

if (mount_name) bisStorageUnmountPartition(bis_partition_id);

if (!success && g_appletStatus)
{
consolePrint("press any button to continue\n");
Expand Down
24 changes: 18 additions & 6 deletions include/core/bis_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,28 @@
extern "C" {
#endif

/// Mounts an eMMC BIS partition using its ID and provides a pointer to a string that holds its mount name, which can be used to carry out FS operations.
/// Mounts the eMMC partitions with IDs `CalibrationFile` (28) through `System` (31) and makes it possible to perform read-only FS operations with them.
/// The mount name for each partition can be retrieved via bisStorageGetMountNameByBisPartitionId().
bool bisStorageInitialize(void);

/// Unmounts all previously mounted eMMC partitions.
void bisStorageExit(void);

/// Returns a pointer to a string that holds the GPT partition name for the provided eMMC BIS partition ID (e.g. FsBisPartitionId_CalibrationFile -> "PRODINFOF").
/// Only eMMC BIS partition IDs `CalibrationFile` (28) through `System` (31) are supported.
bool bisStorageMountPartition(u8 bis_partition_id, const char **out_mount_name);
/// Returns NULL if the eMMC BIS storage interface hasn't been initialized yet, or if an unsupported eMMC BIS partition ID is provided.
const char *bisStorageGetGptPartitionNameByBisPartitionId(u8 bis_partition_id);

/// Unmounts a previously mounted eMMC BIS partition.
/// Returns a pointer to a string that holds the SystemInitializer partition name for the provided eMMC BIS partition ID (e.g. FsBisPartitionId_CalibrationFile -> "CalibrationFile").
/// Only eMMC BIS partition IDs `CalibrationFile` (28) through `System` (31) are supported.
void bisStorageUnmountPartition(u8 bis_partition_id);
/// Returns NULL if the eMMC BIS storage interface hasn't been initialized yet, or if an unsupported eMMC BIS partition ID is provided.
const char *bisStorageGetSystemInitializerPartitionNameByBisPartitionId(u8 bis_partition_id);

/// Unmounts all previously mounted eMMC BIS partitions.
void bisStorageUnmountAllPartitions(void);
/// Returns a pointer to a string that holds the mount name for the provided eMMC BIS partition ID (e.g. FsBisPartitionId_CalibrationFile -> "bisprodinfof").
/// This can be used to perform read-only FS operations on a specific partition.
/// Only eMMC BIS partition IDs `CalibrationFile` (28) through `System` (31) are supported.
/// Returns NULL if the eMMC BIS storage interface hasn't been initialized yet, or if an unsupported eMMC BIS partition ID is provided.
const char *bisStorageGetMountNameByBisPartitionId(u8 bis_partition_id);

/// Returns a pointer to a FsStorage object that matches the provided FatFs drive number, or NULL if it hasn't been mounted.
/// Only used by FatFs's diskio operations.
Expand Down
6 changes: 4 additions & 2 deletions include/core/fatfs/ffconf.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include "../../defines.h"

/*---------------------------------------------------------------------------/
/ Configurations of FatFs Module
/---------------------------------------------------------------------------*/
Expand Down Expand Up @@ -166,11 +168,11 @@
/ Drive/Volume Configurations
/---------------------------------------------------------------------------*/

#define FF_VOLUMES 4
#define FF_VOLUMES BIS_FAT_PARTITION_COUNT
/* Number of volumes (logical drives) to be used. (1-10) */


#define FF_STR_VOLUME_ID 1
#define FF_STR_VOLUME_ID 0
/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
Expand Down
6 changes: 3 additions & 3 deletions include/core/nxdt_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ extern "C" {
#endif

/* Scoped lock macro. */
#define SCOPED_LOCK(mtx) for(UtilsScopedLock ANONYMOUS_VARIABLE(scoped_lock) CLEANUP(utilsUnlockScope) = utilsLockScope(mtx); ANONYMOUS_VARIABLE(scoped_lock).cond; ANONYMOUS_VARIABLE(scoped_lock).cond = 0)
#define SCOPED_LOCK(mtx) for(UtilsScopedLock ANONYMOUS_VARIABLE(scoped_lock_) CLEANUP(utilsUnlockScope) = utilsLockScope(mtx); ANONYMOUS_VARIABLE(scoped_lock_).cond; ANONYMOUS_VARIABLE(scoped_lock_).cond = 0)

/* Scoped try lock macro. */
#define SCOPED_TRY_LOCK(mtx) for(UtilsScopedLock ANONYMOUS_VARIABLE(scoped_lock) CLEANUP(utilsUnlockScope) = utilsTryLockScope(mtx); ANONYMOUS_VARIABLE(scoped_lock).cond; ANONYMOUS_VARIABLE(scoped_lock).cond = 0)
#define SCOPED_TRY_LOCK(mtx) for(UtilsScopedLock ANONYMOUS_VARIABLE(scoped_lock_) CLEANUP(utilsUnlockScope) = utilsTryLockScope(mtx); ANONYMOUS_VARIABLE(scoped_lock_).cond; ANONYMOUS_VARIABLE(scoped_lock_).cond = 0)

/// Used by scoped locks.
typedef struct {
Expand Down Expand Up @@ -150,7 +150,7 @@ void utilsGenerateHexString(char *dst, size_t dst_size, const void *src, size_t
/// 'src' must match the regex /^(?:[A-Fa-f0-9]{2})+$/.
/// 'src_size' may be zero, in which case strlen() will be used to determine the length of 'src'. Furthermore, 'src_size' must always be a multiple of 2.
/// 'dst_size' must be at least 'src_size / 2'.
/// Returns false if there's an error validating input arguments.
/// Returns false if there's an error.
bool utilsParseHexString(void *dst, size_t dst_size, const char *src, size_t src_size);

/// Formats the provided 'size' value to a human-readable size string and stores it in 'dst'.
Expand Down
2 changes: 2 additions & 0 deletions include/defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@
#define LOG_BUF_SIZE 0x400000 /* 4 MiB. */
#define LOG_FORCE_FLUSH 0 /* Forces a log buffer flush each time the logfile is written to. */

#define BIS_FAT_PARTITION_COUNT 4

/// Reference: https://docs.microsoft.com/en-us/windows/win32/fileio/filesystem-functionality-comparison#limits.
/// Reference: https://en.wikipedia.org/wiki/Comparison_of_file_systems#Limits.
/// Most modern filesystems use a 255-byte limit instead of 255-character/codepoint limit, so that's what we're gonna use.
Expand Down
Loading

0 comments on commit 94f0312

Please sign in to comment.