libdragon
Files | Data Structures | Macros | Typedefs | Functions | Variables
newlib Interface Hooks

System hooks to provide low level threading and filesystem functionality to newlib. 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
 

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...
 

Macros

#define STACK_SIZE   0x10000
 Stack size. More...
 
#define DEBUG_OUT(x)   ((uint32_t *)0xA4400044)[0] = ((uint32_t)(x))
 Write to the MESS debug register. More...
 
#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 __register_frame_info (void *begin, uint32_t *ob)
 Register exception frames This is used as a placeholder if the user does not link in libgcc.
 
void __do_global_ctors ()
 Execute global constructors "Constructors are called in reverse order of the list". More...
 
void __wrap___do_global_ctors ()
 Execute global constructors This version is used by the new build system (n64.mk) via the –wrap linker flag. When that is provided, this version will be utilized instead. New build system always links with g++ which is not directly compatible with ld when it comes to constructors and enables that flag by default.
 
void enable_interrupts ()
 Enable interrupts systemwide. More...
 
void disable_interrupts ()
 Disable interrupts systemwide. More...
 
int close (int fildes)
 Close a file. More...
 
int attach_filesystem (const char *const prefix, filesystem_t *filesystem)
 Register a filesystem with newlib. More...
 
int detach_filesystem (const char *const prefix)
 Unregister a filesystem from newlib. More...
 
int chown (const char *path, uid_t owner, gid_t group)
 Change ownership on a file or directory. More...
 
int execve (char *name, char **argv, char **env)
 Load and execute an executable given a path. More...
 
void _exit (int rc)
 End execution on current thread. More...
 
int fork (void)
 Fork execution into two threads. More...
 
int fstat (int fildes, struct stat *st)
 Return stats on an open file handle. More...
 
int getpid (void)
 Return the PID of the current thread. More...
 
int gettimeofday (struct timeval *ptimeval, void *ptimezone)
 Return the current time. More...
 
int isatty (int file)
 Return whether a file is a TTY or a regular file. More...
 
int kill (int pid, int sig)
 Send a signal to a PID. More...
 
int link (char *existing, char *new)
 Link a new file to an existing file. More...
 
int lseek (int file, int ptr, int dir)
 Seek to a location in a file. More...
 
int open (const char *file, int flags,...)
 Open a file given a path. More...
 
int read (int file, char *ptr, int len)
 Read data from a file. More...
 
int readlink (const char *path, char *buf, size_t bufsize)
 Read a link. More...
 
void * sbrk (int incr)
 Return a new chunk of memory to be used as heap. More...
 
int stat (const char *file, struct stat *st)
 Return file stats based on a file name. More...
 
int symlink (const char *path1, const char *path2)
 Create a symbolic link to a file. More...
 
clock_t times (struct tms *buf)
 Return time information on the current process. More...
 
int unlink (char *name)
 Remove a file based on filename. More...
 
int wait (int *status)
 Wait for a child process. More...
 
int write (int file, char *ptr, int len)
 Write data to a file. More...
 
int dir_findfirst (const char *const path, dir_t *dir)
 Find the first file in a directory. More...
 
int dir_findnext (const char *const path, dir_t *dir)
 Find the next file in a directory. More...
 
int hook_stdio_calls (stdio_t *stdio_calls)
 Hook into stdio for STDIN, STDOUT and STDERR callbacks. More...
 
int unhook_stdio_calls (stdio_t *stdio_calls)
 Unhook from stdio. More...
 
int hook_time_call (time_t(*time_fn)(void))
 Hook into gettimeofday with a current time callback. More...
 
int unhook_time_call (time_t(*time_fn)(void))
 Unhook from gettimeofday current time callback. More...
 
void _flush_cache (uint8_t *addr, unsigned long bytes)
 Implement _flush_cache as required by GCC for nested functions. More...
 
void __assert_func (const char *file, int line, const char *func, const char *failedexpr)
 Implement underlying function for assert() More...
 

Variables

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 __EH_FRAME_BEGIN__ []
 Pointer to the beginning of exception frames.
 
char * __env [1] = { 0 }
 Environment variables.
 
void(* __assert_func_ptr )(const char *file, int line, const char *func, const char *failedexpr)=0
 Assert function pointer (initialized at startup)
 
int __bootcic
 Boot CIC. More...
 
time_t(* time_hook )(void) = NULL
 Function to provide the current time.
 

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.
 

Detailed Description

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.


Data Structure Documentation

◆ fs_mapping_t

struct fs_mapping_t

Filesystem mapping structure.

This is used to look up what filesystem to use when passed a generic path.

Data Fields
char * prefix Filesystem prefix.

This controls what filesystem prefix should link to this filesystem (eg. 'rom:/' or 'cf:/')

filesystem_t * fs Filesystem callback pointers.

◆ fs_handle_t

struct fs_handle_t

Filesystem open handle structure.

This is used to look up the correct filesystem function to call when working with an open file handle

