How to set TX2 otg usb as device mode?

Can you verify your device tree edits made it into the final tree? You can extract from your running Jetson and then compare to see if your edits are in place (to see if the flash procedure did as expected):

dtc -I fs -O dts -o extracted.dts /proc/device-tree

I can’t say for sure, but if your initial configuration wasn’t correct (and I don’t know what is correct, I’m just speaking of procedures, not actual content), then even if your edits didn’t exist it could disable USB.

I hava checked these thress files,they have changed.But I am not sure whether it correct or not.
Here I attach those files.
dts.rar (238 KB)

I couldn’t tell you if your device tree changes are valid or not for this purpose…someone else will have to comment on this.

Hi all,
I run the script [url]https://devtalk.nvidia.com/default/topic/1014096/jetson-tx2/how-to-set-tx2-otg-usb-as-device-mode-/1[/url] and I can get otg device mode.However,I also have some questions that I do not understand:
1.The filesystem is ext4 so I can not open it in windows system.So,I have to check it in my virtual machine.
2.The size of disk sapce is 1.1G ,how can I change the size?
3.I mount the disk on my virtual machine and create a new file,but I can not find it in TX2.So Where I get the 1.1G ?

Hi,
The linux commands to generate storage is in the script. It generates 1G with below commands:

dd if=/dev/zero of=/home/ubuntu/msc.ext4.img bs=1M count=1k
mkfs.ext4 /home/ubuntu/msc.ext4.img

Other users may share their experience to give you suggestion for the requests.

Hi,DaneLLL
That’s great!!
So,do you mean I can set the size freely.
Where I save my file and I also get in my virtual machine?

Hi,
You should get 2G if you change count=2k

Don’t know how to initialize non-ext4 format. Other users may share experience.

Basically you are using loopback to make a file appear to be a block device. Block devices transfer in “block size” chunks. A real disk is 512 bytes or multiples of 512 bytes, e.g., 4096 is common in some SSDs, but most old style hard drives stick to 512 bytes. There might be some improved efficiency in using a larger block size if on average your file sizes are larger, but for all cases you can’t go wrong with 512 bytes (consider that if the underlying disk holding the loopback file has a 512 byte block size, then that is read in 512 byte chunks, and thus there is never improvement on larger block sizes for a loopback file on that hard drive…the eMMC is 512 bytes…see “sudo gdisk -l /dev/mmcblk0”).

“dd” is creating a blank file of a specified size. There are many ways of doing this, e.g., the “truncate” command can reduce or enlarge files, while dd only creates from scratch or overwrites an existing content. However, dd might be more efficient for some uses due to working at a lower level than does truncate. Let’s say you want 4GB. Call it “410241024*1024 == 4294967296”. In 512 byte blocks this is “4294967296/512 == 8388608”. So this would create an empty file capable of holding a 4GB file system (raw bytes) using 512 byte blocks:

dd if=/dev/zero of=/some/where/empty.dat bs=512 count=8388608

Once this is covered by loopback it can be treated as if it were a hard disk partition by addressing the loopback device.

FYI, you need to be root (use sudo) for much of the losetup command. A non-root user can query what the first unused loopback device is via:

losetup --find

If the result is “/dev/loop0”, then you can check existence:

ls /dev/loop0

Here is the subtle tip: Running “losetup --find” as non-root will report the first unused loop device. This device might not exist, and if not, it won’t be created. On the other hand, if you use “sudo”, then a simple query of “sudo losetup --find” will also create the device reported as first unused device. You have a limited number of loopback devices available, and it is a leak if you create too many and never release.

So to “cover” a file with loopback, in its simplest form form where the device name is created if needed and also reported as to which device:

sudo losetup --find --show /some/where/empty.dat

If it turns out it was “/dev/loop0” reported, then you could detach loopback in a number of ways, but this is for the specific device:

sudo losetup -d /dev/loop0

To detach all loopback devices which are not bound to some process:

sudo losetup -D

Don’t for get to detach after you are done.

To format this as ext4:

sudo mkfs.ext4 /dev/loop0

To mount this and use it as if it were a partition:

sudo mount /dev/loop0 /some/where/else/

To umount you can do either of these:

sudo umount /dev/loop0
sudo umount /some/where/else

Something you can do is examine:

sudo gdisk -l /dev/loop0

You cannot modify a mounted partition, but if the file is covered by loopback and not mounted, then you can dynamically resize it via:

sudo gparted /dev/loop0

Now if you needed a larger partition, you could change partition size (I won’t guarantee data isn’t lost, but most of the time this is ok). Assuming the file is not covered by loopback and not mounted, and that we are going from 4GiB to 8GiB (originally “bs=512 count=8388608”, so we double count and get "512*83886082 == 8589934592"…this is bytes not count…it is “dd” which uses countbs):

