The robot's computer · Chapter 04 · Time: 2 hours · Level: Intermediate · Status: Done on this robot
On bigbuddy, a checked copy of NVIDIA's Jetson Linux R36.4.3, an Ubuntu 22.04 build container, and a staged root filesystem that already has your user, hostname and SSH key - ready to copy onto the robot's NVMe in chapter 5.
The robot's operating system is NVIDIA's stock Jetson Linux, with nothing from Hiwonder. You do not build it on the
robot. You assemble it on a PC (here bigbuddy), then copy the finished file tree onto the robot's NVMe. bigbuddy runs
Fedora, and NVIDIA's tools expect Ubuntu, so all of the NVIDIA steps run inside an Ubuntu 22.04 container. The robot
is not touched in this chapter except for one read-only look at its factory configuration.
Everything here was done on 2026-09-26 between 16:14 and 17:16 UTC and is in the command log with its output.
New idea: Jetson Linux, the BSP and the root filesystem
The Jetson Orin NX is a module: CPU, GPU and 16 GB of memory on a small board that plugs into a carrier
board with the connectors. On this robot the carrier is NVIDIA's own reference board (p3768-0000), not a
Hiwonder board. NVIDIA's operating system for it is Jetson Linux, also called L4T (Linux for Tegra). JetPack 6.2
is the bundle name for L4T R36.4.3, the version the factory install ran.It comes as two downloads:
- the BSP (board support package),
Jetson_Linux_R36.4.3_aarch64.tbz2. It unpacks to a folder called
Linux_for_Tegra: kernel, device trees, bootloader images, NVIDIA's driver packages, and the flashing scripts.- the sample root filesystem,
Tegra_Linux_Sample-Root-Filesystem_R36.4.3_aarch64.tbz2. This is a plain
Ubuntu 22.04 for 64-bit ARM (arm64, also written aarch64) without NVIDIA's parts. It is unpacked into
Linux_for_Tegra/rootfs.NVIDIA's script
apply_binaries.shinstalls the NVIDIA packages from the BSP into that rootfs. The result is the
complete/of the robot, sitting in a folder on bigbuddy. That folder is called the staged rootfs in this
guide.
New idea: running ARM programs on a PC
The robot's CPU is arm64; bigbuddy's is x86_64. Some steps must run programs inside the staged rootfs (create
a user, generate SSH keys, set a password) withchroot. Those programs are arm64 binaries. Linux can hand each
one to QEMU, a CPU emulator, through a kernel feature called binfmt_misc. On bigbuddy theqemu-aarch64handler
is registered with flagF: the kernel opens the emulator once, when the handler is registered, so the emulator
does not need to exist inside the container or the rootfs. That is whychrootinto an arm64 tree works from
the container below, even afterapply_binaries.shremoves its own copy of QEMU from the rootfs.
These were the values on bigbuddy on 2026-09-26 (log 16:14:08 and 16:15:59).
| Item | Value | Why it matters |
|---|---|---|
| OS | Fedora release 44, kernel 7.2.5-200.fc44.x86_64 | NVIDIA's host tools are written for Ubuntu, hence the container |
| Docker | Docker version 29.8.1; user burgerbarn in group docker |
runs the build container without sudo |
| QEMU | qemu-user-static-10.2.2-1.fc44.x86_64, binfmt handler qemu-aarch64, flags F |
runs arm64 programs in the rootfs |
| SELinux | Enforcing |
every docker -v mount below ends in :z so the container may use the folder |
| Free disk | 82G free on / before starting |
the downloads take 2.4 GB, the work folder 7.4 GB |
| Login shell | fish | see the warning below |
bigbuddy's login shell is fish, not bash
Every@bigbuddyblock in this guide is bash. fish does not understand bash heredocs (<<'EOF'). Either type
bashafter you log in to bigbuddy, or send a block from your laptop the way the log did:
ssh bigbuddy 'bash -s' <<'EOF', the block, thenEOFon its own line (AGENTS.md, Machines table).
At 16:14 bigbuddy had no qemu-user-static; at 16:15 the owner had installed it by hand (it needs his sudo
password). The exact dnf line he typed is not in the log; the package name is qemu-user-static.
On bigbuddy:
rpm -q qemu-user-static; ls /proc/sys/fs/binfmt_misc/ | grep -i aarch64
cat /proc/sys/fs/binfmt_misc/qemu-aarch64 | grep -E "interpreter|flags"
Check
The package, the two aarch64 handlers, and flagF(log 16:15:48 and 17:05:35):qemu-user-static-10.2.2-1.fc44.x86_64 qemu-aarch64 qemu-aarch64_be interpreter /usr/bin/qemu-aarch64-static flags: F
On bigbuddy:
id; docker ps >/dev/null 2>&1 && echo "docker usable without sudo" || echo "docker needs sudo"
systemctl is-active docker
Check
groups=lists968(docker)(the number may differ), thendocker usable without sudoandactive.
If it fails: bigbuddy goes to sleep in the middle of the work
bigbuddy suspends when idle (KDE power management), and SSH traffic does not keep it awake. On 2026-09-26 at
16:27 it vanished mid-session (ssh: connect to host 192.168.1.111 port 22: Operation timed out, ping
Host is down).systemd-inhibitfrom an SSH session is refused by polkit (Failed to inhibit: Access denied as the requested operation requires interactive authentication). What works is asking the KDE session itself.
On bigbuddy:
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus XDG_RUNTIME_DIR=/run/user/$(id -u)
command -v kde-inhibit || echo "no kde-inhibit"
nohup kde-inhibit --power --screenSaver sleep 21600 >/tmp/kde-inhibit.log 2>&1 &
sleep 21600 holds the block for six hours. Check that KDE registered it:
On bigbuddy:
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus XDG_RUNTIME_DIR=/run/user/$(id -u)
pgrep -af kde-inhibit || echo "kde-inhibit not running"
busctl --user call org.kde.Solid.PowerManagement /org/kde/Solid/PowerManagement/PolicyAgent org.kde.Solid.PowerManagement.PolicyAgent ListInhibitions 2>&1 | head -5
Check
From the log (16:48:53):15520 kde-inhibit --power --screenSaver sleep 21600 aas 2 2 "Running Script" "sleep" 2 "Running Script" "sleep"The process ID will differ. Release it when you are done:
pkill -f "kde-inhibit --power --screenSaver sleep 21600".
Before you download anything, read which NVIDIA configuration the factory flashed. You need the name later, and it
tells you which BSP matches the board. This runs on the robot's factory system, logged in as ubuntu.
On the robot:
echo "== nv_boot_control"; cat /etc/nv_boot_control.conf
echo "== dtb in use"; grep -iE "FDT|APPEND|LABEL" /boot/extlinux/extlinux.conf | head
echo "== compatible"; tr '\0' '\n' < /proc/device-tree/compatible
Check
On this robot (log 16:19:00):== nv_boot_control TNSPEC 3767-303-0000-D.1-1-1-jetson-orin-nano-devkit-super- COMPATIBLE_SPEC 3767-000-0000--1--jetson-orin-nano-devkit-super- TEGRA_BOOT_STORAGE nvme0n1 TEGRA_CHIPID 0x23 TEGRA_OTA_BOOT_DEVICE /dev/mtdblock0 TEGRA_OTA_GPT_DEVICE /dev/mtdblock0 == dtb in use LABEL primary MENU LABEL primary kernel APPEND ${cbootargs} root=PARTUUID=59fca1c4-9e3e-406d-8532-cad56c869912 rw rootwait rootfstype=ext4 mminit_loglevel=4 console=ttyTCU0,115200 firmware_class.path=/etc/firmware fbcon=map:0 net.ifnames=0 nospectre_bhb video=efifb:off console=tty0
3767is the module (Orin NX, SKU0000= 16 GB),jetson-orin-nano-devkit-superis NVIDIA's board
configuration for the reference carrier, and/proc/device-tree/compatiblereads
nvidia,p3768-0000+p3767-0000-super(docs/hardware.md). Keep a copy of this output: the
nv_boot_control.conffile comes back in chapter 5.
NVIDIA serves both files without a login. Download them in the background and wait for both:
On bigbuddy:
mkdir -p ~/jetson-flash/downloads && cd ~/jetson-flash/downloads
B=https://developer.download.nvidia.com/embedded/L4T/r36_Release_v4.3/release
for f in Jetson_Linux_R36.4.3_aarch64.tbz2 Tegra_Linux_Sample-Root-Filesystem_R36.4.3_aarch64.tbz2; do
nohup curl -fL -C - -o "$f" "$B/$f" > "$f.log" 2>&1 &
done
On bigbuddy:
cd ~/jetson-flash/downloads
while pgrep -f "curl -fL -C - -o" >/dev/null; do sleep 5; done
ls -l *.tbz2; tail -c 300 *.log | tr '\r' '\n' | tail -4
-C - lets curl resume a broken download if you run the loop again. On bigbuddy the two files took about 30 s at
roughly 58 MB/s.
Then test both archives and record their SHA-256 sums. The same command unpacks a second, read-only copy of the
BSP into ~/jetson-flash/inspect, where you can read NVIDIA's README files and board configurations without the
container:
On bigbuddy:
cd ~/jetson-flash/downloads
for f in *.tbz2; do bzip2 -t "$f" && echo "OK $f"; sha256sum "$f"; done
mkdir -p ~/jetson-flash/inspect && cd ~/jetson-flash/inspect && tar xjf ~/jetson-flash/downloads/Jetson_Linux_R36.4.3_aarch64.tbz2
cd Linux_for_Tegra && ls *.conf | grep -Ei "orin|p3509|p3768|p3767"
Check
Sizes (log 16:16:09):Jetson_Linux_R36.4.3_aarch64.tbz2715765074 bytes,
Tegra_Linux_Sample-Root-Filesystem_R36.4.3_aarch64.tbz21827877026 bytes. Then (log 16:16:30):OK Jetson_Linux_R36.4.3_aarch64.tbz2 949a44049c4ce6a8efdf572ea0820c874f6ee5d41ca3e4935b9f0e38d11873d2 Jetson_Linux_R36.4.3_aarch64.tbz2 OK Tegra_Linux_Sample-Root-Filesystem_R36.4.3_aarch64.tbz2 67b85bae18a532dd2fd75399359ba10829c30c0e60d77231b614df39ab52156d Tegra_Linux_Sample-Root-Filesystem_R36.4.3_aarch64.tbz2The list of
.conffiles must includejetson-orin-nano-devkit-super.conf(in this BSP it is a link to
p3768-0000-p3767-0000-super.conf).
If it fails
- There is no checksum file at NVIDIA's download path: the log's attempt to fetch
sha1sum.txtprinted
no sha1sum.txt at that path. The check this build relied on is the byte size,bzip2 -t, and the two
SHA-256 values above, recorded from this download (docs/status.mdnotes the sizes match NVIDIA's).- If
bzip2 -tfails, delete the file and run the download loop again.
The container is a plain Ubuntu 22.04 with the tools NVIDIA's scripts call. The repo keeps its recipe at
scripts/container/Dockerfile:
On bigbuddy:
FROM ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
sudo bzip2 lbzip2 tar python3 python3-yaml qemu-user-static binfmt-support \
usbutils iproute2 iputils-ping openssh-client udev kmod nfs-kernel-server \
abootimg cpio device-tree-compiler dosfstools libxml2-utils lz4 openssl \
rsync sshpass uuid-runtime xxd zstd whiptail gdisk parted curl ca-certificates \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /work
What the package groups are for:
bzip2 lbzip2 tar lz4 zstd cpio: unpacking NVIDIA's archives (lbzip2 is a parallel bzip2) and the goldenqemu-user-static binfmt-support: running arm64 programs in the rootfs.gdisk parted dosfstools: partition tables and the EFI partition; the restore steps in chapter 8 run here.nfs-kernel-server openssh-client sshpass usbutils iproute2 iputils-ping udev kmod: NVIDIA's initrd flashtools/kernel_flash/README_initrd_flash.txt lists SSH and NFS from the target to the host as requirements.abootimg device-tree-compiler libxml2-utils openssl python3 python3-yaml uuid-runtime xxd whiptail)The base image also brings e2fsprogs 1.46.5 (mke2fs, checked 2026-09-26 21:01). That version matters: Fedora's
mke2fs 1.47.3 creates ext4 filesystems the robot's kernel cannot mount (chapter 5).
The log wrote the file with a heredoc and built it in one go:
On bigbuddy:
mkdir -p ~/jetson-flash/container && cd ~/jetson-flash/container
cat > Dockerfile <<'DF'
FROM ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
sudo bzip2 lbzip2 tar python3 python3-yaml qemu-user-static binfmt-support \
usbutils iproute2 iputils-ping openssh-client udev kmod nfs-kernel-server \
abootimg cpio device-tree-compiler dosfstools libxml2-utils lz4 openssl \
rsync sshpass uuid-runtime xxd zstd whiptail gdisk parted curl ca-certificates \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /work
DF
docker build -q -t jetson-flash:r36.4.3 . && docker images jetson-flash
Check
From the log (16:19:30):sha256:4a08465dc9c1853b43c3497b9e674336177767fb8656369909affa461d137f4b IMAGE ID DISK USAGE CONTENT SIZE EXTRA jetson-flash:r36.4.3 4a08465dc9c1 456MB 119MBYour image ID will differ (Ubuntu's packages change); the tag
jetson-flash:r36.4.3is what later commands use.
One container run unpacks the BSP into ~/jetson-flash/work, unpacks the sample rootfs inside it, installs the
host prerequisites into the container, and runs apply_binaries.sh. The whole run goes to ~/jetson-flash/prep.log.
On bigbuddy:
mkdir -p ~/jetson-flash/work
docker run --rm --privileged -v ~/jetson-flash/downloads:/dl:ro,z -v ~/jetson-flash/work:/work:z jetson-flash:r36.4.3 bash -c '
set -e
cd /work
tar xpf /dl/Jetson_Linux_R36.4.3_aarch64.tbz2 --use-compress-program=lbzip2
cd Linux_for_Tegra/rootfs
tar xpf /dl/Tegra_Linux_Sample-Root-Filesystem_R36.4.3_aarch64.tbz2 --use-compress-program=lbzip2
cd ..
./tools/l4t_flash_prerequisites.sh
./apply_binaries.sh
echo PREP_DONE
' > ~/jetson-flash/prep.log 2>&1
tail -15 ~/jetson-flash/prep.log
Read the command:
--rm deletes the container when it exits; only the mounted folders keep anything.--privileged lets the container mount /proc, /sys and /dev into the rootfs, which apply_binaries.sh-v ~/jetson-flash/downloads:/dl:ro,z shows the downloads to the container read-only at /dl.-v ~/jetson-flash/work:/work:z is where the result goes. ,z / :z relabel the folders for SELinux.tar xpf keeps permissions (p); it runs as root inside the container, so file owners are kept too.l4t_flash_prerequisites.sh installs NVIDIA's list of host packages into this container run. Because of--rm they are gone when the run ends; the saved image keeps only the Dockerfile's list (this matters forapply_binaries.sh installs NVIDIA's L4T packages into Linux_for_Tegra/rootfs and buildsThis took about a minute and a half on bigbuddy (16:19:57 to the next command at 16:21:21).
Check
The end ofprep.log(log 16:19:57):Cleaning up the temporary directory for updating the initrd.. /work/Linux_for_Tegra Removing QEMU binary from rootfs Removing stashed Debian packages from rootfs L4T BSP package installation completed! Disabling NetworkManager-wait-online.service Disable the ondemand service by changing the runlevels to 'K' Success! PREP_DONEThen scan the log for real problems:
grep -inE "error|fail|warn" ~/jetson-flash/prep.log | grep -v "fbdev-blacklist" | head -10On this build the only hits were two
update-alternatives: warning: skip creation of /usr/share/man/man1/nc.1.gz
lines (missing man pages for netcat). They are harmless.
Note the line Disabling NetworkManager-wait-online.service. Because of it, After=network-online.target in a
systemd unit does not wait for addresses on this robot. Chapter 9 comes back to this.
If it fails
- Permission denied when you look at the result. Everything under
~/jetson-flash/workwas created by root
inside the container, and some folders are readable only by root (find: './rootfs/root': Permission denied,
log 17:05:10). Read and count the staged rootfs through the container, as the commands below do.- An empty
/Users/...folder appears on bigbuddy. If you send commands from the Mac, quote remote paths. In
an unquoted command line your laptop's shell expands~to/Users/matty, anddocker -vthen creates an
empty folder of that name on bigbuddy and mounts it instead of your work folder. This happened on 2026-09-26
(/Users/matty/jetson-flash/workexisted on bigbuddy at 17:15;docs/lessons.md).
Why not NVIDIA's default-user script
NVIDIA shipstools/l4t_create_default_user.sh, which creates the first user and skips the first-boot setup
wizard. It requires the--accept-licenseoption, i.e. accepting NVIDIA's license on the owner's behalf. The
decision on 2026-09-26 was that the owner accepts licenses himself, so the user is created with plainuseradd
instead (docs/decisions.md). The script below does by hand the parts of NVIDIA's script that this robot needs.
scripts/prep_rootfs.sh (21 lines) runs as root inside the container against the staged rootfs. It sets up
everything the robot needs to be reachable on its first boot without a screen. Build it up in six pieces.
New idea: the first-boot wizard (oem-config)
A freshly flashed Jetson normally starts NVIDIA's setup wizard on first boot (language, user, password,
license), which needs a screen or a serial console. In the staged rootfs, the systemd default target is a link
to that wizard:etc/systemd/system/default.target -> nv-oem-config.target(log 17:09:50). Remove the link and
the system boots to Ubuntu's normal default target instead.The file
etc/nv/nvautoconfigtells NVIDIA's late-boot script (/etc/systemd/nv-late-init.sh) to apply its
defaults on first boot: it runsnvresizefs.sh, which grows theAPPpartition to the end of the disk, and
nvswap.sh(docs/lessons.md). You will see the result in chapter 6.
Piece 1: stop on the first error, go into the rootfs, and make the host's /proc, /sys and /dev visible inside
it so that chroot programs work. The trap unmounts them however the script ends.
On bigbuddy:
set -e
R=/work/Linux_for_Tegra/rootfs
cd $R
mount --bind /proc proc; mount --bind /sys sys; mount --bind /dev dev
trap 'umount dev sys proc || true' EXIT
Piece 2: the user. groupadd -rf weston-launch creates a group NVIDIA's own script also creates (-f: no error if
it exists). The user gets NVIDIA's standard groups plus dialout, which allows access to serial ports such as the
robot's controller board (/dev/ttyACM0, chapter 10). id burgerbarn || makes the line safe to run twice.
On bigbuddy:
LC_ALL=C chroot . groupadd -rf weston-launch
id burgerbarn >/dev/null 2>&1 || LC_ALL=C chroot . useradd -d /home/burgerbarn -m -G sudo,video,audio,adm,render,weston-launch,dialout -s /bin/bash burgerbarn
Piece 3: skip the wizard, and ask for NVIDIA's first-boot defaults (resize, swap).
On bigbuddy:
rm -f etc/systemd/system/default.target
mkdir -p etc/nv && touch etc/nv/nvautoconfig
Piece 4: the hostname, and the matching 127.0.1.1 line so that sudo and other tools can resolve it.
On bigbuddy:
echo rosorin > etc/hostname
grep -qxF "127.0.1.1 rosorin" etc/hosts || echo "127.0.1.1 rosorin" >> etc/hosts
Piece 5: SSH. ssh-keygen -A creates the robot's host keys (the sample rootfs has none). Your laptop's public key
goes into authorized_keys with the strict permissions sshd insists on (folder 700, file 600, owned by the user).
The drop-in 10-local.conf turns off logins by password and logins as root: the only way in is your key.
On bigbuddy:
LC_ALL=C chroot . ssh-keygen -A
install -d -m 700 -o $(stat -c %u home/burgerbarn) -g $(stat -c %g home/burgerbarn) home/burgerbarn/.ssh
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA11ntpjSWe4Tra27hkn7xnaBG1pqe3aFghGftIxOZGt matty@MacBook-Air-20260808" > home/burgerbarn/.ssh/authorized_keys
chown $(stat -c %u:%g home/burgerbarn) home/burgerbarn/.ssh/authorized_keys; chmod 600 home/burgerbarn/.ssh/authorized_keys
printf 'PasswordAuthentication no\nKbdInteractiveAuthentication no\nPermitRootLogin no\n' > etc/ssh/sshd_config.d/10-local.conf
The stat -c %u home/burgerbarn calls read the numeric owner of the home folder as the rootfs sees it (1000). The
container has no burgerbarn user, so names would not work here.
Piece 6: print what was done, and let sshd check its own configuration.
On bigbuddy:
echo "== verify"
grep burgerbarn etc/passwd; LC_ALL=C chroot . id burgerbarn
cat etc/hostname; ls etc/ssh/ssh_host_*_key.pub; cat etc/ssh/sshd_config.d/10-local.conf
ls -la etc/systemd/system/default.target 2>&1 | tail -1; ls -la home/burgerbarn/.ssh/
LC_ALL=C chroot . sshd -t && echo "sshd config OK"
The complete file, as it is in the repo (scripts/prep_rootfs.sh; it has no #! line because it is always run as
bash /prep.sh). Create it on bigbuddy as ~/jetson-flash/prep_rootfs.sh:
On bigbuddy:
set -e
R=/work/Linux_for_Tegra/rootfs
cd $R
mount --bind /proc proc; mount --bind /sys sys; mount --bind /dev dev
trap 'umount dev sys proc || true' EXIT
LC_ALL=C chroot . groupadd -rf weston-launch
id burgerbarn >/dev/null 2>&1 || LC_ALL=C chroot . useradd -d /home/burgerbarn -m -G sudo,video,audio,adm,render,weston-launch,dialout -s /bin/bash burgerbarn
rm -f etc/systemd/system/default.target
mkdir -p etc/nv && touch etc/nv/nvautoconfig
echo rosorin > etc/hostname
grep -qxF "127.0.1.1 rosorin" etc/hosts || echo "127.0.1.1 rosorin" >> etc/hosts
LC_ALL=C chroot . ssh-keygen -A
install -d -m 700 -o $(stat -c %u home/burgerbarn) -g $(stat -c %g home/burgerbarn) home/burgerbarn/.ssh
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA11ntpjSWe4Tra27hkn7xnaBG1pqe3aFghGftIxOZGt matty@MacBook-Air-20260808" > home/burgerbarn/.ssh/authorized_keys
chown $(stat -c %u:%g home/burgerbarn) home/burgerbarn/.ssh/authorized_keys; chmod 600 home/burgerbarn/.ssh/authorized_keys
printf 'PasswordAuthentication no\nKbdInteractiveAuthentication no\nPermitRootLogin no\n' > etc/ssh/sshd_config.d/10-local.conf
echo "== verify"
grep burgerbarn etc/passwd; LC_ALL=C chroot . id burgerbarn
cat etc/hostname; ls etc/ssh/ssh_host_*_key.pub; cat etc/ssh/sshd_config.d/10-local.conf
ls -la etc/systemd/system/default.target 2>&1 | tail -1; ls -la home/burgerbarn/.ssh/
LC_ALL=C chroot . sshd -t && echo "sshd config OK"
Use your own key
Line 14 is the owner's laptop key (matty@MacBook-Air-20260808). If you rebuild from another laptop, put the
contents of your own~/.ssh/id_ed25519.pubthere. Logins by password are off, so a wrong key means no way in
over the network. (On 2026-09-26 the log did not hard-code the key: it read~/.ssh/id_ed25519.pubon the Mac
and wrote it into the script while creating it.)
Run it in the container:
On bigbuddy:
docker run --rm --privileged -v ~/jetson-flash/work:/work:z -v ~/jetson-flash/prep_rootfs.sh:/prep.sh:ro,z jetson-flash:r36.4.3 bash /prep.sh 2>&1 | tail -25
Check
From the log (17:11:04); the output was cut off after the.sshlisting:ssh-keygen: generating new host keys: RSA DSA ECDSA ED25519 == verify burgerbarn:x:1000:1000::/home/burgerbarn:/bin/bash uid=1000(burgerbarn) gid=1000(burgerbarn) groups=1000(burgerbarn),4(adm),20(dialout),27(sudo),29(audio),44(video),104(render),996(weston-launch) rosorin etc/ssh/ssh_host_dsa_key.pub etc/ssh/ssh_host_ecdsa_key.pub etc/ssh/ssh_host_ed25519_key.pub etc/ssh/ssh_host_rsa_key.pub PasswordAuthentication no KbdInteractiveAuthentication no PermitRootLogin no ls: cannot access 'etc/systemd/system/default.target': No such file or directoryThe
No such file or directoryline is the success case: the wizard link is gone. Expectsshd config OKas
the last line.
The new host keys are made inside the container, so their comment is the container's hostname, not rosorin. On
the robot later: 256 SHA256:Kijh1+qj+MvcpH3FFvPX8TCsUwDDY5yPvl8VYrz4Xzc root@17a580ed7a62 (ED25519) (log
2026-09-27 23:13). That is expected.
SSH uses only your key, so the password is not for logging in over the network. You need it for sudo until
chapter 6 makes sudo passwordless, and for a local console. On first boot sudo asked for it
(a password is required, robot sudo log 2026-09-26 18:46:27).
The owner set it himself with passwd, run through chroot on the staged rootfs inside the container (memory
note 2026-09-26 17:12: "set by user via chroot passwd"). Choose your own password; it is never written in this guide
or in the repo.
The exact command line is not in the record
The line the owner typed was not logged. The check below is the logged command and shows that the container plus
chrootreaches the rootfs'spasswdprogram. To set the password, the same command needspasswdwith the user
name instead ofpasswd -S, and an interactive terminal for the prompt (docker run -it). That combination was
not logged.
On bigbuddy:
docker run --rm -v /home/burgerbarn/jetson-flash/work:/work:z jetson-flash:r36.4.3 chroot /work/Linux_for_Tegra/rootfs passwd -S burgerbarn; cat /home/burgerbarn/jetson-flash/work/Linux_for_Tegra/rootfs/etc/fstab
Check
From the log (17:15:58).Pmeans a usable password is set (Lwould be locked,NPnone):burgerbarn P 09/26/2026 0 99999 7 -1 # /etc/fstab: static file system information. ... /dev/root / ext4 defaults 0 1The rootfs
fstabmounts only/dev/root. The kernel finds the real root partition from its command line,
which you write in chapter 5.
Chapter 5 copies this tree to the robot and compares counts. Record them now:
On bigbuddy:
docker run --rm -v /home/burgerbarn/jetson-flash/work:/work:z jetson-flash:r36.4.3 bash -c "cd /work/Linux_for_Tegra/rootfs && echo files \$(find . -xdev \\( -type f -o -type l \\) | wc -l) dirs \$(find . -xdev -type d | wc -l)"
docker run --rm -v /home/burgerbarn/jetson-flash/work:/work:z jetson-flash:r36.4.3 bash -c "find /work/Linux_for_Tegra/rootfs -xdev -type f -printf \"%s\n\" | awk \"{s+=\\\$1} END {printf \\\"%.0f\\n\\\", s}\""
Check
On this build (log 17:16:24 and 18:36:31):files 188110 dirs 18751 7689137900188,110 files and links, 18,751 folders, 7,689,137,900 bytes in regular files. Your numbers will differ if
you changed anything; what matters is that chapter 5's copy matches your numbers.
If it fails
The byte total must be printed withprintf "%.0f". On 2026-09-26 anawkthat printed with%dgave
2147483647(the largest 32-bit number) instead of the total, and one with plain7.68914e+09.
Nothing in the staged rootfs drives Wi-Fi on this robot: the sample rootfs has only the rtl8822ce driver, not the
rtw89 driver the robot's Realtek RTL8852CE card needs. A build of rtw89 inside the rootfs on bigbuddy was tried
on 2026-09-26 and never ran. The robot comes up on Ethernet first; chapter 7 adds Wi-Fi on the robot itself.
bzip2 -t and their SHA-256 sums match the values above.docker images jetson-flash lists jetson-flash:r36.4.3.~/jetson-flash/prep.log ends with Success! and PREP_DONE.uid=1000(burgerbarn) with dialout among the groups, four host keys, and nodefault.target; authorized_keys holds your laptop key.passwd -S burgerbarn in the rootfs prints P.Where this comes from
Command logcmdlog_bigbuddy.md2026-09-26: 16:14:08 (host check), 16:15:48 / 16:16:09 / 16:16:30 (download,
sizes, SHA-256), 16:19:30 (container), 16:19:57 and 16:21:21 (extract,apply_binaries.sh, prep.log),
16:48:44 / 16:48:53 (kde-inhibit), 17:05:10 / 17:05:35 (root-owned files, binfmt flags), 17:09:50 (oem-config
link), 17:11:04 (prep_rootfs.shand its run), 17:15:06 (stray/Usersfolder), 17:15:58 (passwd -S),
17:16:24 and 18:36:31 (counts); robot 16:19:00 (factorynv_boot_control.conf). Repo:
scripts/container/Dockerfile,scripts/prep_rootfs.sh,docs/decisions.md2026-09-26 (useradd instead of
NVIDIA's script, in-place install),docs/lessons.md"Rebuild (2026-09-26)" (quoting~, bigbuddy suspend,
nvautoconfig, mke2fs versions),docs/status.md"Done (verified)" (BSP, container, staged rootfs),
docs/hardware.md"Compute".AGENTS.md(bigbuddy's fish shell). NVIDIA
Linux_for_Tegra/tools/kernel_flash/README_initrd_flash.txt(Requirements).