Saturday, April 13, 2019

nVidia Jetson Nano: Desktop Use, Kernel Builds, and Deeper Analysis

Last week, I unboxed the Jetson Nano, set it up, and did some basic benchmarking on it.  This week continues the Jetson Nano analysis.  I'm making it into a desktop, I'm measuring power use, and I'm poking at various other places I find interesting or useful.

The result?  After some tweaking and playing around (and the normal-for-me kernel build), it's a very solid little desktop that can handle an awful lot!

What we've got here: A Jetson Nano, running a 4k display at 60Hz, running an Ubuntu Server virtual machine (somewhat slowly - still working on virtualization), Netbeans running, Chrome Chroming with a few fairly heavy tabs open, IRC connected, and Plex Media Server running a video.  Plus the usual terminals.  It's responsive enough that I'm happily typing this post on it.  Does this count as desktop use?  Up to you, but I sure consider it impressive for a little $100 board!

If you haven't read last week's post, go do so.  I'm building on it this week.

ARM Desktops Galore!

I've spent quite a bit of time over the past year or two working on turning little ARM based boxes into desktops - and there's a reason.  I don't like computing monocultures one bit, and in 2019, we find ourselves in one for desktop/laptop use.  There are a few ARM desktops out there (few, far between, and often somewhat expensive), and then there's x86 - and, mostly, Intel-produced x86 chips.  AMD's making a good run, but a desktop class system is still somewhat expensive.

Repurposing ARM architecture hobby boards for a desktop is a bit of a weird rabbit hole to go down, but the thing is, I'm getting pretty good at it - and they're surprisingly capable.

The difference between a "chokes after a few tabs" Raspberry Pi 3 and a "usable with a dozen tabs open, quite a few terminal windows, IRC connections to the world, Hangouts up, and a few other things running" is a proper heatsink, the addition of a USB SSD, and rebuilding the kernel to enable compressed swap.  It makes the machine massively better, and I've been using my hacked up 3B+ since they came out for desktop use without any issues.

nVidia's new little board seems like it should be a whole lot better, so I've been trying to figure out how to tweak it so it's the best little desktop I can make it.

Before diving into the desktop steps, there are still a few points I want to cover that I didn't get to last week.  So, another couple review items, then diving into... well, really, it's all in the kernel build.

Network: Yes, it's True Gigabit

Last week, I didn't cover the network interface because I ran out of time.  The Nano has a gigabit interface - but so is the Raspberry Pi 3B+.  The 3B+ can't push more than about 280Mbit over the link, because it's hung off the USB2 interface.

This one?  No such problem.  I set up an iPerf3 server on my office iMac and saw nearly 940Mbit (TCP) between the two systems.  I'll call that proper gigabit!  I'm sure I could do better if I tweaked things (or had something other than a dirt cheap switch out there), but the interface isn't limited like on the Pi.

If you're curious, the NIC is on the PCI Express bus (not USB - so it's not sharing USB bandwidth), and reports out (lspci) as a Realtek RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 15).  The kernel driver in use is the r8168 driver.

GPIO Layout: Raspberry Pi Compatible

I said last week that the pinout was quite similar to the Raspberry Pi.  On further investigation, it's pretty much identical.  If you find differences, please, comment and let me know.

This is the Nano's pin layout (looking down from the top).

From the Raspberry Pi site, this is the Pi's 40 pin layout.  The voltage and ground pins are all identical, and while the numbers are different, nVidia is labeling the pin ID, and the Raspberry Pi's chart is labeled with the actual chip GPIO number at each point.  It's easy to translate between them.

What about the special purpose pins?  Some of the pins have multiple uses - hardware serial pins, I2C communication, talking to an EEPROM on the board...