truncate /some/where/empty.dat --size=8589934592
sudo losetup --find --show /some/where/empty.dat
sudo gpart /dev/loop0
# ...now just do as normal with gparted telling it to extend the file system...
# ...then use the file for loopback mount as you would normally...

Experiment with it on a test file before doing this on something you value.

NOTE: I know nothing about the virtual machine, but this file would have to be accessible by any VM as a regular file, and the VM kernel would have to support loopback. The loop device is what the VM works with, but the loop device can’t cover a file it can’t see. A Jetson does not normally run a VM, so I guess you are doing something custom.

I do as following(all in root):
1.

sh the configfs_msc_l4t.sh
mkfs.ext4 /dev/loop0

,the result as the attachment
3.

losetup /dev/loop0 msc.ext4.img
mount /dev/loop0 /mnt

5.I connect TX2 with my VM ,the result as the attachment,I can not new a file or copt file in it.I create a file in TX2 /mnt but it can not be seen in VM.


Can you explain the meaning of:

sh the configfs_msc_l4t.sh

…does this mean you ran the script without modification?

First, if you are manually doing loop setup and formatting of the loop device, then you need to be sure the device and file are not already in use…if you ran that script, unmodified, and then tried to manipulate that file with mkfs.ext4, then this would have either failed or behaved in unexpected ways.

Also note that a more general way of saying this is that the file cannot be in use by anything else during any kind of losetup or format operation. The “nv-l4t-usb-device-mode.sh” script does this in ways other than “mount”, but this still places the file and the loop device in use.

How do you want the device to behave? What size do you want the device to be? Is the computer which will use this always going to be Linux (because Windows won’t understand ext4)?

Hi,
I mean I directly run the script by the command:

sh configfs_msc_l4t.sh

I want my device behave like this:
I save videos and pictures in TX2,then I want to connect Tx2 by otg with my Linux computer so that I can directly copy all the files to my computer.The size I need is at least 8G and the more the better.

That script is old, from approximately a year and half back. Unless you are using L4T from that date I’d suggest using the additions made since then which have new scripts. If you are using that older release, then I’d suggest upgrading before you continue.

Which release are you using? See “head -n 1 /etc/nv_tegra_release”.

Do beware that if you run out of disk space on the main root partition you will have trouble logging in. When you create a file for use as a file system (a file pretending to be a partition via loopback), then you can fill up that file without risk so long as the file itself does not fill up the system. Before you start, check this:

df -H /

…note what is available.

Do you have directory “/opt/nvidia/l4t-usb-device-mode/”? If you have a more recent release, then this should exist. In that case see the content of this file instead of the older script:

/opt/nvidia/l4t-usb-device-mode/nv-l4t-usb-device-mode.sh

Within that file there are a couple of different OTG port additions, one being an example ethernet device…you probably don’t want or need that and you could comment out anything ethernet (though you might want it…basically a USB port can become multiple devices on a single wire…ethernet is just one device). A simple way to disable some service would be to set one of these lines (depending on the service) to “=0” instead of “=1”:

enable_rndis=1
enable_acm=1
enable_ecm=1
enable_ums=1

This is for bulk storage, and you would keep this running, but I recommend setting all of the others to “0” unless you know you are using them:

enable_rndis=0
enable_acm=0
enable_ecm=0
# This is bulk storage:
enable_ums=<b>1</b>

If you look at the block of code under this you will see everything done for the OTG port fake disk drive:

if [ ${enable_ums} -eq 1 ]; then

In particular, if you start or stop this emulation of a hard drive via this script, and if you comment out this line, then it will become read-write:

...
    # Prevent users from corrupting the disk image; make it read-only
<b>#</b>    echo 1 > "${func}/lun.0/ro"

The final line of that block of code names the file used to back the fake hard drive:

/opt/nvidia/l4t-usb-device-mode/filesystem.img

This is a raw size, so actual content after formatting will be less, but you can see the size the sample uses:

ls -l /opt/nvidia/l4t-usb-device-mode/filesystem.img

As an example, if the size is “16777216”, then it will be evenly divisible by the block size of 512 a certain number of times. If you put this in terms of KiB (16384KiB), instead divide once by 1024…or MiB (16MiB), divide twice by 1024. It’s convenient that 1024 (or any multiple of 1024) is just two 512 byte blocks. Device space is divided into block sizes.

This file is the one you should adjust after commenting out the read-only line mentioned above:

/opt/nvidia/l4t-usb-device-mode/filesystem.img

…just follow comment #40 and enlarge the file to the size you desire after stopping the service and covering that file with loopback (and be careful to not fill your root partition).

