PythOps

Create your own image for jetson nano board

Last update: 16 January 2022

Introduction

This article will guide you step by step to create a minimalist Ubuntu based image for your NVIDIA Jetson nano board that best suits your project.


Why would you build an image from scratch instead of using the official one ?

First, for fun. It's always interesting to build stuff from scratch as you always learn something in the process. Second, the official image is large in size (over 5GB 😱 ) and it's filled with lot of unnecessary preinstalled packages (ubuntu-desktop, browser ...) that takes lot of disk space and memory. So, let's create a clean and minimalist image.


Download the scripts

Before starting, let's first clone the repository where I put all the needed scripts.

$ git clone https://github.com/pythops/jetson-nano-image
$ cd jetson-nano-image

The directory jetson-nano-image looks like the following:

├── ansible/
├── patches/
├── vagrant/
├── create-image.sh
├── create-rootfs.sh
├── flash-image.sh
└── Readme.md


Build environment (Optional)

This section for those who are using another Linux distribution other than Ubuntu or just want to keep their distribution clean.

To be able to create the image, you'll need an Ubuntu machine. If you happen to run another OS, you can use Vagrant with Virtualbox to create an ubuntu virtual machine.

$ cd vagrant

# Run the VM
$ vagrant up

# Connect to the VM
$ vagrant ssh jetson

Once you're inside the VM, the directory jetson-nano-image is being shared with the VM that you can find in /jetson-nano-image inside the VM.


Create a rootfs

We're gonna use the script create-rootfs.sh to create a basic rootfs. First, we define the location where we want to build it. This is done by defining the environment variable $JETSON_ROOTFS_DIR. The path will be created if it does not exit.

$ export JETSON_ROOTFS_DIR=/path/to/rootfs

Then we build the rootfs by running the following command

$ sudo -E ./create-rootfs.sh
Installing the dependencies...  [OK]
Creating rootfs directory...    [OK]
Downloading the base image...   [OK]
Run debootstrap first stage...  [OK]
Run debootstrap second stage... [OK]
The rootfs has been created successfully.

 -E option for sudo preserve the environment variables


Customize

Now that we have a basic rootfs, we're gonna customize it using one of my favorite tool ever: Ansible. For this step you need to have Ansible installed in your workstation. if it's not the case, just run this command and you're ready to go

$ pip install --user ansible
$ export PATH=$HOME/.local/bin:$PATH

This Ansible role is going to do 3 things:

  • Install some basic tools (ssh, systemd, sudo ...)
  • Setup basic configurations (locales, network ...)
  • Add new user: pythops, the default password is pythops

You can run the playbook as follows

$ cd ansible
$ sudo -E $(which ansible-playbook) jetson.yaml

Feel free to adapt this role to your needs.


Create the image

Now that we customized the rootfs, we're gonna use the script create-image.sh to create our final image. Before we build the image, you need to define the type of your board. Currently, the supported boards are Jetson Nano and Jetson Nano 2GB.

To define the type of your board, you need to set an enviroment variable called $JETSON_NANO_BOARD as following:

For the Jetson nano board

$ export JETSON_NANO_BOARD=jetson-nano

For the Jetson Nano board 2GB

$ export JETSON_NANO_BOARD=jetson-nano-2gb

For Jetson nano board 4GB only, you can specify which board model you wanna use B01 or A02 model. If you buy a new board now, chances are you're gonna get the B01 model.

To specify your model, you need to define a new enviroment variable $JETSON_NANO_REVISION as following:

For B01 model (the default):

$ export JETSON_NANO_REVISION=300

For A02 model:

$ export JETSON_NANO_REVISION=200

We need to define a build directory as well using the enviroment variable $JETSON_BUILD_DIR. This path will be created if it does not exist.

$ export JETSON_BUILD_DIR=/path/to/build_dir

Then we build the image as follows:

 This is the output for Jetson nano A02 model

$ sudo -E ./create-image.sh
Build the image ...
Download L4T...       [OK]
Applying patches...   [OK]
Extract L4T...        [OK]
Creating image for Jetson nano board (200 revision)... [OK]
Image created successfully
Image location ./jetson.img


Flash on the sdcard

 If you're using the VM to build the image, even though you can flash the sd card inside the VM, it's much easier to do it from the host machine.

Finally we're gonna flash the image on the sdcard using the script flash-image.sh.

Insert your sdcard and run this command

$ sudo ./flash-image.sh /path/to/jetson.img /dev/mmcblk0
.
.
.
Success !
Your sdcard is ready !

⚠️ the sdcard path /dev/mmcblk0 may be different in your system.

This script will automatically resize the root partition to occupy all the available space in the sdcard.

Congratulations 🎉 Now you can boot your board with the new image !


Nvidia Libraries

You can install Nvidia libraries using apt

$ sudo apt install -y cuda-toolkit-10-2 libcudnn8 libcudnn8-dev


Result

With the new image only 150MB of RAM is used, which leaves you with 3.85 GB for your projects !


If you find this blog post helpfull, don't forget to give it a star in Github

Read more ...

Setup your Linux workstation with Ansible

Linux User Authentication

compile deeplearning libraries for jetson nano