はじめに
久々に RPI OS のインストールをしようとしたところ,Bookworm 以降 wpa_supplicant.conf による wifi 設定ができない仕様になったらしい.これまで rpi-imager を使わずに headless setup していたので困った.
インターネット上にはあまりまとまった情報が見当たらなかったが,rpi-imager を使えば実現できているようだったので,今回は最新の trixie と rpi-imager での実装方法を整理しておく.
rpi-imager での headless setup の実装方法
先にざっくりと概要だけ書いておくと,初期設定スクリプト firstrun.sh を cmdline.txt で呼び出すことで,ユーザやWIFI等の初期設定を実現している.
以下実装の詳細.
cmdline.txt
bootfs$ cat cmdline.txt
console=serial0,115200 console=tty1 root=PARTUUID=13e740f8-02 rootfstype=ext4 fsck.repair=yes rootwait resize quiet splash plymouth.ignore-serial-consoles cfg80211.ieee80211_regdom=JP systemd.run=/boot/firstrun.sh systemd.run_success_action=reboot systemd.unit=kernel-command-line.target- cfg80211.ieee80211_regdom=JP
- WIFIの規制ドメインに JP を指定
- systemd.run=/boot/firstrun.sh
- TransientUnit として firstrun.sh を実行
- systemd.run_success_action=reboot
- firstrun.sh が成功したら再起動
- systemd.unit=kernel-command-line.target
- systemd のターゲットとして kernel-command-line.target を指定
firstrun.sh(全量)
以下は初期化処理の全量.私の環境固有値は変数 ${xxx} として伏せておく.
このスクリプトをベースを参考すればオリジナルの初期化処理も簡単に書けそう.
bootfs$ cat firstrun.sh
#!/bin/bash
set +e
CURRENT_HOSTNAME=`cat /etc/hostname | tr -d " \t\n\r"`
if [ -f /usr/lib/raspberrypi-sys-mods/imager_custom ]; then
/usr/lib/raspberrypi-sys-mods/imager_custom set_hostname raspberrypi
else
echo raspberrypi >/etc/hostname
sed -i "s/127.0.1.1.*$CURRENT_HOSTNAME/127.0.1.1\traspberrypi/g" /etc/hosts
fi
FIRSTUSER=`getent passwd 1000 | cut -d: -f1`
FIRSTUSERHOME=`getent passwd 1000 | cut -d: -f6`
if [ -f /usr/lib/raspberrypi-sys-mods/imager_custom ]; then
/usr/lib/raspberrypi-sys-mods/imager_custom enable_ssh
else
systemctl enable ssh
fi
if [ -f /usr/lib/userconf-pi/userconf ]; then
/usr/lib/userconf-pi/userconf '${USER}' '${PASSWD}'
else
echo "$FIRSTUSER:"'${PASSWD}' | chpasswd -e
if [ "$FIRSTUSER" != "${USER}" ]; then
usermod -l "${USER}" "$FIRSTUSER"
usermod -m -d "/home/${USER}" "${USER}"
groupmod -n "${USER}" "$FIRSTUSER"
if grep -q "^autologin-user=" /etc/lightdm/lightdm.conf ; then
sed /etc/lightdm/lightdm.conf -i -e "s/^autologin-user=.*/autologin-user=${USER}/"
fi
if [ -f /etc/systemd/system/getty@tty1.service.d/autologin.conf ]; then
sed /etc/systemd/system/getty@tty1.service.d/autologin.conf -i -e "s/$FIRSTUSER/${USER}/"
fi
if [ -f /etc/sudoers.d/010_pi-nopasswd ]; then
sed -i "s/^$FIRSTUSER /${USER} /" /etc/sudoers.d/010_pi-nopasswd
fi
fi
fi
if [ -f /usr/lib/raspberrypi-sys-mods/imager_custom ]; then
/usr/lib/raspberrypi-sys-mods/imager_custom set_wlan '${WIFI_SSID}' '${WIFI_PASSWD}' '${WIFI_COUNTRY}'
else
cat >/etc/wpa_supplicant/wpa_supplicant.conf <<'WPAEOF'
country=${WIFI_COUNTRY}
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
ap_scan=1
update_config=1
network={
ssid="${WIFI_SSID}"
psk=${WIFI_PASSWD}
}
WPAEOF
chmod 600 /etc/wpa_supplicant/wpa_supplicant.conf
rfkill unblock wifi
for filename in /var/lib/systemd/rfkill/*:wlan ; do
echo 0 > $filename
done
fi
if [ -f /usr/lib/raspberrypi-sys-mods/imager_custom ]; then
/usr/lib/raspberrypi-sys-mods/imager_custom set_keymap 'us'
/usr/lib/raspberrypi-sys-mods/imager_custom set_timezone 'Asia/Tokyo'
else
rm -f /etc/localtime
echo "Asia/Tokyo" >/etc/timezone
dpkg-reconfigure -f noninteractive tzdata
cat >/etc/default/keyboard <<'KBEOF'
XKBMODEL="pc105"
XKBLAYOUT="us"
XKBVARIANT=""
XKBOPTIONS=""
KBEOF
dpkg-reconfigure -f noninteractive keyboard-configuration
fi
rm -f /boot/firstrun.sh
sed -i 's| systemd.run.*||g' /boot/cmdline.txt
exit 0ホスト名設定
CURRENT_HOSTNAME=`cat /etc/hostname | tr -d " \t\n\r"`
if [ -f /usr/lib/raspberrypi-sys-mods/imager_custom ]; then
/usr/lib/raspberrypi-sys-mods/imager_custom set_hostname raspberrypi
else
echo raspberrypi >/etc/hostname
sed -i "s/127.0.1.1.*$CURRENT_HOSTNAME/127.0.1.1\traspberrypi/g" /etc/hosts
fiSSH有効化
if [ -f /usr/lib/raspberrypi-sys-mods/imager_custom ]; then
/usr/lib/raspberrypi-sys-mods/imager_custom enable_ssh
else
systemctl enable ssh
fiユーザ&GUログインマネージャ(lightdm)&コンソール(getty)の設定
FIRSTUSER=`getent passwd 1000 | cut -d: -f1`
FIRSTUSERHOME=`getent passwd 1000 | cut -d: -f6`
if [ -f /usr/lib/userconf-pi/userconf ]; then
/usr/lib/userconf-pi/userconf '${USER}' '${PASSWD}'
else
echo "$FIRSTUSER:"'${PASSWD}' | chpasswd -e
if [ "$FIRSTUSER" != "${USER}" ]; then
usermod -l "${USER}" "$FIRSTUSER"
usermod -m -d "/home/${USER}" "${USER}"
groupmod -n "${USER}" "$FIRSTUSER"
if grep -q "^autologin-user=" /etc/lightdm/lightdm.conf ; then
sed /etc/lightdm/lightdm.conf -i -e "s/^autologin-user=.*/autologin-user=${USER}/"
fi
if [ -f /etc/systemd/system/getty@tty1.service.d/autologin.conf ]; then
sed /etc/systemd/system/getty@tty1.service.d/autologin.conf -i -e "s/$FIRSTUSER/${USER}/"
fi
if [ -f /etc/sudoers.d/010_pi-nopasswd ]; then
sed -i "s/^$FIRSTUSER /${USER} /" /etc/sudoers.d/010_pi-nopasswd
fi
fi
fiWi-Fi設定
if [ -f /usr/lib/raspberrypi-sys-mods/imager_custom ]; then
/usr/lib/raspberrypi-sys-mods/imager_custom set_wlan '${WIFI_SSID}' '${WIFI_PASSWD}' '${WIFI_COUNTRY}'
else
cat >/etc/wpa_supplicant/wpa_supplicant.conf <<'WPAEOF'
country=${WIFI_COUNTRY}
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
ap_scan=1
update_config=1
network={
ssid="${WIFI_SSID}"
psk=${WIFI_PASSWD}
}
WPAEOF
chmod 600 /etc/wpa_supplicant/wpa_supplicant.conf
rfkill unblock wifi
for filename in /var/lib/systemd/rfkill/*:wlan ; do
echo 0 > $filename
done
fiキーボードレイアウト&タイムゾーン設定
if [ -f /usr/lib/raspberrypi-sys-mods/imager_custom ]; then
/usr/lib/raspberrypi-sys-mods/imager_custom set_keymap 'us'
/usr/lib/raspberrypi-sys-mods/imager_custom set_timezone 'Asia/Tokyo'
else
rm -f /etc/localtime
echo "Asia/Tokyo" >/etc/timezone
dpkg-reconfigure -f noninteractive tzdata
cat >/etc/default/keyboard <<'KBEOF'
XKBMODEL="pc105"
XKBLAYOUT="us"
XKBVARIANT=""
XKBOPTIONS=""
KBEOF
dpkg-reconfigure -f noninteractive keyboard-configuration
fi終了処理
rm -f /boot/firstrun.sh
sed -i 's| systemd.run.*||g' /boot/cmdline.txt
exit 0firstrun.sh 自身の削除,cmdline.txt からの呼び出し部分 system.run を削除して,初回起動時のみこの処理が行われるようにする.
exit 0 で処理が正常終了すると cmdline.txt の systemd.run_success_action=reboot により再起動が実行される.
おわりに
更に詳しい実装を知りたい人は rpi-imager や imager_custom のソースを読んでどうぞ.
GitHub - raspberrypi/rpi-imager: The home of Raspberry Pi Imager, a user-friendly tool for creating bootable media for Raspberry Pi devices.
The home of Raspberry Pi Imager, a user-friendly tool for creating bootable media for Raspberry Pi devices. - raspberryp...

コメント