Data Fields
int fs_mapping Index into filesystems array.
void * handle The handle assigned to this open file as returned by the filesystem code called to handle the open operation. Will be passed to all subsequent file operations on the file.
int fileno The handle assigned by the filesystem code that will be returned to newlib. All subsequent newlib calls will use this handle which will be used to look up the internal reference.

◆ dir_t

struct dir_t

Directory entry structure.

Data Fields
char d_name[256] The name of the directory entry.
int d_type The type of the directory entry. See DT_REG and DT_DIR.

Macro Definition Documentation

◆ STACK_SIZE

#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.

◆ DEBUG_OUT

#define DEBUG_OUT (   x)    ((uint32_t *)0xA4400044)[0] = ((uint32_t)(x))

Write to the MESS debug register.

Parameters
[in]x32-bit value to write to the MESS debug register

Function Documentation

◆ __do_global_ctors()

void __do_global_ctors ( )

Execute global constructors "Constructors are called in reverse order of the list".

See also
https://gcc.gnu.org/onlinedocs/gccint/Initialization.html

This version of the function is kept for compatibility for projects not using the build system but linking directly with ld in a legacy setup. For the modern version see __wrap___do_global_ctors which is activated by the new build system (n64.mk) via –wrap linker flag. Do not use that flag if you are using ld so that this function is used instead.

◆ enable_interrupts()

void enable_interrupts ( )

Enable interrupts systemwide.

Note
If this is called inside a nested disable call, it will have no effect on the system. Therefore it is safe to nest disable/enable calls. After the least nested enable call, systemwide interrupts will be reenabled.

◆ disable_interrupts()

void disable_interrupts ( )

Disable interrupts systemwide.

Note
If interrupts are already disabled on the system or interrupts have not been initialized, this function will not modify the system state.

◆ close()

int close ( int  fildes)

Close a file.

Parameters
[in]fildesFile handle of the file to close
Returns
0 on success or a negative value on error.

◆ attach_filesystem()

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.

Parameters
[in]prefixPrefix of the filesystem
[in]filesystemStructure of callbacks for various functions in the filesystem. If the registered filesystem doesn't support an operation, it should leave the callback null.
Return values
-1if the parameters are invalid
-2if the prefix is already in use
-3if there are no more slots for filesystems
0if the filesystem was registered successfully

◆ detach_filesystem()

int detach_filesystem ( const char *const  prefix)

Unregister a filesystem from newlib.

Note
This function will make sure all files are closed before unregistering the filesystem.
Parameters
[in]prefixThe prefix that was used to register the filesystem
Return values
-1if the parameters were invalid
-2if the filesystem couldn't be found
0if the filesystem was successfully unregistered

◆ chown()

int chown ( const char *  path,
uid_t  owner,
gid_t  group 
)

Change ownership on a file or directory.

Note
Not supported in libdragon
Parameters
[in]pathPath of the file or directory to operate on
[in]ownerNew owner of the file
[in]groupNew group of the file
Returns
0 on success or a negative value on error.

◆ execve()

int execve ( char *  name,
char **  argv,
char **  env 
)

Load and execute an executable given a path.

Note
Not supported in libdragon
Parameters
[in]nameFilename of the executable
[in]argvArray of pointers to arguments
[in]envArray of pointers to environment variables
Returns
0 on success or a negative value on error.

◆ _exit()

void _exit ( int  rc)

End execution on current thread.

Note
This function does not exit. If this is the last thread, the system will hang.
Parameters
[in]rcReturn value of the exiting program

◆ fork()

int fork ( void  )

Fork execution into two threads.

Note
Not supported in libdragon.
Returns
PID of child process if parent, 0 if child, negative value on failure.

◆ fstat()

int fstat ( int  fildes,
struct stat st 
)

Return stats on an open file handle.

Parameters
[in]fildesFile handle
[out]stPointer to stat struct to be filled
Returns
0 on success or a negative value on error.

◆ getpid()

int getpid ( void  )

Return the PID of the current thread.

Note
Not supported in libdragon.
Returns
The PID on success or a negative value on error.

◆ gettimeofday()

int gettimeofday ( struct timeval *  ptimeval,
void *  ptimezone 
)

Return the current time.

Parameters
[out]ptimevalTime structure to be filled with current time.
[out]ptimezoneTimezone information to be filled. (Not supported)
Returns
0 on success or a negative value on error.

◆ isatty()

int isatty ( int  file)

Return whether a file is a TTY or a regular file.

Parameters
[in]fileFile handle
Returns
1 if the file is a TTY, or 0 if not.

◆ kill()

int kill ( int  pid,
int  sig 
)

Send a signal to a PID.

Note
Not supported in libdragon.
Parameters
[in]pidThe PID of the process
[in]sigThe signal to send
Returns
0 on success or a negative value on error.

◆ link()

int link ( char *  existing,
char *  new 
)

Link a new file to an existing file.

Note
Not supported in libdragon.
Parameters
[in]existingThe path of the existing file
[in]newThe path of the new file
Returns
0 on success or a negative value on error.

◆ lseek()

int lseek ( int  file,
int  ptr,
int  dir 
)

Seek to a location in a file.

Parameters
[in]fileThe file handle of the file to seek
[in]ptrThe offset in bytes to seek to, given the direction in dir
[in]dirThe 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.
Returns
The new location of the file in bytes or -1 on error.

◆ open()

int open ( const char *  file,
int  flags,
  ... 
)

Open a file given a path.

Parameters
[in]fileFile name of the file to open
[in]flagsFlags specifying open flags, such as binary, append.
[in]...mode Mode of the file (currently ignored).
Returns
File handle to refer to this file on success, or a negative value on error.

◆ read()

int read ( int  file,
char *  ptr,
int  len 
)

Read data from a file.

Parameters
[in]fileFile handle
[out]ptrData pointer to read data to
[in]lenLength in bytes of data to read
Returns
Actual number of bytes read or a negative value on error.

◆ readlink()

int readlink ( const char *  path,
char *  buf,
size_t  bufsize 
)

Read a link.

Note
Not supported in libdragon.
Parameters
[in]pathPath of the link
[in]bufBuffer to read the link into
[in]bufsizeSize of the buffer
Returns
0 on success or a negative value on error.

◆ sbrk()

void * sbrk ( int  incr)

Return a new chunk of memory to be used as heap.

Parameters
[in]incrThe amount of memory needed in bytes
Returns
A pointer to the memory or ((void*)-1) on error allocating.

◆ stat()

int stat ( const char *  file,
struct stat *  st 
)

Return file stats based on a file name.

Parameters
[in]fileFile name of the file in question
[out]stStat struct to populate with information from the file
Returns
0 on success or a negative value on error.

◆ symlink()

int symlink ( const char *  path1,
const char *  path2 
)

Create a symbolic link to a file.

Note
Not supported in libdragon.
Parameters
[in]path1Path to symlink to
[in]path2Path to symlink from
Returns
0 on success or a negative value on error.

◆ times()

clock_t times ( struct tms *  buf)

Return time information on the current process.

Note
Not supported in libdragon.
Parameters
[out]bufBuffer to place timing information
Returns
Timing information or a negative value on error.

◆ unlink()

int unlink ( char *  name)

Remove a file based on filename.

Parameters
[in]nameName of the file to remove
Returns
0 on success or a negative value on error.

◆ wait()

int wait ( int *  status)

Wait for a child process.

Note
Not supported in libdragon.
Parameters
[out]statusStatus of the wait operation
Returns
0 on success or a negative value on error.

◆ write()

int write ( int  file,
char *  ptr,
int  len 
)

Write data to a file.

Parameters
[in]fileFile handle
[in]ptrPointer to buffer to write to file
[in]lenLength of data in bytes to be written
Returns
The actual number of bytes written, or a negative value on error.

◆ dir_findfirst()

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.

Parameters
[in]pathPath to the directory structure
[out]dirDirectory entry structure to populate with first entry
Returns
0 on successful lookup or a negative value on error.

◆ dir_findnext()

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.

Parameters
[in]pathPath to the directory structure
[out]dirDirectory entry structure to populate with next entry
Returns
0 on successful lookup or a negative value on error.

◆ hook_stdio_calls()

int hook_stdio_calls ( stdio_t stdio_calls)

Hook into stdio for STDIN, STDOUT and STDERR callbacks.

Parameters
[in]stdio_callsPointer to structure containing callbacks for stdio functions
Returns
0 on successful hook or a negative value on failure.

◆ unhook_stdio_calls()

int unhook_stdio_calls ( stdio_t stdio_calls)

Unhook from stdio.

Parameters
[in]stdio_callsPointer to structure containing callbacks for stdio functions
Returns
0 on successful hook or a negative value on failure.

◆ hook_time_call()

int hook_time_call ( time_t(*)(void)  time_fn)

Hook into gettimeofday with a current time callback.

Parameters
[in]time_fnPointer to callback for the current time function
Returns
0 if successful or a negative value on failure.

◆ unhook_time_call()

int unhook_time_call ( time_t(*)(void)  time_fn)

Unhook from gettimeofday current time callback.

Parameters
[in]time_fnPointer to callback for the current time function
Returns
0 if successful or a negative value on failure.

◆ _flush_cache()

void _flush_cache ( uint8_t *  addr,
unsigned long  bytes 
)

Implement _flush_cache as required by GCC for nested functions.

When using the nested function extensions of GCC, a call to _flush_cache is generated which must be supplied by the operating system or runtime to allow flushing the instruction cache for the generated trampoline.

◆ __assert_func()

void __assert_func ( const char *  file,
int  line,
const char *  func,
const char *  failedexpr 
)

Implement underlying function for assert()

Implementation of the function called when an assert fails. By default, we just abort execution, but this will be overriden at startup with a function that prints the assertion on the screen and via the debug channel (if initialized).

Variable Documentation

◆ __bootcic

int __bootcic
extern

Boot CIC.

Defaults to 6102.