01-18-2018 03:10 AM
I'm trying to run a closed source executable on my myRIO running NI Linux RT, which is unfortunately compiled using the ARM hardfp libraries.
I therefore have three main questions:
Thanks
Matt
01-18-2018 09:20 AM
Hi Matt,
You may want to put the kettle on, this turned into a bit longer of a post than I was expecting.
So, yes, in theory you could try to take a NI Linux RT softfloat target and attempt to "multilib" it (similar to what is done for most desktop distributions to support 32-bit and 64-bit programs), making both hardfp and softfp libraries (and their associated loader) available on the same system.
The biggest issues are:
Another option would be to get a reasonable hardfloat ARM image (e.g. one of the ones meant for the RPi or BBB), extract it to the disk (or USB stick, etc.) and chroot into the other image. This will essentially make the shell session that is chroot'd a hardfp environment. The inverse of this is how the LabVIEW support for BBB/RPi2+ works (chrooting into a softfp environment).
"But wait", you say, "what kernel are you using? Did you somehow boot the kernel in the other system's OS image?" No, the "hardfp" shell is still using the same kernel as the NI Linux RT system. "Wait! You're using a softfp kernel with a hardfp system‽ Won't that run into the same issues that you mention above‽" No, and here's why: The kernel is always compiled softfp, no matter the tools that you use or the target you build for. There is almost no float math in the kernel (some in some drivers working with hardware that doesn't just provide raw values), and I'm guessing it cuts out a major support headache (different compile options, different calling convention, essentially a different architecture) for minimal-to-no performance loss. The fact is that there's no direct calls from userspace to kernelspace (or back) that pass floats directly. All interactions to kernelspace load integers (syscall number) and pointers (values passed) and trigger a transition to kernelspace, and the kernel can then pull the values that it needs.
02-08-2018 10:06 AM - edited 02-08-2018 11:11 AM
Hi Brad,
Thank you for such an in-depth response!
Not being a Linux expert, the chroot option sounds superior. However, I am now also needing to use an armhf compiled shared library in my VI, which I'm calling using a call library function block. Since chroot applies to the current running process, am I right that it won't be possible to use this approach to call a armhf shared library, as this would result in the whole labview process accessing the wrong libraries? (I know it isn't possible to link like this normally, but I'm unsure as to how exactly shared library linking works under the hood in labview)
Alternatively to chroot, I'm wondering if it is possible for me to manually copy /lib from an RPi image into my target as /lib_armhf, and then use the gcc -rpath linker option or the patchelf utility to hardcode my shared library to use this alternative loader and libraries? I am however currently trying this approach with no success so far, so if there is a fundamental flaw with this concept that I'm missing I'd be happy to hear it!
Thanks again
Matt
02-08-2018 12:55 PM
The chroot option won't work for needing to call a shared library from LabVIEW RT (which is softfp). It will run into the issues that I described earlier (namely, the code generated around the CLFN will be expecting the float arguments to be passed to functions in integer registers, not in the FPU registers, while the library will be expecting float arguments to be passed in those FPU registers).
Whole-sale copying /lib (and /usr/lib) from a RPi OS image to a different location on disk and attempting to patch-up (after the fact) would be a tough row to hoe, and even if you did it correctly, you'd be violating the fundamental aim (disallowing cross-ABI calls between binaries). The fact of the matter is that you have two binaries that cannot change ABI (LabVIEW RT and this library), you cannot recompile LabVIEW RT to be a different ABI, and I assume you cannot do that for the library either.
You have two options: