Xavier nx bridge: USB OTG connected host identifies pcie connected nvme ssd as disk

Does Xavier NX supports in “bridging” between USB OTG connected host and a pcie connected nvme ssd?
I have a Xavier NX connected to nvme ssd via pcie. I want to plug the NX to my host and see the ssd as disk.

  1. Is there any “out of the box” solution for that?
  2. If not, can I implement such driver/protocol/filesystem/something else enabling this feature?


Hi BSP_User,

Are you using the devkit or custom board for Xavier NX?
What’s your Jetpack version in use?

What do you mean about “bridging”? Is that about network bridge or filesystem?

There should be a l4tbr0 interface for bridge from your host.
You could run ifconfig on your board to check, and its default address should be
Then, you could use ssh to access your board.

Hi KevinFFF,


  1. Xavier nx on a custom carrier board
  2. Any JP. I will use whatever helps (probably the later ones)

I wish to connect my host PC to the xavier nx via USB OTG and see the nvme ssd as a disk on my host (the ssd is connected via pcie to the xavier nx internally)

Describing how OTG works might help. This usually is not what people think it is.

USB always has a “host” end, and a “device” end. The connection is never two-way. USB-C only looks to be bidirectional, but in reality it has extra wires and ways to identify a host versus a device. The OTG port can accept either a type-A (host mode) connector, or a type-B (device mode) connector; an ID pin tells the Jetson which mode. The micro-B OTG cable used for flashing and serial console tells the Jetson to use device mode. Everything which follows is about device mode.

Many consumer devices, such as music players or smart phones, will appear as a storage device when connected to a type-B connector (charger cables are type-B, but generally have very low quality…literally they might have 2 strands of very thin copper cable, or worse). This is not a definition of “device mode”. The “device” which appears is a matter of programming. It just happens that those consumer devices are almost always programmed to appear as disk storage. They could be something custom, e.g., a USB network adapter would probably need a non-standard driver. A microphone is a “device”, and it might be “standard”, but it won’t appear as a disk.

Device mode can in fact appear as several devices at once on the same cable. The devices would share bandwidth. Jetsons tend to do this whereby they appear as a virtual network device and provide the address of for the Jetson, and the host PC would get address Simultaneously, there is usually a mass storage device also visible, and that is set up as read-only, and only has a README file. This latter is a demonstration of something the Linux kernel makes available as a kind of shortcut “framework”. That is called the USB Gadget API for Linux.

USB itself is just a pipe for data, although USB also provides information about whatever device is connecting. The devihttp://www.linux-usb.org/gadget/ce itself needs its own driver, and USB is not responsible for that. However, there are a number of USB device classes which were created as a means of making a lot of standardized and common devices available without a custom driver for every device. USB Mass Storage is one such class, and USB does provide a driver for that, but this is a convenience, and the Mass Storage driver itself is not a “USB” driver…the “pipe” is a USB driver, the mass storage driver attaches to the disk itself, and is not necessarily aware that this is going through a USB data pipe. See also:

A camera vendor might use the standard USB Video Class (“UVC” device). However, quite often a camera vendor would also implement some sort of control function for that camera, and that function is itself not standard; thus a second device would show up, and that would report itself to the “hot plug” layer, and no standard driver would know how to work with that, and so no driver would load; but if you have the manufacturer’s custom driver, and USB reports this device to all drivers, then the custom driver would know it works with that and would assume ownership to the control side.

There are other standard USB classes, including HID (Human Interface Device). You’re interested in the standard Mass Storage device.

The Gadget framework is essentially a template for the standard device classes. You have to fill in the details before it works to become any given device. The disk behind this within the Linux system actually has its own driver. It’s up to the Gadget software to basically pipe that through to USB. This works if and only if you’ve set up both the disk and the Gadget correctly. Multiple virtual devices exist on Linux for Tegra (L4T, which is Ubuntu plus NVIDIA drivers), and their content can be examined at:
(these are human readable files, and can be manually run, but those files, by default, run as a “service” through systemd, so there are both systemd setup files and Gadget setup there)

The sample gadget mass storage device partition is actually the file “/opt/nvidia/l4t-usb-device-mode/filesystem.img”. The file is not directly used; instead, loopback is used (via “losetup”) to “cover” the file and allow “pretending” that the loopback device is a disk partition.

There are a number of security and other issues related to exposing a system disk to USB mass storage. Before going into the details, consider that every partition is formatted for some particular filesystem type. Linux tends to use ext4. Desktop Windows tends to use NTFS, but removable media on Windows tends to use VFAT (this is a superset of FAT16/FAT32, so on…they are non-journaled filesystems). Understand that no Windows filesystem type has any ability to understand Linux permissions. You can export ext4 through a mechanism which translates to Windows permissions, but it is basically stripping out a lot of information. For example, Windows has shortcuts, but not symbolic links; the user/group/other permissions exist in full in ext4, but much of that is stripped out for Windows.

The example mass storage is formatted as VFAT. If you run your Jetson, and use this command it shows the block devices, their mount point, and the filesystem type:
lsblk -f

Many of those partitions are not mounted (they are used as binary data and are not formatted for mount). Some of those partitions exist in RAM and are not real hard drives. One of those will be “/dev/loop0”, and this is the demo file with the virtual software (the loopback) pretending it is a hard disk partition. That loop device is VFAT. This is what you’d use if you want Windows to be able to use it. If you want full use, and you want to use this strictly with Linux, then you’d be better off with ext4. If this is passing through an actual Windows partition, then it would be best as type NTFS. All of these have different security concerns (except that ext4 can do anything Linux does; you could even enable SElinux labels, and device special files would work).

The simplest case is if you have an actual partition (such as an SSD), and that partition is not used for Linux, but is instead just a “data” partition. You could format that partition with NTFS or VFAT or ext4, and then export this read/write without much concern (you’d set up the partition, and then adjust the Gadget to point at that partition rather than to loopback).

In the case where you share part of the actual Jetson’s root filesystem, it gets to be a lot more complicated. First of all, the rootfs is normally ext4. No Windows system will understand that. If you put rootfs on VFAT, then Linux won’t work right (as soon as sudo or any SUID/GUID program runs, it’ll fail; security will drop dramatically for what works). Often one will export only a subdirectory for the case of exporting within the operating system. For example, it’d be bad to export “/boot” and give the outside world the ability to damage or alter the kernel or boot content. More likely one would create something like “/exports” and put exported content there. Or maybe export a home directory of a particular user (that user might be in name only, and simply be a placeholder for security reasons).

Better yet, to add to the previous example with a placeholder user’s home directory, one would mount a VFAT partition to that home location. Then only that directory would be exposed, and the directory would be understood by both Windows and Linux (but permissions would be cut down). One could create a partition on the SSD and mount it there after formatting it as VFAT, and Gadget could describe that.

If for some reason you were to export the whole rootfs, then you’d better make it read-only. You wouldn’t want to give write access to things like the user password files (including shadow files). It’s rather unnerving thinking about giving someone full access to clone your whole system.

So consider what it is you want to appear as an export. Consider what filesystem type you want, although you’re stuck with ext4 if it is the whole running operating system. Consider what actual content you want to export, e.g., just music or something that isn’t the actual Linux operating system, versus a subset such as a home directory, versus “everything”.

Then explore the sample gadget setup. You can disable the existing mass storage without altering the virtual network. You could create and edit what is otherwise a clone of that, and even make a service such that it leaves alone the original example setup.

Note that if you run the command “lsusb”, that this provides an “ID”. An example ID might be “0955:7e19” (0x0955 is NVIDIA’s USB registry ID; 0x7e19 is one device ID within NVIDIA’s registry). Using that example ID, one can get a much more verbose listing of a single device, and that listing has most of what you’d need (but more) for a Gadget template:
sudo lsusb -d 0955:7e19 -vvv