The back of the Nano has the pinout with more detail, and everything still matches. has the Pi pinout in great detail, and it all lines up (from what's labeled).  Unless you're doing something truly weird, any Raspberry Pi accessory should work just fine (once you port the software and drivers, of course - though they both run Linux, and are both ARM devices, so it shouldn't be hard).  I'm sure you could find something that wasn't happy, but you'd be off in some weeds.

Raspberry Pi Compatible POE Pins!

If you look right in the corner of the board, there are some POE pins - Power Over Ethernet.  With the right adapter, you should be able to power this directly from the network port!

And if I'm not mistaken, the goofy position of the POE pins in the corner is because the arrangement is exactly the same as on the 3B+.  I don't have a POE hat for my Raspberry Pi, but as near as I can tell, if you were to try the Raspberry Pi POE Hat on the Nano, it would work just fine!

The Raspberry Pi hats will hang out over the side of the Jetson Nano dev board, but that's fine - it's the right orientation so they don't interfere with the rest of the board.

If you happen to have a Nano and a Pi POE hat, could you test this out and let me know in the comments?

But, seriously.  The thing is clearly designed to be entirely compatible with the Raspberry Pi board ecosystem, which is totally awesome!  It probably means it'll be cancelled soon as well, just because I really like it.

Serial Port

If you're debugging the device at all, or (say) screwing around with kernels, a serial interface is most useful.  The dev board breaks out the serial port for you.  It's regular TTL serial, and while I'm not sure what voltage it runs at, I'd run the adapter 3.3V to be safe.  This isn't a 5V board.  If all you're doing is watching the output, of course, it doesn't matter.

You'll hook up your handy dandy TTL serial adapter (say, some FTDI232 boards I reworked a while back) properly, configure it to 115200 8N1, and be on your way!  The pinout is clearly labeled on the board, so it's not hard to get it connected.

I could use the terminal to collect the logs... or I could just use the Arduino serial monitor.  The Arduino serial monitor is perfect for this sort of thing.

If you want the full serial messages on boot (up to when the Linux kernel kicks in), I've got a copy over on my GitHub page for the intensely curious.

Displays: 4k/60Hz, HDMI to DVI-D Adapters Work

nVidia claims that the Nano doesn't work with HDMI to DVI adapters for some reason.  I claim it does.

My guess is that there are two issues here.  The Nano appears to support HDCP in some modes, which means that certain content won't play properly unless the computer thinks that it's talking to a "secure" display.  HDCP is totally broken (cryptographically as well as the master key floating around the internet), and is more of a nuisance than an actual protection at this point, but it could still pose an issue.

The other issue is that DVI supports carrying an analog signal.  I don't believe the Nano can emit an analog signal at all, so a DVI adapter to an older display that required an analog signal wouldn't work.

However, if you have DVI-D compatible displays, an HDMI to DVI cable or adapter seems to work just fine.

I was able to run 4k/30Hz over HDMI to a monitor.  I'm not sure if the limit there was the monitor or my cable, but 30Hz is painful.

However, using the DisplayPort on both, I got a comfortable 4k/60Hz, which is just sweet.  If you're looking for a powerhouse media box that uses nearly no power, take a good look at the Nano.

Power Use Numbers

I did some analysis of the Nano power use with my MingHe DPS6015A.  With the USB3 SSD attached (worth about 0.5W), I found that the 10W mode obeyed the limit fairly well (the max I saw was 10.5W, and if you subtract the SSD, it's right at 10W), but the 5W mode definitely exceeded 5W by a good bit every now and then.  I'd guess the 5W limit is for the card only, and the board explains the extra power draw, but if you really need to cap it to 5W, be careful.

These numbers are at 5.25V at the head end of the USB cable.  I was getting brownouts with 5V, and didn't feel like building a barrel adapter.  But, seriously, if you've got anything significant hanging off the USB ports, use the barrel plug.

Interestingly, for the massive hit in CPU performance, the 5W mode really doesn't save much power when running benchmarks.  Idle draw is 3.5W or so (so 3W without my SSD).  I ran cpuburn-a53 for the CPU power numbers (I couldn't find an a57 specific version, so the CPU might draw a bit more in the worst case), a CUDA reduction sample for the GPU power use, and then for an attempt at maximum power, ran both together.  I saw 10.5W in the 10W mode, and about 7.5W in the 5W mode.

Even if you pull the SSD power use out, the 5W mode is of questionable value on this board.  It slaughters performance for remarkably little power savings.  It's a neat trick, but it just doesn't seem to be worth it.

Desktoping the Nano

My Raspberry Pi desktop builds should give you an idea of what's coming.

You need a SSD in a USB3 to SSD adapter to improve IO, and then you'll have to rebuild the kernel if you want to put your root filesystem on the SSD.  For the Raspberry Pi, the kernel build is optional.  For the Nano, it's not - and I'll explain why.

The other thing that isn't included in the stock kernel is zswap.  This is an amazing bit of code that does compressed swap "properly" - it compresses swapped out pages in RAM, but unlike the zram feature, it will evict old pages out to disk, it will reject pages that compress poorly (so they head straight to disk), and if you have a new enough kernel, it will compress "same filled pages" down to zero storage beyond a basic "Hey, it's filled with this value..." note.  It's common to have pages that are entirely zeros swapped out, so this saves space and time compared to compressing them.  I really, really like zswap, and it's a critical part of making a Raspberry Pi work as a desktop.  It helps out a ton here too.

After some (light) stress testing, here's what my zswap stats looked like.  I had 550MB of data swapped out.  It fit in 256MB of RAM (so better than 2x compression), with nearly 70MB of zero filled pages (or any repeating value, really).  Despite all this, not even 3MB of swap file on the disk was in use.  This does a great job of keeping swap traffic away from the disk, while still allowing massive memory savings.  It's genuinely good, and it's worth the hassle of a kernel build.

So, go over to eBay and pick up a mSATA SSD, and a USB3 mSATA adapter that supports UASP.  Plus, if you don't have one, a Jetson Nano.

Let's get started!

Initial Setup: Flash the SD Card

nVidia's initial setup steps are really well written.  Follow them.  You'll go through the normal Ubuntu setup process.  The initial boot takes quite a while, so if your screen is flickering on and off, just let it run.  This process is a multiple cup of coffee sort of thing.

Follow the system configuration wizard for a while - it's pretty standard for Ubuntu.

When the system finishes booting and is at the desktop, go ahead and update things (on the SD card).  It'll take a bit to run some high priority updates, then you can update it the rest of the way yourself.  Open up a terminal window, then:

sudo apt-get update
sudo apt-get dist-upgrade -y

You should find yourself back at the desktop after you log in.

If you've set the system to require a password to log in, you can select between the two stock window managers if you click the little gear icon at the login screen.  There's Unity, and Ubuntu.  The Nano will run either one, but I prefer the old Gnome based one - Ubuntu.  If you really want the speed, set up LXDE and the desktop will fly!

Building the Kernel for Fun and Profit

I promised last week some fun with the kernel - and this week, we're going to have it!

The kernel build here isn't optional if you want to use the USB SSD as your root filesystem.  The stock kernel simply won't do it, so we have to tweak things.  That means a kernel build (and maybe some tweaking of the code, if you're up for it).  It's not that intimidating, I promise!

Why can't we just toss the root filesystem on the USB device and go?  USB firmware.

The USB3 hardware requires the kernel to load a bit of firmware into it on boot before it will work.  This is standard enough on embedded devices, but it means that the USB devices don't work until this firmware is loaded.

Where is the firmware normally stored?  On the root filesystem.  Which... we want to mount via USB.

Fortunately, the Linux kernel doesn't leave you hanging in this situation - it supports embedding the firmware in the kernel image so that you can load the firmware before trying to mount the USB device!  The stock kernel doesn't do this (annoyingly), but it's a pretty simple set of steps to add it.

While we're in there, we'll add zswap support.  Because the 4.9 kernel doesn't include same filled page merging, this requires a bit of patching and then modifying a line or so of code so it builds against the kernel sources.  It's not that hard, I promise!

All of this means that booting straight from USB3 fails spectacularly, if you're curious.  You need the SD card.

What's the difference between a microcontroller and a computer?  The computer can build a kernel and then boot from it.  Cross compiling is great for new platform development, but the Nano is a computer - so we'll be doing this all on the Nano.

So, assuming you have an updated Jetson Nano booted and at the desktop, let's get kernel building!

Downloading the Kernel Sources

Unfortunately, the Nano doesn't run the stock Linux kernel.  It runs a modified variant of it.  We need those sources, and nVidia provides them.

Head over to the L4T download page and pull down the "BSP Sources" link on the Jetson Nano side.  You should end up with a file called "Jetson-Nano-public_sources.tbz2" in your Downloads directory.

Pull up a terminal, and we'll extract the kernel sources.  They're compressed inside the public_sources folder, and we'll extract the kernel sources to the home directory.

cd Downloads
tar -xf Jetson-Nano-public_sources.tbz2
cd ~
tar -xf ~/Downloads/public_sources/kernel_src.tbz2
cd ~/kernel/kernel-4.9

You're now in the kernel directory!

We'll start out with the current kernel configuration.  Normally you can find this in /boot, but it's not here on the Nano install, so we'll just ask the kernel what the configuration is and extract it (this feature is optional, but present).

zcat /proc/config.gz > .config

Changing the Kernel Configs

Next, we need to copy the firmware file from the root filesystem into the kernel directory so it can get built into the kernel.

cp /lib/firmware/tegra21x_xusb_firmware ./firmware/

There are a few ways to change the kernel configs, but menuconfig is the most fun if you have a desktop environment - which we do.  It needs a few extra libraries.

sudo apt-get install libncurses5-dev
make menuconfig

Explore around in here to your heart's content (it's a fascinating place), but we need to make some changes.  Press space to select the various features.  You want a "*" - not a "M".  This means it's built in, not a module.

in Kernel Features:
Select: Enable frontswap to cache swap pages if tmem is present
Select: Compressed cache for swap pages (EXPERIMENTAL) (NEW)
Select: Low (Up to 2x) density storage for compressed pages

The 3x allocator (z3fold) isn't reliable before mid-4.20 kernel versions, and in practice, with same filled page merging, the results are about the same as the zbud 2x allocator.

Exit out, and go to Device Drivers -> Generic Driver Options

Tap down to "External firmware blobs to build into the kernel binary," hit enter, and enter "tegra21x_xusb_firmware" in the field.

Exit out, and save the new config.

Before we build the new kernel, we'll update the zswap source.

Updating ZSwap: Patch the Kernel

I talked earlier about same filled page compression.  The 4.9 kernel doesn't have it yet.

But we can backport it from a newer kernel without too much trouble.

Linus keeps a copy of the kernel on Github, which is pretty easy to explore.  Navigate to mm/zswap.c, then click the "History" button to see the commits.  

"zswap: same-filled pages handling" is a good commit to patch in.  Click that, and you'll see the changes - but they're not useful if we want to apply them to the file.

However, a hidden feature on GitHub is that if you append ".patch" to the URL (before the # target indicator), you can download the patch file for that commit.

Do that, and you'll find the following patch file: a85f878b443f8d2b91ba76f09da21ac0af22e07f.patch

Right click the background, save-as, and put it in your downloads directory.

Now, back in the terminal, we'll apply the patch.

cd ~/kernel/kernel-4.9
patch -p1 < ~/Downloads/a85f878b443f8d2b91ba76f09da21ac0af22e07f.patch

You'll see where the hunks succeeded, and that things are slightly offset.  That's fine.  We could apply the intermediate patches, but it's not critical in this case.  Congratulations, you've patched your first kernel file (if you've never done this before).

But we're not done.  There's a call in there that relies on a kernel feature that doesn't yet exist in 4.9.  A memset_l call, which is an optimized memset.  No problem - we can replace it with the regular memset.  You can make the edit in vim, or use the handy one-liner here to swap it for a functionally identical memset.

You're replacing this:
memset_l(page, value, PAGE_SIZE / sizeof(unsigned long));

With this:
memset(page, value, PAGE_SIZE);

And this command will do it:
sed -i 's/memset_l(page, value, PAGE_SIZE \/ sizeof(unsigned long));/memset(page, value, PAGE_SIZE);/g' mm/zswap.c

Build and Install

Now, time to build the kernel with these changes.  After it's built (assuming no errors), we'll install the modules, and put the kernel image in place in /boot after backing up the original kernel.

The -j parameter tells make to use multiple build threads.  The Nano has 4 cores, so we build with 5 threads (this means the CPU remains busy when the thread is reading from the disk or similar).

Kernel builds take a while.  Kernel builds on little ARM boxes take a long time.  Go get coffee.

cd ~/kernel/kernel-4.9
make -j5
sudo make modules_install
sudo cp /boot/Image /boot/Image.dist
sudo cp arch/arm64/boot/Image /boot

Now... do you feel bold?  Reboot!

If everything comes up again, congratulations!  You're running your new kernel!

If you run 'uname -r', you should see '4.9.140'.  The stock kernel is '4.9.140-tegra' - so the new version string means it's your freshly built kernel!

Pivoting Root to USB

Now, plug your USB SSD in.  We're going to create a filesystem on it, copy the whole root filesystem over, do a bit of fixup, and try to boot from it!

It's almost certainly going to be /dev/sda - there are no other USB volumes attached, and the SD card is /dev/mmcblk0.

So, we'll wipe the partition table (just in case), create some partitions, format them, and get ready to copy things!

sudo dd if=/dev/zero of=/dev/sda bs=1M count=1
sudo cfdisk /dev/sda

Create a GPT partition table, then create a new volume.  Size it a few gigabytes less than your volume, because we're leaving space for a swap partition.  You could use a swapfile instead, if you wanted, but I prefer a dedicated partition.  Since I've got a 32GB SSD (28.9GB by powers of 2), I'm creating a 25GB root partition, and using 3.9GB for swap.  You'll never use that much disk with zswap enabled, but it won't ever swap out more than the swap partition will hold.  Having 4GB of swap for 4GB of RAM is reasonable, though if you had a really large SSD, bigger would be fine.

After you've made the first partition, use the arrow keys to make another one in the free space.  Then, arrow over to "Type" and select "Linux swap" for that second partition.

Go over to "Write," type "yes" when prompted, then quit.

Now, make an ext4 volume and a swap partition, mount it, and copy the root filesystem over!

sudo mkfs.ext4 /dev/sda1
sudo mkswap /dev/sda2
sudo mkdir /mnt/root
sudo mount /dev/sda1 /mnt/root
sudo mkdir /mnt/root/proc
sudo apt -y install rsync
sudo rsync -axHAWX --numeric-ids --info=progress2 --exclude=/proc / /mnt/root

Go get coffee again.  This takes a while.

Finally, edit /boot/extlinux/extlinux.conf to point the kernel at /dev/sda1 instead of /dev/mmcblk0p1 and enable zswap.  The defaults are fine, and fstab uses /dev/root, which will find the proper root filesystem on boot.

sudo sed -i 's/mmcblk0p1/sda1/' /boot/extlinux/extlinux.conf
sudo sed -i 's/rootwait/rootwait zswap.enabled=1/' /boot/extlinux/extlinux.conf

Reboot again, and if all has gone well, you'll be running from the USB SSD!

Tweaking Swap

Just a few things left to do - enable swap, and pull down a zswap reporting script.

echo "/dev/sda2            none                  swap           \
defaults                                     0 1" | sudo tee -a /etc/fstab

cd ~

Reboot, and you should have everything working!

Remember, your "real" /boot is on the SD card.  So if you change things in the kernel, and nothing works, make sure you've put it there.  You should find it in the /media subdirectory, or you can mount it somewhere reasonable.

Using the Nano as a Desktop

So, with all that done: How is it?  Is it better than a Raspberry Pi?  Can you throw out your big heavy Intel desktop?

It's pretty darn good.  I've been beating on it for a week, and while it's clearly not a modern x86 desktop, it handles quite a lot, including chewing through some websites that just strangle the Pi I have.

You can attach a 4k display with no trouble, and it handles it perfectly.  With zswap and the SSD, I can throw an absolutely ton of tasks at it without it choking.  The extra 3GB of RAM over the Pi make a huge, huge difference.

Will it replace an Intel desktop?  That depends on what you do with your desktop.  If it's a light to moderate use system, and you don't do much in the way of gaming - yeah, it probably can.  It won't be quite as fast, but it's far, far more capable than a Pi.  I wouldn't mind using one as a daily driver desktop, even for light development.  If there were remote servers for testing, and/or the project was fairly light?  Yeah, you could use it.

Should you?  Up to you.  I think they're interesting, and this is going to replace my Pi 3B+ for my always-on desktop in my office, with the 3B+ rotating out to a different utility system that's currently a Pi 3.  The Nano is roughly twice the cost (you don't need a case to keep it from throttling), roughly twice the performance, 4x the RAM, and uses the same power as a Pi 3B+.  That's a win, in my book!

Final Thoughts

Sorry about the late post tonight.  I spent the evening building a D2-5 line tracking car with my daughter.  It's a fun little electronics kit that results in a car that chases a black line.  Lots of fun to play with, and lots of fun to put together.  A 4 year old isn't going to be doing the soldering, but she can certainly put the parts through the board and trim the wires off after I've soldered them!  We had a bit of a problem with one of the output transistors, but I had a compatible one laying around in my office.

I'm really, really impressed with the Jetson Nano.  Yeah, you can use it for machine learning - but you can also build a properly good desktop-class machine out of it.  For those on a tight power budget, this thing is awesome.  For those who want something that isn't x86 - give this a shot.  And, if you like the Raspberry Pi but just need more performance?  The dev kit is your ticket to twice the performance and an awful lot more memory!

If you've found this post useful, the donate button is over on the right side.  I use blog income to buy gizmos for the blog.  Or, just use one of my eBay links if you're buying something.  eBay will toss a few coins my way, and not charge you any more money in the process.  Either they pay out affiliate links, or they keep the money.

In two weeks, I'll be making my 200th post on this blog - which surprise me easily as much as it might surprise you.  It's been 4 years, and over half a million words so far.

But, really.  Buy a Nano.  They really are that good!


  1. DVI uses dual links all the little pins are live, (not including the 4 by the spade off to the side)

    Because DVI is a dead standard they haven't upped the pixel clock, HDMI has been upping the clock and does 4k60 as of 2.0

    DisplayPort is great, use that. I did get a 'plugable' brand active DP to HDMI, because HDTVs are 4k, but usually don't come with DP, only HDMI, and Intel onboard video is usually not up to HDMI 2.0

    I was researching this because I have an old 27" ips QHD (4x 720p), and it only uses DP or dual link dvi to get full 1440p, my B360 motherboard does not even have HDMI out at all, and Dual link DVI isnt a popular option at all.

    I like the Nano, price is sad now due to scalpers. Put it in a real case with an SSD bay (m.2? The adata XPG 8200 is FAST)

    1. I have a mini-displayport to dual link DVI adapter running in my office.

      I considered getting one of the chassis that supports a proper SSD, but I'm not convinced the performance gains would be worth the cost there. The chassis are as much as the board, which defeats the point.

      And, yes, prices are high right now. That's true of any new device, though - you see it with gaming consoles all the time, and things stabilize.

  2. the make menuconfig will fail with a libncurses error unless prior to that you do:
    sudo apt-get install libncurses5-dev libncursesw5-dev

    1. Thanks, I've added that - I know I had it in my notes somewhere, and apparently it never made it to the final version.

  3. is there an inbuilt power measurement tool? how did you do it?

    1. I used a bench power supply (the DPS6015A I commonly use), and measured power into the USB port that way. I'm not aware of an onboard power measurement capability on the boards.

    2. @Russell Graves could you check whether there is an inbuilt power measuring way?

    3. So, it turns out, Guillaume Ausset's suggestion was right. You can't get "whole board" stats, but if you look at the output of tegrastats, the last few entries show power in mW. documents it - the various POM_ fields (POM_5V_IN, POM_5V_GPU, POM_5V_CPU) show the current power (in mW) as the first entry, with the average power (over some period of time - unsure what) as the second entry.

      With the reduction and cpuburn running, I can see nearly 8W showing there. This is lower than I measured externally by about 2-2.5W - which is consistent across the board. Idle, it shows 1.3W, vs my measured ~3.5W - which would include the external power conversion circuitry, my SSD, etc. So the offset should be pretty consistent.

      Take a look at that and you should be able to work out what you need!

    4. thank you Russel ijust wanted to know the power consumed by the board!

  4. Can you post a video with desktop usage so we can see the speed/performance of web pages loading and usability?

    1. I suppose I could try to do that - not a thing I really am familiar with doing, though. Unless the system is under a ton of stress, it scrolls about the same as a desktop.

  5. Have you explored overclocking the CPU or RAM?

    1. I have, and have mostly accomplished a variety of ways to render the system not-exactly-booting in the process.

      If you look at the tegra 210 DVFS files in the kernel, you'll be in the right spot to mess with the frequency/voltage/etc, but I'm simply not that familiar with those bits of the kernel, and didn't want to spend the time to learn them in a week. I expect someone from the Android world, familiar with the Tegra DVFS systems, could manage it. I've just got too much on my plate for that at the moment.

    2. I've looked around on XDA and don't see much developers playing around with Tegra unfortunately. But for Nintendo Switch there has been some people who have overclocked it even overclock the CPU to 1.9Ghz (from 1Ghz on the Switch). I'm not familiar with it myself as well, but hopefully someone can look at the switch.

    3. you can use the jetson_clocks utility (located in /usr/bin) to check and set the clock rates. Don't know if you can overclock it though

  6. Hi,

    Awesome post and blog !

    Can you try running in high power mode through the barrel jack ? Maybe it will draw more. I'm interested in what the maximum powerdraw is so I can decide between the and :) ( or maybe someone familiar with the Pololu D24V50F5 can tell me if it get unreasonably hot / drop voltage at 3a or it's fine for real up to 5a )


    1. Unless you have a ton of peripherals hung off it, you should be fine with the 5A version. It normally pulls around 1A, and you have to really load it up deliberately to get near 2A. Even with the standard Chinese derating applied, the 5A one should be fine.

      I don't think the barrel jack will impact the compute card load - it's mostly useful if you have some hungry USB accessories hanging off the stack. I don't have an adapter built to do that test either, but I can't see why it would have a real impact.

    2. So, I managed to test it :)

      I tried to load the Nano as hard as I could and I can't even reach 11W, with the plug. I could try to find an FP16 test but eh, doubt it will even reach 11-12W.

      Pretty impressed. Guess I have no excuse to buy an overpowered buck converter

    3. Well, I think you got more power out than I did - that's 12-13W on the board. Still properly impressive for as much power as it packs!

    4. Which Pololu board did you use in the end Guillaume? The difference between the differnt pololu dc converters would be mainly in the voltage dropout. If you look into the datasheets of each, you can see that the 9amp has a much lower voltage droupout. Hence, this mean that if you have a lots of headroom on your battery supply, i.e. have high voltage, for example a 2s lipo, you should be safe with the 5amp. assume you pull the maximum 4amps, you will get a 1.1V droupout, hence you voltage at your batteries must be atleast 6.1V. If you use a lipo this is not an issue, but if you plan to run the jetson from example a lifepo4 battery or 5pack nimh your are on the limit. With the 9amp regulator you only get around 0.8 volt droupout. So while it is not much there is some differnce, and I also assume the larger board will do better power dissapation!?

  7. Excellent article! I had a quick question for the experts on here : Will a piplate motorplate be compatible with the Jetson Nano?

  8. Good article for nano new comers! An additional question, is there a way to force nano works under a specific hdmi resolution and timing, despite of any physical monitor connected? Usually we do that through a config.txt file under /boot partition for RPi board. In some case, we can force RPi HDMI port work even without a physical monitor plugin.

  9. Would you have any interest in looking into getting hardware transcoding running when using the Nano as a Plex Media Server?

    So far I haven't been able to find much on it, but I know that the Shield TV (which uses the same chip, just more cores) has it enabled on Android

    1. Not really. It should be possible, but I simply don't know that much about the ARM side of hardware acceleration on video transcoding, and with Plex being mostly closed source, it either works or doesn't - there's not an awful lot I could do from my end to fix things. If you're having to regularly realtime transcode high def content, x86 is likely the right answer. I've got a Plex server, and it's a halfway modern x86 box, but I simply don't find myself transcoding newer content. Direct Play for h.264 works fine, and while some content is transcoded, it's usually ancient stuff at low resolution (old kids TV shows or something that were encoded years before h.264 was a thing) - so even a Core 2 Duo can keep up with that sort of load.

      If the Shield TV can do it, it's likely technically possible, but that may be something the Plex developers have to enable.

      I'd take a stab at it as contract work, but it's just not of any particular interest to me otherwise.

  10. Hello!
    Any Chance you could share your finished, compiled Kernel and scripts? I would love to added them to a clean LXQT Ubuntu installation!
    Thank you,

    1. I could, but the steps provided should be sufficient for you to replicate the build.

      You shouldn't trust random people's binaries...

  11. I already boot from USB SSD (without zswap) and I would like to enable zswap and additional kernel configs.
    After compiling kernel and modules, what do I need to copy back to microSD card?

    1. If you build things the way I do (static vs module support), just copy the kernel image back over to the SD card.

  12. I tried to follow this instructions for a Xavier and was able to complete all steps, but the kernel modules that I activated do not actually remain activated/work.

    Is there anything about this that is known to fail on other Jetson family members?

    1. I don't know anything about the Xavier. You should be able to find kernel build instructions for it and modify them as needed to get the support for zswap, though.

  13. Thanks for your Jetson Nano blog posts, hope you can keep them coming. Tried Jetsonhacks version of booting from a usb drive, but it didn't work for me. Mine is a 120GB SSD SATA III 6GB/s as shown in this raspberry pi posting because the SSD is so close to a zero form factor: I will try your approach. Question afterwards is how do you do update/upgrade, from the microSD or from the USB connected drive? Also, how would you back up the microSD after implementing your configuration? Can't seem to do it with Win32DiskImager. Thanks again.

    1. There's not an awful lot left to say about it I haven't already said (at least for my use cases). I'm not using it for robotics or anything - just as a desktop.

      Anything that needs to be updated on the /boot partition (the kernel image, typically) needs to be on the SD card, because the firmware can't read the USB SSD during boot. Once the kernel is online, it can read the USB SSD, so everything else is fine.

    2. OK, thanks for the reply. Just as an FYI, outdated Octane 2.0 score before ssd and swap 7671, and after 7798. Your approached worked. I set up a 100GB sda1 and 10GB sda2. Three cups of coffee ~smiley~.

  14. is this command: sed -i 's/memset_l(page, value, PAGE_SIZE \/ sizeof(unsigned long));/memset(page, value, PAGE_SIZE);/g' mm/zswap.c
    supposed to be sed -i 's/memset_l(page, value, PAGE_SIZE \ sizeof(unsigned long));/memset(page, value, PAGE_SIZE);/g' mm/zswap.c
    see the difference?

    1. I see you've dropped the forward slash (division) that I escaped with the backslash on purpose, yes...

      Pretty sure my command is correct.

  15. Can you clarify how this works for me? Are bootloader and kernel still on sdcard, bootloader quickly loads kernel in memory at startup, kernel uses usb's filesystem and memory card isn't used after that? What about dynamic kernel modules, are those fetched from sdcard at runtime? Also are the any downsides to this approach?

    1. The bootloader and kernel load from the SD card, and once the kernel is online, all filesystem accesses are to the root filesystem on the SSD - so kernel modules are loaded from the SSD. They're not normally in /boot anyway...

      I'm not aware of any downsides. It's working great so far!

    2. This means that sdcard presents no real slowdown, as it's not used after loading initial bootloader+kernel, which together shouldn't be more than 70MB? This is amazing btw :)

    3. Correct. After the system has booted, the SD card is not a bottleneck at all - it's never used.

      One might consider mounting a scrap volume on it, or (with zswap) putting swap partition on it (as the bulk of swap never actually sees the disk), but all the daily file IO comes off the SSD over USB3.

    4. Would it be also possible to modify or replace default bootloader on sdcard to point at grub2 bootloader, which could figure out to boot kernel from usb device? Or is usb driver bound to kernel and can't be used until kernel is loaded?
      I assume only benefits would be those that using grub2 brings?

    5. I have no idea. You're on your own for stuff like that - the firmware might support USB booting, but it didn't seem to try, so if you want to do firmware dev on that board, have fun.

  16. H Russell, excellent write up as always. I was wondering whether you enabled Ext4 Encryption in the config?

    I enabled Ext4 Encryption in the config using menuconfig, but the particular config is replaced after kernel is built and copied. All other changes as done by you persists.

    When I verify the modified .config before building the kernel, it shows correctly as


    But after building the kernel and replacing the kernel, the running config shows -

    # CONFIG_EXT4_ENCRYPTION is not set
    # CONFIG_FS_ENCRYPTION is not set

    I would appreciate your views on this. Thank you/

    1. I did not - I'm simply not that familiar with it. If I need disk encryption, I'll use the dm-crypt extensions to encrypt the entire block device. No ideas, sorry!

  17. Hello!

    Thanks for your Jetson Nano blog posts, hope you can keep them coming.

    I bought a JN30 backplane for the nano.

    It can be recognized after installing Samsung's nvme. Read and write speeds are above 1Gb/s.

    But I don't know how to boot from nvme, or let the root directory of the system run on the nvme disk.

    I modified extlinux.conf, but it seems that the kernel did not load the nvme driver when the system was started, so it failed.

    Does any friend know how to operate?

    Thanks again.

  18. Thanks for your Jetson Nano blog posts, hope you can keep them coming.

    I bought a JN30 backplane for the nano.

    It can be recognized after installing Samsung's nvme. Read and write speeds are above 1Gb/s.

    But I don't know how to boot from nvme, or let the root directory of the system run on the nvme disk.

    I modified extlinux.conf, but it seems that the kernel did not load the nvme driver when the system was started, so it failed.

    Does any friend know how to operate?

    1. You'd probably need to do the same thing I did with the kernel build and put the proper NVMe driver and firmware in the kernel.

  19. Hello Dear Russell!

    Thank you very much for your guide and brief analysis of the Nano as a desktop. Yours is the only article on the internet currently that discusses this issue in any detail!

    The latest Raspberry Pi 4 has come with an improved processor and 4GB of DDR4 RAM. It's being billed as the Pi that finally can act as a proper simple desktop replacement.

    How do you think our Nano made Desktop would compare to it?

    I am interested in using an ARM based desktop as my daily driver, with some python programming and office based productivity tasks on an ultra wide 21:9 monitor.

    Would you kindly suggest me which would be the better of the two, RPi 4 or Netaon Mano?

    Thank you very much!

    1. I haven't played with the Pi4 enough to be able to make a strong statement one way or another. It's on my list of hardware to obtain and play with. If you applied the same techniques, using an external SSD, it would probably be fine. The real key is not using the SD card for the OS beyond the early boot - this is true on the Pi3s, the Nano, and I would assume the Pi4 as well.

      The Nano certainly has a higher quality GPU - a full on desktop grade Maxwell GPU, which is nice. The Pi4 is likely faster on the CPU side, but how this works in actual use, I simply don't know.

      I expect either one will work fine, though!

  20. Tried following your instructions to build a new kernel. I get the following error when running make:
    OBJCOPY arch/arm64/boot/Image
    GZIP arch/arm64/boot/Image.gz
    cp -u arch/arm64/boot/dts/
    cp: missing destination file operand after 'arch/arm64/boot/dts/'
    Try 'cp --help' for more information.
    arch/arm64/boot/dts/Makefile:136: recipe for target 'dtbs' failed
    make[1]: *** [dtbs] Error 1
    arch/arm64/Makefile:154: recipe for target 'dtbs' failed
    make: *** [dtbs] Error 2

    Any idea to what is causing this problem?


Comments on older posts are moderated due to spam issues. If you don't see your comment immediately, and you weren't just spamming me with some irrelevant comment and a link to whatever site you're trying to SEO, your comment should show up relatively soon. If you're trying to use my blog for your SEO purposes, your comments will never show up, so don't waste your time.