Expanding the Memory on Jetson Nano

Hi all,

I purchased SanDisk 256GB Extreme (MicroSDXC) and completed the setup following this tutorial https://developer.nvidia.com/embedded/learn/get-started-jetson-nano-devkit.

I started installing some of the dependency packages for the libraries I’ll be using and soon after (to my surprise) I started receiving the Low Disk Space warning.

Upon checking out the Disk Usage Analyzer, I found out that the usable memory is only 13.2 GB.

How can I expand that to the full extend of the stored SD card? (I vaguely remember a similar phenomenon when I was working with RPi back in the day.)

If you created the SDCard using the SDKManager it’s not going to be easy. The SDKManager assumes a 16gb card and places the root filesystem partition where it can’t easily be expanded. Your best bet is to download the pre-build image from https://developer.nvidia.com/jetson-nano-sd-card-image-r3223 then write that to the SDCard. When you boot with that card the first time, the root filesystem partition should automatically be expanded to the full remaining space on the card.

It is easy peasy.

Flash the tiny image to your big SD card.

Run gparted.

Resize the ~16GB partition. There you go.

There is supposed to be a first boot script that expands the filesystem to fit the full card. If you are running a custom rootfs or linux distro, it might not have such a script. To resize the root filesystem manually to fit your card, run:

sudo resize2fs /dev/mmcblk0p1

That should just work. If it doesn’t, you might consider trying the nvidia script included two posts below.

I’m curious, however, as to why this didn’t happen automatically. Which image did you use to flash and how did you flash it? Did you do anything before first boot (like mount the image and modify it), or just stick the sd card into the Nano directly after flashing?

The RPi has a nearly identical first boot script to Nvidia’s which does the same thing (resizes the filesystem and self deletes). If an image is made by cloning the disk, for example, the script will not exist and resizing won’t work. Many other things will likely be broken as well.

This should work just fine as well. The rootfs SDKM installs by default has nvresizefs.sh in /etc/systemd and a unit set up to run it in /etc/systemd/system/nvresizefs.service.

Actually, create-jetson-nano-sd-card-image.sh in Linux_for_Tegra can create a sd image of any size. sd_blob_size also accepts sizes in GB (rather than G) so you can make an image that fits a sd card exactly.

NOTE:
…Linux_for_Tegra/create-jetson-nano-sd-card-image.sh has been moved to …Linux_for_Tegra/tools/jetson-disk-image-creator.sh in JetPack 4.3

$ ./create-jetson-nano-sd-card-image.sh --help
********************************************
     Jetson-Nano SD Image Creation Tool     
********************************************
ERROR: This script requires root privilege
Usage:
create-jetson-nano-sd-card-image.sh -o <sd_blob_name> -s <sd_blob_size> -r <revision>
	sd_blob_name	- valid file name
	sd_blob_size	- can be specified with G/M/K/B
			- size with no unit will be B
	revision	- SKU revision number
Example:
create-jetson-nano-sd-card-image.sh -o sd-blob.img -s 4G -r 100
create-jetson-nano-sd-card-image.sh -o sd-blob.img -s 4096M -r 200

Likewise, although the paritition is numbered mmcblk0p1 (1) if you examine the scheme in a partition editor, it is the last parititon, making it easy to expand.

However as metioned earlier, if your rootfs doesn’t have this script, or an equivalent, the filesystem will not be resized until you run resize2fs manually. If your rootfs uses systemd, I would recommend just copying over nvidia’s script to rootfs/etc/systemd/ the .service file to rootfs/etc/systemd/system and creating a symlink to that service in rootfs/etc/systemd/system/multi-user.target.wants/

You can see where all the files are supposed to be by looking in the cleanup function of nvresizefs.sh

A copy for convenience:

#!/bin/bash

# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#  * Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#  * Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#  * Neither the name of NVIDIA CORPORATION nor the names of its
#    contributors may be used to endorse or promote products derived
#    from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# This is a script to resize partition and filesystem on the root partition
# This will consume all un-allocated sapce on SD card after boot.

set -e

function cleanup()
{
	# Delete nvresizefs.sh, nvresizefs.service and its symlink
	rm "/etc/systemd/nvresizefs.sh"
	rm "/etc/systemd/system/nvresizefs.service"
	rm "/etc/systemd/system/multi-user.target.wants/nvresizefs.service"
}

if [ -e "/proc/device-tree/compatible" ]; then
	model="$(tr -d '\0' < /proc/device-tree/compatible)"
	if [[ "${model}" =~ "jetson-nano" ]]; then
		model="jetson-nano"
	fi
fi

if [ "${model}" != "jetson-nano" ]; then
	cleanup
	exit 0
fi

# Move backup GPT header to end of disk
sgdisk --move-second-header /dev/mmcblk0

# Get root partition name i.e partition No. 1
partition_name="$(sgdisk -i 1 /dev/mmcblk0 | \
	grep "Partition name" | cut -d\' -f2)"