A good way to manually stop or start this service:

# stop:
sudo /opt/nvidia/l4t-usb-device-mode/nv-l4t-usb-device-mode-<b>stop</b>.sh
# start:
sudo /opt/nvidia/l4t-usb-device-mode/nv-l4t-usb-device-mode.sh

When set up as a service the standard “systemctl” stop/start works. This is why the file “nv-l4t-usb-device-mode.service” is there.

Hi linuxdev,
My release is R28.1(Jul 20 UTC 2017).
I have done some change about uart、spi、iic on this version.I do not know if I upgrade Jetpack to higher version will these changes become invalid.So,I still want to use R28.1,is there any way can satisfy my need?
Allocate about 8-12G size disk which can be recognised by VM.

Looks like the sample OTG code in “/opt” didn’t exist in R28.1. I have not tried what follows, so it might not work, and you are always advised to have a backup (usually a clone) of your rootfs, but what follows is fairly low risk…basically grafting the “/opt” of R28.2 (or R28.2.1) onto your R28.1 rootfs should work. The following applies equally for both a TX1 and a TX2 (these use the same rootfs, but I’ve never actually tested grafting R28.2 OTG code for “/opt” into R28.1).

If you get the R28.2 L4T “sample rootfs” and “driver package” (the rootfs is the same for both TX1 and TX2…the driver package itself might differ in some ways, but not in how rootfs is constructed), then the following steps would produce the “/opt” directory you could recursively copy into your TX1.

Downloads for R28.2 TX1/TX2 are here:
https://developer.nvidia.com/embedded/linux-tegra-r282

You will want sample root filesystem and driver packages. Then you will do part of what would be done for flashing, but you’ll not actually connect the Jetson, nor will you flash.

Unpack the driver package somewhere, which will produce the “Linux_for_Tegra/” and “Linux_for_Tegra/rootfs/” directories. Go to the “rootfs/” subdirectory. From there use sudo to unpack the sample rootfs (do not use sudo for unpacking the driver package), e.g.:

cd /where/ever/Linux_for_Tegra/rootfs
sudo tar xvfj /where/ever/it/is/Tegra210_Linux_R28.2.0_aarch64.tbz2
cd ..
sudo ./apply_binaries.sh

Now the content of “Linux_for_Tegra/rootfs/opt/” can be copied to the running TX1/TX2 in R28.1 while leaving the rest alone…once that is in place you can use the information I gave above. The service would not yet be set to automatically start, but you can use the script in the folder to stop and start…and when that works it can be added as a service for automatic start.

