libdragon
|
System hooks to provide low level threading and filesystem functionality to newlib. More...
Data Structures | |
struct | fs_mapping_t |
Filesystem mapping structure. More... | |
struct | fs_handle_t |
Filesystem open handle structure. More... | |
struct | dir_t |
Directory entry structure. More... | |
struct | filesystem_t |
Filesystem hook structure. More... | |
struct | stdio_t |
Standard I/O hook structure. More... | |
Files | |
file | do_ctors.c |
C++ constructor handling. | |
file | system.c |
newlib Interface Hooks | |
file | dir.h |
Directory handling. | |
file | system.h |
newlib Interface Hooks | |
Defines | |
#define | STACK_SIZE 0x10000 |
Stack size. | |
#define | DEBUG_OUT(x) ((uint32_t *)0xA4400044)[0] = ((uint32_t)(x)) |
Write to the MESS debug register. | |
#define | MAX_FILESYSTEMS 10 |
Number of filesystems that can be attached to the system. | |
#define | MAX_OPEN_HANDLES 100 |
Number of open handles that can be maintained at one time. | |
Typedefs | |
typedef void(* | func_ptr )(void) |
Function pointer. | |
Functions | |
void | __do_global_ctors () |
Execute global constructors. | |
void | enable_interrupts () |
Enable interrupts systemwide. | |
void | disable_interrupts () |
Disable interrupts systemwide. | |
int | close (int fildes) |
Close a file. | |
static int | __strlen (const char *const str) |
Simple implementation of strlen. | |
static void | __memcpy (char *const a, const char *const b, int len) |
Simple implementation of memcpy. | |
static char * | __strdup (const char *const in) |
Simple implementation of strdup. | |
static int | __strncmp (const char *const a, const char *const b, int len) |
Simple iplementation of strncmp. | |
static int | __strcmp (const char *const a, const char *const b) |
Simple implementation of strcmp. | |
static int | __get_new_handle () |
Return a unique filesystem handle. | |
int | attach_filesystem (const char *const prefix, filesystem_t *filesystem) |
Register a filesystem with newlib. | |
int | detach_filesystem (const char *const prefix) |
Unregister a filesystem from newlib. | |
static filesystem_t * | __get_fs_pointer_by_handle (int fileno) |
Get a filesystem pointer by handle. | |
static int | __get_fs_link_by_name (const char *const name) |
Get the index of the registered filesystem based on fully qualified filename. | |
static filesystem_t * | __get_fs_pointer_by_name (const char *const name) |
Get the filesystem callback structure based on a fully qualified filename. | |
static void * | __get_fs_handle (int fileno) |
Look up the internal handle of a file given a file handle. | |
int | chown (const char *path, uid_t owner, gid_t group) |
Change ownership on a file or directory. | |
int | execve (char *name, char **argv, char **env) |
Load and execute an executable given a path. | |
void | exit (int rc) |
End execution on current thread. | |
int | fork (void) |
Fork execution into two threads. | |
int | fstat (int fildes, struct stat *st) |
Return stats on an open file handle. | |
int | getpid (void) |
Return the PID of the current thread. | |
int | gettimeofday (struct timeval *ptimeval, void *ptimezone) |
Return the current time. | |
int | isatty (int file) |
Return whether a file is a TTY or a regular file. | |
int | kill (int pid, int sig) |
Send a signal to a PID. | |
int | link (char *existing, char *new) |
Link a new file to an existing file. | |
int | lseek (int file, int ptr, int dir) |
Seek to a location in a file. | |
int | open (char *file, int flags, int mode) |
Open a file given a path. | |
int | read (int file, char *ptr, int len) |
Read data from a file. | |
int | readlink (const char *path, char *buf, size_t bufsize) |
Read a link. | |
void * | sbrk (int incr) |
Return a new chunk of memory to be used as heap. | |
int | stat (const char *file, struct stat *st) |
Return file stats based on a file name. | |
int | symlink (const char *path1, const char *path2) |
Create a symbolic link to a file. | |
clock_t | times (struct tms *buf) |
Return time information on the current process. | |
int | unlink (char *name) |
Remove a file based on filename. | |
int | wait (int *status) |
Wait for a child process. | |
int | write (int file, char *ptr, int len) |
Write data to a file. | |
int | dir_findfirst (const char *const path, dir_t *dir) |
Find the first file in a directory. | |
int | dir_findnext (const char *const path, dir_t *dir) |
Find the next file in a directory. | |
int | hook_stdio_calls (stdio_t *stdio_calls) |
Hook into stdio for STDIN, STDOUT and STDERR callbacks. | |
int | unhook_stdio_calls () |
Unhook from stdio. | |
Variables | |
uint32_t | __CTOR_LIST_SIZE__ |
Pointer to the size of the constructor list. | |
func_ptr | __CTOR_LIST__ [] |
Pointer to the beginning of the constructor list. | |
func_ptr | __CTOR_END__ [] |
Pointer to the end of the constructor list. | |
char * | __env [1] = { 0 } |
Environment variables. | |
char ** | environ = __env |
Environment variables. | |
int | errno |
Master definition of errno. | |
int | __bootcic |
Boot CIC. | |
static fs_mapping_t | filesystems [MAX_FILESYSTEMS] = { { 0 } } |
Array of filesystems registered. | |
static fs_handle_t | handles [MAX_OPEN_HANDLES] = { { 0 } } |
Array of open handles tracked. | |
static stdio_t | stdio_hooks = { 0 } |
Current stdio hook structure. | |
STDIN/STDOUT/STDERR definitions from unistd.h | |
We can't just include unistd.h as it redefines several of the functions here that we are attempting to replace. | |
#define | STDIN_FILENO 0 |
Standard input file descriptor. | |
#define | STDOUT_FILENO 1 |
Standard output file descriptor. | |
#define | STDERR_FILENO 2 |
Standard error file descriptor. | |
Directory entry type definitions | |
#define | DT_REG 1 |
Regular file. | |
#define | DT_DIR 2 |
Directory. |
System hooks to provide low level threading and filesystem functionality to newlib.
newlib provides all of the standard C libraries for homebrew development. In addition to standard C libraries, newlib provides some additional bridging functionality to allow POSIX function calls to be tied into libdragon. Currently this is used only for filesystems. The newlib interface hooks here are mostly stubs that allow homebrew applications to compile.
The sbrk function is responsible for allowing newlib to find the next chunk of free space for use with malloc calls. This is made somewhat complicated on the N64 by the fact that precompiled code doesn't know in advance if expanded memory is available. libdragon attempts to determine if this additional memory is available and return accordingly but can only do so if it knows what type of CIC/bootcode was used. If you are using a 6102, this has been set for you already. If you are using a 6105 for some reason, you will need to use sys_set_boot_cic to notify libdragon or malloc will not work properly!
libdragon has defined a custom callback structure for filesystems to use. Providing relevant hooks for calls that your filesystem supports and passing the resulting structure to attach_filesystem will hook your filesystem into newlib. Calls to POSIX file operations will be passed on to your filesystem code if the file prefix matches, allowing code to make use of your filesystyem without being rewritten.
For example, your filesystem provides libdragon an interface to access a homebrew SD card interface. You register a filesystem with "sd:/" as the prefix and then attempt to open "sd://directory/file.txt". The open callback for your filesystem will be passed the file "/directory/file.txt". The file handle returned will be passed into all subsequent calls to your filesystem until the file is closed.
#define DEBUG_OUT | ( | x | ) | ((uint32_t *)0xA4400044)[0] = ((uint32_t)(x)) |
Write to the MESS debug register.
[in] | x | 32-bit value to write to the MESS debug register |
#define STACK_SIZE 0x10000 |
Stack size.
This is the maximum stack size for the purpose of malloc. Any malloc call that tries to allocate data will not allocate within this range. However, there is no guarantee that user code won't blow the stack and cause heap corruption. Use this as loose protection at best.
static void* __get_fs_handle | ( | int | fileno | ) | [static] |
Look up the internal handle of a file given a file handle.
[in] | fileno | File handle |
static int __get_fs_link_by_name | ( | const char *const | name | ) | [static] |
Get the index of the registered filesystem based on fully qualified filename.
[in] | name | The filename of the file being opened including the prefix |
static filesystem_t* __get_fs_pointer_by_handle | ( | int | fileno | ) | [static] |
Get a filesystem pointer by handle.
Given a file handle, return the filesystem callback structure.
[in] | fileno | File handle |
static filesystem_t* __get_fs_pointer_by_name | ( | const char *const | name | ) | [static] |
Get the filesystem callback structure based on a fully qualified filename.
[in] | name | The filename of the file being opened including the prefix |
static int __get_new_handle | ( | ) | [static] |
Return a unique filesystem handle.
static void __memcpy | ( | char *const | a, |
const char *const | b, | ||
int | len | ||
) | [static] |
Simple implementation of memcpy.
[out] | a | Destination pointer to copy to |
[in] | b | Source pointer to copy from |
[in] | len | Length in bytes to copy |
static int __strcmp | ( | const char *const | a, |
const char *const | b | ||
) | [static] |
Simple implementation of strcmp.
[in] | a | First string to compare against |
[in] | b | Second string to compare against |
static char* __strdup | ( | const char *const | in | ) | [static] |
Simple implementation of strdup.
[in] | in | String to duplicate |
static int __strlen | ( | const char *const | str | ) | [static] |
Simple implementation of strlen.
[in] | str | Pointer to null-terminated string |
static int __strncmp | ( | const char *const | a, |
const char *const | b, | ||
int | len | ||
) | [static] |
Simple iplementation of strncmp.
[in] | a | First string to compare against |
[in] | b | Second string to compare against |
[in] | len | Number of relevant characters. Specify -1 for infinite |
int attach_filesystem | ( | const char *const | prefix, |
filesystem_t * | filesystem | ||
) |
Register a filesystem with newlib.
This function will take a prefix in the form of 'prefix:/' and a pointer to a filesystem structure of relevant callbacks and register it with newlib. Any standard open/fopen calls with the registered prefix will be passed to this filesystem. Userspace code does not need to know the underlying filesystem, only the prefix that it has been registered under.
The filesystem pointer passed in to this function should not go out of scope for the lifetime of the filesystem.
[in] | prefix | Prefix of the filesystem |
[in] | filesystem | Structure of callbacks for various functions in the filesystem. If the registered filesystem doesn't support an operation, it should leave the callback null. |
-1 | if the parameters are invalid |
-2 | if the prefix is already in use |
-3 | if there are no more slots for filesystems |
0 | if the filesystem was registered successfully |
int chown | ( | const char * | path, |
uid_t | owner, | ||
gid_t | group | ||
) |
Change ownership on a file or directory.
[in] | path | Path of the file or directory to operate on |
[in] | owner | New owner of the file |
[in] | group | New group of the file |
int close | ( | int | fildes | ) |
Close a file.
[in] | fildes | File handle of the file to close |
int detach_filesystem | ( | const char *const | prefix | ) |
Unregister a filesystem from newlib.
[in] | prefix | The prefix that was used to register the filesystem |
-1 | if the parameters were invalid |
-2 | if the filesystem couldn't be found |
0 | if the filesystem was successfully unregistered |
int dir_findfirst | ( | const char *const | path, |
dir_t * | dir | ||
) |
Find the first file in a directory.
This function should be called to start enumerating a directory or whenever a directory enumeration should be restarted.
[in] | path | Path to the directory structure |
[out] | dir | Directory entry structure to populate with first entry |
int dir_findnext | ( | const char *const | path, |
dir_t * | dir | ||
) |
Find the next file in a directory.
After finding the first file in a directory using dir_findfirst, call this to retrieve the rest of the directory entries. Call this repeatedly until a negative error is returned signifying that there are no more directory entries in the directory.
[in] | path | Path to the directory structure |
[out] | dir | Directory entry structure to populate with next entry |
void disable_interrupts | ( | ) |
Disable interrupts systemwide.
void enable_interrupts | ( | ) |
Enable interrupts systemwide.
int execve | ( | char * | name, |
char ** | argv, | ||
char ** | env | ||
) |
Load and execute an executable given a path.
[in] | name | Filename of the executable |
[in] | argv | Array of pointers to arguments |
[in] | env | Array of pointers to environment variables |
void exit | ( | int | rc | ) |
End execution on current thread.
[in] | rc | Return value of the exiting program |
int fork | ( | void | ) |
Fork execution into two threads.
Return stats on an open file handle.
[in] | fildes | File handle |
[out] | st | Pointer to stat struct to be filled |
int getpid | ( | void | ) |
Return the PID of the current thread.
int gettimeofday | ( | struct timeval * | ptimeval, |
void * | ptimezone | ||
) |
Return the current time.
[out] | ptimeval | Time structure to be filled with current time. |
[out] | ptimezone | Timezone information to be filled. |
int hook_stdio_calls | ( | stdio_t * | stdio_calls | ) |
Hook into stdio for STDIN, STDOUT and STDERR callbacks.
[in] | stdio_calls | Pointer to structure containing callbacks for stdio functions |
int isatty | ( | int | file | ) |
Return whether a file is a TTY or a regular file.
[in] | file | File handle |
int kill | ( | int | pid, |
int | sig | ||
) |
Send a signal to a PID.
[in] | pid | The PID of the process |
[in] | sig | The signal to send |
int link | ( | char * | existing, |
char * | new | ||
) |
Link a new file to an existing file.
[in] | existing | The path of the existing file |
[in] | new | The path of the new file |
int lseek | ( | int | file, |
int | ptr, | ||
int | dir | ||
) |
Seek to a location in a file.
[in] | file | The file handle of the file to seek |
[in] | ptr | The offset in bytes to seek to, given the direction in dir |
[in] | dir | The direction to seek. Use SEEK_SET to start from the beginning. Use SEEK_CUR to seek based on the current offset. Use SEEK_END to seek starting at the end of the file. |
int open | ( | char * | file, |
int | flags, | ||
int | mode | ||
) |
Open a file given a path.
[in] | file | File name of the file to open |
[in] | flags | Flags specifying open flags, such as binary, append. |
[in] | mode | Mode of the file. |
int read | ( | int | file, |
char * | ptr, | ||
int | len | ||
) |
Read data from a file.
[in] | file | File handle |
[out] | ptr | Data pointer to read data to |
[in] | len | Length in bytes of data to read |
int readlink | ( | const char * | path, |
char * | buf, | ||
size_t | bufsize | ||
) |
Read a link.
[in] | path | Path of the link |
[in] | buf | Buffer to read the link into |
[in] | bufsize | Size of the buffer |
void* sbrk | ( | int | incr | ) |
Return a new chunk of memory to be used as heap.
[in] | incr | The amount of memory needed in bytes |
Return file stats based on a file name.
[in] | file | File name of the file in question |
[out] | st | Stat struct to populate with information from the file |
int symlink | ( | const char * | path1, |
const char * | path2 | ||
) |
Create a symbolic link to a file.
[in] | path1 | Path to symlink to |
[in] | path2 | Path to symlink from |
clock_t times | ( | struct tms * | buf | ) |
Return time information on the current process.
[out] | buf | Buffer to place timing information |
int unhook_stdio_calls | ( | ) |
Unhook from stdio.
int unlink | ( | char * | name | ) |
Remove a file based on filename.
[in] | name | Name of the file to remove |
int wait | ( | int * | status | ) |
Wait for a child process.
[out] | status | Status of the wait operation |
int write | ( | int | file, |
char * | ptr, | ||
int | len | ||
) |
Write data to a file.
[in] | file | File handle |
[in] | ptr | Pointer to buffer to write to file |
[in] | len | Length of data in bytes to be written |
int __bootcic |
Boot CIC.
Defaults to 6102.