EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  <20212022  2023  2024  Index 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  <20212022  2023  2024 
<== Date ==> <== Thread ==>

Subject: rtems IMFS support/compatibility
From: Michael Davidsaver via Core-talk <core-talk at aps.anl.gov>
To: EPICS core-talk <core-talk at aps.anl.gov>
Cc: "Siddons, David" <siddons at bnl.gov>
Date: Sun, 13 Jun 2021 11:58:33 -0700
Possible usage of IMFS came up in a recent tech-talk thread[1].  I tried again to make
use of the logic in initialize_local_filesystem() from rtems_init.c, and this time was
successful.  Although with some caveats.

As far as I can tell, only the uC5282 target provides special symbols _DownloadLocation,
_FlashBase, and _FlashSize.  I found a archived mail from Eric Norum [2] which gives a
hint about how he meant this to be used

> I do this for my standalone EPICS applications by concatenating the tar file at the end of the bootstrap flash. ...

I couldn't figure out how to make use of this logic as is with pc386 (QEMU).  By changing
the pointer gymnastics to something simpler I was able to load a tar containing an st.cmd
and a .dbd file.  (see attached)

I don't think the idea of concatenating an FS image to an ELF executable or .boot file
can be generalized though.

Linking a tar into an executable can be generalized, but means an executable for each
IOC instance, which seems kind of awkward.



The use of rtems_tarfs_load() also carries a couple of surprises.

1. The 'tar_size' argument is actually not a size, but an upper bound address.

2. Missing directories are not created automatically, and files in them are silently ignored.

eg. "tar -cf image.tar dbd/foo.dbd st.cmd" results in a tar with only two REGTYPE
entries, and no DIRTYPE entry.  "tar -xf" will automatically create "dbd/", but
rtems_tarfs_load() does not.  Further, "foo.dbd" is then ignored without error.
It took me awhile to figure out what was going on...

This can be worked around by "tar -cf image.tar dbd st.cmd", or more explicitly
"tar --no-recursion -cf image.tar dbd dbd/foo.dbd st.cmd", to include an DIRTYPE
entry for "dbd".  (without necessarily including all of its contents.)


[1] https://epics.anl.gov/tech-talk/2021/msg01192.php

[2] https://lists.rtems.org/pipermail/users/2010-March/055394.html

diff --git a/modules/libcom/RTEMS/rtems_init.c b/modules/libcom/RTEMS/rtems_init.c
index c5079b858..aaccdf3b2 100644
--- a/modules/libcom/RTEMS/rtems_init.c
+++ b/modules/libcom/RTEMS/rtems_init.c
@@ -155,32 +155,47 @@ epicsRtemsMountLocalFilesystem(char **argv)
 static int
 initialize_local_filesystem(char **argv)
 {
+#if 0
+    // uC5282 only
     extern char _DownloadLocation[] __attribute__((weak));
     extern char _FlashBase[] __attribute__((weak));
     extern char _FlashSize[]  __attribute__((weak));
+    extern char _edata[];
+    int imageValid = _FlashSize && (_DownloadLocation || _FlashBase;
+    char *imageBase = _FlashBase + _edata - _DownloadLocation;
+    size_t imageSize = (size_t)_FlashSize - (_edata - _DownloadLocation);
+#else
+    extern char _FSImageLocation[] __attribute__((weak));
+    extern char _FSImageEnd[] __attribute__((weak));
+    int imageValid = _FSImageLocation && _FSImageEnd;
+    char *imageBase = _FSImageLocation;
+    size_t imageSize = _FSImageEnd-_FSImageLocation;
+#endif
+    const char* cmdline = rtems_bsdnet_bootp_cmdline ? rtems_bsdnet_bootp_cmdline : "./st.cmd";
+    argv[0] = rtems_bsdnet_bootp_boot_file_name ? rtems_bsdnet_bootp_boot_file_name : "epics.boot";
 
-    argv[0] = rtems_bsdnet_bootp_boot_file_name;
     if (epicsRtemsMountLocalFilesystem(argv)==0) {
         return 1; /* FS setup successful */
-    } else if (_FlashSize && (_DownloadLocation || _FlashBase)) {
-        extern char _edata[];
-        size_t flashIndex = _edata - _DownloadLocation;
-        char *header = _FlashBase + flashIndex;
 
-        if (memcmp(header + 257, "ustar  ", 8) == 0) {
+    } else if (imageBase) {
+        if (memcmp(imageBase + 257, "ustar  ", 8) == 0) {
             int fd;
             printf ("***** Unpack in-memory file system (IMFS) *****\n");
-            if (rtems_tarfs_load("/", (unsigned char *)header, (size_t)_FlashSize - flashIndex) != 0) {
+            if (rtems_tarfs_load("/", (unsigned char *)imageBase, imageSize) != 0) {
                 printf("Can't unpack tar filesystem\n");
                 return 0;
             }
-            if ((fd = open(rtems_bsdnet_bootp_cmdline, 0)) >= 0) {
+            if ((fd = open(cmdline, 0)) >= 0) {
                 close(fd);
-                printf ("***** Found startup script (%s) in IMFS *****\n", rtems_bsdnet_bootp_cmdline);
-                argv[1] = rtems_bsdnet_bootp_cmdline;
+                printf ("***** Found startup script (%s) in IMFS *****\n", cmdline);
+                argv[1] = cmdline;
                 return 1;
             }
-            printf ("***** Startup script (%s) not in IMFS *****\n", rtems_bsdnet_bootp_cmdline);
+            printf ("***** Startup script (%s) not in IMFS *****\n", cmdline);
+            return 1; /* FS setup successful */
+
+        } else {
+            printf ("***** IMFS image @%p is not a ustar, ignoring *****\n", imageBase);
         }
     }
     return 0;
/* fooMain.cpp */
/* Author:  Marty Kraimer Date:    17MAR2000 */

#include <stddef.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>

#include "epicsExit.h"
#include "epicsThread.h"
#include "iocsh.h"

int main(int argc,char *argv[])
{
#ifdef iocshMain
    return iocshMain(argc, argv);
#else
    if(argc>=2) {
        iocsh(argv[1]);
        epicsThreadSleep(.2);
    }
    iocsh(NULL);
    epicsExit(0);
    return(0);
#endif
}

#ifdef __rtems__
__asm__(
".pushsection \".data\" \n"

".global _FSImageLocation \n"
"_FSImageLocation: \n"
".incbin \"image.tar\" \n"

".global _FSImageEnd \n"
"_FSImageEnd: \n"

".popsection \n"
);
#endif

Replies:
Re: rtems IMFS support/compatibility Siddons, David via Core-talk
Re: rtems IMFS support/compatibility Gedare Bloom via Core-talk

Navigate by Date:
Prev: Build failed in Jenkins: EPICS-3.14 #1062 Jenkins EPICS PSI via Core-talk
Next: Re: rtems IMFS support/compatibility Siddons, David via Core-talk
Index: 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  <20212022  2023  2024 
Navigate by Thread:
Prev: Build failed in Jenkins: EPICS-3.14 #1062 Jenkins EPICS PSI via Core-talk
Next: Re: rtems IMFS support/compatibility Siddons, David via Core-talk
Index: 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  <20212022  2023  2024 
ANJ, 15 Jun 2021 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·