The “/opt” directory will already be there on the TX1/TX2, but it will be empty. Any of a number of methods would work to copy the “Linux_for_Tegra/opt/*” into the R28.1 TX1/TX2’s “/opt”. I absolutely prefer ssh key authentication (which works even with root account), but that’s a much longer explanation. Instead I’m going to suggest making a tar file of the PC’s “rootfs/opt/” content, copy that over (e.g., SD card or scp), and then unpack it in “/opt” of the TX1/TX2. Example:

<b>sudo -s</b>
cd /where/ever/it/is/Linux_for_Tegra/rootfs/opt
tar -p -cf opt_nvidia.tar nvidia
# Verify file "opt_nvidia.tar" is the content of the "nvidia/l4t-usb-device-mode/*" content:
cat opt_nvidia.tar | tar --list
# scp example to copy to TX1/TX2...assuming IP address 1.2.3.4 as an example:
scp opt_nvidia.tar nvidia@1.2.3.4
exit

Now log in to the nvidia account of the Jetson…any of ssh, GUI, or serial console will work equally well:

sudo mv opt_nvidia.tar /opt
cd /opt
<b>sudo -s</b>
tar xvf opt_nvidia.tar
# Verify it is there:
cd nvida/l4t-usb-device-mode
ls
# Edit nv-l4t-usb-device-mode.sh as desired. You might want to monitor "dmesg --follow" while testing.
./nv-l4t-usb-device-mode.sh
# Expriment.
./nv-l4t-usb-device-mode-stop.sh
exit

Note that “nv-l4t-usb-device-mode.sh” starts the OTG port based on the content of that file, and “nv-l4t-usb-device-mode-stop.sh” stops the service. It is “nv-l4t-usb-device-mode.sh” my previous post describes editing. File “filesystem.img” is the loopback file which I’ve described increasing the size on using losetup…just be sure the OTG system isn’t running when you do that.

As for a VM…I assume you mean a VM on some other computer. This will be a bulk storage device and it won’t care if a VM is looking at it or a real computer. VMs though can be a pain to work with because you need to make sure the host passes it through to the VM…and if the connection drops and comes back, then you need to make sure it automatically reconnects. The Jetson in OTG device mode will have no control over anything the VM does.

There is a good chance you are going to run out of disk space. Don’t forget “df -H /” prior to changing that backing file’s size…if you run out you’re in for some work to fix it. You could put that file on an SD card though, or a USB disk drive…just edit that script to point at the other location.

hi,linuxdev
Happy new year!
I update my system with Jetpack3.3/R28.2.1 and I can find it in my Win10 computer the size of it is about 16Mbits.
I want enlarge the size so I do as you have said:

truncate /some/where/empty.dat --size=8589934592
sudo losetup --find --show /opt/nvidia/l4t-usb-device-mode/filesystem.img
sudo gparted /dev/loop0

However,I met some problem which was showed as attachment.
After checking “gparted_detais.htm” I found that it comment that “GNU Parted cannot resize this partition to this size.We’re working on ut”! Is there any other way? Something like directly creat a large enough fat16 file and replace filesystem.img?

I using “gparted” because I did not find “gpart” and dit not know how to install it.
apt-get install gparted can not finsh it.

Yes, package is “gparted”, I missed the “ed”…corrected now.

Looks like that loopback file is formatted for VFAT (a.k.a., “fat32”), and my instructions were for ext4. I think in theory if the right tools are installed, then gparted could work with VFAT, but a Jetson won’t have that by default (and several distributions won’t have that by default). The package which should provide that is “dosfstools” (related package “mtools”). To see if you have this:

dpkg -l | egrep -i '(dosfstools|mtools)'

If you don’t have this, then add via:

sudo apt-get install dosfstools
sudo apt-get install mtools

However, it looks like gparted only allows size reduction for VFAT/fat32. So instead I had to destroy the existing file system…meaning you could just as easily have started with a zero size file (e.g., from ‘touch newname.img’), and then done the truncate operation…truncate won’t care if the existing file starts at any particular size.

My testing is on “/opt/nvidia/l4t-usb-device-mode/filesystem.img” while the device is not used (meaning the script for making this available on the OTG port is off, and “losetup” has not bound any loop device to it). I’m testing with VFAT/fat32 with a size of 512MiB (51210241024…which happens to be divisible by 512, the block size):

<i><b>sudo -s</b></i>
cd /opt/nvidia/l4t-usb-device-mode
./nv-l4t-usb-device-mode-stop.sh
losetup -D
truncate ./filesystem.img --size=536870912
losetup --show --find ./filesystem.img 
# Indicates /dev/loop0 for my case...YMMV.
gdisk /dev/loop0
# "p" should show no existing partition.
n
<enter key three times to accept defaults to use full loopback file>
# You can see various types with "L", but for VFAT it'll be "Microsoft basic data", or "0700":
0700
w
y
# gdisk will exit now.
mkfs.vfat /dev/loop0
# It'll complain it isn't the size of a floppy, ignore the warning. Now we test:
mount /dev/loop0 /mnt
df -H -T /mnt
# result using the 512MiB...note that the following is MB, multiples of 1000, not 1024, and so it looks larger than it really is...some space is lost in formatting inefficiencies:
    Filesystem     Type  Size  Used Avail Use% Mounted on
    /dev/loop0     vfat  537M     0  537M   0% /mnt
# Now umount and remove loop device from test location:
umount /dev/loop0
losetup -D
# Now start the script to see if it works for you:
./nv-l4t-usb-device-mode.sh
exit

Does this work for you?

So apparently gparted can only enlarge and preserve a file system of certain types, and VFAT/fat32 is not one of those (ext4 can be extended and preserved).

hi,linuxdev
That’s great! I hane solved all my problem.The method is just satisfied all my need.
Thank you!

when I run nv-l4t-usb-device-mode.sh it always come up with the following errors:

device l4tbr0 already existx ; can't create bridge with the same name

what should I do ?

besides when I execute

gdisk /dev/loop0

it will auto mount to a defaulat path with a straange path name.

Unless you disabled creating the bridge during boot based on the example in “/opt” you will already have that bridge…you can’t create it twice. You have to first stop the original version. Check “ifconfig” prior to running the script to see what is there, and perhaps run the stop script prior to running the start script.

The “/dev/loop0” is not a mount so much as it is a fake disk. Mounting can occur if that disk device is the result of overlay of loopback onto an ext4 formatted file. It is quite possible you are getting some sort of automount, and that the mount is being chosen via a UUID. When loop0 is covering your block device what do you see with the result of:

# Run these as a regular user, not sudo.
df -H -T
lsblk -f
ls /dev/loop*
losetup --find

Automount defaults can be altered, but first it would be better to investigate why it is automounting.