public inbox for newlib@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 1/2] Adding a LittleFS-based self-contained target to libgloss
@ 2023-08-01 23:54 Dan Petrisko
  2023-08-01 23:54 ` [PATCH 2/2] Adding lfs_mem.c Dan Petrisko
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Dan Petrisko @ 2023-08-01 23:54 UTC (permalink / raw)
  To: newlib; +Cc: Dan Petrisko

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

Hello, this is my first time submitting a patch, so let me know of any etiquete errors in addition
to code errors...

This patch adds support for *-*-*-dramfs targets, which is a kind of pseudo-BSP which allows you to
support a filesystem without any I/O hardware support. This is very useful for folks
developing their own processor cores, or bringing up systems without another host managing a shim
layer. It relies on ARM LittleFS to create a DRAM-based file system which is prepopulated by the
user compiling the program. However, once it is created the user is able to use open, write, read
etc. calls like normal.

The tool for creating the filesystem (dramfs_mklfs) is included in this
patch, although it would be reasonable to extract it to its own repo if folks think it's orthogonal
enough.

It also adds LittleFS as a submodule to newlib, which I would guess is undesired. However, it's
required as part of the build process, so not sure what's the preferred way of dealing with that.

More info is available at: https://github.com/bespoke-silicon-group/bsg_newlib_dramfs/tree/dramfs

Thanks!

 .gitmodules                             |   3 +
 COPYING.LIBGLOSS                        |  27 +++
 libgloss/dramfs/Makefile.in             | 304 ++++++++++++++++++++++++++++++++
 libgloss/dramfs/README.md               | 207 ++++++++++++++++++++++
 libgloss/dramfs/configure.in            |  45 +++++
 libgloss/dramfs/dramfs/dramfs_fdtable.c |  62 +++++++
 libgloss/dramfs/dramfs/dramfs_fdtable.h |  23 +++
 libgloss/dramfs/dramfs/dramfs_fs.c      |  35 ++++
 libgloss/dramfs/dramfs/dramfs_fs.h      |  32 ++++
 libgloss/dramfs/dramfs/dramfs_mklfs.c   | 154 ++++++++++++++++
 libgloss/dramfs/dramfs/dramfs_util.c    | 101 +++++++++++
 libgloss/dramfs/dramfs/dramfs_util.h    |  13 ++
 libgloss/dramfs/dramfs/littlefs         |   1 +
 libgloss/dramfs/sys_close.c             |  14 ++
 libgloss/dramfs/sys_execve.c            |  13 ++
 libgloss/dramfs/sys_exit.c              |  14 ++
 libgloss/dramfs/sys_fork.c              |  12 ++
 libgloss/dramfs/sys_fstat.c             |  21 +++
 libgloss/dramfs/sys_getpid.c            |   9 +
 libgloss/dramfs/sys_gettimeofday.c      |  13 ++
 libgloss/dramfs/sys_isatty.c            |   9 +
 libgloss/dramfs/sys_kill.c              |  13 ++
 libgloss/dramfs/sys_link.c              |  11 ++
 libgloss/dramfs/sys_lseek.c             |  17 ++
 libgloss/dramfs/sys_open.c              |  37 ++++
 libgloss/dramfs/sys_read.c              |  40 +++++
 libgloss/dramfs/sys_sbrk.c              |  22 +++
 libgloss/dramfs/sys_stat.c              |  23 +++
 libgloss/dramfs/sys_times.c             |   8 +
 libgloss/dramfs/sys_unlink.c            |  12 ++
 libgloss/dramfs/sys_wait.c              |  12 ++
 libgloss/dramfs/sys_write.c             |  25 +++
 32 files changed, 1332 insertions(+)
 create mode 100644 .gitmodules
 create mode 100644 libgloss/dramfs/Makefile.in
 create mode 100644 libgloss/dramfs/README.md
 create mode 100644 libgloss/dramfs/configure.in
 create mode 100644 libgloss/dramfs/dramfs/dramfs_fdtable.c
 create mode 100644 libgloss/dramfs/dramfs/dramfs_fdtable.h
 create mode 100644 libgloss/dramfs/dramfs/dramfs_fs.c
 create mode 100644 libgloss/dramfs/dramfs/dramfs_fs.h
 create mode 100644 libgloss/dramfs/dramfs/dramfs_mklfs.c
 create mode 100644 libgloss/dramfs/dramfs/dramfs_util.c
 create mode 100644 libgloss/dramfs/dramfs/dramfs_util.h
 create mode 160000 libgloss/dramfs/dramfs/littlefs
 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..4692df17b
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "libgloss/dramfs/dramfs/littlefs"]
+	path = libgloss/dramfs/dramfs/littlefs
+	url = https://github.com/littlefs-project/littlefs.git
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/libgloss/dramfs/Makefile.in b/libgloss/dramfs/Makefile.in
new file mode 100644
index 000000000..a0d8b99a9
--- /dev/null
+++ b/libgloss/dramfs/Makefile.in
@@ -0,0 +1,304 @@
+#----------------------------------------------------------------------
+# Newlib File System sources
+#----------------------------------------------------------------------
+
+dramfs_incs = \
+	-I@srcdir@/dramfs \
+	-I@srcdir@/dramfs/littlefs/lfs \
+	-I@srcdir@/dramfs/littlefs/bd
+
+dramfs_srcs = \
+	lfs_mem.c \
+	dramfs_fs.c \
+	dramfs_fdtable.c \
+	lfs.c \
+	lfs_util.c \
+	lfs_bd.c
+
+dramfs_hdrs = \
+	dramfs/dramfs_fs.h \
+	dramfs/dramfs_fdtable.h \
+	dramfs/littlefs/lfs/lfs.h \
+	dramfs/littlefs/bd/lfs_bd.h
+
+dramfs_mkfs_srcs = \
+	dramfs_mklfs.c \
+	dramfs_util.c \
+	lfs.c \
+	lfs_util.c \
+	lfs_bd.c
+
+dramfs_mkfs_bin = \
+	dramfs_mklfs
+
+#-------------------------------------------------------------------------
+# 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
+
+#-------------------------------------------------------------------------
+# NEWLIB FS build rules 
+#-------------------------------------------------------------------------
+
+dramfs_objs = $(patsubst %.c, %.o, $(dramfs_srcs))
+
+vpath %.c @srcdir@/dramfs @srcdir@/dramfs/littlefs/lfs @srcdir@/dramfs/littlefs/bd
+
+DRAMFS_CC     = @CC@
+DRAMFS_CFLAGS = -O1
+DRAMFS_CFLAGS += $(dramfs_incs)
+DRAMFS_CFLAGS += -std=c99 -mcmodel=medany
+DRAMFS_CFLAGS += -DLFS_NO_ASSERT -DLFS_NO_DEBUG \
+                        -DLFS_NO_WARN -DLFS_NO_ERROR -DLFS_NO_INTRINSICS
+
+$(dramfs_objs): %.o : %.c
+	$(DRAMFS_CC) $(DRAMFS_CFLAGS) -c $< -o $@
+
+gloss_hdrs += $(dramfs_hdrs)
+gloss_objs += $(dramfs_objs)
+junk += $(dramfs_objs)
+
+#-------------------------------------------------------------------------
+# NEWLIB mkfs rules 
+#-------------------------------------------------------------------------
+
+dramfs_mkfs_objs = $(patsubst %.c, %_host.o, $(dramfs_mkfs_srcs))
+
+DRAMFS_MKFS_CC     = gcc
+DRAMFS_MKFS_CFLAGS = -O1
+DRAMFS_MKFS_CFLAGS += $(dramfs_incs)
+DRAMFS_MKFS_CFLAGS += -std=gnu99
+
+$(dramfs_mkfs_objs): %_host.o : %.c
+	$(DRAMFS_MKFS_CC) $(DRAMFS_MKFS_CFLAGS) -c $< -o $@
+
+$(dramfs_mkfs_bin): $(dramfs_mkfs_objs)
+	$(DRAMFS_MKFS_CC) $(dramfs_mkfs_objs) -o $@
+
+gloss_bins += $(dramfs_mkfs_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..77c482779
--- /dev/null
+++ b/libgloss/dramfs/README.md
@@ -0,0 +1,207 @@
+# 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;
+}
+```
+
+## Usage
+
+Running a program with Newlib/Dramfs requires user to link an additional file consisting of initial LittleFS image with input files to the program. LittleFS image can be automatically generated by a tool called `dramfs_mklfs` that has already been installed with this BSP! The tool needs two parameters `lfs_block_size` and `lfs_block_count`. Total size of the file-system would be `lfs_block_size*lfs_block_count`. See [2] for information about how to play with these parameters to improve performance.
+
+Usage of `dramfs_mklfs`:
+```
+dramfs_mklfs <lfs_block_size> <lfs_block_count> <inputfile1> <inputdir1> <inputfile2> ...
+```
+
+After installation and porting, the procedure for running programs with Newlib/Dramfs is summarized by a sample program below. Let's say we want to run a file i/o program on a bare metal system which takes `hello.txt` as input.
+
+```
+$ cat fhello.c 
+/*
+ * fhello.c
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main() {
+  int c;
+
+  /* Open hello.txt for reading */
+  FILE *hello = fopen("hello.txt", "r");
+  if(hello == NULL)
+    return -1;
+
+
+  /* Iterate through the entire file
+   * and print the contents to stdout
+   */
+
+  putchar('\n');
+
+  while((c = fgetc(hello)) != EOF) {
+    putchar(c);
+  }
+
+  fclose(hello);
+  return 0;
+}
+$ cat hello.txt 
+Hello! This is Little FS!
+$ dramfs_mklfs 128 256 hello.txt > lfs_mem.c
+$ <xxx>-<xxx>-<xxx>dramfs-gcc -c crt.S lfs_mem.c dramfs_intf.c fhello.c
+$ <xxx>-<xxx>-<xxx>dramfs-gcc -nostartfiles -T link.ld lfs_mem.o crt.o dramfs_intf.o fhello.o  -o fhello
+$ <Your system's runtime executable> fhello
+
+Hello! This is Little FS!
+```
+
+## 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/configure.in b/libgloss/dramfs/configure.in
new file mode 100644
index 000000000..5694013d4
--- /dev/null
+++ b/libgloss/dramfs/configure.in
@@ -0,0 +1,45 @@
+#=========================================================================
+# configure.ac for riscv libgloss and crt0
+#=========================================================================
+
+#-------------------------------------------------------------------------
+# Setup
+#-------------------------------------------------------------------------
+
+AC_INIT([crt0.S])
+AC_CONFIG_SRCDIR([crt0.S])
+AC_CONFIG_AUX_DIR([${srcdir}/../..])
+
+#-------------------------------------------------------------------------
+# Checks for programs
+#-------------------------------------------------------------------------
+
+LIB_AC_PROG_CC
+AC_CHECK_TOOL([AR],[ar])
+AC_CHECK_TOOL([RANLIB],[ranlib])
+AC_PROG_INSTALL
+
+#-------------------------------------------------------------------------
+# Output
+#-------------------------------------------------------------------------
+
+if test "$srcdir" = "." ; then
+  if test "${with_target_subdir}" != "." ; then
+    libgloss_topdir="${srcdir}/${with_multisrctop}../../.."
+  else
+    libgloss_topdir="${srcdir}/${with_multisrctop}../.."
+  fi
+else
+  libgloss_topdir="${srcdir}/../.."
+fi
+AC_CONFIG_AUX_DIR($libgloss_topdir)
+AC_CONFIG_FILES(Makefile,
+. ${libgloss_topdir}/config-ml.in,
+srcdir=${srcdir}
+target=${target}
+with_multisubdir=${with_multisubdir}
+ac_configure_args="${ac_configure_args} --enable-multilib"
+CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+libgloss_topdir=${libgloss_topdir}
+)
+AC_OUTPUT
diff --git a/libgloss/dramfs/dramfs/dramfs_fdtable.c b/libgloss/dramfs/dramfs/dramfs_fdtable.c
new file mode 100644
index 000000000..32cfb28f9
--- /dev/null
+++ b/libgloss/dramfs/dramfs/dramfs_fdtable.c
@@ -0,0 +1,62 @@
+#include "dramfs_fdtable.h"
+#include "dramfs_fs.h"
+
+typedef struct dramfs_fd_entry {
+  int used;
+  int nonblock;
+  lfs_file_t file;
+} dramfs_fd_entry_t;
+
+static dramfs_fd_entry_t dramfs_fdtable[DRAMFS_MAX_FDS];
+
+void dramfs_init_fdtable(void) {
+  for(int i=0; i<DRAMFS_MAX_FDS; i++) {
+    dramfs_fdtable[i].used = 0;
+    dramfs_fdtable[i].nonblock = 0;
+  }
+}
+
+int dramfs_check_fd(int fd) {
+  if(fd < 0 || fd >= DRAMFS_MAX_FDS || dramfs_fdtable[fd].used == 0) {
+    errno = EBADF;
+    return -1;
+  }
+
+  return 0;
+}
+
+int dramfs_nonblock_fd(int fd) {
+  if(dramfs_fdtable[fd].nonblock == 1) {
+    return 1;
+  }
+
+  return 0;
+}
+
+int dramfs_reserve_fd(void) {
+  int fd = 0;
+
+  for(;fd < DRAMFS_MAX_FDS; fd++) {
+    if(dramfs_fdtable[fd].used == 0) {
+      dramfs_fdtable[fd].used = 1;
+      return fd;
+    }
+  }
+
+  errno = ENFILE;
+  return -1;
+}
+
+lfs_file_t *dramfs_get_file(int fd) {
+  return &dramfs_fdtable[fd].file;
+}
+
+int dramfs_free_fd(int fd) {
+  if (dramfs_fdtable[fd].used == 1) {
+    lfs_file_t *fptr = dramfs_get_file(fd);
+    dramfs_fdtable[fd].used = 0;
+    return lfs_file_close(&dramfs_fs, fptr);
+  } else {
+    return 0;
+  }
+}
diff --git a/libgloss/dramfs/dramfs/dramfs_fdtable.h b/libgloss/dramfs/dramfs/dramfs_fdtable.h
new file mode 100644
index 000000000..f26fd7613
--- /dev/null
+++ b/libgloss/dramfs/dramfs/dramfs_fdtable.h
@@ -0,0 +1,23 @@
+#ifndef DRAMFS_FDTABLE_H
+#define DRAMFS_FDTABLE_H
+
+#include <errno.h>
+#include "lfs.h"
+
+#ifndef DRAMFS_MAX_FDS
+#define DRAMFS_MAX_FDS 20
+#endif
+
+void dramfs_init_fdtable(void);
+
+int dramfs_check_fd(int fd);
+
+int dramfs_nonblock_fd(int fd);
+
+int dramfs_reserve_fd(void);
+
+int dramfs_free_fd(int fd);
+
+lfs_file_t *dramfs_get_file(int fd);
+
+#endif // DRAMFS_FDTABLE_H
diff --git a/libgloss/dramfs/dramfs/dramfs_fs.c b/libgloss/dramfs/dramfs/dramfs_fs.c
new file mode 100644
index 000000000..b4d6c51ae
--- /dev/null
+++ b/libgloss/dramfs/dramfs/dramfs_fs.c
@@ -0,0 +1,35 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include "lfs.h"
+#include "lfs_bd.h"
+#include "dramfs_fs.h"
+#include "dramfs_fdtable.h"
+
+// File system memory pointer
+uint8_t* lfs_ptr = lfs_mem;
+
+// Init routine for Newlib FS
+int dramfs_fs_init() {
+  // initiate fdtable
+  dramfs_init_fdtable();
+
+	// mount the file system
+	if(lfs_mount(&dramfs_fs, &dramfs_fs_cfg) < 0) {
+		return -1;
+	}
+
+  // Open stdio files
+  if(open("stdin", O_RDONLY) != 0) { 
+    return -1;
+  }
+
+  if(open("stdout", O_WRONLY) != 1) {
+    return -1;
+  }
+
+  if(open("stderr", O_WRONLY) != 2) {
+    return -1;
+  }
+
+	return 0;
+}
diff --git a/libgloss/dramfs/dramfs/dramfs_fs.h b/libgloss/dramfs/dramfs/dramfs_fs.h
new file mode 100644
index 000000000..94f38d37d
--- /dev/null
+++ b/libgloss/dramfs/dramfs/dramfs_fs.h
@@ -0,0 +1,32 @@
+#ifndef DRAMFS_FS_H
+#define DRAMFS_FS_H
+
+#include "lfs.h"
+
+// Toplevel filesystem struct
+extern lfs_t dramfs_fs;
+
+// File system configuration structure
+// Initalized externally and can be generated by dramfs_mklfs
+extern struct lfs_config dramfs_fs_cfg;
+
+// Array with initial LFS image
+// Initialized externally and can be generated by dramfs_mklfs
+extern uint8_t lfs_mem[];
+
+// Exit routine: exit() calls this routine
+// Definition provided externally by user
+extern void dramfs_exit(int);
+
+// Utility to print a char to console
+// Definition provided externally by user
+extern void dramfs_sendchar(char);
+
+// Utility to get a char from console
+// Definition provided externally by user
+extern int dramfs_getchar(void);
+
+// LFS init routine: Should be called before calling main
+int dramfs_fs_init(void) __attribute__((weak));
+
+#endif // DRAMFS_FS_H
diff --git a/libgloss/dramfs/dramfs/dramfs_mklfs.c b/libgloss/dramfs/dramfs/dramfs_mklfs.c
new file mode 100644
index 000000000..1bdf7d0f5
--- /dev/null
+++ b/libgloss/dramfs/dramfs/dramfs_mklfs.c
@@ -0,0 +1,154 @@
+// Program to create littlefs image comprising of input files/dirs
+//
+// Bandhav Veluri
+// 03-07-2019
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include "lfs.h"
+#include "lfs_bd.h"
+#include "dramfs_util.h"
+
+// Main file system struct
+lfs_t lfs;
+
+// LFS configuration
+struct lfs_config lfs_cfg = {
+    // block device operations: lfs_bd.h
+    .read  = lfs_read,
+    .prog  = lfs_prog,
+    .erase = lfs_erase,
+    .sync  = lfs_sync,
+
+    // block device default configuration
+    .read_size   = 32,
+    .prog_size   = 32,
+    .block_size  = 0,
+    .block_count = 0,
+    .lookahead   = 32
+};
+
+// Pointer to filesystem memory
+// lfs_bd uses this allocation as block device
+uint8_t *lfs_ptr;
+
+int main(int argc, char *argv[]) {
+  int block_size;
+  int block_count;
+  FILE *img; // output fs image file handler
+
+  if(argc < 3) {
+    printf("Usage: dramfs_mklfs <block_size> <block_count> [input file(s)/dir(s)]\n");
+    return -1;
+  }
+
+  block_size = atoi(argv[1]);
+  block_count = atoi(argv[2]);
+
+
+  //+------------------------------------------------------
+  //| Allocate memory for building Little FS image
+  //+------------------------------------------------------
+
+  // memory allocation for lfs
+  lfs_ptr = (char *) malloc(block_size*block_count);
+
+  // configure the size
+  lfs_cfg.block_size = block_size;
+  lfs_cfg.block_count = block_count;
+
+  // format the fs
+  if(lfs_format(&lfs, &lfs_cfg) < 0) {
+    printf("LFS format error\n");
+    return -1;
+  }
+
+  // mount the file system
+  if(lfs_mount(&lfs, &lfs_cfg) < 0) {
+    printf("LFS mount error\n");
+    return -1;
+  }
+  
+
+  //+-------------------------------------------------------
+  //| Create stdin, stdout and stderr files in the littlefs
+  //+-------------------------------------------------------
+    
+  lfs_file_t lfs_stdin, lfs_stdout, lfs_stderr;
+
+  // Create stdio files
+  lfs_file_open(&lfs, &lfs_stdin, "stdin", LFS_O_WRONLY | LFS_O_CREAT);
+  lfs_file_open(&lfs, &lfs_stdout, "stdout", LFS_O_WRONLY | LFS_O_CREAT);
+  lfs_file_open(&lfs, &lfs_stderr, "stderr", LFS_O_WRONLY | LFS_O_CREAT);
+
+  // Close stdio files
+  lfs_file_close(&lfs, &lfs_stdin);
+  lfs_file_close(&lfs, &lfs_stdout);
+  lfs_file_close(&lfs, &lfs_stderr);
+
+
+  //+-------------------------------------------------------
+  //| Copy input files/dirs to LFS image
+  //+-------------------------------------------------------
+
+  for(int i = 3; i < argc; i++) {
+    if(lfs_cp(argv[i], &lfs) < 0)
+      return -1;
+  }
+
+  // Unmount lfs
+  if(lfs_unmount(&lfs) < 0){
+    printf("LFS unmounting error\n");
+    return -1;
+  }
+
+
+  //+------------------------------------------------------
+  //| Print the LFS image as a C array
+  //+------------------------------------------------------
+
+  printf("// Newlib File System Initialization\n");
+  printf("//\n");
+  printf("// Autogenerated by dramfs_mkfs utility\n");
+  printf("\n");
+  printf("#include <sys/types.h>\n");
+  printf("#include <machine/lfs.h>\n");
+  printf("#include <machine/lfs_bd.h>\n");
+  printf("\n");
+
+  printf( "// LFS configuration\n"
+          "struct lfs_config dramfs_fs_cfg = {\n"
+          "    // block device operations: lfs_bd.h\n"
+          "    .read  = lfs_read,\n"
+          "    .prog  = lfs_prog,\n"
+          "    .erase = lfs_erase,\n"
+          "    .sync  = lfs_sync,\n"
+          "\n"
+          "    // block device default configuration\n"
+          "    .read_size   = 32,\n"
+          "    .prog_size   = 32,\n"
+          "    .block_size  = %d,\n"
+          "    .block_count = %d,\n"
+          "    .lookahead   = 32\n"
+          "};\n\n", block_size, block_count);
+
+  printf("lfs_t dramfs_fs;\n");
+
+  printf("uint8_t lfs_mem[] = {\n");
+  
+  // dump fs memory to stdout in C array format
+  for(int i=0; i < block_size*block_count; i++) {
+    printf("0x%0x", lfs_ptr[i]);
+
+    if(i != (block_size*block_count) - 1)
+      putchar(',');
+
+    putchar('\n');
+  }
+
+  printf("};");
+
+  return 0;
+}
diff --git a/libgloss/dramfs/dramfs/dramfs_util.c b/libgloss/dramfs/dramfs/dramfs_util.c
new file mode 100644
index 000000000..3b5e4aed9
--- /dev/null
+++ b/libgloss/dramfs/dramfs/dramfs_util.c
@@ -0,0 +1,101 @@
+// Newlib utility functions
+//
+// Bandhav Veluri
+// 08/15/2019
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <string.h>
+#include "dramfs_util.h"
+
+int is_file(const char* path) {
+	struct stat s;
+	stat(path, &s);
+	return S_ISREG(s.st_mode);
+}
+
+int is_dir(const char* path) {
+	struct stat s;
+	stat(path, &s);
+	return S_ISDIR(s.st_mode);
+}
+
+int cp_file_to_lfs(const char* path, lfs_t* lfs) {
+	if(!is_file(path)) {
+		return -1;
+	}
+
+  // open input file for reading
+  FILE *infile = fopen(path, "r");
+  if(infile == NULL) {
+  	fprintf(stderr, "Error opening input file %s\n", path);
+  	return -1;
+  }
+
+  // create a lfs file for writing
+  lfs_file_t lfs_file;
+  if(lfs_file_open(lfs, &lfs_file, path, LFS_O_WRONLY | LFS_O_CREAT) < 0) {
+  	fprintf(stderr, "LFS file open error %s\n", path);
+  	return -1;
+  }
+
+  int c = fgetc(infile);
+  while (c != EOF) {
+  	lfs_file_write(lfs, &lfs_file, &c, 1);
+  	c = fgetc(infile);
+  }
+
+  fclose(infile);
+  lfs_file_close(lfs, &lfs_file);
+
+	return 0;
+}
+
+int lfs_cp(const char* path, lfs_t* lfs) {
+	if(is_file(path)) {
+		return cp_file_to_lfs(path, lfs);
+	} else if(is_dir(path)) {
+		DIR* dir;
+		struct dirent* ent;
+
+		if(dir = opendir(path)) {
+			if(lfs_mkdir(lfs, path) < 0) {
+				fprintf(stderr, "LFS COPY: Error creating %s in lfs\n", path);
+				return -1;
+			}
+
+			while(ent = readdir(dir)) {
+				// Build the full path of file or dir
+				char sep[] = "/";
+				char* ent_full_path = (char*) malloc(strlen(path)+strlen(sep)+strlen(ent->d_name)+1);
+				strcpy(ent_full_path, path);
+				strcat(ent_full_path, sep);
+				strcat(ent_full_path, ent->d_name);
+
+				if((strcmp(ent->d_name, ".") == 0) | (strcmp(ent->d_name, "..")==0)) {
+					continue;
+				} else {
+					if(ent->d_type == DT_REG) {
+						if(cp_file_to_lfs(ent_full_path, lfs) < 0) 
+							return -1;
+					} else if(ent->d_type == DT_DIR) {
+						// Recursively copy the dir
+						if(lfs_cp(ent_full_path, lfs) < 0)
+							return -1;
+					}
+				}
+			}
+
+			return 0;
+		} else {
+			fprintf(stderr, "LFS COPY: Error opening directory %s\n", path);
+			return -1;
+		}
+	}
+
+	fprintf(stderr, "LFS COPY: argument should be a file or directory\n");
+	return -1;
+}
diff --git a/libgloss/dramfs/dramfs/dramfs_util.h b/libgloss/dramfs/dramfs/dramfs_util.h
new file mode 100644
index 000000000..3c68c46d7
--- /dev/null
+++ b/libgloss/dramfs/dramfs/dramfs_util.h
@@ -0,0 +1,13 @@
+#include "lfs.h"
+
+// Check if a path is a regular file
+int is_file(const char*);
+
+// Check if a path is a directory
+int is_dir(const char*);
+
+// Copy a file to lfs struct
+int cp_file_to_lfs(const char*, lfs_t*);
+
+// Copy a file/directory recursively to lfs struct
+int lfs_cp(const char*, lfs_t*);
diff --git a/libgloss/dramfs/dramfs/littlefs b/libgloss/dramfs/dramfs/littlefs
new file mode 160000
index 000000000..611c9b20d
--- /dev/null
+++ b/libgloss/dramfs/dramfs/littlefs
@@ -0,0 +1 @@
+Subproject commit 611c9b20db2b99faee261daa7cc9bbe175d3eaca
diff --git a/libgloss/dramfs/sys_close.c b/libgloss/dramfs/sys_close.c
new file mode 100644
index 000000000..864a3beed
--- /dev/null
+++ b/libgloss/dramfs/sys_close.c
@@ -0,0 +1,14 @@
+#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..d4a298b2e
--- /dev/null
+++ b/libgloss/dramfs/sys_execve.c
@@ -0,0 +1,13 @@
+#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..6be34a868
--- /dev/null
+++ b/libgloss/dramfs/sys_exit.c
@@ -0,0 +1,14 @@
+#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..db808492f
--- /dev/null
+++ b/libgloss/dramfs/sys_fork.c
@@ -0,0 +1,12 @@
+#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..df5ded6df
--- /dev/null
+++ b/libgloss/dramfs/sys_fstat.c
@@ -0,0 +1,21 @@
+#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..dc0ae9272
--- /dev/null
+++ b/libgloss/dramfs/sys_getpid.c
@@ -0,0 +1,9 @@
+/* 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..c362ef182
--- /dev/null
+++ b/libgloss/dramfs/sys_gettimeofday.c
@@ -0,0 +1,13 @@
+#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..479291135
--- /dev/null
+++ b/libgloss/dramfs/sys_isatty.c
@@ -0,0 +1,9 @@
+/* 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..32c4d2422
--- /dev/null
+++ b/libgloss/dramfs/sys_kill.c
@@ -0,0 +1,13 @@
+#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..3c33977be
--- /dev/null
+++ b/libgloss/dramfs/sys_link.c
@@ -0,0 +1,11 @@
+#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..746041759
--- /dev/null
+++ b/libgloss/dramfs/sys_lseek.c
@@ -0,0 +1,17 @@
+#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..48a4830cd
--- /dev/null
+++ b/libgloss/dramfs/sys_open.c
@@ -0,0 +1,37 @@
+#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..d5a382c38
--- /dev/null
+++ b/libgloss/dramfs/sys_read.c
@@ -0,0 +1,40 @@
+#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..8c2eea688
--- /dev/null
+++ b/libgloss/dramfs/sys_sbrk.c
@@ -0,0 +1,22 @@
+// 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..a9d6ad4d3
--- /dev/null
+++ b/libgloss/dramfs/sys_stat.c
@@ -0,0 +1,23 @@
+#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..4856817bb
--- /dev/null
+++ b/libgloss/dramfs/sys_times.c
@@ -0,0 +1,8 @@
+#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..677b81603
--- /dev/null
+++ b/libgloss/dramfs/sys_unlink.c
@@ -0,0 +1,12 @@
+#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..44a3512fb
--- /dev/null
+++ b/libgloss/dramfs/sys_wait.c
@@ -0,0 +1,12 @@
+#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..76370331d
--- /dev/null
+++ b/libgloss/dramfs/sys_write.c
@@ -0,0 +1,25 @@
+#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


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 2/2] Adding lfs_mem.c
  2023-08-01 23:54 [PATCH 1/2] Adding a LittleFS-based self-contained target to libgloss Dan Petrisko
@ 2023-08-01 23:54 ` 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
  2 siblings, 0 replies; 13+ messages in thread
From: Dan Petrisko @ 2023-08-01 23:54 UTC (permalink / raw)
  To: newlib; +Cc: Dan Petrisko

---
 libgloss/dramfs/lfs_mem.c | 8225 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 8225 insertions(+)
 create mode 100644 libgloss/dramfs/lfs_mem.c

diff --git a/libgloss/dramfs/lfs_mem.c b/libgloss/dramfs/lfs_mem.c
new file mode 100644
index 000000000..cf1a0b8fb
--- /dev/null
+++ b/libgloss/dramfs/lfs_mem.c
@@ -0,0 +1,8225 @@
+// Default Newlib File System Initialization
+//
+// Generated by dramfs_mkfs utility
+// dramfs_mklfs 128 64
+
+#include <sys/types.h>
+#include "lfs.h"
+#include "lfs_bd.h"
+
+// Dummy functions needed by crt0.S
+void __attribute__((weak)) dramfs_sendchar(char ch) {}
+int __attribute__((weak)) dramfs_getchar(void) {}
+void __attribute__((weak)) dramfs_exit(int exit_status) {}
+
+// LFS configuration
+struct lfs_config __attribute__((weak)) dramfs_fs_cfg = {
+    // block device operations: lfs_bd.h
+    .read  = lfs_read,
+    .prog  = lfs_prog,
+    .erase = lfs_erase,
+    .sync  = lfs_sync,
+
+    // block device default configuration
+    .read_size   = 32,
+    .prog_size   = 32,
+    .block_size  = 128,
+    .block_count = 64,
+    .lookahead   = 32
+};
+
+lfs_t __attribute__((weak)) dramfs_fs;
+uint8_t __attribute__((weak)) lfs_mem[] = {
+0x3,
+0x0,
+0x0,
+0x0,
+0x34,
+0x0,
+0x0,
+0x0,
+0x3,
+0x0,
+0x0,
+0x0,
+0x2,
+0x0,
+0x0,
+0x0,
+0x2e,
+0x14,
+0x0,
+0x8,
+0x3,
+0x0,
+0x0,
+0x0,
+0x2,
+0x0,
+0x0,
+0x0,
+0x80,
+0x0,
+0x0,
+0x0,
+0x40,
+0x0,
+0x0,
+0x0,
+0x1,
+0x0,
+0x1,
+0x0,
+0x6c,
+0x69,
+0x74,
+0x74,
+0x6c,
+0x65,
+0x66,
+0x73,
+0x2c,
+0x43,
+0x7c,
+0x73,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x2,
+0x0,
+0x0,
+0x0,
+0x34,
+0x0,
+0x0,
+0x0,
+0x3,
+0x0,
+0x0,
+0x0,
+0x2,
+0x0,
+0x0,
+0x0,
+0x2e,
+0x14,
+0x0,
+0x8,
+0x3,
+0x0,
+0x0,
+0x0,
+0x2,
+0x0,
+0x0,
+0x0,
+0x80,
+0x0,
+0x0,
+0x0,
+0x40,
+0x0,
+0x0,
+0x0,
+0x1,
+0x0,
+0x1,
+0x0,
+0x6c,
+0x69,
+0x74,
+0x74,
+0x6c,
+0x65,
+0x66,
+0x73,
+0xf0,
+0xaf,
+0xcd,
+0x4e,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x5,
+0x0,
+0x0,
+0x0,
+0x49,
+0x0,
+0x0,
+0x0,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x11,
+0x8,
+0x0,
+0x5,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x73,
+0x74,
+0x64,
+0x69,
+0x6e,
+0x11,
+0x8,
+0x0,
+0x6,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x73,
+0x74,
+0x64,
+0x6f,
+0x75,
+0x74,
+0x11,
+0x8,
+0x0,
+0x6,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x73,
+0x74,
+0x64,
+0x65,
+0x72,
+0x72,
+0x61,
+0xfc,
+0xe5,
+0x1,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x4,
+0x0,
+0x0,
+0x0,
+0x37,
+0x0,
+0x0,
+0x0,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x11,
+0x8,
+0x0,
+0x5,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x73,
+0x74,
+0x64,
+0x69,
+0x6e,
+0x11,
+0x8,
+0x0,
+0x6,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x73,
+0x74,
+0x64,
+0x6f,
+0x75,
+0x74,
+0x15,
+0x4f,
+0xac,
+0x38,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0
+};
-- 
2.16.5


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/2] Adding a LittleFS-based self-contained target to libgloss
  2023-08-01 23:54 [PATCH 1/2] Adding a LittleFS-based self-contained target to libgloss Dan Petrisko
  2023-08-01 23:54 ` [PATCH 2/2] Adding lfs_mem.c Dan Petrisko
@ 2023-08-09 10:04 ` Corinna Vinschen
  2023-08-09 19:12 ` Jeff Johnston
  2 siblings, 0 replies; 13+ messages in thread
From: Corinna Vinschen @ 2023-08-09 10:04 UTC (permalink / raw)
  To: Jeff Johnston; +Cc: newlib, Dan Petrisko

Ping Jeff.

On Aug  1 16:54, Dan Petrisko wrote:
> 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>
> ---
> 
> Hello, this is my first time submitting a patch, so let me know of any etiquete errors in addition
> to code errors...
> 
> This patch adds support for *-*-*-dramfs targets, which is a kind of pseudo-BSP which allows you to
> support a filesystem without any I/O hardware support. This is very useful for folks
> developing their own processor cores, or bringing up systems without another host managing a shim
> layer. It relies on ARM LittleFS to create a DRAM-based file system which is prepopulated by the
> user compiling the program. However, once it is created the user is able to use open, write, read
> etc. calls like normal.
> 
> The tool for creating the filesystem (dramfs_mklfs) is included in this
> patch, although it would be reasonable to extract it to its own repo if folks think it's orthogonal
> enough.
> 
> It also adds LittleFS as a submodule to newlib, which I would guess is undesired. However, it's
> required as part of the build process, so not sure what's the preferred way of dealing with that.
> 
> More info is available at: https://github.com/bespoke-silicon-group/bsg_newlib_dramfs/tree/dramfs
> 
> Thanks!
> 
>  .gitmodules                             |   3 +
>  COPYING.LIBGLOSS                        |  27 +++
>  libgloss/dramfs/Makefile.in             | 304 ++++++++++++++++++++++++++++++++
>  libgloss/dramfs/README.md               | 207 ++++++++++++++++++++++
>  libgloss/dramfs/configure.in            |  45 +++++
>  libgloss/dramfs/dramfs/dramfs_fdtable.c |  62 +++++++
>  libgloss/dramfs/dramfs/dramfs_fdtable.h |  23 +++
>  libgloss/dramfs/dramfs/dramfs_fs.c      |  35 ++++
>  libgloss/dramfs/dramfs/dramfs_fs.h      |  32 ++++
>  libgloss/dramfs/dramfs/dramfs_mklfs.c   | 154 ++++++++++++++++
>  libgloss/dramfs/dramfs/dramfs_util.c    | 101 +++++++++++
>  libgloss/dramfs/dramfs/dramfs_util.h    |  13 ++
>  libgloss/dramfs/dramfs/littlefs         |   1 +
>  libgloss/dramfs/sys_close.c             |  14 ++
>  libgloss/dramfs/sys_execve.c            |  13 ++
>  libgloss/dramfs/sys_exit.c              |  14 ++
>  libgloss/dramfs/sys_fork.c              |  12 ++
>  libgloss/dramfs/sys_fstat.c             |  21 +++
>  libgloss/dramfs/sys_getpid.c            |   9 +
>  libgloss/dramfs/sys_gettimeofday.c      |  13 ++
>  libgloss/dramfs/sys_isatty.c            |   9 +
>  libgloss/dramfs/sys_kill.c              |  13 ++
>  libgloss/dramfs/sys_link.c              |  11 ++
>  libgloss/dramfs/sys_lseek.c             |  17 ++
>  libgloss/dramfs/sys_open.c              |  37 ++++
>  libgloss/dramfs/sys_read.c              |  40 +++++
>  libgloss/dramfs/sys_sbrk.c              |  22 +++
>  libgloss/dramfs/sys_stat.c              |  23 +++
>  libgloss/dramfs/sys_times.c             |   8 +
>  libgloss/dramfs/sys_unlink.c            |  12 ++
>  libgloss/dramfs/sys_wait.c              |  12 ++
>  libgloss/dramfs/sys_write.c             |  25 +++
>  32 files changed, 1332 insertions(+)
>  create mode 100644 .gitmodules
>  create mode 100644 libgloss/dramfs/Makefile.in
>  create mode 100644 libgloss/dramfs/README.md
>  create mode 100644 libgloss/dramfs/configure.in
>  create mode 100644 libgloss/dramfs/dramfs/dramfs_fdtable.c
>  create mode 100644 libgloss/dramfs/dramfs/dramfs_fdtable.h
>  create mode 100644 libgloss/dramfs/dramfs/dramfs_fs.c
>  create mode 100644 libgloss/dramfs/dramfs/dramfs_fs.h
>  create mode 100644 libgloss/dramfs/dramfs/dramfs_mklfs.c
>  create mode 100644 libgloss/dramfs/dramfs/dramfs_util.c
>  create mode 100644 libgloss/dramfs/dramfs/dramfs_util.h
>  create mode 160000 libgloss/dramfs/dramfs/littlefs
>  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..4692df17b
> --- /dev/null
> +++ b/.gitmodules
> @@ -0,0 +1,3 @@
> +[submodule "libgloss/dramfs/dramfs/littlefs"]
> +	path = libgloss/dramfs/dramfs/littlefs
> +	url = https://github.com/littlefs-project/littlefs.git
> 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/libgloss/dramfs/Makefile.in b/libgloss/dramfs/Makefile.in
> new file mode 100644
> index 000000000..a0d8b99a9
> --- /dev/null
> +++ b/libgloss/dramfs/Makefile.in
> @@ -0,0 +1,304 @@
> +#----------------------------------------------------------------------
> +# Newlib File System sources
> +#----------------------------------------------------------------------
> +
> +dramfs_incs = \
> +	-I@srcdir@/dramfs \
> +	-I@srcdir@/dramfs/littlefs/lfs \
> +	-I@srcdir@/dramfs/littlefs/bd
> +
> +dramfs_srcs = \
> +	lfs_mem.c \
> +	dramfs_fs.c \
> +	dramfs_fdtable.c \
> +	lfs.c \
> +	lfs_util.c \
> +	lfs_bd.c
> +
> +dramfs_hdrs = \
> +	dramfs/dramfs_fs.h \
> +	dramfs/dramfs_fdtable.h \
> +	dramfs/littlefs/lfs/lfs.h \
> +	dramfs/littlefs/bd/lfs_bd.h
> +
> +dramfs_mkfs_srcs = \
> +	dramfs_mklfs.c \
> +	dramfs_util.c \
> +	lfs.c \
> +	lfs_util.c \
> +	lfs_bd.c
> +
> +dramfs_mkfs_bin = \
> +	dramfs_mklfs
> +
> +#-------------------------------------------------------------------------
> +# 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
> +
> +#-------------------------------------------------------------------------
> +# NEWLIB FS build rules 
> +#-------------------------------------------------------------------------
> +
> +dramfs_objs = $(patsubst %.c, %.o, $(dramfs_srcs))
> +
> +vpath %.c @srcdir@/dramfs @srcdir@/dramfs/littlefs/lfs @srcdir@/dramfs/littlefs/bd
> +
> +DRAMFS_CC     = @CC@
> +DRAMFS_CFLAGS = -O1
> +DRAMFS_CFLAGS += $(dramfs_incs)
> +DRAMFS_CFLAGS += -std=c99 -mcmodel=medany
> +DRAMFS_CFLAGS += -DLFS_NO_ASSERT -DLFS_NO_DEBUG \
> +                        -DLFS_NO_WARN -DLFS_NO_ERROR -DLFS_NO_INTRINSICS
> +
> +$(dramfs_objs): %.o : %.c
> +	$(DRAMFS_CC) $(DRAMFS_CFLAGS) -c $< -o $@
> +
> +gloss_hdrs += $(dramfs_hdrs)
> +gloss_objs += $(dramfs_objs)
> +junk += $(dramfs_objs)
> +
> +#-------------------------------------------------------------------------
> +# NEWLIB mkfs rules 
> +#-------------------------------------------------------------------------
> +
> +dramfs_mkfs_objs = $(patsubst %.c, %_host.o, $(dramfs_mkfs_srcs))
> +
> +DRAMFS_MKFS_CC     = gcc
> +DRAMFS_MKFS_CFLAGS = -O1
> +DRAMFS_MKFS_CFLAGS += $(dramfs_incs)
> +DRAMFS_MKFS_CFLAGS += -std=gnu99
> +
> +$(dramfs_mkfs_objs): %_host.o : %.c
> +	$(DRAMFS_MKFS_CC) $(DRAMFS_MKFS_CFLAGS) -c $< -o $@
> +
> +$(dramfs_mkfs_bin): $(dramfs_mkfs_objs)
> +	$(DRAMFS_MKFS_CC) $(dramfs_mkfs_objs) -o $@
> +
> +gloss_bins += $(dramfs_mkfs_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..77c482779
> --- /dev/null
> +++ b/libgloss/dramfs/README.md
> @@ -0,0 +1,207 @@
> +# 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;
> +}
> +```
> +
> +## Usage
> +
> +Running a program with Newlib/Dramfs requires user to link an additional file consisting of initial LittleFS image with input files to the program. LittleFS image can be automatically generated by a tool called `dramfs_mklfs` that has already been installed with this BSP! The tool needs two parameters `lfs_block_size` and `lfs_block_count`. Total size of the file-system would be `lfs_block_size*lfs_block_count`. See [2] for information about how to play with these parameters to improve performance.
> +
> +Usage of `dramfs_mklfs`:
> +```
> +dramfs_mklfs <lfs_block_size> <lfs_block_count> <inputfile1> <inputdir1> <inputfile2> ...
> +```
> +
> +After installation and porting, the procedure for running programs with Newlib/Dramfs is summarized by a sample program below. Let's say we want to run a file i/o program on a bare metal system which takes `hello.txt` as input.
> +
> +```
> +$ cat fhello.c 
> +/*
> + * fhello.c
> + */
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +
> +int main() {
> +  int c;
> +
> +  /* Open hello.txt for reading */
> +  FILE *hello = fopen("hello.txt", "r");
> +  if(hello == NULL)
> +    return -1;
> +
> +
> +  /* Iterate through the entire file
> +   * and print the contents to stdout
> +   */
> +
> +  putchar('\n');
> +
> +  while((c = fgetc(hello)) != EOF) {
> +    putchar(c);
> +  }
> +
> +  fclose(hello);
> +  return 0;
> +}
> +$ cat hello.txt 
> +Hello! This is Little FS!
> +$ dramfs_mklfs 128 256 hello.txt > lfs_mem.c
> +$ <xxx>-<xxx>-<xxx>dramfs-gcc -c crt.S lfs_mem.c dramfs_intf.c fhello.c
> +$ <xxx>-<xxx>-<xxx>dramfs-gcc -nostartfiles -T link.ld lfs_mem.o crt.o dramfs_intf.o fhello.o  -o fhello
> +$ <Your system's runtime executable> fhello
> +
> +Hello! This is Little FS!
> +```
> +
> +## 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/configure.in b/libgloss/dramfs/configure.in
> new file mode 100644
> index 000000000..5694013d4
> --- /dev/null
> +++ b/libgloss/dramfs/configure.in
> @@ -0,0 +1,45 @@
> +#=========================================================================
> +# configure.ac for riscv libgloss and crt0
> +#=========================================================================
> +
> +#-------------------------------------------------------------------------
> +# Setup
> +#-------------------------------------------------------------------------
> +
> +AC_INIT([crt0.S])
> +AC_CONFIG_SRCDIR([crt0.S])
> +AC_CONFIG_AUX_DIR([${srcdir}/../..])
> +
> +#-------------------------------------------------------------------------
> +# Checks for programs
> +#-------------------------------------------------------------------------
> +
> +LIB_AC_PROG_CC
> +AC_CHECK_TOOL([AR],[ar])
> +AC_CHECK_TOOL([RANLIB],[ranlib])
> +AC_PROG_INSTALL
> +
> +#-------------------------------------------------------------------------
> +# Output
> +#-------------------------------------------------------------------------
> +
> +if test "$srcdir" = "." ; then
> +  if test "${with_target_subdir}" != "." ; then
> +    libgloss_topdir="${srcdir}/${with_multisrctop}../../.."
> +  else
> +    libgloss_topdir="${srcdir}/${with_multisrctop}../.."
> +  fi
> +else
> +  libgloss_topdir="${srcdir}/../.."
> +fi
> +AC_CONFIG_AUX_DIR($libgloss_topdir)
> +AC_CONFIG_FILES(Makefile,
> +. ${libgloss_topdir}/config-ml.in,
> +srcdir=${srcdir}
> +target=${target}
> +with_multisubdir=${with_multisubdir}
> +ac_configure_args="${ac_configure_args} --enable-multilib"
> +CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
> +libgloss_topdir=${libgloss_topdir}
> +)
> +AC_OUTPUT
> diff --git a/libgloss/dramfs/dramfs/dramfs_fdtable.c b/libgloss/dramfs/dramfs/dramfs_fdtable.c
> new file mode 100644
> index 000000000..32cfb28f9
> --- /dev/null
> +++ b/libgloss/dramfs/dramfs/dramfs_fdtable.c
> @@ -0,0 +1,62 @@
> +#include "dramfs_fdtable.h"
> +#include "dramfs_fs.h"
> +
> +typedef struct dramfs_fd_entry {
> +  int used;
> +  int nonblock;
> +  lfs_file_t file;
> +} dramfs_fd_entry_t;
> +
> +static dramfs_fd_entry_t dramfs_fdtable[DRAMFS_MAX_FDS];
> +
> +void dramfs_init_fdtable(void) {
> +  for(int i=0; i<DRAMFS_MAX_FDS; i++) {
> +    dramfs_fdtable[i].used = 0;
> +    dramfs_fdtable[i].nonblock = 0;
> +  }
> +}
> +
> +int dramfs_check_fd(int fd) {
> +  if(fd < 0 || fd >= DRAMFS_MAX_FDS || dramfs_fdtable[fd].used == 0) {
> +    errno = EBADF;
> +    return -1;
> +  }
> +
> +  return 0;
> +}
> +
> +int dramfs_nonblock_fd(int fd) {
> +  if(dramfs_fdtable[fd].nonblock == 1) {
> +    return 1;
> +  }
> +
> +  return 0;
> +}
> +
> +int dramfs_reserve_fd(void) {
> +  int fd = 0;
> +
> +  for(;fd < DRAMFS_MAX_FDS; fd++) {
> +    if(dramfs_fdtable[fd].used == 0) {
> +      dramfs_fdtable[fd].used = 1;
> +      return fd;
> +    }
> +  }
> +
> +  errno = ENFILE;
> +  return -1;
> +}
> +
> +lfs_file_t *dramfs_get_file(int fd) {
> +  return &dramfs_fdtable[fd].file;
> +}
> +
> +int dramfs_free_fd(int fd) {
> +  if (dramfs_fdtable[fd].used == 1) {
> +    lfs_file_t *fptr = dramfs_get_file(fd);
> +    dramfs_fdtable[fd].used = 0;
> +    return lfs_file_close(&dramfs_fs, fptr);
> +  } else {
> +    return 0;
> +  }
> +}
> diff --git a/libgloss/dramfs/dramfs/dramfs_fdtable.h b/libgloss/dramfs/dramfs/dramfs_fdtable.h
> new file mode 100644
> index 000000000..f26fd7613
> --- /dev/null
> +++ b/libgloss/dramfs/dramfs/dramfs_fdtable.h
> @@ -0,0 +1,23 @@
> +#ifndef DRAMFS_FDTABLE_H
> +#define DRAMFS_FDTABLE_H
> +
> +#include <errno.h>
> +#include "lfs.h"
> +
> +#ifndef DRAMFS_MAX_FDS
> +#define DRAMFS_MAX_FDS 20
> +#endif
> +
> +void dramfs_init_fdtable(void);
> +
> +int dramfs_check_fd(int fd);
> +
> +int dramfs_nonblock_fd(int fd);
> +
> +int dramfs_reserve_fd(void);
> +
> +int dramfs_free_fd(int fd);
> +
> +lfs_file_t *dramfs_get_file(int fd);
> +
> +#endif // DRAMFS_FDTABLE_H
> diff --git a/libgloss/dramfs/dramfs/dramfs_fs.c b/libgloss/dramfs/dramfs/dramfs_fs.c
> new file mode 100644
> index 000000000..b4d6c51ae
> --- /dev/null
> +++ b/libgloss/dramfs/dramfs/dramfs_fs.c
> @@ -0,0 +1,35 @@
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include "lfs.h"
> +#include "lfs_bd.h"
> +#include "dramfs_fs.h"
> +#include "dramfs_fdtable.h"
> +
> +// File system memory pointer
> +uint8_t* lfs_ptr = lfs_mem;
> +
> +// Init routine for Newlib FS
> +int dramfs_fs_init() {
> +  // initiate fdtable
> +  dramfs_init_fdtable();
> +
> +	// mount the file system
> +	if(lfs_mount(&dramfs_fs, &dramfs_fs_cfg) < 0) {
> +		return -1;
> +	}
> +
> +  // Open stdio files
> +  if(open("stdin", O_RDONLY) != 0) { 
> +    return -1;
> +  }
> +
> +  if(open("stdout", O_WRONLY) != 1) {
> +    return -1;
> +  }
> +
> +  if(open("stderr", O_WRONLY) != 2) {
> +    return -1;
> +  }
> +
> +	return 0;
> +}
> diff --git a/libgloss/dramfs/dramfs/dramfs_fs.h b/libgloss/dramfs/dramfs/dramfs_fs.h
> new file mode 100644
> index 000000000..94f38d37d
> --- /dev/null
> +++ b/libgloss/dramfs/dramfs/dramfs_fs.h
> @@ -0,0 +1,32 @@
> +#ifndef DRAMFS_FS_H
> +#define DRAMFS_FS_H
> +
> +#include "lfs.h"
> +
> +// Toplevel filesystem struct
> +extern lfs_t dramfs_fs;
> +
> +// File system configuration structure
> +// Initalized externally and can be generated by dramfs_mklfs
> +extern struct lfs_config dramfs_fs_cfg;
> +
> +// Array with initial LFS image
> +// Initialized externally and can be generated by dramfs_mklfs
> +extern uint8_t lfs_mem[];
> +
> +// Exit routine: exit() calls this routine
> +// Definition provided externally by user
> +extern void dramfs_exit(int);
> +
> +// Utility to print a char to console
> +// Definition provided externally by user
> +extern void dramfs_sendchar(char);
> +
> +// Utility to get a char from console
> +// Definition provided externally by user
> +extern int dramfs_getchar(void);
> +
> +// LFS init routine: Should be called before calling main
> +int dramfs_fs_init(void) __attribute__((weak));
> +
> +#endif // DRAMFS_FS_H
> diff --git a/libgloss/dramfs/dramfs/dramfs_mklfs.c b/libgloss/dramfs/dramfs/dramfs_mklfs.c
> new file mode 100644
> index 000000000..1bdf7d0f5
> --- /dev/null
> +++ b/libgloss/dramfs/dramfs/dramfs_mklfs.c
> @@ -0,0 +1,154 @@
> +// Program to create littlefs image comprising of input files/dirs
> +//
> +// Bandhav Veluri
> +// 03-07-2019
> +
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include "lfs.h"
> +#include "lfs_bd.h"
> +#include "dramfs_util.h"
> +
> +// Main file system struct
> +lfs_t lfs;
> +
> +// LFS configuration
> +struct lfs_config lfs_cfg = {
> +    // block device operations: lfs_bd.h
> +    .read  = lfs_read,
> +    .prog  = lfs_prog,
> +    .erase = lfs_erase,
> +    .sync  = lfs_sync,
> +
> +    // block device default configuration
> +    .read_size   = 32,
> +    .prog_size   = 32,
> +    .block_size  = 0,
> +    .block_count = 0,
> +    .lookahead   = 32
> +};
> +
> +// Pointer to filesystem memory
> +// lfs_bd uses this allocation as block device
> +uint8_t *lfs_ptr;
> +
> +int main(int argc, char *argv[]) {
> +  int block_size;
> +  int block_count;
> +  FILE *img; // output fs image file handler
> +
> +  if(argc < 3) {
> +    printf("Usage: dramfs_mklfs <block_size> <block_count> [input file(s)/dir(s)]\n");
> +    return -1;
> +  }
> +
> +  block_size = atoi(argv[1]);
> +  block_count = atoi(argv[2]);
> +
> +
> +  //+------------------------------------------------------
> +  //| Allocate memory for building Little FS image
> +  //+------------------------------------------------------
> +
> +  // memory allocation for lfs
> +  lfs_ptr = (char *) malloc(block_size*block_count);
> +
> +  // configure the size
> +  lfs_cfg.block_size = block_size;
> +  lfs_cfg.block_count = block_count;
> +
> +  // format the fs
> +  if(lfs_format(&lfs, &lfs_cfg) < 0) {
> +    printf("LFS format error\n");
> +    return -1;
> +  }
> +
> +  // mount the file system
> +  if(lfs_mount(&lfs, &lfs_cfg) < 0) {
> +    printf("LFS mount error\n");
> +    return -1;
> +  }
> +  
> +
> +  //+-------------------------------------------------------
> +  //| Create stdin, stdout and stderr files in the littlefs
> +  //+-------------------------------------------------------
> +    
> +  lfs_file_t lfs_stdin, lfs_stdout, lfs_stderr;
> +
> +  // Create stdio files
> +  lfs_file_open(&lfs, &lfs_stdin, "stdin", LFS_O_WRONLY | LFS_O_CREAT);
> +  lfs_file_open(&lfs, &lfs_stdout, "stdout", LFS_O_WRONLY | LFS_O_CREAT);
> +  lfs_file_open(&lfs, &lfs_stderr, "stderr", LFS_O_WRONLY | LFS_O_CREAT);
> +
> +  // Close stdio files
> +  lfs_file_close(&lfs, &lfs_stdin);
> +  lfs_file_close(&lfs, &lfs_stdout);
> +  lfs_file_close(&lfs, &lfs_stderr);
> +
> +
> +  //+-------------------------------------------------------
> +  //| Copy input files/dirs to LFS image
> +  //+-------------------------------------------------------
> +
> +  for(int i = 3; i < argc; i++) {
> +    if(lfs_cp(argv[i], &lfs) < 0)
> +      return -1;
> +  }
> +
> +  // Unmount lfs
> +  if(lfs_unmount(&lfs) < 0){
> +    printf("LFS unmounting error\n");
> +    return -1;
> +  }
> +
> +
> +  //+------------------------------------------------------
> +  //| Print the LFS image as a C array
> +  //+------------------------------------------------------
> +
> +  printf("// Newlib File System Initialization\n");
> +  printf("//\n");
> +  printf("// Autogenerated by dramfs_mkfs utility\n");
> +  printf("\n");
> +  printf("#include <sys/types.h>\n");
> +  printf("#include <machine/lfs.h>\n");
> +  printf("#include <machine/lfs_bd.h>\n");
> +  printf("\n");
> +
> +  printf( "// LFS configuration\n"
> +          "struct lfs_config dramfs_fs_cfg = {\n"
> +          "    // block device operations: lfs_bd.h\n"
> +          "    .read  = lfs_read,\n"
> +          "    .prog  = lfs_prog,\n"
> +          "    .erase = lfs_erase,\n"
> +          "    .sync  = lfs_sync,\n"
> +          "\n"
> +          "    // block device default configuration\n"
> +          "    .read_size   = 32,\n"
> +          "    .prog_size   = 32,\n"
> +          "    .block_size  = %d,\n"
> +          "    .block_count = %d,\n"
> +          "    .lookahead   = 32\n"
> +          "};\n\n", block_size, block_count);
> +
> +  printf("lfs_t dramfs_fs;\n");
> +
> +  printf("uint8_t lfs_mem[] = {\n");
> +  
> +  // dump fs memory to stdout in C array format
> +  for(int i=0; i < block_size*block_count; i++) {
> +    printf("0x%0x", lfs_ptr[i]);
> +
> +    if(i != (block_size*block_count) - 1)
> +      putchar(',');
> +
> +    putchar('\n');
> +  }
> +
> +  printf("};");
> +
> +  return 0;
> +}
> diff --git a/libgloss/dramfs/dramfs/dramfs_util.c b/libgloss/dramfs/dramfs/dramfs_util.c
> new file mode 100644
> index 000000000..3b5e4aed9
> --- /dev/null
> +++ b/libgloss/dramfs/dramfs/dramfs_util.c
> @@ -0,0 +1,101 @@
> +// Newlib utility functions
> +//
> +// Bandhav Veluri
> +// 08/15/2019
> +
> +#include <stdio.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <unistd.h>
> +#include <dirent.h>
> +#include <string.h>
> +#include "dramfs_util.h"
> +
> +int is_file(const char* path) {
> +	struct stat s;
> +	stat(path, &s);
> +	return S_ISREG(s.st_mode);
> +}
> +
> +int is_dir(const char* path) {
> +	struct stat s;
> +	stat(path, &s);
> +	return S_ISDIR(s.st_mode);
> +}
> +
> +int cp_file_to_lfs(const char* path, lfs_t* lfs) {
> +	if(!is_file(path)) {
> +		return -1;
> +	}
> +
> +  // open input file for reading
> +  FILE *infile = fopen(path, "r");
> +  if(infile == NULL) {
> +  	fprintf(stderr, "Error opening input file %s\n", path);
> +  	return -1;
> +  }
> +
> +  // create a lfs file for writing
> +  lfs_file_t lfs_file;
> +  if(lfs_file_open(lfs, &lfs_file, path, LFS_O_WRONLY | LFS_O_CREAT) < 0) {
> +  	fprintf(stderr, "LFS file open error %s\n", path);
> +  	return -1;
> +  }
> +
> +  int c = fgetc(infile);
> +  while (c != EOF) {
> +  	lfs_file_write(lfs, &lfs_file, &c, 1);
> +  	c = fgetc(infile);
> +  }
> +
> +  fclose(infile);
> +  lfs_file_close(lfs, &lfs_file);
> +
> +	return 0;
> +}
> +
> +int lfs_cp(const char* path, lfs_t* lfs) {
> +	if(is_file(path)) {
> +		return cp_file_to_lfs(path, lfs);
> +	} else if(is_dir(path)) {
> +		DIR* dir;
> +		struct dirent* ent;
> +
> +		if(dir = opendir(path)) {
> +			if(lfs_mkdir(lfs, path) < 0) {
> +				fprintf(stderr, "LFS COPY: Error creating %s in lfs\n", path);
> +				return -1;
> +			}
> +
> +			while(ent = readdir(dir)) {
> +				// Build the full path of file or dir
> +				char sep[] = "/";
> +				char* ent_full_path = (char*) malloc(strlen(path)+strlen(sep)+strlen(ent->d_name)+1);
> +				strcpy(ent_full_path, path);
> +				strcat(ent_full_path, sep);
> +				strcat(ent_full_path, ent->d_name);
> +
> +				if((strcmp(ent->d_name, ".") == 0) | (strcmp(ent->d_name, "..")==0)) {
> +					continue;
> +				} else {
> +					if(ent->d_type == DT_REG) {
> +						if(cp_file_to_lfs(ent_full_path, lfs) < 0) 
> +							return -1;
> +					} else if(ent->d_type == DT_DIR) {
> +						// Recursively copy the dir
> +						if(lfs_cp(ent_full_path, lfs) < 0)
> +							return -1;
> +					}
> +				}
> +			}
> +
> +			return 0;
> +		} else {
> +			fprintf(stderr, "LFS COPY: Error opening directory %s\n", path);
> +			return -1;
> +		}
> +	}
> +
> +	fprintf(stderr, "LFS COPY: argument should be a file or directory\n");
> +	return -1;
> +}
> diff --git a/libgloss/dramfs/dramfs/dramfs_util.h b/libgloss/dramfs/dramfs/dramfs_util.h
> new file mode 100644
> index 000000000..3c68c46d7
> --- /dev/null
> +++ b/libgloss/dramfs/dramfs/dramfs_util.h
> @@ -0,0 +1,13 @@
> +#include "lfs.h"
> +
> +// Check if a path is a regular file
> +int is_file(const char*);
> +
> +// Check if a path is a directory
> +int is_dir(const char*);
> +
> +// Copy a file to lfs struct
> +int cp_file_to_lfs(const char*, lfs_t*);
> +
> +// Copy a file/directory recursively to lfs struct
> +int lfs_cp(const char*, lfs_t*);
> diff --git a/libgloss/dramfs/dramfs/littlefs b/libgloss/dramfs/dramfs/littlefs
> new file mode 160000
> index 000000000..611c9b20d
> --- /dev/null
> +++ b/libgloss/dramfs/dramfs/littlefs
> @@ -0,0 +1 @@
> +Subproject commit 611c9b20db2b99faee261daa7cc9bbe175d3eaca
> diff --git a/libgloss/dramfs/sys_close.c b/libgloss/dramfs/sys_close.c
> new file mode 100644
> index 000000000..864a3beed
> --- /dev/null
> +++ b/libgloss/dramfs/sys_close.c
> @@ -0,0 +1,14 @@
> +#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..d4a298b2e
> --- /dev/null
> +++ b/libgloss/dramfs/sys_execve.c
> @@ -0,0 +1,13 @@
> +#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..6be34a868
> --- /dev/null
> +++ b/libgloss/dramfs/sys_exit.c
> @@ -0,0 +1,14 @@
> +#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..db808492f
> --- /dev/null
> +++ b/libgloss/dramfs/sys_fork.c
> @@ -0,0 +1,12 @@
> +#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..df5ded6df
> --- /dev/null
> +++ b/libgloss/dramfs/sys_fstat.c
> @@ -0,0 +1,21 @@
> +#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..dc0ae9272
> --- /dev/null
> +++ b/libgloss/dramfs/sys_getpid.c
> @@ -0,0 +1,9 @@
> +/* 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..c362ef182
> --- /dev/null
> +++ b/libgloss/dramfs/sys_gettimeofday.c
> @@ -0,0 +1,13 @@
> +#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..479291135
> --- /dev/null
> +++ b/libgloss/dramfs/sys_isatty.c
> @@ -0,0 +1,9 @@
> +/* 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..32c4d2422
> --- /dev/null
> +++ b/libgloss/dramfs/sys_kill.c
> @@ -0,0 +1,13 @@
> +#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..3c33977be
> --- /dev/null
> +++ b/libgloss/dramfs/sys_link.c
> @@ -0,0 +1,11 @@
> +#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..746041759
> --- /dev/null
> +++ b/libgloss/dramfs/sys_lseek.c
> @@ -0,0 +1,17 @@
> +#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..48a4830cd
> --- /dev/null
> +++ b/libgloss/dramfs/sys_open.c
> @@ -0,0 +1,37 @@
> +#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..d5a382c38
> --- /dev/null
> +++ b/libgloss/dramfs/sys_read.c
> @@ -0,0 +1,40 @@
> +#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..8c2eea688
> --- /dev/null
> +++ b/libgloss/dramfs/sys_sbrk.c
> @@ -0,0 +1,22 @@
> +// 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..a9d6ad4d3
> --- /dev/null
> +++ b/libgloss/dramfs/sys_stat.c
> @@ -0,0 +1,23 @@
> +#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..4856817bb
> --- /dev/null
> +++ b/libgloss/dramfs/sys_times.c
> @@ -0,0 +1,8 @@
> +#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..677b81603
> --- /dev/null
> +++ b/libgloss/dramfs/sys_unlink.c
> @@ -0,0 +1,12 @@
> +#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..44a3512fb
> --- /dev/null
> +++ b/libgloss/dramfs/sys_wait.c
> @@ -0,0 +1,12 @@
> +#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..76370331d
> --- /dev/null
> +++ b/libgloss/dramfs/sys_write.c
> @@ -0,0 +1,25 @@
> +#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


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/2] Adding a LittleFS-based self-contained target to libgloss
  2023-08-01 23:54 [PATCH 1/2] Adding a LittleFS-based self-contained target to libgloss 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
  2 siblings, 1 reply; 13+ messages in thread
From: Jeff Johnston @ 2023-08-09 19:12 UTC (permalink / raw)
  To: Dan Petrisko; +Cc: newlib

[-- Attachment #1: Type: text/plain, Size: 53912 bytes --]

Hi Dan,

Thanks for submitting your first patch.  For starters, all files you
contribute (other than generated ones) need to have
a license in them (no GPL license).  If you have any files you didn't write
or that you simply modified, you need to preserve the original licenses
that were
found in them.  As you figured, the sub-module isn't a good idea.  It would
be better if you had instructions on how
to check out the required module and then have the build use an option or
environment variable to find the needed elements.

-- Jeff J.

On Tue, Aug 1, 2023 at 7:55 PM Dan Petrisko <petrisko@cs.washington.edu>
wrote:

> 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>
> ---
>
> Hello, this is my first time submitting a patch, so let me know of any
> etiquete errors in addition
> to code errors...
>
> This patch adds support for *-*-*-dramfs targets, which is a kind of
> pseudo-BSP which allows you to
> support a filesystem without any I/O hardware support. This is very useful
> for folks
> developing their own processor cores, or bringing up systems without
> another host managing a shim
> layer. It relies on ARM LittleFS to create a DRAM-based file system which
> is prepopulated by the
> user compiling the program. However, once it is created the user is able
> to use open, write, read
> etc. calls like normal.
>
> The tool for creating the filesystem (dramfs_mklfs) is included in this
> patch, although it would be reasonable to extract it to its own repo if
> folks think it's orthogonal
> enough.
>
> It also adds LittleFS as a submodule to newlib, which I would guess is
> undesired. However, it's
> required as part of the build process, so not sure what's the preferred
> way of dealing with that.
>
> More info is available at:
> https://github.com/bespoke-silicon-group/bsg_newlib_dramfs/tree/dramfs
>
> Thanks!
>
>  .gitmodules                             |   3 +
>  COPYING.LIBGLOSS                        |  27 +++
>  libgloss/dramfs/Makefile.in             | 304
> ++++++++++++++++++++++++++++++++
>  libgloss/dramfs/README.md               | 207 ++++++++++++++++++++++
>  libgloss/dramfs/configure.in            |  45 +++++
>  libgloss/dramfs/dramfs/dramfs_fdtable.c |  62 +++++++
>  libgloss/dramfs/dramfs/dramfs_fdtable.h |  23 +++
>  libgloss/dramfs/dramfs/dramfs_fs.c      |  35 ++++
>  libgloss/dramfs/dramfs/dramfs_fs.h      |  32 ++++
>  libgloss/dramfs/dramfs/dramfs_mklfs.c   | 154 ++++++++++++++++
>  libgloss/dramfs/dramfs/dramfs_util.c    | 101 +++++++++++
>  libgloss/dramfs/dramfs/dramfs_util.h    |  13 ++
>  libgloss/dramfs/dramfs/littlefs         |   1 +
>  libgloss/dramfs/sys_close.c             |  14 ++
>  libgloss/dramfs/sys_execve.c            |  13 ++
>  libgloss/dramfs/sys_exit.c              |  14 ++
>  libgloss/dramfs/sys_fork.c              |  12 ++
>  libgloss/dramfs/sys_fstat.c             |  21 +++
>  libgloss/dramfs/sys_getpid.c            |   9 +
>  libgloss/dramfs/sys_gettimeofday.c      |  13 ++
>  libgloss/dramfs/sys_isatty.c            |   9 +
>  libgloss/dramfs/sys_kill.c              |  13 ++
>  libgloss/dramfs/sys_link.c              |  11 ++
>  libgloss/dramfs/sys_lseek.c             |  17 ++
>  libgloss/dramfs/sys_open.c              |  37 ++++
>  libgloss/dramfs/sys_read.c              |  40 +++++
>  libgloss/dramfs/sys_sbrk.c              |  22 +++
>  libgloss/dramfs/sys_stat.c              |  23 +++
>  libgloss/dramfs/sys_times.c             |   8 +
>  libgloss/dramfs/sys_unlink.c            |  12 ++
>  libgloss/dramfs/sys_wait.c              |  12 ++
>  libgloss/dramfs/sys_write.c             |  25 +++
>  32 files changed, 1332 insertions(+)
>  create mode 100644 .gitmodules
>  create mode 100644 libgloss/dramfs/Makefile.in
>  create mode 100644 libgloss/dramfs/README.md
>  create mode 100644 libgloss/dramfs/configure.in
>  create mode 100644 libgloss/dramfs/dramfs/dramfs_fdtable.c
>  create mode 100644 libgloss/dramfs/dramfs/dramfs_fdtable.h
>  create mode 100644 libgloss/dramfs/dramfs/dramfs_fs.c
>  create mode 100644 libgloss/dramfs/dramfs/dramfs_fs.h
>  create mode 100644 libgloss/dramfs/dramfs/dramfs_mklfs.c
>  create mode 100644 libgloss/dramfs/dramfs/dramfs_util.c
>  create mode 100644 libgloss/dramfs/dramfs/dramfs_util.h
>  create mode 160000 libgloss/dramfs/dramfs/littlefs
>  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..4692df17b
> --- /dev/null
> +++ b/.gitmodules
> @@ -0,0 +1,3 @@
> +[submodule "libgloss/dramfs/dramfs/littlefs"]
> +       path = libgloss/dramfs/dramfs/littlefs
> +       url = https://github.com/littlefs-project/littlefs.git
> 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/libgloss/dramfs/Makefile.in b/libgloss/dramfs/Makefile.in
> new file mode 100644
> index 000000000..a0d8b99a9
> --- /dev/null
> +++ b/libgloss/dramfs/Makefile.in
> @@ -0,0 +1,304 @@
> +#----------------------------------------------------------------------
> +# Newlib File System sources
> +#----------------------------------------------------------------------
> +
> +dramfs_incs = \
> +       -I@srcdir@/dramfs \
> +       -I@srcdir@/dramfs/littlefs/lfs \
> +       -I@srcdir@/dramfs/littlefs/bd
> +
> +dramfs_srcs = \
> +       lfs_mem.c \
> +       dramfs_fs.c \
> +       dramfs_fdtable.c \
> +       lfs.c \
> +       lfs_util.c \
> +       lfs_bd.c
> +
> +dramfs_hdrs = \
> +       dramfs/dramfs_fs.h \
> +       dramfs/dramfs_fdtable.h \
> +       dramfs/littlefs/lfs/lfs.h \
> +       dramfs/littlefs/bd/lfs_bd.h
> +
> +dramfs_mkfs_srcs = \
> +       dramfs_mklfs.c \
> +       dramfs_util.c \
> +       lfs.c \
> +       lfs_util.c \
> +       lfs_bd.c
> +
> +dramfs_mkfs_bin = \
> +       dramfs_mklfs
> +
> +#-------------------------------------------------------------------------
> +# 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
> +
> +#-------------------------------------------------------------------------
> +# NEWLIB FS build rules
> +#-------------------------------------------------------------------------
> +
> +dramfs_objs = $(patsubst %.c, %.o, $(dramfs_srcs))
> +
> +vpath %.c @srcdir@/dramfs @srcdir@/dramfs/littlefs/lfs @srcdir@
> /dramfs/littlefs/bd
> +
> +DRAMFS_CC     = @CC@
> +DRAMFS_CFLAGS = -O1
> +DRAMFS_CFLAGS += $(dramfs_incs)
> +DRAMFS_CFLAGS += -std=c99 -mcmodel=medany
> +DRAMFS_CFLAGS += -DLFS_NO_ASSERT -DLFS_NO_DEBUG \
> +                        -DLFS_NO_WARN -DLFS_NO_ERROR -DLFS_NO_INTRINSICS
> +
> +$(dramfs_objs): %.o : %.c
> +       $(DRAMFS_CC) $(DRAMFS_CFLAGS) -c $< -o $@
> +
> +gloss_hdrs += $(dramfs_hdrs)
> +gloss_objs += $(dramfs_objs)
> +junk += $(dramfs_objs)
> +
> +#-------------------------------------------------------------------------
> +# NEWLIB mkfs rules
> +#-------------------------------------------------------------------------
> +
> +dramfs_mkfs_objs = $(patsubst %.c, %_host.o, $(dramfs_mkfs_srcs))
> +
> +DRAMFS_MKFS_CC     = gcc
> +DRAMFS_MKFS_CFLAGS = -O1
> +DRAMFS_MKFS_CFLAGS += $(dramfs_incs)
> +DRAMFS_MKFS_CFLAGS += -std=gnu99
> +
> +$(dramfs_mkfs_objs): %_host.o : %.c
> +       $(DRAMFS_MKFS_CC) $(DRAMFS_MKFS_CFLAGS) -c $< -o $@
> +
> +$(dramfs_mkfs_bin): $(dramfs_mkfs_objs)
> +       $(DRAMFS_MKFS_CC) $(dramfs_mkfs_objs) -o $@
> +
> +gloss_bins += $(dramfs_mkfs_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..77c482779
> --- /dev/null
> +++ b/libgloss/dramfs/README.md
> @@ -0,0 +1,207 @@
> +# 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;
> +}
> +```
> +
> +## Usage
> +
> +Running a program with Newlib/Dramfs requires user to link an additional
> file consisting of initial LittleFS image with input files to the program.
> LittleFS image can be automatically generated by a tool called
> `dramfs_mklfs` that has already been installed with this BSP! The tool
> needs two parameters `lfs_block_size` and `lfs_block_count`. Total size of
> the file-system would be `lfs_block_size*lfs_block_count`. See [2] for
> information about how to play with these parameters to improve performance.
> +
> +Usage of `dramfs_mklfs`:
> +```
> +dramfs_mklfs <lfs_block_size> <lfs_block_count> <inputfile1> <inputdir1>
> <inputfile2> ...
> +```
> +
> +After installation and porting, the procedure for running programs with
> Newlib/Dramfs is summarized by a sample program below. Let's say we want to
> run a file i/o program on a bare metal system which takes `hello.txt` as
> input.
> +
> +```
> +$ cat fhello.c
> +/*
> + * fhello.c
> + */
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +
> +int main() {
> +  int c;
> +
> +  /* Open hello.txt for reading */
> +  FILE *hello = fopen("hello.txt", "r");
> +  if(hello == NULL)
> +    return -1;
> +
> +
> +  /* Iterate through the entire file
> +   * and print the contents to stdout
> +   */
> +
> +  putchar('\n');
> +
> +  while((c = fgetc(hello)) != EOF) {
> +    putchar(c);
> +  }
> +
> +  fclose(hello);
> +  return 0;
> +}
> +$ cat hello.txt
> +Hello! This is Little FS!
> +$ dramfs_mklfs 128 256 hello.txt > lfs_mem.c
> +$ <xxx>-<xxx>-<xxx>dramfs-gcc -c crt.S lfs_mem.c dramfs_intf.c fhello.c
> +$ <xxx>-<xxx>-<xxx>dramfs-gcc -nostartfiles -T link.ld lfs_mem.o crt.o
> dramfs_intf.o fhello.o  -o fhello
> +$ <Your system's runtime executable> fhello
> +
> +Hello! This is Little FS!
> +```
> +
> +## 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/configure.in b/libgloss/dramfs/configure.in
> new file mode 100644
> index 000000000..5694013d4
> --- /dev/null
> +++ b/libgloss/dramfs/configure.in
> @@ -0,0 +1,45 @@
> +#=========================================================================
> +# configure.ac for riscv libgloss and crt0
> +#=========================================================================
> +
> +#-------------------------------------------------------------------------
> +# Setup
> +#-------------------------------------------------------------------------
> +
> +AC_INIT([crt0.S])
> +AC_CONFIG_SRCDIR([crt0.S])
> +AC_CONFIG_AUX_DIR([${srcdir}/../..])
> +
> +#-------------------------------------------------------------------------
> +# Checks for programs
> +#-------------------------------------------------------------------------
> +
> +LIB_AC_PROG_CC
> +AC_CHECK_TOOL([AR],[ar])
> +AC_CHECK_TOOL([RANLIB],[ranlib])
> +AC_PROG_INSTALL
> +
> +#-------------------------------------------------------------------------
> +# Output
> +#-------------------------------------------------------------------------
> +
> +if test "$srcdir" = "." ; then
> +  if test "${with_target_subdir}" != "." ; then
> +    libgloss_topdir="${srcdir}/${with_multisrctop}../../.."
> +  else
> +    libgloss_topdir="${srcdir}/${with_multisrctop}../.."
> +  fi
> +else
> +  libgloss_topdir="${srcdir}/../.."
> +fi
> +AC_CONFIG_AUX_DIR($libgloss_topdir)
> +AC_CONFIG_FILES(Makefile,
> +. ${libgloss_topdir}/config-ml.in,
> +srcdir=${srcdir}
> +target=${target}
> +with_multisubdir=${with_multisubdir}
> +ac_configure_args="${ac_configure_args} --enable-multilib"
> +CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
> +libgloss_topdir=${libgloss_topdir}
> +)
> +AC_OUTPUT
> diff --git a/libgloss/dramfs/dramfs/dramfs_fdtable.c
> b/libgloss/dramfs/dramfs/dramfs_fdtable.c
> new file mode 100644
> index 000000000..32cfb28f9
> --- /dev/null
> +++ b/libgloss/dramfs/dramfs/dramfs_fdtable.c
> @@ -0,0 +1,62 @@
> +#include "dramfs_fdtable.h"
> +#include "dramfs_fs.h"
> +
> +typedef struct dramfs_fd_entry {
> +  int used;
> +  int nonblock;
> +  lfs_file_t file;
> +} dramfs_fd_entry_t;
> +
> +static dramfs_fd_entry_t dramfs_fdtable[DRAMFS_MAX_FDS];
> +
> +void dramfs_init_fdtable(void) {
> +  for(int i=0; i<DRAMFS_MAX_FDS; i++) {
> +    dramfs_fdtable[i].used = 0;
> +    dramfs_fdtable[i].nonblock = 0;
> +  }
> +}
> +
> +int dramfs_check_fd(int fd) {
> +  if(fd < 0 || fd >= DRAMFS_MAX_FDS || dramfs_fdtable[fd].used == 0) {
> +    errno = EBADF;
> +    return -1;
> +  }
> +
> +  return 0;
> +}
> +
> +int dramfs_nonblock_fd(int fd) {
> +  if(dramfs_fdtable[fd].nonblock == 1) {
> +    return 1;
> +  }
> +
> +  return 0;
> +}
> +
> +int dramfs_reserve_fd(void) {
> +  int fd = 0;
> +
> +  for(;fd < DRAMFS_MAX_FDS; fd++) {
> +    if(dramfs_fdtable[fd].used == 0) {
> +      dramfs_fdtable[fd].used = 1;
> +      return fd;
> +    }
> +  }
> +
> +  errno = ENFILE;
> +  return -1;
> +}
> +
> +lfs_file_t *dramfs_get_file(int fd) {
> +  return &dramfs_fdtable[fd].file;
> +}
> +
> +int dramfs_free_fd(int fd) {
> +  if (dramfs_fdtable[fd].used == 1) {
> +    lfs_file_t *fptr = dramfs_get_file(fd);
> +    dramfs_fdtable[fd].used = 0;
> +    return lfs_file_close(&dramfs_fs, fptr);
> +  } else {
> +    return 0;
> +  }
> +}
> diff --git a/libgloss/dramfs/dramfs/dramfs_fdtable.h
> b/libgloss/dramfs/dramfs/dramfs_fdtable.h
> new file mode 100644
> index 000000000..f26fd7613
> --- /dev/null
> +++ b/libgloss/dramfs/dramfs/dramfs_fdtable.h
> @@ -0,0 +1,23 @@
> +#ifndef DRAMFS_FDTABLE_H
> +#define DRAMFS_FDTABLE_H
> +
> +#include <errno.h>
> +#include "lfs.h"
> +
> +#ifndef DRAMFS_MAX_FDS
> +#define DRAMFS_MAX_FDS 20
> +#endif
> +
> +void dramfs_init_fdtable(void);
> +
> +int dramfs_check_fd(int fd);
> +
> +int dramfs_nonblock_fd(int fd);
> +
> +int dramfs_reserve_fd(void);
> +
> +int dramfs_free_fd(int fd);
> +
> +lfs_file_t *dramfs_get_file(int fd);
> +
> +#endif // DRAMFS_FDTABLE_H
> diff --git a/libgloss/dramfs/dramfs/dramfs_fs.c
> b/libgloss/dramfs/dramfs/dramfs_fs.c
> new file mode 100644
> index 000000000..b4d6c51ae
> --- /dev/null
> +++ b/libgloss/dramfs/dramfs/dramfs_fs.c
> @@ -0,0 +1,35 @@
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include "lfs.h"
> +#include "lfs_bd.h"
> +#include "dramfs_fs.h"
> +#include "dramfs_fdtable.h"
> +
> +// File system memory pointer
> +uint8_t* lfs_ptr = lfs_mem;
> +
> +// Init routine for Newlib FS
> +int dramfs_fs_init() {
> +  // initiate fdtable
> +  dramfs_init_fdtable();
> +
> +       // mount the file system
> +       if(lfs_mount(&dramfs_fs, &dramfs_fs_cfg) < 0) {
> +               return -1;
> +       }
> +
> +  // Open stdio files
> +  if(open("stdin", O_RDONLY) != 0) {
> +    return -1;
> +  }
> +
> +  if(open("stdout", O_WRONLY) != 1) {
> +    return -1;
> +  }
> +
> +  if(open("stderr", O_WRONLY) != 2) {
> +    return -1;
> +  }
> +
> +       return 0;
> +}
> diff --git a/libgloss/dramfs/dramfs/dramfs_fs.h
> b/libgloss/dramfs/dramfs/dramfs_fs.h
> new file mode 100644
> index 000000000..94f38d37d
> --- /dev/null
> +++ b/libgloss/dramfs/dramfs/dramfs_fs.h
> @@ -0,0 +1,32 @@
> +#ifndef DRAMFS_FS_H
> +#define DRAMFS_FS_H
> +
> +#include "lfs.h"
> +
> +// Toplevel filesystem struct
> +extern lfs_t dramfs_fs;
> +
> +// File system configuration structure
> +// Initalized externally and can be generated by dramfs_mklfs
> +extern struct lfs_config dramfs_fs_cfg;
> +
> +// Array with initial LFS image
> +// Initialized externally and can be generated by dramfs_mklfs
> +extern uint8_t lfs_mem[];
> +
> +// Exit routine: exit() calls this routine
> +// Definition provided externally by user
> +extern void dramfs_exit(int);
> +
> +// Utility to print a char to console
> +// Definition provided externally by user
> +extern void dramfs_sendchar(char);
> +
> +// Utility to get a char from console
> +// Definition provided externally by user
> +extern int dramfs_getchar(void);
> +
> +// LFS init routine: Should be called before calling main
> +int dramfs_fs_init(void) __attribute__((weak));
> +
> +#endif // DRAMFS_FS_H
> diff --git a/libgloss/dramfs/dramfs/dramfs_mklfs.c
> b/libgloss/dramfs/dramfs/dramfs_mklfs.c
> new file mode 100644
> index 000000000..1bdf7d0f5
> --- /dev/null
> +++ b/libgloss/dramfs/dramfs/dramfs_mklfs.c
> @@ -0,0 +1,154 @@
> +// Program to create littlefs image comprising of input files/dirs
> +//
> +// Bandhav Veluri
> +// 03-07-2019
> +
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include "lfs.h"
> +#include "lfs_bd.h"
> +#include "dramfs_util.h"
> +
> +// Main file system struct
> +lfs_t lfs;
> +
> +// LFS configuration
> +struct lfs_config lfs_cfg = {
> +    // block device operations: lfs_bd.h
> +    .read  = lfs_read,
> +    .prog  = lfs_prog,
> +    .erase = lfs_erase,
> +    .sync  = lfs_sync,
> +
> +    // block device default configuration
> +    .read_size   = 32,
> +    .prog_size   = 32,
> +    .block_size  = 0,
> +    .block_count = 0,
> +    .lookahead   = 32
> +};
> +
> +// Pointer to filesystem memory
> +// lfs_bd uses this allocation as block device
> +uint8_t *lfs_ptr;
> +
> +int main(int argc, char *argv[]) {
> +  int block_size;
> +  int block_count;
> +  FILE *img; // output fs image file handler
> +
> +  if(argc < 3) {
> +    printf("Usage: dramfs_mklfs <block_size> <block_count> [input
> file(s)/dir(s)]\n");
> +    return -1;
> +  }
> +
> +  block_size = atoi(argv[1]);
> +  block_count = atoi(argv[2]);
> +
> +
> +  //+------------------------------------------------------
> +  //| Allocate memory for building Little FS image
> +  //+------------------------------------------------------
> +
> +  // memory allocation for lfs
> +  lfs_ptr = (char *) malloc(block_size*block_count);
> +
> +  // configure the size
> +  lfs_cfg.block_size = block_size;
> +  lfs_cfg.block_count = block_count;
> +
> +  // format the fs
> +  if(lfs_format(&lfs, &lfs_cfg) < 0) {
> +    printf("LFS format error\n");
> +    return -1;
> +  }
> +
> +  // mount the file system
> +  if(lfs_mount(&lfs, &lfs_cfg) < 0) {
> +    printf("LFS mount error\n");
> +    return -1;
> +  }
> +
> +
> +  //+-------------------------------------------------------
> +  //| Create stdin, stdout and stderr files in the littlefs
> +  //+-------------------------------------------------------
> +
> +  lfs_file_t lfs_stdin, lfs_stdout, lfs_stderr;
> +
> +  // Create stdio files
> +  lfs_file_open(&lfs, &lfs_stdin, "stdin", LFS_O_WRONLY | LFS_O_CREAT);
> +  lfs_file_open(&lfs, &lfs_stdout, "stdout", LFS_O_WRONLY | LFS_O_CREAT);
> +  lfs_file_open(&lfs, &lfs_stderr, "stderr", LFS_O_WRONLY | LFS_O_CREAT);
> +
> +  // Close stdio files
> +  lfs_file_close(&lfs, &lfs_stdin);
> +  lfs_file_close(&lfs, &lfs_stdout);
> +  lfs_file_close(&lfs, &lfs_stderr);
> +
> +
> +  //+-------------------------------------------------------
> +  //| Copy input files/dirs to LFS image
> +  //+-------------------------------------------------------
> +
> +  for(int i = 3; i < argc; i++) {
> +    if(lfs_cp(argv[i], &lfs) < 0)
> +      return -1;
> +  }
> +
> +  // Unmount lfs
> +  if(lfs_unmount(&lfs) < 0){
> +    printf("LFS unmounting error\n");
> +    return -1;
> +  }
> +
> +
> +  //+------------------------------------------------------
> +  //| Print the LFS image as a C array
> +  //+------------------------------------------------------
> +
> +  printf("// Newlib File System Initialization\n");
> +  printf("//\n");
> +  printf("// Autogenerated by dramfs_mkfs utility\n");
> +  printf("\n");
> +  printf("#include <sys/types.h>\n");
> +  printf("#include <machine/lfs.h>\n");
> +  printf("#include <machine/lfs_bd.h>\n");
> +  printf("\n");
> +
> +  printf( "// LFS configuration\n"
> +          "struct lfs_config dramfs_fs_cfg = {\n"
> +          "    // block device operations: lfs_bd.h\n"
> +          "    .read  = lfs_read,\n"
> +          "    .prog  = lfs_prog,\n"
> +          "    .erase = lfs_erase,\n"
> +          "    .sync  = lfs_sync,\n"
> +          "\n"
> +          "    // block device default configuration\n"
> +          "    .read_size   = 32,\n"
> +          "    .prog_size   = 32,\n"
> +          "    .block_size  = %d,\n"
> +          "    .block_count = %d,\n"
> +          "    .lookahead   = 32\n"
> +          "};\n\n", block_size, block_count);
> +
> +  printf("lfs_t dramfs_fs;\n");
> +
> +  printf("uint8_t lfs_mem[] = {\n");
> +
> +  // dump fs memory to stdout in C array format
> +  for(int i=0; i < block_size*block_count; i++) {
> +    printf("0x%0x", lfs_ptr[i]);
> +
> +    if(i != (block_size*block_count) - 1)
> +      putchar(',');
> +
> +    putchar('\n');
> +  }
> +
> +  printf("};");
> +
> +  return 0;
> +}
> diff --git a/libgloss/dramfs/dramfs/dramfs_util.c
> b/libgloss/dramfs/dramfs/dramfs_util.c
> new file mode 100644
> index 000000000..3b5e4aed9
> --- /dev/null
> +++ b/libgloss/dramfs/dramfs/dramfs_util.c
> @@ -0,0 +1,101 @@
> +// Newlib utility functions
> +//
> +// Bandhav Veluri
> +// 08/15/2019
> +
> +#include <stdio.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <unistd.h>
> +#include <dirent.h>
> +#include <string.h>
> +#include "dramfs_util.h"
> +
> +int is_file(const char* path) {
> +       struct stat s;
> +       stat(path, &s);
> +       return S_ISREG(s.st_mode);
> +}
> +
> +int is_dir(const char* path) {
> +       struct stat s;
> +       stat(path, &s);
> +       return S_ISDIR(s.st_mode);
> +}
> +
> +int cp_file_to_lfs(const char* path, lfs_t* lfs) {
> +       if(!is_file(path)) {
> +               return -1;
> +       }
> +
> +  // open input file for reading
> +  FILE *infile = fopen(path, "r");
> +  if(infile == NULL) {
> +       fprintf(stderr, "Error opening input file %s\n", path);
> +       return -1;
> +  }
> +
> +  // create a lfs file for writing
> +  lfs_file_t lfs_file;
> +  if(lfs_file_open(lfs, &lfs_file, path, LFS_O_WRONLY | LFS_O_CREAT) < 0)
> {
> +       fprintf(stderr, "LFS file open error %s\n", path);
> +       return -1;
> +  }
> +
> +  int c = fgetc(infile);
> +  while (c != EOF) {
> +       lfs_file_write(lfs, &lfs_file, &c, 1);
> +       c = fgetc(infile);
> +  }
> +
> +  fclose(infile);
> +  lfs_file_close(lfs, &lfs_file);
> +
> +       return 0;
> +}
> +
> +int lfs_cp(const char* path, lfs_t* lfs) {
> +       if(is_file(path)) {
> +               return cp_file_to_lfs(path, lfs);
> +       } else if(is_dir(path)) {
> +               DIR* dir;
> +               struct dirent* ent;
> +
> +               if(dir = opendir(path)) {
> +                       if(lfs_mkdir(lfs, path) < 0) {
> +                               fprintf(stderr, "LFS COPY: Error creating
> %s in lfs\n", path);
> +                               return -1;
> +                       }
> +
> +                       while(ent = readdir(dir)) {
> +                               // Build the full path of file or dir
> +                               char sep[] = "/";
> +                               char* ent_full_path = (char*)
> malloc(strlen(path)+strlen(sep)+strlen(ent->d_name)+1);
> +                               strcpy(ent_full_path, path);
> +                               strcat(ent_full_path, sep);
> +                               strcat(ent_full_path, ent->d_name);
> +
> +                               if((strcmp(ent->d_name, ".") == 0) |
> (strcmp(ent->d_name, "..")==0)) {
> +                                       continue;
> +                               } else {
> +                                       if(ent->d_type == DT_REG) {
> +
>  if(cp_file_to_lfs(ent_full_path, lfs) < 0)
> +                                                       return -1;
> +                                       } else if(ent->d_type == DT_DIR) {
> +                                               // Recursively copy the dir
> +                                               if(lfs_cp(ent_full_path,
> lfs) < 0)
> +                                                       return -1;
> +                                       }
> +                               }
> +                       }
> +
> +                       return 0;
> +               } else {
> +                       fprintf(stderr, "LFS COPY: Error opening directory
> %s\n", path);
> +                       return -1;
> +               }
> +       }
> +
> +       fprintf(stderr, "LFS COPY: argument should be a file or
> directory\n");
> +       return -1;
> +}
> diff --git a/libgloss/dramfs/dramfs/dramfs_util.h
> b/libgloss/dramfs/dramfs/dramfs_util.h
> new file mode 100644
> index 000000000..3c68c46d7
> --- /dev/null
> +++ b/libgloss/dramfs/dramfs/dramfs_util.h
> @@ -0,0 +1,13 @@
> +#include "lfs.h"
> +
> +// Check if a path is a regular file
> +int is_file(const char*);
> +
> +// Check if a path is a directory
> +int is_dir(const char*);
> +
> +// Copy a file to lfs struct
> +int cp_file_to_lfs(const char*, lfs_t*);
> +
> +// Copy a file/directory recursively to lfs struct
> +int lfs_cp(const char*, lfs_t*);
> diff --git a/libgloss/dramfs/dramfs/littlefs
> b/libgloss/dramfs/dramfs/littlefs
> new file mode 160000
> index 000000000..611c9b20d
> --- /dev/null
> +++ b/libgloss/dramfs/dramfs/littlefs
> @@ -0,0 +1 @@
> +Subproject commit 611c9b20db2b99faee261daa7cc9bbe175d3eaca
> diff --git a/libgloss/dramfs/sys_close.c b/libgloss/dramfs/sys_close.c
> new file mode 100644
> index 000000000..864a3beed
> --- /dev/null
> +++ b/libgloss/dramfs/sys_close.c
> @@ -0,0 +1,14 @@
> +#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..d4a298b2e
> --- /dev/null
> +++ b/libgloss/dramfs/sys_execve.c
> @@ -0,0 +1,13 @@
> +#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..6be34a868
> --- /dev/null
> +++ b/libgloss/dramfs/sys_exit.c
> @@ -0,0 +1,14 @@
> +#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..db808492f
> --- /dev/null
> +++ b/libgloss/dramfs/sys_fork.c
> @@ -0,0 +1,12 @@
> +#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..df5ded6df
> --- /dev/null
> +++ b/libgloss/dramfs/sys_fstat.c
> @@ -0,0 +1,21 @@
> +#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..dc0ae9272
> --- /dev/null
> +++ b/libgloss/dramfs/sys_getpid.c
> @@ -0,0 +1,9 @@
> +/* 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..c362ef182
> --- /dev/null
> +++ b/libgloss/dramfs/sys_gettimeofday.c
> @@ -0,0 +1,13 @@
> +#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..479291135
> --- /dev/null
> +++ b/libgloss/dramfs/sys_isatty.c
> @@ -0,0 +1,9 @@
> +/* 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..32c4d2422
> --- /dev/null
> +++ b/libgloss/dramfs/sys_kill.c
> @@ -0,0 +1,13 @@
> +#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..3c33977be
> --- /dev/null
> +++ b/libgloss/dramfs/sys_link.c
> @@ -0,0 +1,11 @@
> +#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..746041759
> --- /dev/null
> +++ b/libgloss/dramfs/sys_lseek.c
> @@ -0,0 +1,17 @@
> +#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..48a4830cd
> --- /dev/null
> +++ b/libgloss/dramfs/sys_open.c
> @@ -0,0 +1,37 @@
> +#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..d5a382c38
> --- /dev/null
> +++ b/libgloss/dramfs/sys_read.c
> @@ -0,0 +1,40 @@
> +#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..8c2eea688
> --- /dev/null
> +++ b/libgloss/dramfs/sys_sbrk.c
> @@ -0,0 +1,22 @@
> +// 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..a9d6ad4d3
> --- /dev/null
> +++ b/libgloss/dramfs/sys_stat.c
> @@ -0,0 +1,23 @@
> +#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..4856817bb
> --- /dev/null
> +++ b/libgloss/dramfs/sys_times.c
> @@ -0,0 +1,8 @@
> +#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..677b81603
> --- /dev/null
> +++ b/libgloss/dramfs/sys_unlink.c
> @@ -0,0 +1,12 @@
> +#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..44a3512fb
> --- /dev/null
> +++ b/libgloss/dramfs/sys_wait.c
> @@ -0,0 +1,12 @@
> +#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..76370331d
> --- /dev/null
> +++ b/libgloss/dramfs/sys_write.c
> @@ -0,0 +1,25 @@
> +#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
>
>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Adding a LittleFS-based self-contained target to libgloss
  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-09 22:21     ` [PATCH 2/2] Adding lfs_mem.c Dan Petrisko
  0 siblings, 2 replies; 13+ messages in thread
From: Dan Petrisko @ 2023-08-09 22:21 UTC (permalink / raw)
  To: newlib

Hi Jeff,

Thank you for the feedback! I have added the copyright notices and removed the submodule. Now there
is a pointer to an external repo which hosts the dramfs_mklfs tool.

Best,
-Dan


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/2] Adding a LittleFS-based self-contained target to libgloss
  2023-08-09 22:21   ` Dan Petrisko
@ 2023-08-09 22:21     ` Dan Petrisko
  2023-08-10 17:45       ` Jeff Johnston
  2023-08-09 22:21     ` [PATCH 2/2] Adding lfs_mem.c Dan Petrisko
  1 sibling, 1 reply; 13+ messages in thread
From: Dan Petrisko @ 2023-08-09 22:21 UTC (permalink / raw)
  To: newlib; +Cc: Dan Petrisko

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 +++++
 libgloss/dramfs/Makefile.in        | 230 +++++++++++++++++++++++++++++++++++++
 libgloss/dramfs/README.md          | 158 +++++++++++++++++++++++++
 libgloss/dramfs/configure.in       |  45 ++++++++
 libgloss/dramfs/crt0.S             |  44 +++++++
 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 +++++++++
 25 files changed, 1342 insertions(+)
 create mode 100644 .gitmodules
 create mode 100644 libgloss/dramfs/Makefile.in
 create mode 100644 libgloss/dramfs/README.md
 create mode 100644 libgloss/dramfs/configure.in
 create mode 100644 libgloss/dramfs/crt0.S
 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/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..09b92b1a1
--- /dev/null
+++ b/libgloss/dramfs/README.md
@@ -0,0 +1,158 @@
+# 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;
+}
+```
+
+#### 5. Creating the DRAM lfs.c
+
+See instructions at https://github.com/bsg-external/bsg_dramfs_mklfs
+
+## 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/configure.in b/libgloss/dramfs/configure.in
new file mode 100644
index 000000000..5694013d4
--- /dev/null
+++ b/libgloss/dramfs/configure.in
@@ -0,0 +1,45 @@
+#=========================================================================
+# configure.ac for riscv libgloss and crt0
+#=========================================================================
+
+#-------------------------------------------------------------------------
+# Setup
+#-------------------------------------------------------------------------
+
+AC_INIT([crt0.S])
+AC_CONFIG_SRCDIR([crt0.S])
+AC_CONFIG_AUX_DIR([${srcdir}/../..])
+
+#-------------------------------------------------------------------------
+# Checks for programs
+#-------------------------------------------------------------------------
+
+LIB_AC_PROG_CC
+AC_CHECK_TOOL([AR],[ar])
+AC_CHECK_TOOL([RANLIB],[ranlib])
+AC_PROG_INSTALL
+
+#-------------------------------------------------------------------------
+# Output
+#-------------------------------------------------------------------------
+
+if test "$srcdir" = "." ; then
+  if test "${with_target_subdir}" != "." ; then
+    libgloss_topdir="${srcdir}/${with_multisrctop}../../.."
+  else
+    libgloss_topdir="${srcdir}/${with_multisrctop}../.."
+  fi
+else
+  libgloss_topdir="${srcdir}/../.."
+fi
+AC_CONFIG_AUX_DIR($libgloss_topdir)
+AC_CONFIG_FILES(Makefile,
+. ${libgloss_topdir}/config-ml.in,
+srcdir=${srcdir}
+target=${target}
+with_multisubdir=${with_multisubdir}
+ac_configure_args="${ac_configure_args} --enable-multilib"
+CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+libgloss_topdir=${libgloss_topdir}
+)
+AC_OUTPUT
diff --git a/libgloss/dramfs/crt0.S b/libgloss/dramfs/crt0.S
new file mode 100644
index 000000000..218d23104
--- /dev/null
+++ b/libgloss/dramfs/crt0.S
@@ -0,0 +1,44 @@
+/* Copyright (c) 2017  SiFive Inc. All rights reserved.
+
+   This copyrighted material is made available to anyone wishing to use,
+   modify, copy, or redistribute it subject to the terms and conditions
+   of the FreeBSD License.   This program is distributed in the hope that
+   it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
+   including the implied warranties of MERCHANTABILITY or FITNESS FOR
+   A PARTICULAR PURPOSE.  A copy of this license is available at
+   http://www.opensource.org/licenses.
+*/
+
+#=========================================================================
+# crt0.S : Entry point for RISC-V user programs
+#=========================================================================
+
+  .text
+  .global _start
+  .type   _start, @function
+_start:
+  # Initialize global pointer
+.option push
+.option norelax
+1:auipc gp, %pcrel_hi(__global_pointer$)
+  addi  gp, gp, %pcrel_lo(1b)
+.option pop
+
+  # Clear the bss segment
+  la      a0, _edata
+  la      a2, _end
+  sub     a2, a2, a0
+  li      a1, 0
+  call    memset
+
+  la      a0, __libc_fini_array   # Register global termination functions
+  call    atexit                  #  to be called upon exit
+  call    __libc_init_array       # Run global initialization functions
+
+  call    dramfs_fs_init             # initialize dramfs
+  lw      a0, 0(sp)                  # a0 = argc
+  addi    a1, sp, __SIZEOF_POINTER__ # a1 = argv
+  li      a2, 0                      # a2 = envp = NULL
+  call    main
+  tail    exit
+  .size  _start, .-_start
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


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 2/2] Adding lfs_mem.c
  2023-08-09 22:21   ` Dan Petrisko
  2023-08-09 22:21     ` [PATCH 1/2] " Dan Petrisko
@ 2023-08-09 22:21     ` Dan Petrisko
  1 sibling, 0 replies; 13+ messages in thread
From: Dan Petrisko @ 2023-08-09 22:21 UTC (permalink / raw)
  To: newlib; +Cc: Dan Petrisko

---
 libgloss/dramfs/lfs_mem.c | 8225 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 8225 insertions(+)
 create mode 100644 libgloss/dramfs/lfs_mem.c

diff --git a/libgloss/dramfs/lfs_mem.c b/libgloss/dramfs/lfs_mem.c
new file mode 100644
index 000000000..cf1a0b8fb
--- /dev/null
+++ b/libgloss/dramfs/lfs_mem.c
@@ -0,0 +1,8225 @@
+// Default Newlib File System Initialization
+//
+// Generated by dramfs_mkfs utility
+// dramfs_mklfs 128 64
+
+#include <sys/types.h>
+#include "lfs.h"
+#include "lfs_bd.h"
+
+// Dummy functions needed by crt0.S
+void __attribute__((weak)) dramfs_sendchar(char ch) {}
+int __attribute__((weak)) dramfs_getchar(void) {}
+void __attribute__((weak)) dramfs_exit(int exit_status) {}
+
+// LFS configuration
+struct lfs_config __attribute__((weak)) dramfs_fs_cfg = {
+    // block device operations: lfs_bd.h
+    .read  = lfs_read,
+    .prog  = lfs_prog,
+    .erase = lfs_erase,
+    .sync  = lfs_sync,
+
+    // block device default configuration
+    .read_size   = 32,
+    .prog_size   = 32,
+    .block_size  = 128,
+    .block_count = 64,
+    .lookahead   = 32
+};
+
+lfs_t __attribute__((weak)) dramfs_fs;
+uint8_t __attribute__((weak)) lfs_mem[] = {
+0x3,
+0x0,
+0x0,
+0x0,
+0x34,
+0x0,
+0x0,
+0x0,
+0x3,
+0x0,
+0x0,
+0x0,
+0x2,
+0x0,
+0x0,
+0x0,
+0x2e,
+0x14,
+0x0,
+0x8,
+0x3,
+0x0,
+0x0,
+0x0,
+0x2,
+0x0,
+0x0,
+0x0,
+0x80,
+0x0,
+0x0,
+0x0,
+0x40,
+0x0,
+0x0,
+0x0,
+0x1,
+0x0,
+0x1,
+0x0,
+0x6c,
+0x69,
+0x74,
+0x74,
+0x6c,
+0x65,
+0x66,
+0x73,
+0x2c,
+0x43,
+0x7c,
+0x73,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x2,
+0x0,
+0x0,
+0x0,
+0x34,
+0x0,
+0x0,
+0x0,
+0x3,
+0x0,
+0x0,
+0x0,
+0x2,
+0x0,
+0x0,
+0x0,
+0x2e,
+0x14,
+0x0,
+0x8,
+0x3,
+0x0,
+0x0,
+0x0,
+0x2,
+0x0,
+0x0,
+0x0,
+0x80,
+0x0,
+0x0,
+0x0,
+0x40,
+0x0,
+0x0,
+0x0,
+0x1,
+0x0,
+0x1,
+0x0,
+0x6c,
+0x69,
+0x74,
+0x74,
+0x6c,
+0x65,
+0x66,
+0x73,
+0xf0,
+0xaf,
+0xcd,
+0x4e,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x5,
+0x0,
+0x0,
+0x0,
+0x49,
+0x0,
+0x0,
+0x0,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x11,
+0x8,
+0x0,
+0x5,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x73,
+0x74,
+0x64,
+0x69,
+0x6e,
+0x11,
+0x8,
+0x0,
+0x6,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x73,
+0x74,
+0x64,
+0x6f,
+0x75,
+0x74,
+0x11,
+0x8,
+0x0,
+0x6,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x73,
+0x74,
+0x64,
+0x65,
+0x72,
+0x72,
+0x61,
+0xfc,
+0xe5,
+0x1,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x4,
+0x0,
+0x0,
+0x0,
+0x37,
+0x0,
+0x0,
+0x0,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x11,
+0x8,
+0x0,
+0x5,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x73,
+0x74,
+0x64,
+0x69,
+0x6e,
+0x11,
+0x8,
+0x0,
+0x6,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x73,
+0x74,
+0x64,
+0x6f,
+0x75,
+0x74,
+0x15,
+0x4f,
+0xac,
+0x38,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0
+};
-- 
2.16.5


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/2] Adding a LittleFS-based self-contained target to libgloss
  2023-08-09 22:21     ` [PATCH 1/2] " Dan Petrisko
@ 2023-08-10 17:45       ` Jeff Johnston
  2023-08-10 19:50         ` Dan Petrisko
  0 siblings, 1 reply; 13+ messages in thread
From: Jeff Johnston @ 2023-08-10 17:45 UTC (permalink / raw)
  To: Dan Petrisko; +Cc: newlib

[-- Attachment #1: Type: text/plain, Size: 68836 bytes --]

Hi Dan,

Thanks for the updates.  A few more comments.

Your readme states that adding -dramfs to the end of a target will enable
the support, but there is no logic yet added here to the top-level
configure.ac to specify building in dramfs directory.   Libgloss has
recently been cleaned up to move all configuration into the top-level
libgloss directory (none of the targets have their own
configure.in/configure.ac).  The way it is now, building libgloss/dramfs
would have to be done manually in the dramfs directory.

There is a comment mentioning risc-v and configure.ac in your configure.in
file.

Regards,

-- Jeff J.

On Wed, Aug 9, 2023 at 6:22 PM Dan Petrisko <petrisko@cs.washington.edu>
wrote:

> 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 +++++
>  libgloss/dramfs/Makefile.in        | 230
> +++++++++++++++++++++++++++++++++++++
>  libgloss/dramfs/README.md          | 158 +++++++++++++++++++++++++
>  libgloss/dramfs/configure.in       |  45 ++++++++
>  libgloss/dramfs/crt0.S             |  44 +++++++
>  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 +++++++++
>  25 files changed, 1342 insertions(+)
>  create mode 100644 .gitmodules
>  create mode 100644 libgloss/dramfs/Makefile.in
>  create mode 100644 libgloss/dramfs/README.md
>  create mode 100644 libgloss/dramfs/configure.in
>  create mode 100644 libgloss/dramfs/crt0.S
>  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/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..09b92b1a1
> --- /dev/null
> +++ b/libgloss/dramfs/README.md
> @@ -0,0 +1,158 @@
> +# 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;
> +}
> +```
> +
> +#### 5. Creating the DRAM lfs.c
> +
> +See instructions at https://github.com/bsg-external/bsg_dramfs_mklfs
> +
> +## 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/configure.in b/libgloss/dramfs/configure.in
> new file mode 100644
> index 000000000..5694013d4
> --- /dev/null
> +++ b/libgloss/dramfs/configure.in
> @@ -0,0 +1,45 @@
> +#=========================================================================
> +# configure.ac for riscv libgloss and crt0
> +#=========================================================================
> +
> +#-------------------------------------------------------------------------
> +# Setup
> +#-------------------------------------------------------------------------
> +
> +AC_INIT([crt0.S])
> +AC_CONFIG_SRCDIR([crt0.S])
> +AC_CONFIG_AUX_DIR([${srcdir}/../..])
> +
> +#-------------------------------------------------------------------------
> +# Checks for programs
> +#-------------------------------------------------------------------------
> +
> +LIB_AC_PROG_CC
> +AC_CHECK_TOOL([AR],[ar])
> +AC_CHECK_TOOL([RANLIB],[ranlib])
> +AC_PROG_INSTALL
> +
> +#-------------------------------------------------------------------------
> +# Output
> +#-------------------------------------------------------------------------
> +
> +if test "$srcdir" = "." ; then
> +  if test "${with_target_subdir}" != "." ; then
> +    libgloss_topdir="${srcdir}/${with_multisrctop}../../.."
> +  else
> +    libgloss_topdir="${srcdir}/${with_multisrctop}../.."
> +  fi
> +else
> +  libgloss_topdir="${srcdir}/../.."
> +fi
> +AC_CONFIG_AUX_DIR($libgloss_topdir)
> +AC_CONFIG_FILES(Makefile,
> +. ${libgloss_topdir}/config-ml.in,
> +srcdir=${srcdir}
> +target=${target}
> +with_multisubdir=${with_multisubdir}
> +ac_configure_args="${ac_configure_args} --enable-multilib"
> +CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
> +libgloss_topdir=${libgloss_topdir}
> +)
> +AC_OUTPUT
> diff --git a/libgloss/dramfs/crt0.S b/libgloss/dramfs/crt0.S
> new file mode 100644
> index 000000000..218d23104
> --- /dev/null
> +++ b/libgloss/dramfs/crt0.S
> @@ -0,0 +1,44 @@
> +/* Copyright (c) 2017  SiFive Inc. All rights reserved.
> +
> +   This copyrighted material is made available to anyone wishing to use,
> +   modify, copy, or redistribute it subject to the terms and conditions
> +   of the FreeBSD License.   This program is distributed in the hope that
> +   it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
> +   including the implied warranties of MERCHANTABILITY or FITNESS FOR
> +   A PARTICULAR PURPOSE.  A copy of this license is available at
> +   http://www.opensource.org/licenses.
> +*/
> +
> +#=========================================================================
> +# crt0.S : Entry point for RISC-V user programs
> +#=========================================================================
> +
> +  .text
> +  .global _start
> +  .type   _start, @function
> +_start:
> +  # Initialize global pointer
> +.option push
> +.option norelax
> +1:auipc gp, %pcrel_hi(__global_pointer$)
> +  addi  gp, gp, %pcrel_lo(1b)
> +.option pop
> +
> +  # Clear the bss segment
> +  la      a0, _edata
> +  la      a2, _end
> +  sub     a2, a2, a0
> +  li      a1, 0
> +  call    memset
> +
> +  la      a0, __libc_fini_array   # Register global termination functions
> +  call    atexit                  #  to be called upon exit
> +  call    __libc_init_array       # Run global initialization functions
> +
> +  call    dramfs_fs_init             # initialize dramfs
> +  lw      a0, 0(sp)                  # a0 = argc
> +  addi    a1, sp, __SIZEOF_POINTER__ # a1 = argv
> +  li      a2, 0                      # a2 = envp = NULL
> +  call    main
> +  tail    exit
> +  .size  _start, .-_start
> 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
>
>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Adding a LittleFS-based self-contained target to libgloss
  2023-08-10 17:45       ` Jeff Johnston
@ 2023-08-10 19:50         ` Dan Petrisko
  2023-08-10 19:50           ` [PATCH 1/2] " Dan Petrisko
                             ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Dan Petrisko @ 2023-08-10 19:50 UTC (permalink / raw)
  To: newlib

Got it! I've extracted the configure changes to the toplevel configure.ac. BTW, what is the correct
branch to base my changes on?

Thanks,
-Dan


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/2] Adding a LittleFS-based self-contained target to libgloss
  2023-08-10 19:50         ` Dan Petrisko
@ 2023-08-10 19:50           ` Dan Petrisko
  2023-08-10 21:47             ` 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
  2 siblings, 1 reply; 13+ messages in thread
From: Dan Petrisko @ 2023-08-10 19:50 UTC (permalink / raw)
  To: newlib; +Cc: Dan Petrisko

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


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 2/2] Adding lfs_mem.c
  2023-08-10 19:50         ` Dan Petrisko
  2023-08-10 19:50           ` [PATCH 1/2] " Dan Petrisko
@ 2023-08-10 19:50           ` Dan Petrisko
  2023-08-10 20:46           ` Adding a LittleFS-based self-contained target to libgloss Jeff Johnston
  2 siblings, 0 replies; 13+ messages in thread
From: Dan Petrisko @ 2023-08-10 19:50 UTC (permalink / raw)
  To: newlib; +Cc: Dan Petrisko

---
 libgloss/dramfs/lfs_mem.c | 8225 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 8225 insertions(+)
 create mode 100644 libgloss/dramfs/lfs_mem.c

diff --git a/libgloss/dramfs/lfs_mem.c b/libgloss/dramfs/lfs_mem.c
new file mode 100644
index 000000000..cf1a0b8fb
--- /dev/null
+++ b/libgloss/dramfs/lfs_mem.c
@@ -0,0 +1,8225 @@
+// Default Newlib File System Initialization
+//
+// Generated by dramfs_mkfs utility
+// dramfs_mklfs 128 64
+
+#include <sys/types.h>
+#include "lfs.h"
+#include "lfs_bd.h"
+
+// Dummy functions needed by crt0.S
+void __attribute__((weak)) dramfs_sendchar(char ch) {}
+int __attribute__((weak)) dramfs_getchar(void) {}
+void __attribute__((weak)) dramfs_exit(int exit_status) {}
+
+// LFS configuration
+struct lfs_config __attribute__((weak)) dramfs_fs_cfg = {
+    // block device operations: lfs_bd.h
+    .read  = lfs_read,
+    .prog  = lfs_prog,
+    .erase = lfs_erase,
+    .sync  = lfs_sync,
+
+    // block device default configuration
+    .read_size   = 32,
+    .prog_size   = 32,
+    .block_size  = 128,
+    .block_count = 64,
+    .lookahead   = 32
+};
+
+lfs_t __attribute__((weak)) dramfs_fs;
+uint8_t __attribute__((weak)) lfs_mem[] = {
+0x3,
+0x0,
+0x0,
+0x0,
+0x34,
+0x0,
+0x0,
+0x0,
+0x3,
+0x0,
+0x0,
+0x0,
+0x2,
+0x0,
+0x0,
+0x0,
+0x2e,
+0x14,
+0x0,
+0x8,
+0x3,
+0x0,
+0x0,
+0x0,
+0x2,
+0x0,
+0x0,
+0x0,
+0x80,
+0x0,
+0x0,
+0x0,
+0x40,
+0x0,
+0x0,
+0x0,
+0x1,
+0x0,
+0x1,
+0x0,
+0x6c,
+0x69,
+0x74,
+0x74,
+0x6c,
+0x65,
+0x66,
+0x73,
+0x2c,
+0x43,
+0x7c,
+0x73,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x2,
+0x0,
+0x0,
+0x0,
+0x34,
+0x0,
+0x0,
+0x0,
+0x3,
+0x0,
+0x0,
+0x0,
+0x2,
+0x0,
+0x0,
+0x0,
+0x2e,
+0x14,
+0x0,
+0x8,
+0x3,
+0x0,
+0x0,
+0x0,
+0x2,
+0x0,
+0x0,
+0x0,
+0x80,
+0x0,
+0x0,
+0x0,
+0x40,
+0x0,
+0x0,
+0x0,
+0x1,
+0x0,
+0x1,
+0x0,
+0x6c,
+0x69,
+0x74,
+0x74,
+0x6c,
+0x65,
+0x66,
+0x73,
+0xf0,
+0xaf,
+0xcd,
+0x4e,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x5,
+0x0,
+0x0,
+0x0,
+0x49,
+0x0,
+0x0,
+0x0,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x11,
+0x8,
+0x0,
+0x5,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x73,
+0x74,
+0x64,
+0x69,
+0x6e,
+0x11,
+0x8,
+0x0,
+0x6,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x73,
+0x74,
+0x64,
+0x6f,
+0x75,
+0x74,
+0x11,
+0x8,
+0x0,
+0x6,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x73,
+0x74,
+0x64,
+0x65,
+0x72,
+0x72,
+0x61,
+0xfc,
+0xe5,
+0x1,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x4,
+0x0,
+0x0,
+0x0,
+0x37,
+0x0,
+0x0,
+0x0,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x11,
+0x8,
+0x0,
+0x5,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x73,
+0x74,
+0x64,
+0x69,
+0x6e,
+0x11,
+0x8,
+0x0,
+0x6,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x73,
+0x74,
+0x64,
+0x6f,
+0x75,
+0x74,
+0x15,
+0x4f,
+0xac,
+0x38,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0
+};
-- 
2.16.5


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Adding a LittleFS-based self-contained target to libgloss
  2023-08-10 19:50         ` Dan Petrisko
  2023-08-10 19:50           ` [PATCH 1/2] " Dan Petrisko
  2023-08-10 19:50           ` [PATCH 2/2] Adding lfs_mem.c Dan Petrisko
@ 2023-08-10 20:46           ` Jeff Johnston
  2 siblings, 0 replies; 13+ messages in thread
From: Jeff Johnston @ 2023-08-10 20:46 UTC (permalink / raw)
  To: Dan Petrisko; +Cc: newlib

[-- Attachment #1: Type: text/plain, Size: 330 bytes --]

If you referring to main vs master, you can choose either.

-- Jeff J.

On Thu, Aug 10, 2023 at 3:51 PM Dan Petrisko <petrisko@cs.washington.edu>
wrote:

> Got it! I've extracted the configure changes to the toplevel configure.ac.
> BTW, what is the correct
> branch to base my changes on?
>
> Thanks,
> -Dan
>
>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/2] Adding a LittleFS-based self-contained target to libgloss
  2023-08-10 19:50           ` [PATCH 1/2] " Dan Petrisko
@ 2023-08-10 21:47             ` Jeff Johnston
  0 siblings, 0 replies; 13+ messages in thread
From: Jeff Johnston @ 2023-08-10 21:47 UTC (permalink / raw)
  To: Dan Petrisko; +Cc: newlib

[-- Attachment #1: Type: text/plain, Size: 65396 bytes --]

You'll need to change libgloss/configure.ac to ensure it creates your
Makefile (AC_CONFIG_FILES(dramfs/Makefile)).

After thinking about it, you shouldn't alter the target spec so you need
another way to enable the dramfs libgloss library.
I think the best way is to add a new configuration option to enable it
(e.g. --enable-libgloss-dramfs).   I am envisioning that this will
be an optional library to link with similar to libnosys.  For example, some
libgloss libraries set
up linker scripts etc.. to run on different boards and I think the user
should still have access to those if they enable building the
dramfs libgloss library.  I don't think that the top-level libgloss needs
to be changed with this strategy and the user simply specifies the
appropriate
-l option when building.

-- Jeff J.



On Thu, Aug 10, 2023 at 3:51 PM Dan Petrisko <petrisko@cs.washington.edu>
wrote:

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

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2023-08-10 21:47 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-01 23:54 [PATCH 1/2] Adding a LittleFS-based self-contained target to libgloss 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           ` [PATCH 1/2] " Dan Petrisko
2023-08-10 21:47             ` 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

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