Then examine the gadget setup and compare it what you see from a verbose device listing (plug in an external USB disk and see what shows up for a verbose lsusb on that disk). Go from there.

First of all thank you for your detailed answer.
Secondly, I apologies for saying this, but you gave me a lot information that I didn’t understand and I got lost.

  1. My host is Ubuntu as well (not Windows)

  2. the nvme that I want to see on my host doesn’t have to contain the rootfs. It can hold “regular” files which I want to get access to from the host.

  3. I understood that I need to further read about USB OTG, the “host” and “device” concept and the USB Gadget API for Linux. I didn’t understand if the bottom line is that its possible to achieve what I want and if there is an “out of the box” solution for that or not. In case not, what I need to implement in order for that to work.

Thanks again

this is an answer generated by chatGPT:

Here are the steps to set up the connection and access the NVMe SSD:

  1. Connect the USB OTG cable or adapter between the Xavier NX module and your host PC.
  2. On the Xavier NX module, you will need to configure the USB port in Device mode. This can typically be done through software configuration or by modifying the device tree configuration. Refer to the documentation or support resources for your specific carrier board to understand how to enable USB OTG mode.
  3. Once the Xavier NX module is in USB OTG mode, it should appear as a USB device on your host PC.
  4. On your host PC, open a terminal and run the lsusb command to check if the Xavier NX module is recognized as a USB device. You should see an entry related to the Xavier NX.
  5. If the Xavier NX is recognized, you may need to install additional drivers or configure the host system to treat the Xavier NX as a storage device. The steps for this may vary depending on your host system and the specific USB-to-PCIe bridge used in your carrier board.
  6. After the necessary drivers and configurations are in place, you should be able to access the NVMe SSD on the Xavier NX as a storage device on your host PC. It will likely appear as a block device, such as /dev/sdX, where X represents a specific device identifier.

Please note that the process of enabling USB OTG mode and accessing the NVMe SSD via USB may require some level of customization and configuration specific to your hardware setup. It is recommended to refer to the documentation and support resources provided by your carrier board manufacturer for detailed instructions and guidance.

Please use latest JP5.1.1 (R35.3.1) to verify and we could synchronize the status.

Could you recognize the SSD on your board and use it as a storage device currenltly?

If yes, you could just use l4tbr0 for the file sharing from your host PC to any location of your board.
There’s should be a L4T-README disk appear when your host PC recognize the board and you also could do file sharing from it, but you can’t access the content of NVMe drive from this. I would suggest using ssh or scp related command to do file sharing or any operation for your board from your host PC.

Are you thinking of network sharing, but network access over the USB, or are you thinking of files simply being accessed directly over USB? I’m reminded by @KevinFFF’s comments that perhaps you are just thinking of network sharing; on the other hand, maybe you are thinking of direct file access. I think it is direct file access, but incidentally, if the drive is set up correctly, then you could do both network and USB file access (the twist on that story is that USB device is already set up on Jetsons to provide a virtual network; you’d simply use normal network access for content on the NVMe, but this might not be convenient in the way you are thinking).

Can you provide an example use-case of how you want to use the Jetson? File copy? Directly playing music, e.g., file sharing? This can drastically change the best approach. The network access via ssh/scp/sftp is already almost all there; it would mostly be a case of setting up the NVMe correctly. Other uses require more setup for sharing.

Since your NVMe does not have any particular security concerns either method should be possible without a lot of extra work (that’s a relative term though) from the NVMe side. You’d want a partition on it, and since it is used by Linux, probably you’d format it as ext4. Then put files on it with the proper permissions, and perhaps mount it on a mount point with the correct permissions. Other methods of exporting would require this as well, but details would get more complicated.

