NAND API

Introduction

The NAND library provides functions to access the NAND flash memory built into the Wii console. NAND flash memory has the following characteristics:

The NAND memory capacity of the Wii console is 512 MB. However, not all of the 512 MB space can be used by the application program, as some of the space will be taken by the system files written at the factory or for permanently reserved system needs.

The NAND library provides a file system with the following characteristics.

We have prepared sample demo programs that demonstrate how to use the NAND library under the path $REVOLUTION_SDK_ROOT/build/demos/nanddemo/. Function declarations are in the $REVOLUTION_SDK_ROOT/include/revolution/nand.h header file.

Banners

You must create a banner file in order to create an application save file in Wii console NAND memory. In the Wii Menu, home directories without a banner file are deleted. If creating multiple files that include a banner file, be sure to create the banner file last. If the banner file is created first, and then an accident such as a power interruption occurs, the home directory would have a banner file, but some of the save files might not be there. This could confuse players because it would appear from the save data screen in the Wii Menu that the application had no problem creating the save files, when in fact there was a problem. See the Guidelines For Creating Wii Save Data for details.

The NANDBanner structure and the NANDInitBanner, NANDGetIconSpeed and NANDSetIconSpeed functions have been prepared to simplify the process of creating banners. Also, reference the banner sample demo program.

Functions That Determine Whether a File or Directory Can Be Newly Created

As mentioned before, Wii console NAND memory has a capacity of 512MB, but not all of it can be used by the application program. The memory includes system programs represented by console feature applications, a reserved region for bad blocks, and a free region which must be allocated for system use. Do not conclude whether a new file/directory can be created solely based on available space in the file system; use of NANDFreeBlocks[Async] is not recommended.
When the application attempts to create files or directories in the home directory, determine whether to go ahead and create the new files/directories or to perform some process such as displaying a message indicating insufficient memory space based on responses from the functions below.

NANDCheck[Async]

The NANDCheck and NANDCheckAsync functions report the number of file system blocks and inodes that the application is about to consume. If the application is creating a new file or directory under the home directory, call the NANDCheck or NANDCheckAsync function first. The total number of file system blocks and inodes for the file or directory that the application will create is passed to the NANDCheck and NANDCheckAsync functions. The system will calculate whether a sufficient space to fulfill that request is available in the file system, and will give the verdict to the application program.

Determining Whether Multiple Files or Directories Can Be Created

If the application requires multiple files or directories to proceed, sum the total number of file system blocks and inodes consumed by each, and then branch to either "Create file/directory group" or "Create no files/directories," based on the result of a single call to the NANDCheck[Async] function. Do not call the NANDCheck[Async] function every time a file or directory is created. If you call the NANDCheck[Async] function multiple times to create multiple files and directories, depending on the available space in Wii console NAND memory you may not be able to create all of the required files and directories.


// Correct sequence (pseudo-code)
NANDCheck(FileA+FileB+FileC);    // Check A & B & C at once.
if(success){
    createFileA();
    createFileB();
    createFileC();
}

// Incorrect sequence (pseudo-code)
NANDCheck(FileA);   // Check A
if(success){
    createFileA();
}

NANDCheck(FileB);   // Check B
if(success){
    createFileB();
}

NANDCheck(FileC)    // Check C
if(success){
    createFileC()
}

The number of file system blocks (FS blocks) consumed by a given file is rounded up to be an integer value of the file size divided by 16 KB. Thus, an 8 KB file consumes one FS block, and a 40 KB consumes three FS blocks. Accordingly, if an application needs to create two files, one 8 KB and one 40 KB, that file group consumes four FS blocks (1 + 3 = 4). Do not calculate this as (40+8)/16 = 3 and call the NANDCheck[Async] function under the assumption that three FS blocks will be consumed.

Functions That Get the Available Space for an Application

The NANDCheck and the NANDCheckAsync functions determine whether files/directories can be created, but they are not suited to determine exactly how much free space is available. If you want to inform the player how much free space is available for the application to use in Wii console NAND memory, use the NANDGetAvailableArea or the NANDGetAvailableAreaAsync function. These functions get the number of file system blocks and inodes that the application can consume.

Process Flow

First, call the NANDInit function to initialize the NAND library before using NAND functions. (Note: Starting with RevolutionSDK 2.1, patch 1, the NANDInit function is automatically called by the system.)If the application is creating a new file or directory in a directory other than /tmp, first call the NANDCheck or NANDCheckAsync function to verify that the file system has sufficient free space and inodes for the application before calling the NANDCreate function.

