I have a large number of Jetson TX2 developer kits here. We are attempting to connect them to two different USB devices. One is a GSM modem, and the other is a UART.
I plugged in the GSM modem on an Ubuntu 1604 PC and it worked easily. /dev/ttyUSB0 through 3 were created, the NetworkManager detected that there’s mobile broadband, I entered APN settings, and everything works.
On the Jetson TX2, however, it doesn’t create the /dev/ttyUSB… devices. I notice that there’s no usbserial.ko in the modules.
Can anyone suggest what I need to do to get those modules to install?
You will probably need to know which module/driver is used for that particular serial UART. I suspect it isn’t FTDI (the most common USB serial UART out there) since this would be enabled by default. You would probably need that driver plus the basic serial driver. To see what serial drivers there are (it is a long list):
gunzip < /proc/config.gz | egrep 'CONFIG_USB_SERIAL'
If you use the default config under R28.1 you’ll be able to confirm basic serial is enabled via:
The FTDI driver on my system shows:
Unfortunately many desktop distributions don’t bother to enable config.gz, but if you are lucky enough that the desktop which works uses a module format (which is actually likely), then you might page up and down in this list and see if anything might be powering your existing PC’s driver (do this from the PC while the device is connected):
lsmod | less
Once you know the driver you just need to build a module, put the module in place, and run “sudo depmod -a” to register it.
I think you don’t need to install module for usbserial. The driver is built into kernel.
gunzip -c /proc/config.gz | grep USB_SERIAL | head -1
y stands for built into kernel, m for module, n for not supported.
[EDIT: Sorry for the confusing information. This was run on R27.0.1.]
The question is why it doesn’t work on Jetson.
You may run
sudo dmesg --follow
to see kernel messages as they happen, and plug your modem and check the kernel messages to see what is detected or failing.
You may also disable usbcore autosuspend by adding :
to file /boot/extlinux/extlinux.conf and reboot.
One extra thing to think about is power. Jetson may not provide as much power as your PC, and if your modem needs a lot of power, you may use an externally powered hub for hosting the modem.
Doesn’t appear to be.
I did that and I think that’s a basic problem:
# USB port drivers
# CONFIG_USB_SERIAL is not set
I’m sorry for the ignorance. I’m used to running Ubuntu on my desktop where things generally “just work” and I haven’t rebuilt a kernel in a long time. What do I need to do to get usb serial working on this? I assume I need to change the config and rebuild the kernel ?
I’m doing some searches on building kernel for Jetson.
Do post exact information on the model of device you are using. “lsusb” may show some information, the “-d” option of lsusb helps select by ID of the specific device…then you can run a very verbose query on just that device (I’m making up an ID, use what your device shows):
sudo lsusb -d 0955:7721 -vvv
(knowing exact model and lsusb verbose details may help to nail down which chipset is used, and thus which module is needed)
You probably only need a module. Some kernel features must be integrated directly in, but serial drivers can be modules. More than one module may be needed, e.g., one for serial protocol and another for the specific chipset.
To start with it will help to understand that your “/proc/config.gz” is the starting configuration you will be interested in, and the module will be added to this configuration. This will take the place of any default configuration because it is guaranteed to match the existing kernel. Using this means modules will be compatible and no direct compile of a kernel will be needed.
Modules are searched for based on “/lib/modules/$(uname -a)/”. “uname -a” will typically be the kernel version number with “CONFIG_LOCALVERSION” (part of the config) appended to it. “/proc/config.gz” will need CONFIG_LOCALVERSION set to match before compiling the module. As an example, the TX2 kernel under R28.1 is “4.4.38”. The command “uname -r” returns “4.4.38-tegra”. This implies the kernel has CONFIG_LOCALVERSION set to “-tegra”, and that modules are searched for at “/lib/modules/4.4.38-tegra/”. When you install a driver it will be somewhere under “/lib/modules/4.4.38-tegra/kernel/drivers/” (it could be a different subdirectory, but you are building drivers).
You might see documentation suggesting starting with “make tegra18_defconfig”. This is to set up a default configuration. Don’t do this unless you don’t have “/proc/config.gz”. config.gz is a guaranteed match. Either way the “.config” file you read about and look at needs CONFIG_LOCALVERSION edited (either directly by an editor or through a menu program like “make menuconfig” or “make nconfig”). Other than this just read the docs from here, and keep in mind that R28.1 is available for both a TX1 and TX2, so you are interested in anything tegra18 or tegra186 for a TX2 (TX1 is a tegra210 or tegra21). See (look for Documentation, then for kernel customization within this):
Other information you find on the web will apply towards building kernel modules. The main difference is that many documents on the web don’t mention cross-compiles, they assume compiling on the same machine for which the module will be used. Pay attention to any “O=” option in the compile, this names an alternate location.
Hi Linuxdev, thank you for the hints there. I will follow your advice.
Here is the output from lsusb:
Bus 001 Device 007: ID 0f3d:68aa Airprime, Incorporated
bDeviceClass 0 (Defined at Interface level)
idVendor 0x0f3d Airprime, Incorporated
iManufacturer 3 Sierra Wireless, Incorporated
iProduct 2 AirCard 313U
iSerial 4 012615002916683
iConfiguration 1 Sierra Configuration
It goes on and on but I don’t want to overwhelm with output from that.
On my desktop it shows up as /dev/ttyUSB1 through 3 and shows up in the NetworkManager and connects just fine.
I’m looking into how to build just the module without needing to rebuild the entire system. I hope that’s practical to do.
USB serial is, indeed, not enabled by default on Jetpack 27.1. (I have not upgraded to 28.1, so I can’t check there.)
You need to download the NVIDIA kernel sources (“Linux for Tegra”) as well as the sample root file system.
Then you need to configure them and build the kernel.
Then you need to use flash.sh to flash your Jetson (this will re-install the “initial” file system, wiping all files you’ve previously put on the Jetson.)
Note that the first time you build the kernel, you need to do “sudo make O=… ARCH=… tegra18_defconfig” before you build.
You also need to edit the .config file before you actually build, after “make tegra18_defconfig” to enable the drivers you need. For example if it says
# CONFIG_USB_SERIAL is not set
Change it to this:
Here is a script I use to re-build the kernel:
# If this is the first time, first do
# make O=$TEGRA_KERNEL_OUT ARCH=$ARCH tegra18_defconfig
# and then edit the file $TEGRA_BASE/kernel/.config to enable drivers
# you need.
make O=$TEGRA_KERNEL_OUT ARCH=$ARCH modules_prepare
make O=$TEGRA_KERNEL_OUT ARCH=$ARCH zImage
make O=$TEGRA_KERNEL_OUT ARCH=$ARCH dtbs
make O=$TEGRA_KERNEL_OUT ARCH=$ARCH modules
make O=$TEGRA_KERNEL_OUT ARCH=$ARCH modules_install INSTALL_MOD_PATH=$TEGRA_BASE/rootfs
tar cvfj $TEGRA_BASE/kernel/fresh-modules.tbz lib/modules
cp kernel/arch/arm64/boot/dts/*.dtb kernel/dtb/
And heere’s the command to flash the Jetson over USB once you’ve built the kernel, and pressed RECOVERY+RESET on the Jetson:
sudo ./flash.sh -t jetson-tx2 mmcblk0p1
Flashing will take quite a while (10-30 minutes.)
After flashing, you will want to log into the new image and sudo apt-get update, sudo apt-get dist-upgrade to get up to date.
Personally, I’ve created my own rootfs image that has newer versions of things and some settings I want (vimrc and so forth) that I use when flashing. You’ll probably want to do that yourself, too.
FYI, the lsusb in verbose mode may not list everything without “sudo”. Is there more information when you run the lsusb command with sudo? It’s just for finding out more about which drivers may be desired. As mentioned the serial protocol itself can easily be built as just a module, and likely also any other required driver (lsusb might give more information about drivers), especially from a system where the unit works and you can monitor “dmesg” while the unit is inserted. The official “Documentation” download should have additional kernel module build information in the “kernel customization” section. NOTE: No need to flash if it is just a module, you can copy the module to the right directory. The location would mirror the same place it is on your desktop PC under the “/lib/modules/$(uname -r)/” directory.
It’s important to note that this assumes that the kernel/.config file contains the directive:
If you forget to make this part of the .config file before you start building, the modules won’t have the same version string as the kernel, and the kernel will refuse to load the modules.
So do I need to rebuild the entire kernel, or can I build the module file itself and install just that? Obviously I would prefer not to have to fully reflash these things if I can instead just install one module.
Thanks for all the guidance on this.
You typically re-build the entire kernel and all modules. However, if the config is the same for the kernel (including the CONFIG_LOCALVERSION) then the new modules you built will be able to copy to the right lib/modules directory on the Jetson.
The fact that you say you prefer not to re-flash it makes me wonder if you have made changes that are not automated to the module. I highly recommend that you use some kind of automate-able configuration management tool to put all the software you need onto the Jetson. If you develop and compile on the Jetson, use a script that installs all the packages you need, and use good source control to actually store the source you develop. You WILL need to re-flash these units every once in a while, and getting into the habit of making it No Big Deal is going to serve you very well.
Don’t be this guy: https://goo.gl/pBxkJq
Thanks Snarky. I’m working on it. I’m trying to get cross compiling working, because building on my desktop should be much faster.
We don’t really want any customized kernel modules, just to get usbserial working, plus whatever other modules we need to get our GSM WWAN card working. That card works easily and perfectly on ordinary Ubuntu 1604 so it should be just a matter of the right modules. I hope… Thanks again for your help.
Also note: You’ll want CONFIG_USB_SERIAL=m, not =y, if you want to build a module that you can transfer and install. =y will build the driver straight into the kernel and would require a kernel transplant (most easily done by flashing.)
Cool, yup, figured that out. I’m using menuconfig which is curses based. I think my best option is to install this card on my working Linux desktop and figure out exactly which modules it is using, because there are soooo many options on menuconfig, I can’t guess which chips it’s using.
I have my first kernel cross-compile going now.
I will definitely try both flashing, and installing the module by itself.
I plugged the thing in to my Linux desktop and looked at /proc/modules. I could see clearly it’s using the sierra_net module, which depends on usbnet, and the sierra module, which depends on usbserial. So those are the modules I need to build and copy over as my first test.
I have had good success with this whole process, with one major quirk.
When I do my kernel rebuild it rebuilds the DTB files. Following all the instructions here, I copied them over into the new rootfs like this:
cp $TEGRA_KERNEL_OUT/arch/arm64/boot/dts/*.dtb kernel/dtb
cp $TEGRA_KERNEL_OUT/arch/arm64/boot/dts/*.dtb rootfs/boot
The problem is that when I do this, I can’t access any CUDA functions. The new DTB files mess up whatever device driver is needed for CUDA. If I leave the rootfs DTB files alone, everything works.
Any ideas on this? I would like to understand what’s happening. Am I skipping a step in compiling the DTB files, or ?
I’m glad I have a working process but I do want to know why this one step isn’t what I expected.
Just to make sure details don’t get in the way, was this R28.1, or was it something earlier? Current L4T release is R28.1 (see “head -n 1 /etc/nv_tegra_release”). Instructions for working with the dtb changed in R28.1 and the FDT entry of extlinux.conf became invalid (some of the information stayed in extlinux.conf, but most moved to a partition).
My release is :
R28 (release), REVISION: 1.0, GCID: 9379712, BOARD: t186ref, EABI: aarch64, DATE: Thu Jul 20 07:59:31 UTC 2017
Where do I find instructions on DTB for this release?
The “Documentation” download has a section on device tree. Downloads at:
Keep in mind when reading that the TX1 and TX2 now share the R28.1 rootfs, and in some cases instructions differ depending on whether you are looking at TX1 or TX2 (some documentation is shared and differences are pointed out at times).
There are also alternative methods of doing this via dd. See for example: