Jetson/Filesystem Emulation/Emulating Jetson Filesystem with QEMU and L4T Docker Container
This tutorial guides you through the steps of setting up a Jetson filesystem and then emulating it on a host machine (x86). This, for instance, can work as an alternative to the compilation of source code directly on the target device. The emulation of the target file system on a host PC can be useful to the developer and can potentially accelerate the compilation process. The approach can also be useful for other use-cases.
The following instructions guide through the process of setting up the file system on the target device, installing the dependencies and making sure everything works fine on the device itself. As a next step, the target filesystem is going to be converted into an image to be mounted on the host PC. With these steps completed the L4T docker container is going to be emulated on the host PC, while the mounted image will provide the docker runtime the necessary dependencies for the compilation.
Setting up the Target Device
From the L4T Archive, download the desired L4T Driver Package and corresponding sample filesystem.
Flash the target device following the instructions described here.. After flashing, the device will reboot. Please configure the device at first boot and log into the OS.
Installing the Dependencies
The dependencies to be installed are specific to the task to be performed on the emulated filesystem. For the sake of exemplification, the Jetson Multimedia API samples will be compiled, therefore the dependencies are set for this purpose.
For more details, please see the documentation for the Multimedia API Sample Applications.
On the target, issue the following commands:
$ sudo apt update $ apt list --upgradable $ sudo apt upgrade $ sudo apt install nvidia-jetpack
Clone Your Device's Image
After installing the JetPack, shut down the device and set it into recovery mode.
Now, on the host PC, issue the following commands to clone your device's image.
$ cd <path_to_L4T> $ sudo ./flash.sh -r -k APP -G <name_of_the_img> <target> mmcblk0p1
Setting up Emulation Environment
Install docker and Nvidia Container Runtime. See instructions here.
Install QEMU and dependencies:
$ sudo apt-get update $ sudo apt-get install qemu binfmt-support qemu-user-static
Mount your target filesystem
$ mkdir $HOME/jetsonfs $ sudo mount -t ext4 <path_to_image>/<name_of_image>.img.raw $HOME/jetsonfs
You can find the Jetson Multimedia API in the mounted file system under following path:
Pull the NVIDIA L4T Base docker image that matches the L4T version you flashed on the Jetson.
$ docker pull nvcr.io/nvidia/l4t-base:r<release-number>
Further information about the docker image can be found in NGC.
Running the container
As the docker image and multimedia API samples have been downloaded, run the container with the following command:
$ sudo docker run -it --network=host -v <path_to_mounted_jetson_image>/usr/:/usr/ -v <path_to_mounted_jetson_image>/bin/:/bin/ -v <path_to_mounted_jetson_image>/sbin/:/sbin/ -v <path_to_mounted_jetson_image>/lib/:/lib/ -v <path_to_mounted_jetson_image>/var/:/var/ -v <path_to_mounted_jetson_image>/opt/:/opt/ -v <path_to_mounted_jetson_image>/snap/:/snap/ -v /usr/bin/qemu-aarch64-static:/usr/bin/qemu-aarch64-static nvcr.io/nvidia/l4t-base:r<release-number>
To verify whether the running container corresponds to an ARM-based one:
The console output should look like the following:
Install the dependencies in the container
$ apt-get update && apt-get install -y --no-install-recommends make g++
From inside the container, go to the desired MMAPI sample folder and build it.
$ cd /usr/src/jetson_multimedia_api/samples/00_video_decode $ make
For larger tasks, you can assign the a larger number of jobs to the build. The number of jobs usually matches the number of available cores. For example, in a system with 12 CPU cores:
$ make -j12
Copying the binaries to the device
Check the container ID:
$ sudo docker ps
Copy the binaries from the container to the host PC
$ sudo docker cp <CONTAINER_ID>:/usr/src/jetson_multimedia_api/00_video_decode/video_decode /$HOME
Lastly copy the binaries to the target device (here connected over USB)
$ sudo cd ~ $ sudo scp ./video_decode firstname.lastname@example.org:~