Preparing headless SD card for Raspberry Pi Zero 2 W without Raspberry Pi Imager

Intro

Recently I bought Raspberry Pi Zero 2 W for my electric car project:

It is very neat board with a good pricing. As I am lazy I didn’t even wanted to connect keyboard and HDMI (or UART) – I just wanted to be able to connect to it remotely using ssh. It was all, what I needed. I thought that preparing an official SD card with Raspberry Pi OS for headless boot will be piece of cake.
Oh… I was wrong ๐Ÿ™‚

TL;DR

This article is about manually preparing a headless SD card image. If you’re not familiar with below stuff/commands I recommend to use a tool called Raspberry Pi Imager (read last paragraph below).

Current state

I know that this article may be outdated soon as Raspberry are changing software (and distros regularly), so I only want to say that the following tutorial was written 27.02.2024 and the version/sha of the Raspberry Pi OS which I am referring to (and downloaded) is:

9ce5e2c8c6c7637cd2227fdaaf0e34633e6ebedf05f1c88e00f833cbb644db4b 2023-12-11-raspios-bookworm-arm64-lite.img.xz

Release date: December 5th 2023

Preparing SD card

Saving an image was the easiest part: I’ve fetched the official Raspberry Pi OS Lite from official site, checked the SHA256 checksum and dd it on SD card.

Then I followed some tutorials and yt films. As the result I mounted the boot partition, and created an empty ssh file on it. This should enable automatic start of the ssh service. I also added specially crafted wpa_supplicant.conf with my WiFi settings.

SSH and WiFi connection

As according to the tutorials that was all, so I unmounted the card and booted the Pi. Unfortunately looking inside my Access Point, I didn’t see any connection attempts at all.
I’ve re-plugged the card back to my computer and I saw that the file ssh is gone (this is OK – and just means that it enabled the ssh), but the wpa_supplicant.conf file was still there…

And here starts the long story about inserting the SD into computer, trying some additional changes (like a country setting), putting it back into Pi, waiting, and so on, and so on…

Finally when I was damn sure that the wpa_supplicant.conf should be OK i just used this file in the laptop and … it was working fine!

This leads me to googling more … and I finally found this thread. My problem was that the tutorials was outdated (for the previous bullseye release, while I have bookworm). As the result, I realized that instead of wpa_supplicant I have to create a NetworkManager WiFi profile file (sic!).

I’ve created the file with the following content:

[connection]
id=MYSSID
uuid=11111111-2222-3333-4444-555555555555
type=wifi
interface-name=wlan0
autoconnect=true

[wifi]
mode=infrastructure
ssid=MYSSID

[wifi-security]
auth-alg=open
key-mgmt=wpa-psk
psk=MYWIFIPASSWORD

[ipv4]
method=auto

[ipv6]
method=auto

UUID is just unique ID and should be generated from some wide-available generators (or just leaved as above if you’re lazy ๐Ÿ˜‰ ).

The file needs to be named same as the SSID of the network (following above: MYSSID.nmconnection) and placed in: /etc/NetworkManager/system-connections of the system partition. Additionally it has to be chmod-ed to 600 and owned by root.

But this was not enough! I had to create a firstrun.sh file, place it in /boot/firmware of the system partition (the second one with the system, not boot) and make it executable (+x).
The file has the following contents:

#!/bin/bash
# Stripped back version of the Bookworm firstrun.sh generated by the Raspberry Pi Imager
# also calls raspi-config to set Wifi country, which in turn calls iw on Bookworm
set +e
rfkill unblock wifi
for filename in /var/lib/systemd/rfkill/*:wlan ; do
    echo 0 > $filename
done
raspi-config nonint do_wifi_country GB
# edited to remove a bug in rpi-imager that is a hangover from Bullseye
# rm -f /boot/firstrun.sh
rm -f /boot/firmware/firstrun.sh
exit 0

Without this file the WiFi will not start/work (tested ;))

After all these above steps, I was finally able to see a new connection on the AP and a new DHCP entry on the server! ๐Ÿ™‚

So I was good to go. Work done! Now I was able to log in with SSH and wide-known user pi and password raspberry, right? ๐Ÿ™‚
Not so fast… ๐Ÿ˜€

User

It quickly turned out, that similar as with changing the wpa_supplicant to NetworkManager, the bookworm also got rid the default pi user. If I want to create specific user (side note: which I wanted because I forgot, that I could just add the public key and not messing with this, but this is another story), I had to create it with special file. Shorting the article:

[…] create a file called userconf or userconf.txt in the boot partition of the SD card
This file should contain a single line of text, consisting of username:encrypted-password

Password can be generated with:
echo 'mypassword' | openssl passwd -6 -stdin

After this, a user was created indeed and finally I was able to remotely login via SSH!

The easy way

At the end I have to mention that if you use Raspberry Pi Imager then all this stuff can be configured with this tool. But this is a GUI tool (QT if I remember correctly) and of course it has to be installed separately.

Comments

  1. Try dietpi.
    Image the sd.
    Edit the dietpi.txt file on the imaged SD.
    Edit the dietpi-wifi.txt on the SD.
    Eject the SD.
    Pop it in your pi.
    Boot.
    If you connecting your hdmi you can monitor the results. Otherwise just wait.

  2. hi! BIG THANKS for this tutorial !!
    After 30 browser tabs finally a well explained and working way !
    (tested with pi4B+latest bookwork&desktop 64bit)

Leave a Reply

Your email address will not be published. Required fields are marked *