general/other Linux binaries: USB device not found

jbo@

Developer
I'm trying to run a Linux binary on FreeBSD for the very first time and could use some help.
For those following along at home, I am trying to make use of a SEGGER J-Link adapter for which you can get Linux binaries from here: https://www.segger.com/downloads/jlink/

Note: I'm running FreeBSD 13.0-RELEASE (64-bit) and downloaded the 64-bit Linux binaries.

After loading the linux kernel module (running kldstat shows both linux.ko and linux_common.ko) I tried to simply execute the binary. I was presented with the following error:
Code:
jbo@fbsd_beefy01 /u/h/j/d/j/JLink_Linux_V756d_x86_64> ./JLinkGDBServer
ELF binary type "0" not known.
Failed to execute process './JLinkGDBServer'. Reason:
exec: Exec format error
The file './JLinkGDBServer' is marked as an executable but could not be run by the operating system.

Following the handbook I used brandelf to mark the binary as a Linux binary:
Code:
brandelf -t Linux JLinkGDBServer

However, this was not very successful. I am still getting an error regarding the ELF binary type although this time showing 3 instead of 0:
Code:
jbo@fbsd_beefy01 /u/h/j/d/j/JLink_Linux_V756d_x86_64> ./JLinkGDBServer
ELF binary type "3" not known.
Failed to execute process './JLinkGDBServer'. Reason:
exec: Exec format error
The file './JLinkGDBServer' is marked as an executable but could not be run by the operating system.

Could somebody enlighten me about what I'm missing or doing wrong?
 
Yes... I was being stupid. I needed to install emulators/linux_base-c7 as the handbook also suggests. I skipped that section because I thought that would not be necessary when running pre-built binaries... duuuh.

After installing that port along some other emulators/linux-c7-* ports necessary the application actually starts up. However, the fun is not over.

The J-Link is a device connected via USB 2.0. It shows up on usbconfig:
Code:
ugen0.7: <SEGGER J-Link Ultra> at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (100mA)

The J-Link application I am trying to run usually provides the option to choose whether to connect to a J-Link adapter via USB or TCP/IP. However, in my case the USB option is not available as the application informs me that no adapter is present. Yet it shows up on usbconfig.
Any ideas on this? Am I missing something crucial to allow Linux applications to access USB devices?

I did try this with mounting the filesystems that were mentioned:
Code:
linprocfs  /compat/linux/proc     linprocfs   rw            0   0
linsysfs   /compat/linux/sys      linsysfs    rw            0   0
tmpfs      /compat/linux/dev/shm  tmpfs       rw,mode=1777  0   0
but the USB device is apparently still unavailable to the Linux binary.
I also tried running the binary with sudo getting the same results.
 
I read the manual of the J-Link software and there is a way to manually specify the USB device using -select usb=<number>.
I tried that but got the message:
Code:
USBBULK: Failed to load libudev.so. Needed for identification of J-Links connected via USB

Any ideas? I have devel/libudev-devd and devel/libgudev installed on the host. I couldn't spot any corresponding emulators/linux* packages.
 
I don't have /usr/compat/centos available.
Here's what I tried instead:
Code:
sudo chroot /compat/linux /bin/bash

Then I tried to launch the binary again. It complains about not being able to access Fontconfig and the X server:
Code:
bash-4.2# JLink_Linux_V756d_x86_64/JLinkGDBServerCLExe 
SEGGER J-Link GDB Server V7.56d Command Line Version

JLinkARM.dll V7.56d (DLL compiled Oct 29 2021 14:01:31)

-----GDB Server start settings-----
GDBInit file:                  none
GDB Server Listening port:     2331
SWO raw output listening port: 2332
Terminal I/O port:             2333
Accept remote connection:      yes
Generate logfile:              off
Verify download:               off
Init regs on start:            off
Silent mode:                   off
Single run mode:               off
Target connection timeout:     0 ms
------J-Link related settings------
J-Link Host interface:         USB
J-Link script:                 none
J-Link settings file:          none
------Target related settings------
Target device:                 Unspecified
Target interface:              JTAG
Target interface speed:        4000kHz
Target endian:                 little

Connecting to J-Link...
Fontconfig error: Cannot load default config file
JLinkGUIServerExe: cannot connect to X server :0
Connecting to J-Link failed. Connected correctly?
GDBServer will be closed...
Shutting down...
Could not connect to J-Link.
Please check power, connection and settings.bash-4.2# exit
exit
 
if it needs X then you have to either run xprotocol over tcp or run it without chroot
if you run it without chroot you have to configure it to choose the correct shared object directories
probably by using LD_LIBRARY_PATH? I haven't use linuxlator in a while and can't remember how to tell linux ld.so where to search for libs
 
