Adding POSIX APIs to Newlib / Testing with RTEMS

Matthew Joyce
6 min readJul 18, 2021

I am building and testing with the SPARC ERC32 Board Support Package (BSP), a radiation-tolerant SPARC V7 processor developed for space applications. The ERC32 BSP has a robust simulator that runs test executables on the host computer and is recommended in the RTEMS quick-start guide.[1]

General steps to follow:

1) Ensure you have built the RTEMS tool chain for SPARC architecture using the RTEMS Source Builder.²

2) Clone the Newlib source code.

Having followed the RTEMS quick-start guide, my $HOME/quick-start/ directory is pictured below. Yours may differ depending on how you have set up RTEMS.

$ cd $HOME/quick-start
$ mkdir –p newlib
$ cd newlib
$ git clone git://sourceware.org/git/newlib-cygwin.git

3) Add function prototypes to appropriate header file in newlib.

For the first functions I have added (sig2str and str2sig), the prototypes were added into $HOME/quick-start/newlib/newlib-cygwin/newlib/libc/include/sys/signal.h

4) Build newlib to ensure it compiles

Here, we will use the j-newlib script to simplify the process.

Download the j-newlib script into the newlib source directory. ($HOME/quick-start/newlib/newlib-cygwin/)

Set path variable to where your RTEMS tools are installed. For me, this was:

$ export PATH=$HOME/quick-start/rtems/6/bin:$PATH

Edit the j-newlib script as appropriate. In my case, I:

— Commented out all architectures other than sparc-rtems6

— Set the NEWLIB variable to the complete path to the newlib source directory (/home/mj/quick-start/newlib/newlib-cygwin)

— Set the PREFIX variable to the same prefix where you built the RTEMS tool chain. (/home/mj/quick-start/rtems/6)

— Edited the path to ensure the “configure” command is running from the proper directory (from the newlib source directory into the newly created b-sparc-rtems6-newlib directory.

— Run the j-newlib script. This tends to take around 15 minutes on my machine.

Navigate into the newly created b-sparc-rtems6-newlib directory.

$ make install > /dev/null

(Redirecting output into /dev/null will set it so only any errors are displayed on the screen).

If it installs with no errors, your prototypes have built successfully.

NB: I encountered permissions issues when building newlib. I attempted to solve this by running: “sudo make install” but learned that running sudo resets the path variable that we lovingly set in this step. I eventually got around this issue by running “su -p”. This is the “switch user” command (which defaults to root) with the -p (preserve environment) option. Once you authenticate, you should be able to run “make install > /dev/null” successfully.

5) Implement functions

I implemented sig2str() and str2sig() by adding a file “sig2str.c” in $HOME/quick-start/newlib/newlib-cygwin/newlib/libc/signal

After writing the implementation we will rebuild newlib using the same steps as above. Since we have added a source file, however, we first have a few additional steps to do.

Navigate to the directory where the source file was added. (/newlib-cygwin/newlib/libc/signal)

Edit the file Makefile.am as follows:

— In LIB_SOURCES, add the name of the new file (sig2str.c)

— In CHEWOUT_FILES, add <filename>.def (sig2str.def)

Next we want to run autoreconf. Navigate to the closest directory to the new file that has a configure.in file. (In this case /newlib-cygwin/newlib/libc). This step reduces the number of unnecessary changes that autoreconf has to make. Then run:

$ autoreconf -fvi

NB: Previous years’ GSoC students encountered issues requiring the use of multiple versions of autoconf (https://medium.com/my-gsoc-2019-journey/how-to-handle-two-versions-of-autoconf-b1e28de8617b) In my case, I only required the default version (currently 2.69).

Then re-build newlib using the j-newlib script and make install as outlined above.

Once this has run successfully, you should be able to find your newly defined symbols in the newlib compiled libraries.

$ cd $HOME/quick-start/newlib/b-sparc-rtems6-newlib/sparc-rtems6/newlib

$ sparc-rtems6-nm libc.a | grep sig2str

If they appear with T next to them, you have successfully defined the methods.

6) Submit the patch

Now that we have added our methods to Newlib, we must create patches and submit them to devel@rtems.org. As the changes should span more than one commit, create a clean patch of the additions using git rebase -i HEAD~<number of commits to squash>. While conducting this interactive rebase, it is possible to re-order commits if they are not adjacent to one another. This page has a good explanation of this process: https://www.scraggo.com/how-to-squash-commits/ .

Create the patch itself using:

git format-patch — cover-letter HEAD^

The cover-letter option will allow you to create an introduction to your patch set for the mailing list.

Then submit the patch using:

git send-email — annotate [cover letter patch] [patch name]

The annotate option will allow you to edit the cover letter itself and give you the chance to make any edits you want to the subject line of the patches to be submitted.

(Please note: you must edit your .gitconfig file to include your email account settings. See https://git-scm.com/docs/git-send-email for more details)

Adding the Tests to RTEMS

When adding a new POSIX API, we should add two tests in RTEMS. RTEMS advocates Test Driven Development, so these steps can actually be done before adding code to newlib.

1) A compile only test in rtems/testsuites/psxtests/psxhdrs. The purpose is to just make sure our header files involved with the addition function properly.

2) A full test in rtems/testsuites/psxtests. For sig2str/str2sig, this meant adding on another test (psxsignal09) after the currently existing psxsignal01 — psxsignal08.

After writing your test in rtems/testsuites/psxtests, how do you get the BSP to include it in its build? There are a few steps to take to make this happen.

Navigate to $HOME/quick-start/src/rtems/spec/build/testsuites/psxtests

First, add the compile only test to the file libpsxhdrs.yml. (You will just need to open the document with an editor and add the path to the file).

Next, open the file grp.yml with an editor. Add in the following lines (as shown with the “+” from the git diff:

Next, in the same directory ($HOME/quick-start/src/rtems/spec/build/testsuites/psxtests), add a .yml file with the name of your new test. (In this case, psxsignal09.yml). As a template, I used one of the similar .yml files from the psxsignalxx group. This identifies the source file and the target (.exe) file when the BSP builds. (See image below)

Then we need to make some additions to the config and makefiles.

Navigate to $HOME/quick-start/src/rtems/testsuites/psxtests

Open Makefile.am with an editor. Add in an entry for your new test. For psxsignal09, I followed the example of the previous psxsignalxx series. (see image below).

The .scn and .doc files need to be added to your new test folder as well. They contain the expected output and the header/additional documentation for the test respectively.

Finally, in the same directory, add into configure.ac: RTEMS_TEST_CHECK([<test name>]) where appropriate.

[1] https://docs.rtems.org/branches/master/user/start/preparation.html#selecting-a-bsp; https://en.wikipedia.org/wiki/ERC32; http://microelectronics.esa.int/erc32/index.html.

[2] https://docs.rtems.org/branches/master/user/start/tools.html

--

--

Matthew Joyce

Studies Computer Science at Oregon State University. Student Developer with the RTEMS project through Google Summer of Code, 2021. Lives in Berlin, Germany.