Refer to NAND Processing Sequence for an example of process flow including the error processing.

Directory Structure

Although a number of directories are available for the file system in Wii console NAND memory, the application programmer should be aware of the following.
Path Description
/title/<title-id(Hi)>/<title-id(Low)>/data This is the application home directory. The home directory is provided automatically by the system. Save the application's save data and other application-related data in this directory.
/tmp Temporary directory. Files and directories stored under this directory are deleted when the system starts up.
/tmp/sys This directory is reserved for use by the system as a temporary directory. Avoid having application programs access this directory directly. Doing so can lead to system instability.

<title-id (Hi)> is a 32-bit value determined according to the application type. It is assigned by the system and displayed as a string in hexadecimal notation. The value is 00010000 for disc applications and 00010001 and higher for NAND applications. At the present time, the value 00010001 is assigned to <title-id (Hi)> for WiiWare (but this might change in the future).
<title-id (Low)> is equivalent to the four-character game code unique to each application, after conversion to a hexadecimal-notation string based on the ASCII character code table. For example, if the initial code is "RABJ", it is converted to 5241424a. The <title-id (Low)> string is not automatically updated with the DDF file's GameName when an ELF file is executed on NDEV, so it must be directly specified separately using setinitialcode.

Directory and File Access

The Wii console NAND memory file system controls access using three levels of permissions: Owner, Group, and Other. Owner and Group permissions are managed by the application, using access control IDs called the Owner ID and Group ID, respectively. Other permissions apply to titles whose Owner ID and Group ID both differ.

The Owner ID is a unique ID given to titles imported into Wii console NAND memory, and is assigned automatically by the system. A Wii console can hold multiple imported titles, but they will never be assigned duplicate Owner IDs.
The Group ID is a characteristic ID assigned to individual companies. In the case of a disc application, when creating master data using the makemaster command, the two-byte string set for the Company variable in the DDF file's [DiskID] is converted into hexadecimal notation based on the ASCII character code table, and this value is used as the Group ID. For example, if the Company variable is [00], the Group ID is [0x3030].

Application Save Data

Use the NAND library to save application data. Refer to the gamesave sample demo program for more information on saving data.

When the NAND library is initialized, the current directory is automatically set as the home directory. This directory is hardwired in software in the development device environment and is common to all applications. However, a unique home directory is provided for each application on the production units.

Synchronous and Asynchronous Functions

Certain NAND functions provide both synchronous and asynchronous access to Wii console NAND memory.
Synchronous functions block the current thread until the process is completed and control is transferred to other executable threads. Asynchronous functions return immediately. If an asynchronous function request starts normally, a callback function is called at the completion of the process, and a result code and command block are passed to it. This callback function and command block are specified when the asynchronous function is called. If the asynchronous function call ends in an error (that is, if the result code is other than a normal exit), the specified callback function will not be called. Asynchronous functions contain the suffix Async.

Inodes

File management is done through inodes in the NAND library file system. One available inode is required for each file or directory that is created. The number of available i-nodes can be checked using the NANDFreeBlocks or NANDFreeBlocksAsync function.
However, the values obtained by these functions are the available inode counts for the entire file system. In actuality, some free inodes must always be reserved for the system, so please do not determine whether a new file/directory can be created solely based on the value obtained by these functions. When creating a new file or directory in a location other than /tmp, please use the NANDCheck or NANDCheckAsync function to make your determination.

Result Code List