Actually, this is all automatic when the required libs are installed below /compat/linux, this acts as an overlay when running linux binaries. You only need chroot et al if you install a different linux userland in some different prefix.
 
Actually, this is all automatic when the required libs are installed below /compat/linux, this acts as an overlay when running linux binaries. You only need chroot et al if you install a different linux userland in some different prefix.
So how would this work in a situation like this where I get a tarball with binaries in them? Do I just copy the downloaded archive to /compat/linux and launch the binary from that location?
Because that is exactly what I did. The application does work as intended. The only problem is that it apparently cannot find the USB device which is connected to the host (and shows up no usbconfig).

That being said - is there anything translation/shim wise going on which would need the host to "know" the USB device (eg. have a driver for it - loaded & working)? Or does the Linux layer simply get the USB device and everything should work out of the box? If so, is there a way to check whether the Linux layer actually sees the USB device?
 
I still didn't manage to get my SEGGER J-Link Ultra+ to work via USB. I purchased a SEGGER J-Link Pro in the meantime which also features an ethernet/IP interface. Using that interface everything is working as expected. So other than the USB shituation we're good.

Would still like to get USB working tho.
 
I know it's not an answer to your question but wouldn't it be easier to use VM and pass usb to it? It was always pain (for me) to make anything running under this linux ABI (true the last thing I was running this way on FreeBSD was skype1).
I tried that quickly on my FreeBSD host, seems to be working (don't have any target to debug at hand right now):

host:
Code:
ugen0.3: <SEGGER J-Link> at usbus0, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (100mA)
vm:
Code:
Bus 001 Device 004: ID 1366:0101 SEGGER J-Link PLUS

root@h2olx:/home/martin/JLink_Linux_V760c_x86_64# ./JLinkExe
SEGGER J-Link Commander V7.60c (Compiled Jan  7 2022 16:13:49)
DLL version V7.60c, compiled Jan  7 2022 16:13:33

Connecting to J-Link via USB...O.K.
Firmware: J-Link V9 compiled May  7 2021 16:26:12
Hardware version: V9.40
S/N: XXXXXX
License(s): FlashBP, GDB
OEM: SEGGER-EDU
VTref=0.000V


Type "connect" to establish a target connection, '?' for help
J-Link>
 
I know it's not an answer to your question but wouldn't it be easier to use VM and pass usb to it?
Certainly an option I see as viable. However, unless I am missing something we don't really have any solution other than running VirtualBox if the goal is to pass through a single USB device (last time I checked bhyve didn't have this capability and I am unable to passthrough an entire USB controller in some situations (such as laptops or a desktop which doesn't have any free PCIe expansion slots available to add another USB controller).
I've actually used VirtualBox on Windows with a Linux guest and passed through the J-Link to the guest successfully for a project where the customer's stuff only built on Linux (fixed by now). While this worked, the USB device passthrough is... flakey.


I tried that quickly on my FreeBSD host, seems to be working (don't have any target to debug at hand right now):
Can you provide more information regarding your specific setup - especially the used hypervisor and the way you provided the guest VM with access to the J-Link USB device?
 
True, not many good options available. qemu might be an option but lack of kvm would be most likely painful. If I've an option to choose any host I like when I use virtualization I tend to go VMware on desktop and qemu anywhere else. I'm stuck with VirtualBox on FreeBSD. But it got better over time (started using it around version 3 or 4 I think).

I used VirtualBox in this example. I don't have any targets to test this setup though, output from what I shared seems OK. (I use Ubuntu as a host when I use my j-link). As it happens I do have xorg installed on this test FreeBSD machine so I used GUI to configure it all. It was as easy as go to USB settings and pass the given device (by name) to VM.
 
(I use Ubuntu as a host when I use my j-link)
This topic/thread exists mainly because of not wanting to do that :p
I wonder if it's worth reaching out to SEGGER to survey how they'd feel about producing native FreeBSD binaries. Given that their stuff is pretty much all based on Qt there should be little work required other than the actual USB/ethernet interfacing which - for now - I'll naively assume would be trivial to port to FreeBSD if it's already running on Linux, Windows & MacOS.

Anyway: Thank you for your input, _martin. I will most likely end up giving it a shot with VirtualBox on a FreeBSD host. I just really don't like that solution (partly because VirtualBox an partly because Linux VM). I think either of those would be fine for me but both combined just feel like being forced to work with a "shitty" setup/environment. But I guess we wouldn't be talking about this if that were not already the case :p
 
I understand. It would be easier to use it semi-natively.

Today I'm not in the mood of testing this kind of stuff but have you seen the thread here ? The problem I ran into was a lib one and I didn't want to resolve that manually (installing rpm, or even worse, extracting rpm to the linux base). Maybe worth pointing out - how does /compat/linux/dev see the device ? Does it even see it? Should devfs be adjusted for that,etc.
 
Back
Top