partition_type="$(sgdisk -i 1 /dev/mmcblk0 | \
	grep "Partition GUID code:" | cut -d' ' -f4)"

partition_uuid="$(sgdisk -i 1 /dev/mmcblk0 | \
	grep "Partition unique GUID:" | cut -d' ' -f4)"

# Get start sector of the root partition
start_sector="$(cat /sys/block/mmcblk0/mmcblk0p1/start)"

# Delete and re-create the root partition
# This will resize the root partition.
sgdisk -d 1 -n 1:"${start_sector}":0 -c 1:"${partition_name}" \
	-t 1:"${partition_type}" -u 1:"${partition_uuid}" /dev/mmcblk0

# Inform kernel and OS about change in partitin table and root
# partition size
partprobe /dev/mmcblk0

# Resize filesystem on root partition to consume all un-allocated
# space on disk
resize2fs /dev/mmcblk0p1

# Clean up
cleanup

@mdegans
The SD card stopped responding after I tried to expand the partition with Gparted. Now, I’m trying to format it, if that works out, I will reflash the firmware. I suspect my colleague made a mistake somewhere when he was following the tutorial I mentioned in the original post.

Trying to repartition the sd card manually is not recommended. This may break automatic expansion of the sd card on first boot. Likewise you do not need to reformat the sd card. Flashing it with etcher (highly recommended because it does a verification pass) will overwrite the partition table anyway. If you follow Nvidia’s instructions to the letter, everything should work fine. Simply flash the image to the sd card, put it in the nano, and apply power. By the time first boot is done, the / partition should be expanded to fit the whole drive. Again, attempts to manually repartition will likely cause issues like you’re seeing.

The SDKManager root filesystem has the correct scripts but the partition layout it creates places the rootfs partition as a 14gb partition at the beginning of the card, then places the system partitions after that. You can’t expand that. The downloadable image places the rootfs partition after the system partitions (even though it’s still numbered 1). That’s easy to expand as said earlier, just use parted to expand it, then on the first boot the filesystem itself will be expanded to fit the new partition.

Maybe if you did everthing manually, but I haven’t had that problem using create-jetson-nano-sd-card-image.sh. You can have a look for yourself at the relavent bit:

function create_partitions()
{
        echo "${script_name} - create partitions"

        partitions=(\
                'part_num=2;part_name=TBC;part_size=131072;part_file=nvtboot_cpu.bin.encrypt' \
                'part_num=3;part_name=RP1;part_size=458752;part_file=tegra210-p3448-0000-p3449-0000-${dtb_id}.dtb.encrypt' \
                'part_num=4;part_name=EBT;part_size=589824;part_file=cboot.bin.encrypt' \
                'part_num=5;part_name=WB0;part_size=65536;part_file=warmboot.bin.encrypt' \
                'part_num=6;part_name=BPF;part_size=196608;part_file=sc7entry-firmware.bin.encrypt' \
                'part_num=7;part_name=TOS;part_size=589824;part_file=tos-mon-only.img.encrypt' \
                'part_num=8;part_name=EKS;part_size=65536;part_file=eks.img' \
                'part_num=9;part_name=LNX;part_size=655360;part_file=boot.img.encrypt' \
                'part_num=10;part_name=DTB;part_size=458752;part_file=tegra210-p3448-0000-p3449-0000-${dtb_id}.dtb.encrypt' \
                'part_num=11;part_name=RP4;part_size=131072;part_file=rp4.blob' \
                'part_num=12;part_name=BMP;part_size=81920;part_file=bmp.blob' \
                'part_num=1;part_name=APP;part_size=0;part_file='
        )

        part_type=8300 # Linux Filesystem

        sgdisk -og "${sd_blob_name}"
        for part in "${partitions[@]}"; do
                eval "${part}"
                part_size=$((${part_size} / 512)) # convert to sectors
                sgdisk -n "${part_num}":0:+"${part_size}" \
                        -c "${part_num}":"${part_name}" \
                        -t "${part_num}":"${part_type}" "${sd_blob_name}"
        done
}

That’s the order in which the partitions are created. Expanding works fine on first boot, just as the official, downloaded, image does.

I have not had luck with that.

That’s the order if you use the scripts in the Linux_for_Tegra download, or use the pre-built image.

The SDKManager does not create that. It creates a 14 partition layout with the APP partition first and sized so the total space used on the card is 16gb. Here’s a post with an example of what it creates…
https://devtalk.nvidia.com/default/topic/1063338/jetson-nano/sd-card-32g-became-15g-after-flash/post/5384792/#5384792

Actually, here’s the image from that post…

https://imgur.com/EY2KZEA

O_o

If that’s the case, that sounds like a bug in SDKM. You sure they haven’t fixed that already? To be honest I’ve never flashed my nano directly with SDKM (instead always flashing the card with a reader). I had assumed it would create the card image using the existing script that works, create-jetson-nano-sd-card-image.sh