Return Values Description
NAND_RESULT_OK Completed successfully.
NAND_RESULT_ACCESS The are no permission/access privileges for accessing files or directories.
NAND_RESULT_ALLOC_FAILED The library failed internally to secure the memory needed for receiving a large volume of requests at one time. However, if you wait some time and call the NAND function again, the process might succeed.
NAND_RESULT_AUTHENTICATION Data authentication failed. Data may have been damaged due to faulty hardware, or data in Wii console NAND memory may have been altered illegally.
NAND_RESULT_BUSY Busy state (the queue holding requests is full). If you wait some time and call the NAND function again, the process might succeed.
NAND_RESULT_CORRUPT Wear in the FAT region has caused irreparable damage to Wii console NAND memory.
NAND_RESULT_ECC_CRIT Indicates that a fatal ECC error has been detected (that is, data error correction is not possible). This code might be returned when Wii console NAND memory is severely worn because the number of write/delete cycles has exceeded the device guaranteed performance.
NAND_RESULT_EXISTS File or directory with the same name already exists.
NAND_RESULT_INVALID An input parameter, or the function call itself, is invalid. This code is returned when an incorrect argument is passed to a NAND function, an attempt is made to close a file twice, or an attempt is made to use the NANDSimpleSafe[Close] functions to close a file that was opened by the NANDOpen[Async] functions (or vice versa).
NAND_RESULT_MAXBLOCKS All of the FS blocks in the file system have been used, so there is no free space. This code is also returned when, due to device wear, the number of bad blocks has reached the upper limit.
NAND_RESULT_MAXDEPTH A directory structure deeper than this cannot be created (8 levels maximum).
NAND_RESULT_MAXFD No more files can be opened because all of the file descriptor entries have been used. Reduce the number of files you open at one time.
NAND_RESULT_MAXFILES No more files/directories can be created because the file system's inodes have been used up.
NAND_RESULT_NOEXISTS The specified file or directory does not exist.
NAND_RESULT_NOTEMPTY File is not empty.
NAND_RESULT_OPENFD The file descriptor has been left open. This code is returned when an attempt is made to delete a file that has not yet been closed (The NANDSafeClose[Async] functions may potentially return this code because they perform Delete operations internally).
NAND_RESULT_UNKNOWN Unknown error. When this code is returned, there is a high probability that there is some problem with the SDK. If possible, report the issue to Nintendo.
NAND_RESULT_FATAL_ERROR The error code for problems resulting from flawed program design (for example, the library is not initialized, or the like).

Of these, the following are result codes that might be returned by asynchronous function calls. Also, with the exception of certain asynchronous functions (NANDSafeOpenAsync, NANDSafeCloseAsync, NANDSimpleSafeOpenAsync, NANDSimpleSafeCloseAsync, and NANDSimpleSafeCancelAsync), the specified callback function will not receive either NAND_RESULT_ALLOC_FAILED or NAND_RESULT_BUSY.

Starting from SDK Version 2.3 (firmware Version 12.0.2), most synchronous NAND functions can return NAND_RESULT_ALLOC_FAILED and NAND_RESULT_BUSY. These result codes may be returned when a synchronous NAND API is called while the queue for receiving requests is full (for example, due to a succession of calls to asynchronous NAND functions over a short period of time).

Result Code Handling

The following table indicates the guidelines for handling result codes. Also refer to the NAND Processing Sequence page.

A. Items that applications must support NAND_RESULT_AUTHENTICATION
NAND_RESULT_CORRUPT
NAND_RESULT_ECC_CRIT
B. Items that applications must support for which a bug report to Nintendo is expected (if possible) NAND_RESULT_ALLOC_FAILED
NAND_RESULT_BUSY
NAND_RESULT_MAXBLOCKS
NAND_RESULT_MAXFILES
NAND_RESULT_UNKNOWN
C. Must be removed during the development or hidden from the player NAND_RESULT_ACCESS
NAND_RESULT_EXISTS
NAND_RESULT_INVALID
NAND_RESULT_MAXDEPTH
NAND_RESULT_MAXFD
NAND_RESULT_NOEXISTS
NAND_RESULT_NOTEMPTY
NAND_RESULT_OPENFD
NAND_RESULT_FATAL_ERROR

Result codes that are classified as (A) are the codes that may be caused by issues such as wear to Wii console NAND memory.
Result codes that are classified as (B) are the codes that should not appear as long as the Wii system is running normally. If result codes in this category appear, please send a bug report to Nintendo if possible, as there is a chance of a defect in either RevolutionSDK or the Wii console/Wii development console.
Result codes that are classified as (C) are the codes that mainly suggest coding errors by the application programmers.

Notes

Precautions When Writing Data

The file system used to manage Wii console NAND memory has been designed to survive unexpected power shutdowns. There is no worry of the entire file system crashing even if the power shuts down in the middle of FAT update in the internal NAND memory. The system will instead restart from a FAT state immediately before the update. However, care must be taken regarding write timing. Assume that the following operations have been performed on a given file.

  1. Open()
  2. Read()
  3. Write()
  4. Write()
  5. Write()
  6. Close()