Jetsons are not typical for their USB “out of the box”. You’re in luck that a virtual mass storage device exists, but it is only an example (@KevinFFF mentioned the L4T-README…this is the one item set up as read-only, and normally this does not exist on a regular computer). So the Jetson is “closer” to “out of the box” for device mode. Something like a smart phone goes further by default. There is probably a learning curve involved in taking the Jetson from just the read-only L4T-README to something more, but because you have a separate partition on the NVMe, and because the consumer of the data is another Linux system, this is simpler than starting from scratch and making it work for other computer operating systems.

I’m not sure ChatGPT always answers correctly. For example:

On the other hand, generally speaking, ChatGPT was not wrong about device mode, although ChatGPT seems to only have partial information…device mode itself is a bit like a suggestion about how to drive from Chicago to New York starting with “build a road”, and none of the details. Device mode alone has no meaning. It’s an empty pipe.

We already have device mode on the micro-B USB port (I’m assuming your NX model has the micro-USB port…a type-C port changes things, and a type-A port cannot work). You should not modify the device tree since it is already correct and there is a reasonable chance changing this could break something such that you’d end up reflashing. Device trees are not too bad for working with, but there are some things you should know before experimenting with them.

ChatGPT mentions possibly needing drivers. You can’t even know what drivers are needed until the type of device at the device end is set up. Standard devices already have drivers in most Linux installations. Custom devices do need extra drivers. Mass storage and virtual network devices are already supported (although security might require you to ok using them at the host PC end).

Just to emphasize, ChatGPT is quite wrong in its omission of what device mode does. Apparently ChatGPT does not understand that device mode makes it possible for a device to be attached, but in and of itself, device mode is not the end device. Device mode is an empty pipe. You have to connect the actual device, and in this case, it is a partition on the NVMe. Setting up the NVMe by partitioning it and formatting it and making a mount point is normal even without sharing, and is a first step in using that disk regardless of how you wish to use it.

Do you want to set up the NVMe for general file storage use? This would be needed no matter how you expect to use it. Instructions are available for this if you have not already formatted it.

Thank you both for your answers.

I need a direct file access from my host to the ssd storage. Not by network. I want the ssd storage (connected via pcie internally to the nx) will be identified “as a disk” or as a partition by my host and access its files directly without network. I want the ability to put files there by my host (again, without network).

I can partition the ssd, create an ext4 fs and mount it wherever is needed.
The main goal is to identify it and access its filesystem (read and write) from the host.

If I understood correctly, KevinFFF said its not possible and you say it is?

Do note that ssh and scp and sftp over ethernet can be over USB since there is a virtual ethernet device on the USB. However, it sounds like the following are options (difficulties vary):

  • As a USB “Gadget”, this would just be a disk. Since the computers using this are Linux, you would want to format it as ext4.
  • If other computers are involved, especially Windows, then the old Network Neighborhood could be used (Linux can mount that too, but it is a lot of work). In that case you’d format as NTFS. This is network, but it looks like a local disk, and the USB can be used for the network.
  • If other Linux (or *NIX flavors such as BSD) are to all share this, then NFS could be used. This too is network, but it looks like a local disk, and the USB can be used for the network.
  • iSCSI. Only a single computer can use this, and it is over the network. Again, this can be over a USB ethernet. This is tricky to set up. In the case of gigabit or faster (which the USB is not), this is ideal…the best performance is possible, and often this works in some strange environments.

For the case of being available over USB and appearing as a disk, you are stuck with the USB Gadget. You need to partition the disk, and then format as ext4. With the disk mounted, what do you currently see from “lsblk -f” (you only need to show the results related to the SSD)?

This is possible, but it is not possible by default. There is no “out of the box” solution. There is a significant learning curve, but information on the topic is available since a lot of people have done this, and because the Gadget API was extensively refined starting several years ago. I will emphasize this is not out of the box.

Thank you for your replies.
So I want to make sure I understood correctly:

  1. I can use ssh,scp,sftp from my host by creating a virtual Ethernet interface and read/write data via USB.
    The virtual interface is actually a USB gadget.
    I saw an example here:
    How to create USB Ethernet gadget for Jetson through configfs - RidgeRun Developer Connection
    This solution is fairly easy to implement, just need to know the exact needed functions and configurations.

  2. I can use same USB gadget method to make the nvme partition identified as a disk by my host? (isn’t that like previous options just choosing other suitable functions and configurations?)

