User:Gig/Jetson Nano QEMU chroot

From Gentoo Wiki
Jump to:navigation Jump to:search

The guide details the process for running the Jetson Nano Developer Kit image in a chroot environment. Since the Jetson Nano uses a Cortex A57 CPU, QEMU is necessary for running arm64 (aarch64) code on a non-arm64 machine (e.g. x86_64).

The steps here could likely be used as a template for any arm64 image.

Download and mount the Jetson Nano sdcard image

Download the "Jetson Nano Developer Kit SD Card Image" from, or download it directly with:


user $unzip

Inspect the image file with fdisk:

user $fdisk -l sd-blob-b01.img
Disk sd-blob-b01.img: 12.87 GiB, 13816037376 bytes, 26984448 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 91FC289A-1E03-495A-9DAD-732401089949

Device            Start      End  Sectors  Size Type
sd-blob-b01.img1  28672 26980351 26951680 12.9G Linux filesystem
sd-blob-b01.img2   2048     2303      256  128K Linux filesystem
sd-blob-b01.img3   4096     4991      896  448K Linux filesystem
sd-blob-b01.img4   6144     7295     1152  576K Linux filesystem
sd-blob-b01.img5   8192     8319      128   64K Linux filesystem
sd-blob-b01.img6  10240    10623      384  192K Linux filesystem
sd-blob-b01.img7  12288    13055      768  384K Linux filesystem
sd-blob-b01.img8  14336    14463      128   64K Linux filesystem
sd-blob-b01.img9  16384    17279      896  448K Linux filesystem
sd-blob-b01.img10 18432    19327      896  448K Linux filesystem
sd-blob-b01.img11 20480    22015     1536  768K Linux filesystem
sd-blob-b01.img12 22528    22655      128   64K Linux filesystem
sd-blob-b01.img13 24576    24959      384  192K Linux filesystem
sd-blob-b01.img14 26624    26879      256  128K Linux filesystem

Partition table entries are not in disk order.

Note the sector size (512 bytes) and the starting offset of the first (and largest) partition. Use this information to mount the image:

root #mount -o loop,offset=$((512 * 28672)) sd-blob-b01.img /mnt

Optionally, consider copying the contents of the loop mount to somewhere else on disk. This isn't strictly necessary, but the chroot will have little to no free space if this is not done:

root #cp -r /mnt/. ~/jetson/

(At this point, if struggling for disk space, the original zip and img file can be deleted.)

Set up QEMU

Unsurprisingly, app-emulation/qemu will need to be installed. The package itself (likely) needs the static-user USE variable, and QEMU_USER_TARGETS will require aarch64. If qemu is already installed, re-emerge the package after making these changes:

FILE /etc/portage/package.use/qemu
app-emulation/qemu static-user # alongside other USE variables if necessary
FILE /etc/portage/make.conf
QEMU_USER_TARGETS="aarch64" # alongside other targets if necessary

Convince the kernel to interpret arm64 binaries with QEMU

To prevent errors when attempting to run arm64 binaries, tell the kernel to pass said binaries to qemu-aarch64. (On non-Gentoo systems, this program might be named qemu-aarch64-static.)

The kernel will need support for binfmt_misc; the Embedded Handbook explains how to do this if necessary.

Register aarch64 binaries with /usr/bin/qemu-aarch64:

root #echo ':aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00:\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-aarch64:' > /proc/sys/fs/binfmt_misc/register

After doing so, /proc/sys/fs/binfmt_misc/aarch64 should be created, and the contents should look something like this:

FILE /proc/sys/fs/binfmt_misc/aarch64
interpreter /usr/bin/qemu-aarch64
offset 0
magic 7f454c460201010000000000000000000200b700
mask fffffffffffffffcfffffffffffffffffeffffff

Chroot into the Jetson environment

Before chrooting directly into the Jetson environment, mount some necessary filesystems first:

root #for f in proc sys dev run; do mount --bind /$f ~/jetson/$f; done

Finally, chroot!

root #chroot ~/jetson/
/usr/bin/groups: cannot find name for group ID 11
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.


Fixing Internet access

If, within the chroot, /etc/resolv.conf is symlinked to a non-existent file in /run, DNS will likely be broken. It can be fixed by copying DNS information from the host system:

root #cp /etc/resolv.conf ~/jetson/etc/resolv.conf


When done with the chroot, consider unmounting the necessary filesystems:

root #for f in proc sys dev run; do umount ~/jetson/$f; done