The Write function alone does not update the FAT in the built-in flash memory (the FAT in memory is updated). Therefore, even if the power is disconnected midway through the execution of the Write function, file content will start from the state in effect before the Write function was invoked. However, if an operation that involves updating the FAT in built-in flash memory occurs as an interrupt between instances of the Write function, the data written by the Write function up to that point will be applied to built-in flash memory. For example, if another thread or process executes the Create function immediately after the Write function on line three has finished executing, the FAT in built-in flash memory will be updated. If the power is disconnected immediately after this Create function has finished executing, only the data written by the Write function on line three will be applied to the file. Although this behavior may not pose a problem depending on the data structure recorded for the file, when any of the of Write invocations on lines three, four, or five are left out, problems will result if this causes data inconsistency.

One method of avoiding inconsistency of data due to this type of FAT update timing is to use a temporary file. First, copy the target file to /tmp and then perform all subsequent reads and writes on the file copied to /tmp. Finally, after the copied file is closed, the Move function can be used to overwrite the original file, thus avoiding the aforementioned data inconsistency. This algorithm is implemented by the NANDSimpleSafeOpen, NANDSimpleSafeOpenAsync, NANDSimpleSafeClose and NANDSimpleSafeCloseAsync functions. The safe sample demo is provided to demonstrate the atomic nature of updating files using these functions.

NAND API Functions to Update the FAT in Wii Console NAND Memory

The following functions in the NAND API update the FAT in Wii console NAND memory. For details, see the manual page for each function.

About the NANDSimpleSafe Functions

The NANDSimpleSafe-type functions have been prepared to resolve problems with the NANDSafe-type functions (there was no way to recover if a function call terminated in an error). If a NANDSimpleSafe function exits with an error, call NANDSimpleSafeCancel[Async]. These functions will try to release resources used by NANDSimpleSafe-type functions.

Although the NANDSimpleSafeOpen[Async] and NANDSimpleSafeClose[Async] functions guarantee the atomicity of file updates, to achieve it they incur a higher cost than the ordinary NANDOpen[Async] and NANDClose[Async] functions. When using these functions, note the following points.

Disadvantages of NANDSafe Functions

(Use of NANDSafe-related functions is not recommended. Instead, consider using the new NANDSimpleSafe-type functions.)

Although the NANDSimpleSafeOpen[Async] and NANDSimpleSafeClose[Async] functions guarantee the atomicity of file updates, to achieve it they incur a higher cost than the ordinary NANDOpen[Async] and NANDClose[Async] functions. When using these functions, note the following points.

Allowable Characters in File and Directory Names

The characters that can be used in file and directory names are limited to the alphanumeric characters [0-9a-zA-Z] and a few symbols [-_.].

Buffer Alignment

The buffers used for reading and writing data and the buffers used for getting directory lists must be 32-byte aligned. Furthermore, the buffer for data read/directory list retrieval must be a multiple of 32 bytes.

Performance is slightly enhanced by using 64-byte alignment for the buffer used to read/write data.

File/Directory Properties

You can set properties for files/directories. However, as of 2006/06/16, no decision has been made regarding what type of properties to provide. Although arguments for specifying attributes are included with functions that create files/directories and functions that change properties, at present, do not specify any value other than zero for these arguments.

Prohibition on Frequent Read Access

As a characteristic of NAND flash devices, if read access is repeated frequently several hundred thousand times or more on a given region without performing an erase or write operation, data may become corrupted in the periphery of that region.If it is necessary to read data saved in Wii console NAND memory repeatedly, first load a sizeable chunk of data in MEM1 or MEM2, and then read data from MEM1 or MEM2 to reduce the number of read access operations on Wii console NAND memory.
For example, the following types of Read access are prohibited.

Wear on Wii Console NAND Memory

Write operations will wear out Wii console NAND memory, so please avoid frequent writing. (Use as virtual memory is prohibited.) When performing auto-save, please limit its average frequency to less than once per minute. When saves are automatically performed using NANDSimpleSafe-related functions, the process of opening and closing files causes the FAT to be updated four times. Therefore, to avoid wear and tear on the FAT, you need to increase the interval between automatic saves (to less than once every four minutes on average). Limitations become even more severe when performing automatic saves using NANDSafe-related functions (which are not recommended). Because NANDSafe-related functions perform six FAT updates during the process of opening and closing a file, you need to increase the interval between automatic saves even more (to less than once every six minutes on average) to avoid wear and tear on the FAT.

Fluctuations in Access Time

Due to the characteristics of the NAND flash device, the time required to access data may vary even though the amount of data being read/written is the same. For this reason, do not write game programs that depend on access time.

Reset/Shutdown Processes

