Shared memory Linux<>FreeBSD?

Hi all,

I have a Linux binary running in /compat/linux and I need to share data to a FreeBSD binary. I tried using shared memory and writing from a Linux binary seems to be OK but the FreeBSD binary only reads zeros. I'm using the same approach I do for two FreeBSD binaries.

Is this not possible? What would be the recommended way to share data this way? I need to transfer about 80,000 bytes at 30 FPS.

Grateful for any hints!
 
Greetings @yohanesu75.

I see this is your first post, welcome! :)

To your question; I'm having difficulty following you here. Are you trying to modify FreeBSD binaries in Linux compatibility mode? Are you attempting to get your Linux application to communicate with your FreeBSD application? Could you please clarify? I'd be happy to try, and assist. I just need more data. :)

--chris

P.S. Don't forget that Linux binaries are ELF, and FreeBSD are not. See strip(5), if you're curious.
 
Last edited by a moderator:
Chris_H said:
P.S. Don't forget that Linux binaries are ELF, and FreeBSD are not.
Are you sure?
Code:
(0:45) host:/tmp# uname
FreeBSD
(0:46) host:/tmp# file /bin/sh
/bin/sh: ELF 64-bit LSB executable, x86-64, version 1 (FreeBSD), dynamically linked (uses shared libs), for FreeBSD 8.4 (804500), stripped

From the FreeBSD Handbook:

"To understand why FreeBSD uses the elf(5) format..."
 
Hi and thank you!

Yeah, I have a Linux binary-only driver for a special camera that I want to use on FreeBSD. So, I have to run a small Linux binary that retrieves data from the camera. However, I want to have the main part of my program, the part doing the image processing, being a FreeBSD binary so the Linux binary should only hand over the raw data from the camera to the FreeBSD binary for processing. I guess using sockets via the local IP address is one solution but if it's possible to use shared memory that would more efficient.

This would be a temporary solution so non-fancy, non-efficient methods are also OK.
 
Linux uses (requires) glib, which is ELF. FreeBSD' (current) use of ld(1) effectively eliminates the use of a.out, and the other older ELF, and elf-isms. In fact, a few years ago, when I was closely investigating FreeBSD "internals", I deduced that FreeBSD's use of ld(1) allowed me to use both versions of Apache (version(s) 1, and 2) at the same time, on the same system, without symbol crash/collision. The associated libraries bits could live in separate "spaces". Anyway, it's been awhile, and I'd best not elaborate too much, as the details are not as clear in my mind, this very moment. :)

On to your struggle; What type of output file does your Linux application generate? Does it simply "dump" it's output to file? What is the nature of it? An executable? A "loadable"? I'm confident what you seek to accomplish, is doable. But without greater detail from you, I suffer a bit handicapped.

Best wishes.

--chris
 
Hi Chris

My Linux application grabs an image (actually five images) from a ToF camera and through some secret algorithm hidden in the binary-only driver generates a depth map. I have the depth map (a grey scale image) in the Linux application's memory heap. From there I can do what I want. Copy it to shared memory, save to disk, write to socket, etc... All I want to do here is copy/send it over to my FreeBSD application in an appropriate way.
 
OK. Let's try this. Just for S and G. Why don't you dump it to a file -- something with an innocuous extension, or better, no extension at all. Then (assuming you're running the Linux ABI on a FreeBSD box), ask what file(1) thinks it is (post the output from file in this thread). Then we should have no zero difficulty knowing how to pass it on to your FreeBSD application.

I'll keep a watch. :)

--chris
 
But it's just a block of arbitrary data. Saving it to a file doesn't give any additional information. I won't be saving a file and reading the file from a FreeBSD application anyway because that seems like a bad approach. If I use sockets or shared memory, the contents of the data doesn't matter.
 
Chris_H said:
In fact, a few years ago, when I was closely investigating FreeBSD "internals", I deduced that FreeBSD's use of ld(1) allowed me to use both versions of Apache (version(s) 1, and 2) at the same time, on the same system, without symbol crash/collision. The associated libraries bits could live in separate "spaces". Anyway, it's been awhile, and I'd best not elaborate too much, as the details are not as clear in my mind, this very moment. :)
I haven't looked "under the covers" recently, either. Many years ago (I'd say during FreeBSD 4.x) I was consulting for a vendor of commercial software who wanted a "universal" binary for the various *BSD's. I actually created a build process for them which generated a binary that would run unmodified on BSD/OS, FreeBBSD, and NetBSD. This was an a.out(ish) binary, and was the output from ld(1), not something glued together from multiple systems later.

The trick was finding the system that had the minimum set of features (BSD/OS) and building it on there. Aside from the funky ld(1) command line, the only magic was a source file that emulated some library function which used a syscall unique to BSD/OS.

Of course, the next release the vendor stopped building for *BSD and told everybody to use the Linux version under the emulator instead.
 
Terry_Kennedy said:
Of course, the next release the vendor stopped building for *BSD and told everybody to use the Linux version under the emulator instead.

You mean the Linux ABI under FreeBSD?

--chris
 
Sorry if this is stating the obvious, just trying to help; could the data not just be 'piped' between your two appications/binaries (?).
 
Hi @fatmac,

Thanks for the suggestion. Yeah, of course that's an option. However, currently I'm using sockets via the loopback interface. Perhaps pipes would be even simpler?
 
Last edited by a moderator:
yohanesu75 said:
Hi @fatmac,

Thanks for the suggestion. Yeah, of course that's an option. However, currently I'm using sockets via the loopback interface. Perhaps pipes would be even simpler?
Pipes and sockets are just shared memory that use the file API. If you only need one-way communication, it might be easiest to pipe(2), fork, dup2(2) the output end of the pipe over STDOUT_FILENO, and execvp the program that reads from the camera. The program that reads from the camera would then write the frames to standard output, and the other program would read the frames from the input end of the pipe. If you need two-way communication, do the same thing but with socketpair(2) instead of pipe.

Kevin Barry
 
Last edited by a moderator:
Hi Kevin

Thank you.

Actually the socket thing didn't work out too well. In every few frame the whole image becomes translated in both x and y like the offset is messed up. I changed to using named pipe which was very easy to implement and now its working fine.
 
yohanesu75 said:
Hi Kevin

Thank you.

Actually the socket thing didn't work out too well. In every few frame the whole image becomes translated in both x and y like the offset is messed up. I changed to using named pipe which was very easy to implement and now its working fine.
This is probably related to reading or writing less data than was expected. The read and write system calls won't always read/write the exact amount you tell them to. When using either system call directly, you need to assume that it's going to do less than you asked it to and retry until the returns add up to the proper amount. If your problem happened with only sockets and not pipes, that doesn't mean it couldn't also happen with pipes.

Kevin Barry
 
Back
Top