public inbox for newlib@sourceware.org
 help / color / mirror / Atom feed
From: Dan Petrisko <petrisko@cs.washington.edu>
To: newlib@sourceware.org
Cc: Dan Petrisko <petrisko@cs.washington.edu>
Subject: [PATCH 1/2] Adding a LittleFS-based self-contained target to libgloss
Date: Thu, 10 Aug 2023 12:50:56 -0700	[thread overview]
Message-ID: <20230810195057.18266-2-petrisko@cs.washington.edu> (raw)
In-Reply-To: <20230810195057.18266-1-petrisko@cs.washington.edu>

Co-authored-by: Bandhav Veluri <bandhav.veluri00@gmail.com>
Co-authored-by: farzamgl <farzamgl@uw.edu>
Co-authored-by: taylor-bsg <taylor-bsg@users.noreply.github.com>
---
 .gitmodules                        |   0
 COPYING.LIBGLOSS                   |  27 +++++
 configure.ac                       |   3 +
 libgloss/dramfs/Makefile.in        | 230 +++++++++++++++++++++++++++++++++++++
 libgloss/dramfs/README.md          | 154 +++++++++++++++++++++++++
 libgloss/dramfs/sys_close.c        |  41 +++++++
 libgloss/dramfs/sys_execve.c       |  40 +++++++
 libgloss/dramfs/sys_exit.c         |  41 +++++++
 libgloss/dramfs/sys_fork.c         |  39 +++++++
 libgloss/dramfs/sys_fstat.c        |  48 ++++++++
 libgloss/dramfs/sys_getpid.c       |  36 ++++++
 libgloss/dramfs/sys_gettimeofday.c |  40 +++++++
 libgloss/dramfs/sys_isatty.c       |  36 ++++++
 libgloss/dramfs/sys_kill.c         |  40 +++++++
 libgloss/dramfs/sys_link.c         |  38 ++++++
 libgloss/dramfs/sys_lseek.c        |  44 +++++++
 libgloss/dramfs/sys_open.c         |  64 +++++++++++
 libgloss/dramfs/sys_read.c         |  67 +++++++++++
 libgloss/dramfs/sys_sbrk.c         |  49 ++++++++
 libgloss/dramfs/sys_stat.c         |  50 ++++++++
 libgloss/dramfs/sys_times.c        |  35 ++++++
 libgloss/dramfs/sys_unlink.c       |  39 +++++++
 libgloss/dramfs/sys_wait.c         |  39 +++++++
 libgloss/dramfs/sys_write.c        |  52 +++++++++
 24 files changed, 1252 insertions(+)
 create mode 100644 .gitmodules
 create mode 100644 libgloss/dramfs/Makefile.in
 create mode 100644 libgloss/dramfs/README.md
 create mode 100644 libgloss/dramfs/sys_close.c
 create mode 100644 libgloss/dramfs/sys_execve.c
 create mode 100644 libgloss/dramfs/sys_exit.c
 create mode 100644 libgloss/dramfs/sys_fork.c
 create mode 100644 libgloss/dramfs/sys_fstat.c
 create mode 100644 libgloss/dramfs/sys_getpid.c
 create mode 100644 libgloss/dramfs/sys_gettimeofday.c
 create mode 100644 libgloss/dramfs/sys_isatty.c
 create mode 100644 libgloss/dramfs/sys_kill.c
 create mode 100644 libgloss/dramfs/sys_link.c
 create mode 100644 libgloss/dramfs/sys_lseek.c
 create mode 100644 libgloss/dramfs/sys_open.c
 create mode 100644 libgloss/dramfs/sys_read.c
 create mode 100644 libgloss/dramfs/sys_sbrk.c
 create mode 100644 libgloss/dramfs/sys_stat.c
 create mode 100644 libgloss/dramfs/sys_times.c
 create mode 100644 libgloss/dramfs/sys_unlink.c
 create mode 100644 libgloss/dramfs/sys_wait.c
 create mode 100644 libgloss/dramfs/sys_write.c

diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 000000000..e69de29bb
diff --git a/COPYING.LIBGLOSS b/COPYING.LIBGLOSS
index c7a4c2924..0b30092a2 100644
--- a/COPYING.LIBGLOSS
+++ b/COPYING.LIBGLOSS
@@ -425,3 +425,30 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
 
+(21) - University of Washington (*-*-*-dramfs targets)
+
+Copyright (c) 2023, University of Washington
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of the University of Washington nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/configure.ac b/configure.ac
index cf856e567..a9c40d1bc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -919,6 +919,9 @@ fi
 libgloss_dir="$target_cpu"
 
 case "${target}" in
+  *-*-*-dramfs)
+    libgloss_dir=dramfs
+    ;;
   sh*-*-pe|mips*-*-pe|*arm-wince-pe)
     libgloss_dir=wince
     ;;
diff --git a/libgloss/dramfs/Makefile.in b/libgloss/dramfs/Makefile.in
new file mode 100644
index 000000000..4d3d5013e
--- /dev/null
+++ b/libgloss/dramfs/Makefile.in
@@ -0,0 +1,230 @@
+#-------------------------------------------------------------------------
+# Source files
+#-------------------------------------------------------------------------
+gloss_srcs = \
+	sys_close.c \
+	sys_execve.c \
+	sys_exit.c \
+	sys_fork.c \
+	sys_fstat.c \
+	sys_getpid.c \
+	sys_gettimeofday.c \
+	sys_isatty.c \
+	sys_kill.c \
+	sys_link.c \
+	sys_lseek.c \
+	sys_open.c \
+	sys_read.c \
+	sys_sbrk.c \
+	sys_stat.c \
+	sys_times.c \
+	sys_unlink.c \
+	sys_wait.c \
+	sys_write.c
+
+# Extra files
+
+crt0_asm      = crt0.S
+
+# Multilib support variables.
+# TOP is used instead of MULTI{BUILD,SRC}TOP.
+
+MULTIDIRS =
+MULTISUBDIR =
+MULTIDO = true
+MULTICLEAN = true
+
+#-------------------------------------------------------------------------
+# Basic setup
+#-------------------------------------------------------------------------
+
+# Remove all default implicit rules since they can cause subtle bugs
+# and they just make things run slower
+
+.SUFFIXES:
+% : %,v
+% : RCS/%,v
+% : RCS/%
+% : s.%
+% : SCCS/s.%
+
+# Default is to build the prereqs of the all target (defined at bottom)
+
+default : all
+.PHONY : default
+
+# Source directory
+
+obj_dir := .
+src_dir := @srcdir@
+VPATH   := $(src_dir) $(src_dir)/machine
+
+# Installation directories
+
+prefix  := @prefix@
+DESTDIR ?= $(prefix)
+
+install_hdrs_dir := $(DESTDIR)$(prefix)/$(target_alias)/include/machine
+install_libs_dir  = $(DESTDIR)$(prefix)/$(target_alias)/lib${MULTISUBDIR}
+install_bins_dir := $(DESTDIR)$(prefix)/$(target_alias)/bin
+
+#-------------------------------------------------------------------------
+# Programs and flags 
+#-------------------------------------------------------------------------
+
+# C compiler
+
+CC            := @CC@
+CFLAGS        := @CFLAGS@
+CFLAGS        += -mcmodel=medany
+CPPFLAGS      := -I$(obj_dir) -I$(src_dir) $(dramfs_incs) -mcmodel=medany
+COMPILE       := $(CC) -MMD -MP $(CPPFLAGS) $(CFLAGS)
+
+# Library creation
+
+AR            := @AR@
+RANLIB        := @RANLIB@
+
+# Installation
+
+INSTALL       := @INSTALL@
+INSTALL_DATA  := @INSTALL_DATA@
+
+#-------------------------------------------------------------------------
+# Build Object Files from C Source
+#-------------------------------------------------------------------------
+
+gloss_c_srcs = $(filter %.c, $(gloss_srcs))
+gloss_c_objs = $(patsubst %.c, %.o, $(notdir $(gloss_c_srcs)))
+gloss_c_deps = $(patsubst %.c, %.d, $(notdir $(gloss_c_srcs)))
+
+$(gloss_c_objs) : %.o : %.c
+	$(COMPILE) -c $<
+
+gloss_objs += $(gloss_c_objs)
+deps += $(gloss_c_deps)
+junk += $(gloss_c_deps) $(gloss_c_objs)
+
+#-------------------------------------------------------------------------
+# Build Object Files from Assembly Source
+#-------------------------------------------------------------------------
+
+gloss_asm_srcs = $(filter %.S, $(gloss_srcs))
+gloss_asm_objs = $(patsubst %.S, %.o, $(notdir $(gloss_asm_srcs)))
+gloss_asm_deps = $(patsubst %.S, %.d, $(notdir $(gloss_asm_srcs)))
+
+$(gloss_asm_objs) : %.o : %.S
+	$(COMPILE) -c -o $@ $<
+
+gloss_objs += $(gloss_asm_objs)
+deps += $(gloss_asm_deps)
+junk += $(gloss_asm_deps) $(gloss_asm_objs)
+
+#-------------------------------------------------------------------------
+# Build libgloss.a
+#-------------------------------------------------------------------------
+
+gloss_lib  = libgloss.a
+$(gloss_lib) : $(gloss_objs)
+	$(AR) rcv $@ $^
+	$(RANLIB) $@
+
+junk += $(gloss_lib)
+
+install_hdrs += $(gloss_hdrs)
+install_libs += $(gloss_lib)
+install_specs += $(gloss_specs)
+install_bins += $(gloss_bins)
+
+#-------------------------------------------------------------------------
+# Build crt0.o
+#-------------------------------------------------------------------------
+
+crt0_obj  = $(patsubst %.S, %.o, $(crt0_asm))
+crt0_deps = $(patsubst %.S, %.d, $(crt0_asm))
+
+$(crt0_obj) : %.o : %.S
+	$(COMPILE) -c $<
+
+deps += $(crt0_deps)
+junk += $(crt0_deps) $(crt0_obj)
+
+install_libs += $(crt0_obj)
+
+#-------------------------------------------------------------------------
+# Autodependency files
+#-------------------------------------------------------------------------
+
+-include $(deps)
+
+deps : $(deps)
+.PHONY : deps
+
+#-------------------------------------------------------------------------
+# Installation
+#-------------------------------------------------------------------------
+
+install_hdrs_wdir += $(addprefix $(src_dir)/, $(install_hdrs))
+install-hdrs : $(install_hdrs_wdir)
+	test -d $(install_hdrs_dir) || mkdir -p $(install_hdrs_dir)
+	for file in $^; do \
+		$(INSTALL_DATA) $$file $(install_hdrs_dir)/; \
+	done
+
+install-libs : $(install_libs)
+	test -d $(install_libs_dir) || mkdir -p $(install_libs_dir)
+	for file in $^; do \
+		$(INSTALL_DATA) $$file $(install_libs_dir)/$$file; \
+	done
+
+install-specs : $(install_specs)
+	test -d $(install_libs_dir) || mkdir -p $(install_libs_dir)
+	for file in $^; do \
+		$(INSTALL_DATA) $$file $(install_libs_dir)/; \
+	done
+
+install-bins : $(install_bins)
+	test -d $(install_bins_dir) || mkdir -p $(install_bins_dir)
+	for file in $^; do \
+		$(INSTALL) $$file $(install_bins_dir)/; \
+	done
+
+install : install-hdrs install-libs install-specs install-bins
+.PHONY : install install-hdrs install-libs
+
+#-------------------------------------------------------------------------
+# Regenerate configure information
+#-------------------------------------------------------------------------
+
+configure_prereq = \
+  $(src_dir)/configure.in \
+
+$(src_dir)/configure : $(configure_prereq)
+	cd $(src_dir) && autoconf
+
+config.status : $(src_dir)/configure
+	./config.status --recheck
+
+Makefile : $(src_dir)/Makefile.in config.status
+	./config.status
+
+dist_junk += config.status Makefile config.log
+
+#-------------------------------------------------------------------------
+# Default
+#-------------------------------------------------------------------------
+
+all : $(install_libs) $(install_bins)
+.PHONY : all
+
+#-------------------------------------------------------------------------
+# Clean up junk
+#-------------------------------------------------------------------------
+
+clean :
+	rm -rf *~ \#* $(junk)
+
+distclean :
+	rm -rf *~ \#* $(junk) $(dist_junk)
+
+.PHONY : clean distclean
diff --git a/libgloss/dramfs/README.md b/libgloss/dramfs/README.md
new file mode 100644
index 000000000..081a5e114
--- /dev/null
+++ b/libgloss/dramfs/README.md
@@ -0,0 +1,154 @@
+# Newlib/DRAMFS  
+###### Bandhav Veluri and Michael Taylor, Bespoke Silicon Group UW  
+
+Note: Mirror changes to this file to https://github.com/bespoke-silicon-group/bsg_newlib_dramfs/blob/dramfs/README.md
+
+## Introduction
+
+Newlib is a light-weight C standard library implementation for embedded systems. It elegantly separates system specific functionality (system calls) into an easily portable portion called Libgloss. Libgloss contains system call implementations for different architectures/systems in it. Porting Newlib to an architecture/system essentially involves porting these system call implementations in Libgloss. Complete guide for porting Newlib can be found in [5].
+
+Running POSIX programs on bare metal systems require some sort of implementation for file i/o and malloc. Malloc depends on just one system-call called sbrk, which essentially increments or decrements heap pointer as and when requested. Whereas, file i/o requires an actual file system, or an interface that can mimic a file system. This Newlib port uses an open-source lightweight file-system designed for embedded flash file systems by ARM called LittleFS (LFS). LittleFS also supports a DRAM-based file system, which is the one we use. 
+
+The idea is to implement file i/o syscalls by simply translating them to LFS function calls, which in turn will operate on memory, rather than trying to use a more complex I/O emulation facility, like proxy kernels, that package up I/O calls and ship them over to a host. This allows for more reproducible I/O emulation, since the host is no longer an asynchronous process. It also eliminates the infrastructure pain caused by mapping these proxy-IO calls to different embodiments of the design -- simulator, VCS, verilator, FPGA emulation, ASIC testboard, and PCI-e hosted chip.
+
+## Installation
+
+Newlib/Dramfs is intended to be a separate Board Support Package (BSP) in Newlib. Newlib can be configured to install this BSP by setting the target to end with `dramfs`:
+
+```
+$ ./configure --target=<AnyArchiteture>-<AnyVendor>-<AnyString>dramfs [<other options>]
+```
+
+Since this BSP works with any ISA, architecture field could be anything!
+
+## Porting
+
+Porting Newlib/Dramfs requires following four steps:
+1. Implement `dramfs_exit(int)` (routine to exit the execution environment). 
+2. Implement `dramfs_sendchar(char)` (routine to output non-file I/O (for debugging etc)).
+3. Implment C-runtime initiation including a call to `dramfs_fs_init()` in it.
+4. Implement linker command script including definition of `_end` symbol (heap pointer) in it.
+
+#### 1, 2. Interfacing functions:
+```
+/*
+ * dramfs_intf.c
+ * 
+ * Sample Implementation of Newlib/DRAMFS interface
+ */
+
+#include <stdlib.h>
+#include <machine/dramfs_fs.h> // This header is installed with this BSP!
+
+void dramfs_exit(int exit_status) {
+  if(exit_status == EXIT_SUCCESS) {
+    // Exit the environment successfully
+    
+    // Replace this with code to exit
+    // successfully on your system.
+  } else {
+    // Exit the environment with failure
+    
+    // Replace this with code to exit
+    // with failure on your system.
+  }
+
+  // do nothing until we exit
+  while(1);
+}
+
+void dramfs_sendchar(char ch) {
+  // code to display ‘ch’
+  // in many cases you may just want to have a memory
+  // mapped I/O location that you write to
+  // whether that is simulator magic, a NOC, a UART, or PCIe.
+}
+```
+
+#### 3. Adding `dramfs_fs_init` call to C-runtime initialization code:
+
+The function `dramfs_fs_init` (implemented in this BSP) has to called before calling the main. This step mounts the LittleFS image using a tiny block device driver implemeted by us. A sample C-runtime initialization is provided below:
+
+```
+# Sample crt.S
+# 
+# This is architecture specific; hence user would implement this code
+# Following example is for a RISC-V system.
+
+.section .crtbegin,"a"
+
+.globl _start
+_start:
+
+  # initialize global pointer
+  la gp, _gp
+
+  # initialize stack pointer
+  la sp, _sp
+
+  call dramfs_fs_init # initialize dramfs
+  lw a0, 0(sp)        # argc
+  lw a1, -4(sp)       # argv
+  li a2, 0            # envp = NULL
+  call main
+  tail exit
+
+2:
+  # Should never this point
+  j 2b
+```
+
+#### 4. Defining `_end` symbol in the linker command file:
+
+This can be done as shown in the sample linker script below:
+
+```
+/* link.ld */
+/* Sample linker command file */
+
+SECTIONS
+{
+  . = 0x80000000; /* text and data start at 0x80000000 */
+
+  .text : {
+     *(.crtbegin)
+     *(.text)
+     *(.text.startup)
+     *(.text.*)
+  }
+
+  .data : {
+    *(.data*)
+    *(.rodata*)
+    *(.sdata .sdata.* .srodata*)
+  }
+
+  /* global pointer */
+  _gp = .;
+
+  .bss : {
+    *(.bss*)
+    *(.sbss*)
+  }
+
+  /* Initial heap pointer */
+  _end = . ;
+ 
+  /* Initial stack pointer */
+  _sp = 0x81000000;
+}
+```
+
+## Notes
+
+- Newlib is implemented on top of a set of operating system syscalls listed in [4]. Newlib/dramfs currently implements `sbrk`, `open`, `close`, `read`, `write`, `exit`, `lseek`, `stat` and `fstat`. These are sufficient to handle the vast majority of newlib POSIX calls. For those that are not supported, they return setting appropriate error number. We plan to increase this set over time, and also encourage your pull requests.
+- Block size and count can be tweaked to improve performance depending on your system. More on this can be understood from [2].
+- Current implementations of syscalls are *not* thread-safe. So, this can only be used for single threaded programs as of now.
+
+## References
+
+[1] Bootstrapping Idea: https://drive.google.com/open?id=1_Ie94nZvyvMjEb1GQTPzfcBNaVs6xfVXZ_bHTH5_z3k  
+[2] LittleFS: https://github.com/ARMmbed/littlefs  
+[3] RISC-V BSP: https://github.com/riscv/riscv-newlib/tree/riscv-newlib-3.1.0/libgloss/riscv  
+[4] Newlib OS interface: https://sourceware.org/newlib/libc.html#Syscalls  
+[5] Newlib porting guide: https://www.embecosm.com/appnotes/ean9/ean9-howto-newlib-1.0.html 
diff --git a/libgloss/dramfs/sys_close.c b/libgloss/dramfs/sys_close.c
new file mode 100644
index 000000000..fcb0a4faa
--- /dev/null
+++ b/libgloss/dramfs/sys_close.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2023, University of Washington
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the University of Washington nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include "dramfs_fdtable.h"
+#include "dramfs_fs.h"
+
+/* Close a file.  */
+int
+_close(int fd)
+{
+  if(dramfs_check_fd(fd) < 0) {
+    return -1;
+  }
+
+  return dramfs_free_fd(fd);
+}
diff --git a/libgloss/dramfs/sys_execve.c b/libgloss/dramfs/sys_execve.c
new file mode 100644
index 000000000..8448ed6ae
--- /dev/null
+++ b/libgloss/dramfs/sys_execve.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2023, University of Washington
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the University of Washington nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <errno.h>
+
+#undef errno
+extern int errno;
+
+/* Transfer control to a new process. Minimal implementation for a
+   system without processes from newlib documentation.  */
+int
+_execve(const char *name, char *const argv[], char *const env[])
+{
+  errno = ENOMEM;
+  return -1;
+}
diff --git a/libgloss/dramfs/sys_exit.c b/libgloss/dramfs/sys_exit.c
new file mode 100644
index 000000000..d402bbe09
--- /dev/null
+++ b/libgloss/dramfs/sys_exit.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2023, University of Washington
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the University of Washington nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <unistd.h>
+#include "dramfs_fs.h"
+
+/* Exit a program without cleaning up files.  */
+void
+_exit(int exit_status) {
+  // close stdio
+  close(0);
+  close(1);
+  close(2);
+
+  dramfs_exit(exit_status);
+  while(1);
+}
diff --git a/libgloss/dramfs/sys_fork.c b/libgloss/dramfs/sys_fork.c
new file mode 100644
index 000000000..6994ad55c
--- /dev/null
+++ b/libgloss/dramfs/sys_fork.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2023, University of Washington
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the University of Washington nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <errno.h>
+
+#undef errno
+extern int errno;
+
+/* Create a new process. Minimal implementation for a system without
+   processes from newlib documentation.  */
+int _fork()
+{
+  errno = EAGAIN;
+  return -1;
+}
diff --git a/libgloss/dramfs/sys_fstat.c b/libgloss/dramfs/sys_fstat.c
new file mode 100644
index 000000000..2ba8952da
--- /dev/null
+++ b/libgloss/dramfs/sys_fstat.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2023, University of Washington
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the University of Washington nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/stat.h>
+#include <dramfs_fs.h>
+#include <dramfs_fdtable.h>
+
+int
+_fstat(int file, struct stat *st)
+{
+  lfs_file_t *fptr;
+  struct lfs_info finfo;
+
+  if(dramfs_check_fd(file) < 0)
+    return -1;
+  else
+    fptr = dramfs_get_file(file);
+
+  st->st_mode = S_IFREG;
+  st->st_size = (off_t) fptr->size;
+  st->st_blksize = (blksize_t) dramfs_fs_cfg.block_size;
+  st->st_blocks  = (blkcnt_t) dramfs_fs_cfg.block_count;
+  return 0;
+}
diff --git a/libgloss/dramfs/sys_getpid.c b/libgloss/dramfs/sys_getpid.c
new file mode 100644
index 000000000..15ea50a09
--- /dev/null
+++ b/libgloss/dramfs/sys_getpid.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2023, University of Washington
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the University of Washington nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Get process id. This is sometimes used to generate strings unlikely
+   to conflict with other processes. Minimal implementation for a
+   system without processes just returns 1.  */
+
+int
+_getpid()
+{
+  return 1;
+}
diff --git a/libgloss/dramfs/sys_gettimeofday.c b/libgloss/dramfs/sys_gettimeofday.c
new file mode 100644
index 000000000..ac66268bf
--- /dev/null
+++ b/libgloss/dramfs/sys_gettimeofday.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2023, University of Washington
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the University of Washington nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/time.h>
+#include <errno.h>
+
+#undef errno
+extern int errno;
+
+/* Get the current time.  Only relatively correct.  */
+int
+_gettimeofday(struct timeval *tp, void *tzp)
+{
+  errno = EINVAL;
+  return -1;
+}
diff --git a/libgloss/dramfs/sys_isatty.c b/libgloss/dramfs/sys_isatty.c
new file mode 100644
index 000000000..f372dfda2
--- /dev/null
+++ b/libgloss/dramfs/sys_isatty.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2023, University of Washington
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the University of Washington nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Query whether output stream is a terminal. For consistency with the
+   other minimal implementations, which only support output to stdout,
+   this minimal implementation is suggested by the newlib docs.  */
+
+int
+_isatty(int file)
+{
+  return 1;
+}
diff --git a/libgloss/dramfs/sys_kill.c b/libgloss/dramfs/sys_kill.c
new file mode 100644
index 000000000..3a2597d25
--- /dev/null
+++ b/libgloss/dramfs/sys_kill.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2023, University of Washington
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the University of Washington nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <errno.h>
+
+#undef errno
+extern int errno;
+
+/* Send a signal. Minimal implementation for a system without processes
+   just causes an error.  */
+int
+_kill(int pid, int sig)
+{
+  errno = EINVAL;
+  return -1;
+}
diff --git a/libgloss/dramfs/sys_link.c b/libgloss/dramfs/sys_link.c
new file mode 100644
index 000000000..fd2af719d
--- /dev/null
+++ b/libgloss/dramfs/sys_link.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2023, University of Washington
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the University of Washington nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <errno.h>
+
+#undef errno
+extern int errno;
+
+/* Establish a new name for an existing file. Minimal implementation */
+int _link(const char *old_name, const char *new_name)
+{
+  errno = EMLINK;
+  return -1;
+}
diff --git a/libgloss/dramfs/sys_lseek.c b/libgloss/dramfs/sys_lseek.c
new file mode 100644
index 000000000..27c25c305
--- /dev/null
+++ b/libgloss/dramfs/sys_lseek.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2023, University of Washington
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the University of Washington nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <dramfs_fs.h>
+#include <dramfs_fdtable.h>
+
+/* Set position in a file.  */
+off_t
+_lseek(int file, off_t ptr, int dir)
+{
+  lfs_file_t *fptr;
+
+  if(dramfs_check_fd(file) < 0)
+    return -1;
+  else
+    fptr = dramfs_get_file(file);
+
+  return lfs_file_seek(&dramfs_fs, fptr, ptr, dir);
+}
diff --git a/libgloss/dramfs/sys_open.c b/libgloss/dramfs/sys_open.c
new file mode 100644
index 000000000..5580d5c4d
--- /dev/null
+++ b/libgloss/dramfs/sys_open.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2023, University of Washington
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the University of Washington nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include "dramfs_fdtable.h"
+#include "dramfs_fs.h"
+
+/* Open a file.  */
+int
+_open(const char *name, int flags, int mode)
+{
+  int fd = dramfs_reserve_fd();
+  int lfs_flags = 0;
+
+  // File open flags mapping
+  lfs_flags |= (flags & O_RDONLY  ) ? LFS_O_RDONLY   : 0;
+  lfs_flags |= (flags & O_WRONLY  ) ? LFS_O_WRONLY   : 0;
+  lfs_flags |= (flags & O_RDWR    ) ? LFS_O_RDWR     : 0;
+  lfs_flags |= (flags & O_APPEND  ) ? LFS_O_APPEND   : 0;
+  lfs_flags |= (flags & O_CREAT   ) ? LFS_O_CREAT    : 0;
+  lfs_flags |= (flags & O_TRUNC   ) ? LFS_O_TRUNC    : 0;
+  lfs_flags |= (flags & O_EXCL    ) ? LFS_O_EXCL     : 0;
+  lfs_flags |= (flags & O_NONBLOCK) ? LFS_O_NONBLOCK : 0;
+
+  if(fd < 0) {
+    return -1;
+  } else {
+    lfs_file_t *fptr = dramfs_get_file(fd);
+
+    int ret = lfs_file_open(&dramfs_fs, fptr, name, lfs_flags);
+
+    if(ret < 0) {
+      errno = ret;
+      return -1;
+    } else {
+      return fd;
+    }
+  }
+}
diff --git a/libgloss/dramfs/sys_read.c b/libgloss/dramfs/sys_read.c
new file mode 100644
index 000000000..8ef6b6a45
--- /dev/null
+++ b/libgloss/dramfs/sys_read.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2023, University of Washington
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the University of Washington nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <sys/types.h>
+#include "dramfs_fdtable.h"
+#include "dramfs_fs.h"
+
+/* Read from a file.  */
+ssize_t _read(int fd, void *ptr, size_t len)
+{
+  if(dramfs_check_fd(fd) < 0) {
+    return -1;
+  }
+
+  if(fd == 0) {
+    uint8_t *data = (uint8_t *)ptr;
+
+    // Return early on len == 0
+    if (len == 0) return (ssize_t) 0;
+
+    int ch;
+    if (dramfs_nonblock_fd(fd) == 0) {
+      // Block to read just 1 character to start
+      while ((ch = dramfs_getchar()) == -1);
+    } else {
+      // Read the first character, and return immediately if it's EOF
+      if ((ch = dramfs_getchar()) == -1) return (ssize_t) 0;
+    }
+
+    // Keep reading until new
+    int i = 0;
+    do {
+      data[i++] = ch;
+      if (i == len) break;
+    } while ((ch = dramfs_getchar()) != -1);
+
+    return (ssize_t) i;
+  }
+
+  lfs_file_t *fptr = dramfs_get_file(fd);
+  return (ssize_t) lfs_file_read(&dramfs_fs, fptr, ptr, (lfs_size_t) len);
+}
diff --git a/libgloss/dramfs/sys_sbrk.c b/libgloss/dramfs/sys_sbrk.c
new file mode 100644
index 000000000..300356a08
--- /dev/null
+++ b/libgloss/dramfs/sys_sbrk.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2023, University of Washington
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the University of Washington nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Dynamic allocation in the dram
+// TODO: add mutex
+extern char _end[]; /* _end is set in the linker command file */
+
+char *heap_ptr = _end;
+
+/*
+ * sbrk -- changes heap size size. Get nbytes more
+ *         RAM. We just increment a pointer in what's
+ *         left of memory on the board.
+ */
+char *
+_sbrk (nbytes)
+     int nbytes;
+{
+  char        *base;
+  
+  base = heap_ptr;
+  heap_ptr += nbytes;
+
+  return base;
+}
diff --git a/libgloss/dramfs/sys_stat.c b/libgloss/dramfs/sys_stat.c
new file mode 100644
index 000000000..f19309e16
--- /dev/null
+++ b/libgloss/dramfs/sys_stat.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2023, University of Washington
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the University of Washington nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <dramfs_fs.h>
+
+/* Status of a file (by name).  */
+
+int
+_stat(const char *file, struct stat *st)
+{
+  struct lfs_info finfo;
+
+  int res = lfs_stat(&dramfs_fs, file, &finfo);
+  if(res < 0) {
+    errno = res;
+    return -1;
+  } else {
+    st->st_mode = S_IFREG;
+    st->st_size = (off_t) finfo.size;
+    st->st_blksize = (blksize_t) dramfs_fs_cfg.block_size;
+    st->st_blocks  = (blkcnt_t) dramfs_fs_cfg.block_count;
+    return 0;
+  }
+}
diff --git a/libgloss/dramfs/sys_times.c b/libgloss/dramfs/sys_times.c
new file mode 100644
index 000000000..1c8ed9ceb
--- /dev/null
+++ b/libgloss/dramfs/sys_times.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2023, University of Washington
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the University of Washington nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/times.h>
+
+/* Timing info for current process. Minimal implementation */
+clock_t
+_times(struct tms *buf)
+{
+  return -1;
+}
diff --git a/libgloss/dramfs/sys_unlink.c b/libgloss/dramfs/sys_unlink.c
new file mode 100644
index 000000000..4f4c4c750
--- /dev/null
+++ b/libgloss/dramfs/sys_unlink.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2023, University of Washington
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the University of Washington nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <errno.h>
+
+#undef errno
+extern int errno;
+
+/* Remove a file's directory entry.  */
+int
+_unlink(const char *name)
+{
+  errno = ENOENT;
+  return -1;
+}
diff --git a/libgloss/dramfs/sys_wait.c b/libgloss/dramfs/sys_wait.c
new file mode 100644
index 000000000..b593511fe
--- /dev/null
+++ b/libgloss/dramfs/sys_wait.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2023, University of Washington
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the University of Washington nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <errno.h>
+
+#undef errno
+extern int errno;
+
+/* Wait for a child process. Minimal implementation for a system without
+   processes just causes an error.  */
+int _wait(int *status)
+{
+  errno = ECHILD;
+  return -1;
+}
diff --git a/libgloss/dramfs/sys_write.c b/libgloss/dramfs/sys_write.c
new file mode 100644
index 000000000..082ef748d
--- /dev/null
+++ b/libgloss/dramfs/sys_write.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2023, University of Washington
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the University of Washington nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <sys/types.h>
+#include "dramfs_fdtable.h"
+#include "dramfs_fs.h"
+
+/* Write to a file.  */
+ssize_t
+_write(int fd, const void *ptr, size_t len)
+{
+  if(dramfs_check_fd(fd) < 0) {
+    return -1;
+  }
+
+  // write to console if it's stdout
+  if(fd == 1 || fd==2) {
+    for(int i=0; i<len; i++){
+      char* cp = (char*) ptr;
+      dramfs_sendchar(cp[i]);
+    }
+    return len;
+  }
+
+  lfs_file_t *fptr = dramfs_get_file(fd);
+  return (ssize_t) lfs_file_write(&dramfs_fs, fptr, ptr, (lfs_size_t) len);
+}
-- 
2.16.5


  reply	other threads:[~2023-08-10 19:51 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-01 23:54 Dan Petrisko
2023-08-01 23:54 ` [PATCH 2/2] Adding lfs_mem.c Dan Petrisko
2023-08-09 10:04 ` [PATCH 1/2] Adding a LittleFS-based self-contained target to libgloss Corinna Vinschen
2023-08-09 19:12 ` Jeff Johnston
2023-08-09 22:21   ` Dan Petrisko
2023-08-09 22:21     ` [PATCH 1/2] " Dan Petrisko
2023-08-10 17:45       ` Jeff Johnston
2023-08-10 19:50         ` Dan Petrisko
2023-08-10 19:50           ` Dan Petrisko [this message]
2023-08-10 21:47             ` [PATCH 1/2] " Jeff Johnston
2023-08-10 19:50           ` [PATCH 2/2] Adding lfs_mem.c Dan Petrisko
2023-08-10 20:46           ` Adding a LittleFS-based self-contained target to libgloss Jeff Johnston
2023-08-09 22:21     ` [PATCH 2/2] Adding lfs_mem.c Dan Petrisko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230810195057.18266-2-petrisko@cs.washington.edu \
    --to=petrisko@cs.washington.edu \
    --cc=newlib@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).