We recommend not calling the reset/shutdown functions until all Wii console NAND memory operations issued by the application program are completed.
The reset/shutdown functions will execute without waiting for the NAND functions issued by the application to end. The file system managing Wii console NAND memory will guarantee the integrity of the entire file system against accidents such as power outages which may occur at any time, but will not guarantee integrity of the data that was in the middle of a write operation. Also refer to Reset Function/Shutdown Function regarding reset/shutdown operations.

Regarding Data Tampering

The file system managing Wii console NAND memory is strong by design against data tampering or prying. In general, there is no need to implement any tampering protection for save data saved to Wii console NAND memory from the application side. However, security is not guaranteed for the future, so data tampering processing can also be implemented by the application in order to ensure better security.

Periodic Access from the System

Starting with SDK 2.1 patch 1 (2006/08/30), the system now periodically accesses Wii console NAND memory. There will be a file write once per minute, and a file open/close once every five minutes (FAT will also be updated at the close). For this reason, a single file descriptor will always be consumed. Also, when the timing of an access by the system and an access by the application happen to overlap, it may take longer than normal for the process to complete.

Limitations on Use

The following restrictions apply regarding the use of Wii console NAND memory. Note that the files and/or directories created under /tmp/sys will also be subject to these restrictions. If the application is updating a 1MB save file using NANDSafe-type functions, the upper limit on the capacity of files that can be freely created in /tmp by the application will decrease to 39MB.
Coverage Upper Limit
Maximum capacity of files that can be created in the home directory 16 MB
Number of files/directories that can be created in the home directory 32
Maximum capacity of files that can be created in /tmp 40 MB
Number of files/directories that can be created in /tmp 64

Revision History

2008/09/26 Added an explanation about WiiWare title-id(Hi).
2008/08/28 Revised the descriptions of title-id(Hi) and title-id(Low).
2008/08/01 Revised the functions in the NAND API for updating the FAT in Wii console NAND memory. Revised the description regarding data tampering.
2008/07/29 Added text about result codes.
2008/05/16 Deleted explanations for the CARD library.
2008/05/13 Added NAND API functions to update the FAT in Wii console NAND memory.
2008/05/13 Added explanations for title-id(Hi) and title-id(Low).
2007/05/ E Added guidelines for handling result codes.
2007/05/ M Added a simple explanation concerning group permissions.
2007/05/ M Added a note about the frequency of NANDSimpleSafe-type function calls.
2007/05/09 Added a note stating that callback functions are not invoked when an asynchronous function call exits with an error.
2007/05/09 Added descriptions for NANDSimpleSafe-type functions. Added a note recommending against the use of NANDSafe-type functions.
2007/02/xx Added the NAND_RESULT_MAXDEPTH result code.
2007/02/xx Added a supplementary note about the NAND_RESULT_OPENFD result code.
2006/12/18 Added a description of the prohibition on frequent Read access.
2006/11/30 Added text about result codes.
2006/11/30 Added text noting that many synchronous functions can return NAND_RESULT_ALLOC_FAILED and NAND_RESULT_BUSY.
2006/11/30 Deleted text about NANDGetAvailableArea[Async] as an alternative to NANDCheck[Async].
2006/11/10 Added supplemental information about banner files and NANDCheck[Async].
2006/10/25 Added an explanation of NANDGetAvailableArea[Async].
2006/10/25 Standardized the terminology.
2006/10/25 Added information regarding periodic access from the system.
2006/09/28 Explained the implementation details regarding NANDSafe-type functions. Clarified the limitations on use.
2006/09/25 Specified the home directory location.
2006/09/19 Added details regarding the result codes that the NANDSafeOpenAsync and NANDSafeCloseAsync function callbacks may receive.
2006/09/19 Added information about banner files.
2006/08/30 Added a note that NANDInit is now automatically called by the system.
2006/08/30 Added information regarding NANDCheck.
2006/08/30 Fixed spelling errors in the result code.
2006/08/15 Revised the table of limitations on use.
2006/08/15 Added a description of the NANDSafe-type functions.
2006/08/15 Described the maximum allowable depth of the directory hierarchy.
2006/08/15 Deleted the NAND_RESULT_INIT_FAILED result code.
2006/08/15 Added description of characters allowed in file/directory names.
2006/08/15 Revised the description of /tmp/sys.
2006/08/15 Revised description of maximum path length.
2006/08/15 Added precautions regarding writing data.
2006/08/15 Added a description of the NAND_RESULT_AUTHENTICATION result code.
2006/06/16 Initial version.


CONFIDENTIAL