I checked and confirm that when my host is connected through usb I see the following eth interfaces on the nx side:

  1. usb0
  2. l4tbr0
    they have almost the same mac address.

I assume I need to assign to one of these interfaces an ip address and then try to ssh from my host to the nx (therefore gain access to my ssd partition)

I didn’t tried it yet since I want to go for the other “harder” option: make my ssd identified as a disk on my host and read/write its files like a regular disk (using the host GUI)

Can I achieve that by configuring a USB gadget with the right functions and configurations?


About this:

I can use ssh,scp,sftp from my host by creating a virtual Ethernet interface and read/write data via USB.
The virtual interface is actually a USB gadget.
I saw an example here:
How to create USB Ethernet gadget for Jetson through configfs - RidgeRun Developer Connection
This solution is fairly easy to implement, just need to know the exact needed functions and configurations.

Yes, you can access those files via those network commands. There are clients which work via those commands if you prefer that over command line or scripting. PuTTY is one example, and that program runs on both Linux and Windows. Most people only know about PuTTY because it can serve as a serial console program. PuTTY can also use ssh, scp, and sftp, which means it looks like a file manager when told to, but uses those network protocols instead of directly operating on storage devices (at least at the remote end).

You can use command line over ssh to log in to a Jetson over any ethernet, including the virtual one. With this you have access to command line tools as if you are logged in on the remote system. You can for example format a disk, partition a disk, delete or copy files, so on. It is important to know if the system you are running the client on is also Linux, or if it is Windows, as this changes which clients are available. This is not the same as the content appearing as if it is a hard disk, but the functionality is quite convenient and easy to set up. PuTTY is one example compatible with several operating systems. What would not happen is that you plug in the device and new storage shows up.

Those network interfaces, on the Jetson side, are indeed part of the virtual USB device. That device mode USB interface appears to the other computer as if it is a router. Should the other end of the ethernet accept this virtual router, then the following IP addresses are automatically set up via DHCP:

  • For the Jetson, (from either computer “ping” will ping the Jetson).
  • For the remote end, (from either computer “ping” will ping that other computer).

Any of the above would avoid needing to set up the Gadget template, although it is not quite as convenient. Incidentally, network access via a client means it won’t care about permissions, filesystem types, so on; access would be based on the user credentials at each end.

Your understanding is correct that you would need USB gadget to make the Jetson’s SSD show up as a disk to the remote system. That virtual ethernet and a README file are examples of Gadget setup, whereby the README itself has its access set up exactly as you want…the example sets up a tiny read-only partition with a README file via the Gadget API. You would be performing the same steps, except you would be naming the SSD’s partition (which you need to set up) as read-write instead of naming a loopback device covering a file which pretends to be a partition.

Btw, you can do both Gadget API and ethernet ssh/scp/sftp access. The ethernet part is already there, you just have to run the client.

One possible catch on ethernet: The other end which accepts the ethernet might have security set up to force you to verify that you are ok with that network device. This is often the default, but not always the case.

Thank you for your reply and patience.

I want to go on the “ssd identifies as a disk” option.

I understand there is already a similar USB gadget - the README partition.

My questions are:

  1. Where are this gadget configuration and settings files located? I assume I will copy them and make the appropriate changes.
  2. Is there some kind of tutorial for “newbies” regarding the different configurations and different functions options available when creating a new USB gadget?
  3. Is there some kind of tutorial explaining how to do the exact thing I want to do?
    How to create a usb gadget which makes existing partition with ext4 file system to identify as a disk by the host? (I know you help me with that but maybe I can learn more from some guide someone already written)

In general, the demonstration of Gadget device mode includes both the virtual ethernet and the block device with the README file. You’ll perhaps want to copy that, and remove the ethernet part (so the original is not changed), followed by editing the block device (mass storage) content to point at your partition instead of creating and pointing at a loopback device (the “losetup” content “covers” a file in order to make the file look like a partition). That location is in:
(more on that below)

Before you start though, can you verify the SSD’s partition you wish to use, and say if it is able to mount and umount to some temporary location? What do you see from the command “lsblk -f”? Mostly you will want to set up some sample file to see if it can be read, and place it on the partition, but you won’t want the partition mounted while actually working with it.

Regarding the example mass storage code, it is both simplified and made more complex because it is enabled as a service. Are you familiar with reading bash shell script code? Mostly it is just the same as what people would type in on command line (your login shell is in fact a bash shell…the same interpreter is reading the scripts we look at that also looks at what you type into the command line when operating normally).

The scripts in that location have a manual “stop” and “start” shell script, which will be obvious by their names. There is also a “service” setup, which is used during startup by the operating system to enable/disable/start/stop that same service (the service is a front end wrapper to the start and stop of the actual function, and you want to work only with a start and stop of function, and not with start and stop of a service). When the operating system starts or stops this it is given the service name “nv-l4t-usb-device-mode.service”, and it starts or stops both the mass storage and the virtual ethernet services. When you go to work on a copy you’ll need to initially not stop or start this as a service (leave the original service and files alone, and when working, just stop or start the edited nv-l4t-usb-device-mode.sh or stop.sh which avoids touching any files or resource from the original demonstration of mass storage).

A demonstration of the service is to query the status:
systemctl status nv-l4t-usb-device-mode
(you won’t be using this, but it is useful to see if the service is running)

Note the file “filesystem.img”. This is the file which pretending to be a partition. Any command you see related to networking you can remove from your copy, and any command related to “losetup” can also be removed (this is part of mass storage, but you are not emulating a partition, you have an actual partition). You will need to operate as root for all edits, so you’ll drop into a root shell via “sudo -s”.

I would first “cd /opt/nvidia”. Then I’d make a copy of the content under a new directory:

# Warning: This gives you permission to destroy the o/s:
sudo -s
cd /opt/nvidia
cp -adpR ./l4t-usb-device-mode ssd
cd ssd
rm dhcp*
rm *filesystem*
rm mac-addresses
rm nv-l4t-usb-device-mode.service

The above will remove much of the content which you won’t be using. Explore those files. Find the parts which are related to a virtual network device, and remove them or comment them out. Incidentally, in a bash script, you always leave the top two lines alone, whereby the second line is blank. So you won’t touch this:


(known as the “shebang”)

Note that comments start with “#”. If you wonder if something does something, but don’t want to delete it, you can make those lines inert via prefixing with “#”. You don’t need to remove comments related to networking, but you could. The comments might be useful in figuring out what is related to mass storage versus networking. Sections with IP addresses, MAC addresses, routing, so on, can all be deleted. Parts related to fs_img or filesystem or partitioning will be edited. Parts related to “loop0” (or any particular “loop#”) will need to be edited to point at the actual partition (“loop0” is a virtual partition).

Incidentally, this lists block devices, and you’ll find “loop0” (which is “/dev/loop0”) listed:
lsblk -f

Eventually you will link the SSD you see in that command. loop0 will still be present because you are not editing the original demo, you’re adding your own edited version in a new directory.

During the editing you’ll have to start learning about the Gadget API from some of those documents listed in earlier replies. Feel free to ask questions, for example, if you want to know how to edit a particular line of code in a file, or what the hexadecimal means for USB parameters, so on. This will not be without a learning curve.

1 Like

I start working on this matter.

I noticed that after powering on the xavier nx my host doesn’t see any new disk. The L4T-README partition (/dev/loop0) is seen from the nx itself only and not by my host.

(JP 4.4)

This tends to be a USB issue. If you monitor “dmesg --follow” on the host PC, and if you plug in the correct cable on the NX and to the host, what shows up in the logs as a result of that plugin?