Raspberry Pi OS (Debian bookworm 12)のインストールを、Raspberry Pi Imagerと、OSイメージファイルのSDカード直接書き込みで「処理の中身」がどう違うのか考察してみた。
OSのバージョンアップにより、2018年5月に書いた『 Raspberry Pi Zero Wの初期設定(Wifi/SSH有効化, /tmpと/var/logのRAM Disk化, 基本ツール類インストールほか) 』と現在の方法では、Wifi設定で劇的な変更点がある。
OSインストールの2種類の方法
Raspberry Pi Imager を使う場合
Raspberry Pi Imager
Raspberry Pi Imagerを利用すると、セットアップ時に「ユーザ名・パスワード、SSHサーバの有効化、Wifi SSIDとパスワード」などの個別設定を行うことができる。
この個別設定情報は、初回起動時に bootパーティション(bootfs)のfirstrun.shという設定ファイルから読み込まれる。
OSイメージファイルのSDカード直接書き込みする場合
公式サイトより 2024-03-15-raspios-bookworm-armhf-lite.img.xz のようなイメージファイルをダウンロードする。
Ubuntuの場合xz形式で圧縮されたファイルをダブルクリックすると、このような手動書き込みダイアログが表示される。
Ubuntu標準機能を使ってイメージファイルをSDメモリーカードに直接書き込み
もしくは、xz圧縮を展開して次のようにSDメモリーカードに直接書き込む。
$ sudo dd bs=4M if=2024-03-15-raspios-bookworm-armhf-lite.img of=/dev/sdb
OSバージョンアップによるWifi設定方法の劇的な変化
かつては、bootパーティションにwpa_supplicant.confファイルを作成すれば、初回起動時に認識され/etc/wpa_supplicant/wpa_supplicant.confにコピーされていた。
現在は、Network Managerに対応した方法でないと認識されなくなった。
Raspberry Pi OSのRelease notesで変更点を追ってみると次のようになっていた。
- 2023-10-10
- Based on Debian bookworm
- NetworkManager used instead of dhcpcd as networking interface; various changes made to networking plugin to support this
- 2022-09-06:
- raspi-config - option to switch between dhcpcd and Network Manager added
- 2021-10-30:
- Based on Debian version 11 (bullseye)
- 2019-06-20:
- Based on Debian Buster
- 2017-08-16:
- Based on Raspbian Stretch (Debian version 9)
- Based on Raspbian Stretch (Debian version 9)
今後の予想として、現在はbootパーティションに空の(長さゼロの)sshというファイルがあれば、初回起動時にsshdサービスが有効化されるのだが、この機能も除去されるかもしれない。
Raspberry Pi Imagerで作成される自動セットアップファイルを解析してみた
/etc/fstabの設定により、bootパーティション(bootfs)は、rootパーティション(rootfs)の /boot ディレクトリにマウントされる。
rootfs:/etc/fstab
proc /proc proc defaults 0 0 PARTUUID=6b2ecde3-01 /boot vfat defaults 0 2 ← bootパーティション(bootfs) PARTUUID=6b2ecde3-02 / ext4 defaults,noatime 0 1 ← rootパーティション(rootfs)
/bootにマウントされるbootパーティション(bootfs)のファイル一覧をここで見ておく。セットアップ時に重要なファイルはcmdline.txt と firstrun.sh の2つ。
また、ファイル config.txt は初回起動時に /boot/firmware/ ディレクトリにコピーされる。
$ ls -la /boot 合計 50512 drwxr-xr-x 3 vm vm 4096 1970-01-01 09:00:00 ./ drwxr-x---+ 4 root root 4096 2024-04-23 16:06:50 ../ -rw-r--r-- 1 vm vm 18693 2023-04-05 11:32:16 COPYING.linux -rw-r--r-- 1 vm vm 1594 2023-04-05 11:32:16 LICENCE.broadcom -rw-r--r-- 1 vm vm 28822 2023-04-05 11:32:16 bcm2708-rpi-b-plus.dtb -rw-r--r-- 1 vm vm 28182 2023-04-05 11:32:16 bcm2708-rpi-b-rev1.dtb -rw-r--r-- 1 vm vm 28503 2023-04-05 11:32:16 bcm2708-rpi-b.dtb -rw-r--r-- 1 vm vm 28246 2023-04-05 11:32:16 bcm2708-rpi-cm.dtb -rw-r--r-- 1 vm vm 29539 2023-04-05 11:32:16 bcm2708-rpi-zero-w.dtb -rw-r--r-- 1 vm vm 28128 2023-04-05 11:32:16 bcm2708-rpi-zero.dtb 〜 省略 〜 -rw-r--r-- 1 vm vm 53202 2023-04-05 11:32:16 bcm2711-rpi-cm4.dtb -rw-r--r-- 1 vm vm 50504 2023-04-05 11:32:16 bcm2711-rpi-cm4s.dtb -rw-r--r-- 1 vm vm 52476 2023-04-05 11:32:16 bootcode.bin -rw-r--r-- 1 vm vm 286 2024-04-23 13:35:16 cmdline.txt -rw-r--r-- 1 vm vm 2075 2024-03-12 01:06:00 config.txt -rw-r--r-- 1 vm vm 2332 2024-04-23 13:35:16 firstrun.sh -rw-r--r-- 1 vm vm 7266 2023-04-05 11:32:16 fixup.dat -rw-r--r-- 1 vm vm 5399 2023-04-05 11:32:16 fixup4.dat 〜 省略 〜 -rw-r--r-- 1 vm vm 805756 2023-04-05 11:32:16 start_cd.elf -rw-r--r-- 1 vm vm 4819624 2023-04-05 11:32:16 start_db.elf -rw-r--r-- 1 vm vm 3722504 2023-04-05 11:32:16 start_x.elf
rootパーティション(rootfs)では、/usr/lib/raspberrypi-sys-mods ディレクトリなどには、この後に使われる各種ファイルも格納されているので、ここでその一覧を見ておく。重要そうなファイル行は赤着色している。
$ ls -la /usr/lib/raspberrypi-sys-mods 合計 40 drwxr-xr-x 2 root root 4096 2024-03-12 10:06:41 ./ drwxr-xr-x 66 root root 4096 2024-03-12 10:07:19 ../ -rwxr-xr-x 1 root root 7020 2023-05-10 15:00:36 firstboot* -rwxr-xr-x 1 root root 419 2022-01-06 17:45:24 i2cprobe* -rwxr-xr-x 1 root root 6370 2023-05-10 15:37:04 imager_custom* -rwxr-xr-x 1 root root 7243 2023-05-10 15:00:36 init_config* -rwxr-xr-x 1 root root 210 2023-05-10 15:00:36 regenerate_ssh_host_keys* $ ls -la /usr/lib/raspberrypi-net-mods 合計 12 drwxr-xr-x 2 root root 4096 2024-03-12 10:07:19 ./ drwxr-xr-x 66 root root 4096 2024-03-12 10:07:19 ../ -rwxr-xr-x 1 root root 324 2022-08-08 19:20:23 wpa_copy* $ ls -la /usr/lib/userconf-pi 合計 16 drwxr-xr-x 2 root root 4096 2024-03-12 10:06:42 ./ drwxr-xr-x 66 root root 4096 2024-03-12 10:07:19 ../ -rwxr-xr-x 1 root root 768 2022-03-21 20:38:07 userconf* -rwxr-xr-x 1 root root 3408 2022-06-19 05:23:53 userconf-service*
(Raspberry Pi Imager) カーネルパラメータの設定からfirstbootスクリプトが呼び出される
Linux起動時に使われるカーネルパラメータは、/boot/cmdline.txt ファイルに記載されている。(カーネルパラメータの書式については、Debianの「bootparam - Linux カーネル起動時パラメーター」ドキュメントに詳述されている)
/boot/cmdline.txt (カーネルパラメータ)
console=serial0,115200 console=tty1 root=PARTUUID=6b2ecde3-02 rootfstype=ext4 fsck.repair=yes rootwait quiet init=/usr/lib/raspberrypi-sys-mods/firstboot cfg80211.ieee80211_regdom=JP systemd.run=/boot/firstrun.sh systemd.run_success_action=reboot systemd.unit=kernel-command-line.target
着色部分のinit設定により、/usr/lib/raspberrypi-sys-mods/firstboot が初期コマンドとして実行される。
また、この部分はfirstbootスクリプトが一度実行された後、次の記述により自動削除される。
/usr/lib/raspberrypi-sys-mods/firstboot より抜粋
sed -i 's| init=/usr/lib/raspberrypi-sys-mods/firstboot||' "$FWLOC/cmdline.txt"
(Raspberry Pi Imager) カーネルパラメータの設定からfirstrun.shスクリプトが呼び出される
/boot/cmdline.txt ファイルに記載されているカーネルパラメータのsystemdのコマンドラインにより、/boot/firstrun.sh が実行される。(systemdのコマンドラインについては、Debianの「systemd : Kernel command line parameters」ドキュメントに詳述されている)
/boot/cmdline.txt (カーネルパラメータ)
console=serial0,115200 console=tty1 root=PARTUUID=6b2ecde3-02 rootfstype=ext4 fsck.repair=yes rootwait quiet init=/usr/lib/raspberrypi-sys-mods/firstboot cfg80211.ieee80211_regdom=JP systemd.run=/boot/firstrun.sh systemd.run_success_action=reboot systemd.unit=kernel-command-line.target
また、この部分はfirstrun.shが一度実行された後、次の記述により自動削除される。そして、firstrun.sh ファイルも自己削除される。
/boot/firstrun.sh より最後の3行を抜粋
rm -f /boot/firstrun.sh sed -i 's| systemd.run.*||g' /boot/cmdline.txt exit 0
(Raspberry Pi Imager) firstrun.shスクリプトで行われること
大まかな概要として、次のような処理が行われている。
- sshd の有効化
- /usr/lib/raspberrypi-sys-mods/imager_custom ファイルが存在すれば、それが実行される。
その中で systemd enable sshd が実行される。 - 存在しない場合は systemd enable sshd が実行される。
- /usr/lib/raspberrypi-sys-mods/imager_custom ファイルが存在すれば、それが実行される。
- Wifi 接続の設定
- /usr/lib/raspberrypi-sys-mods/imager ファイルが存在すれば、それが実行される。
その中で /etc/wpa_supplicant/wpa_supplicant.conf が作成される。 - 存在しない場合は /etc/wpa_supplicant/wpa_supplicant.conf が作成される。
- /usr/lib/raspberrypi-sys-mods/imager ファイルが存在すれば、それが実行される。
-
ユーザ名・パスワードの変更
- /usr/lib/userconf-pi/userconf ファイルが存在すれば、その中で
- 存在しない場合は firstrun.sh 内で同様の処理を行う
これらの処理について、詳細にスクリプトを読んで以下に記載してみる。
(Raspberry Pi Imager) SSH接続の有効化方法を詳しく見てみる
bootパーティション(bootfs)に空の(長さゼロの)sshというファイルを作るのではなく、firstrun.sh で実行されることをなぞってみる。
/boot/firstrun.sh より該当箇所
if [ -f /usr/lib/raspberrypi-sys-mods/imager_custom ]; then ← この判定式はTRUE(imager_customファイルが存在するため) /usr/lib/raspberrypi-sys-mods/imager_custom enable_ssh ← この行が実行される else systemctl enable ssh fi
/usr/lib/raspberrypi-sys-mods/imager_custom より該当箇所
enable_ssh () ( ENABLE=1 KEY_ONLY_SED_STR='s/^[#\s]*PasswordAuthentication\s\+\S\+$/PasswordAuthentication no/' PASSAUTH_SED_STR='s/^[#\s]*PasswordAuthentication\s\+\S\+$/PasswordAuthentication yes/' for arg in "$@"; do ← 引数なしなので、このループは飛ばされる if [ "$arg" = "-k" ] || [ "$arg" = "--key-only" ]; then sed -i "$KEY_ONLY_SED_STR" /etc/ssh/sshd_config elif [ "$arg" = "-p" ] || [ "$arg" = "--pass-auth" ]; then sed -i "$PASSAUTH_SED_STR" /etc/ssh/sshd_config elif [ "$arg" = "-d" ] || [ "$arg" = "--disabled" ]; then ENABLE=0 else add_ssh_keys "$arg" fi done if [ "$ENABLE" = 1 ]; then systemctl -q enable ssh ← この行が実行される fi )
(Raspberry Pi Imager) Wifi接続の設定方法を詳しく見てみる
/boot/firstrun.sh よりWifi接続設定の該当箇所
if [ -f /usr/lib/raspberrypi-sys-mods/imager_custom ]; then ← この判定式はTRUE(imager_customファイルが存在するため) /usr/lib/raspberrypi-sys-mods/imager_custom set_wlan 'SSID_TEST' '0c1faf2119bbafcaa4cbd97ba674727951b3ae958317178e4655fa1298a3b24c' 'JP' ← この行が実行される else ← この行より下は実行されない(かつてのwpa_supplicant.confが作成されるスクリプト) cat >/etc/wpa_supplicant/wpa_supplicant.conf <<'WPAEOF' country=JP ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev ap_scan=1 update_config=1 network={ ssid="SSID_TEST" psk=0c1faf2119bbafcaa4cbd97ba674727951b3ae958317178e4655fa1298a3b24c } 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
firstrun.shから呼び出されるimager_customスクリプトから、核心部を抜粋してみる。
/usr/lib/raspberrypi-sys-mods/imager_custom よりWifi接続設定の該当箇所
set_wlan () ( HIDDEN=0 PLAIN=0 SCRIPT='/var/lib/raspberrypi-sys-mods/set-wlan' ← 新規作成されるスクリプトのフルパス名 for arg in "$@"; do # shellcheck disable=SC2031 if [ "$arg" = "-h" ] || [ "$arg" = "--hidden" ]; then HIDDEN=1 elif [ "$arg" = "-p" ] || [ "$arg" = "--plain" ]; then PLAIN=1 elif [ -z "${SSID+set}" ]; then SSID="$arg" elif [ -z "${PASS+set}" ]; then PASS="$arg" elif [ -z "${COUNTRY+set}" ]; then COUNTRY="$arg" else usage set_wlan exit 1 fi done if [ -z "${SSID+set}" ]; then usage set_wlan exit 1 fi if [ -e /boot/wpa_supplicant.conf ]; then echo "Ignoring network configuration: /boot/wpa_supplicant.conf exists" exit 0 fi if [ -n "$COUNTRY" ]; then set_wlan_country "$COUNTRY" fi # Replace ' with '\'' in SSID and PASS to support single-quote characters SSID=$(printf '%s' "$SSID" | sed "s/'/'\\\\''/g") PASS=$(printf '%s' "$PASS" | sed "s/'/'\\\\''/g") mkdir -p "$(dirname "$SCRIPT")" # shellcheck disable=SC2094 cat <<- EOF > "$SCRIPT" ← 新規作成されるスクリプトの内容はここから下 #!/bin/sh COUNTER=0 while [ "\$COUNTER" -lt 10 ]; do COUNTER=\$((COUNTER + 1)) if raspi-config nonint do_wifi_ssid_passphrase '$SSID' '$PASS' '$HIDDEN' '$PLAIN'; then break fi sleep 5 done systemctl stop set-wlan.timer systemctl disable set-wlan.timer rm -f "\$0" rm -f /etc/systemd/system/set-wlan.timer rm -f /etc/systemd/system/set-wlan.service rmdir --ignore-fail-on-non-empty '$(dirname "$SCRIPT")' EOF chmod 700 "$SCRIPT" cat <<- EOF > /etc/systemd/system/set-wlan.timer ← このファイルも新規作成される [Unit] Description=Configure WLAN for rpi-imager [Timer] OnBootSec=1 OnUnitActiveSec=10 [Install] WantedBy=timers.target EOF cat <<- EOF > /etc/systemd/system/set-wlan.service ← このファイルも新規作成される [Unit] Description=Configure WLAN for rpi-imager After=NetworkManager.service dhcpcd.service ConditionPathIsDirectory=|/run/wpa_supplicant ConditionPathExists=|/run/dhcpcd.pid [Service] Type=oneshot ExecStart=$SCRIPT EOF ln -f -s /etc/systemd/system/set-wlan.timer \ /etc/systemd/system/timers.target.wants/set-wlan.timer )
/var/lib/raspberrypi-sys-mods/set-wlan スクリプトファイルが新規作成され、このスクリプトはsystemd から起動される set-wlan.service で呼び出される。
そして、set-wlanから/usr/bin/raspi-configスクリプトが呼び出される。その中で、NetworkManagerのnmcliコマンドでWifi接続が行われる。
/usr/bin/raspi-config よりWifi接続設定の該当箇所
do_wifi_ssid_passphrase() { RET=0 if [ "$INTERACTIVE" = True ] && [ -z "$(get_wifi_country)" ]; then do_wifi_country fi 〜 省略 〜 if systemctl -q is-active dhcpcd; then ← 現在のRPi OSはdhcpcdではないので、このifセクションはFALSEとなる wpa_cli -i "$IFACE" list_networks \ 〜 省略 〜 else if [ "$HIDDEN" -ne 0 ]; then nmcli device wifi connect "$SSID" password "$PASSPHRASE" hidden true | grep -q "activated" else nmcli device wifi connect "$SSID" password "$PASSPHRASE" | grep -q "activated" fi RET=$((RET + $?)) fi return "$RET" }
/etc/NetworkManager/system-connections/ ディレクトリにキーファイルを作成するなら、次のようなコマンドを使うべきだが...
nmcli connection add con-name コネクション名 ifname wlp2s0 type wifi ssid SSID名 nmcli connection modify コネクション名 wifi-sec.key-mgmt wpa-psk nmcli connection modify コネクション名 wifi-sec.psk パスワード nmcli connection modify コネクション名 connection.autoconnect yes
毎回、nmcliコマンドを直接叩くというのは、どうなんだろう。
(Raspberry Pi Imager) ユーザ名・パスワード設定方法を詳しく見てみる
/boot/firstrun.sh より抜粋
if [ -f /usr/lib/userconf-pi/userconf ]; then ← userconfファイルが存在するため、ここはTRUEとなる /usr/lib/userconf-pi/userconf 'pi' '$5$nI92OMl4c.CLlr5D$3t8fHwPV3R0.DyayqWgz.n8HTc.UE6MQTRWZL1ufVW2' else echo "$FIRSTUSER:"'$5$nI92OMl4c.CLlr5D$3t8fHwPV3R0.DyayqWgz.n8HTc.UE6MQTRWZL1ufVW2' | chpasswd -e if [ "$FIRSTUSER" != "pi" ]; then usermod -l "pi" "$FIRSTUSER" usermod -m -d "/home/pi" "pi" groupmod -n "pi" "$FIRSTUSER" if grep -q "^autologin-user=" /etc/lightdm/lightdm.conf ; then sed /etc/lightdm/lightdm.conf -i -e "s/^autologin-user=.*/autologin-user=pi/" 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/pi/" fi if [ -f /etc/sudoers.d/010_pi-nopasswd ]; then sed -i "s/^$FIRSTUSER /pi /" /etc/sudoers.d/010_pi-nopasswd fi fi fi
/usr/lib/userconf-pi/userconf
#!/bin/sh rename_user () { usermod -l "$NEWNAME" "$FIRSTUSER" usermod -m -d "/home/$NEWNAME" "$NEWNAME" groupmod -n "$NEWNAME" "$FIRSTGROUP" for file in /etc/subuid /etc/subgid; do sed -i "s/^$FIRSTUSER:/$NEWNAME:/" "$file" done if [ -f /etc/sudoers.d/010_pi-nopasswd ]; then sed -i "s/^$FIRSTUSER /$NEWNAME /" /etc/sudoers.d/010_pi-nopasswd fi } if [ $# -eq 3 ]; then ← 引数はユーザ名・パスワードの2個なので、ここはFALSEとなる FIRSTUSER="$1" FIRSTGROUP="$1" shift else FIRSTUSER="$(getent passwd 1000 | cut -d: -f1)" ← ビルトインではなく作成されたUID先頭1000のユーザ名 FIRSTGROUP="$(getent group 1000 | cut -d: -f1)" ← ビルトインではなく作成されたUID先頭1000のグループ名 fi NEWNAME=$1 NEWPASS=$2 if [ "$FIRSTUSER" != "$NEWNAME" ]; then rename_user fi if [ -n "$NEWPASS" ]; then echo "$NEWNAME:$NEWPASS" | chpasswd -e fi /usr/bin/cancel-rename "$NEWNAME"
また、sudoで全てのコマンドをパスワード無しで実行できる設定となっている。
/etc/sudoers.d/010_pi-nopasswd
pi ALL=(ALL) NOPASSWD: ALL
ちなみに/etc/passwdと/etc/groupの初期値は、$FIRSTUSER = "pi", $FIRSTGROUP = "pi" である。passwdの2番めのフィールドにパスワードではなく「x」のばあいは、shadowファイルにパスワードが記録されていることを示す。
/etc/passwd より抜粋
pi:x:1000:1000:,,,:/home/pi:/bin/bash
/etc/group より抜粋
pi:x:1000:
shadowの2番めのフィールドが「*」の場合は、パスワードが設定されておらず、このままではログオンできない。
/etc/shadow より抜粋
pi:*:19794:0:99999:7:::
OSイメージファイルのSDカード直接書き込みで作成される自動セットアップファイルを解析してみた
今回解析したのは 2024-03-15-raspios-bookworm-armhf-lite.img.xz
/etc/fstabの設定により、bootパーティション(bootfs)は、rootパーティション(rootfs)の /boot ディレクトリにマウントされる。
/etc/fstab
proc /proc proc defaults 0 0 PARTUUID=662b4900-01 /boot/firmware vfat defaults 0 2 PARTUUID=662b4900-02 / ext4 defaults,noatime 0 1
bootパーティション(bootfs)に含まれるファイルは次のようになっていて、firstrun.sh が存在しないなど、Raspberry Pi Imagerの場合とかなり違う。
ソースコード
$ ls -la /boot 合計 95036 drwxr-xr-x 3 vm vm 6144 1970-01-01 09:00:00 ./ drwxr-x---+ 4 root root 4096 2024-05-01 11:29:15 ../ -rw-r--r-- 1 vm vm 1594 2024-03-15 14:59:32 LICENCE.broadcom -rw-r--r-- 1 vm vm 29578 2024-03-07 14:51:30 bcm2708-rpi-b-plus.dtb -rw-r--r-- 1 vm vm 28937 2024-03-07 14:51:30 bcm2708-rpi-b-rev1.dtb -rw-r--r-- 1 vm vm 29275 2024-03-07 14:51:30 bcm2708-rpi-b.dtb -rw-r--r-- 1 vm vm 29018 2024-03-07 14:51:30 bcm2708-rpi-cm.dtb -rw-r--r-- 1 vm vm 30755 2024-03-07 14:51:30 bcm2708-rpi-zero-w.dtb 〜 省略 〜 -rw-r--r-- 1 vm vm 77691 2024-03-07 14:51:30 bcm2712-rpi-cm5-cm5io.dtb -rw-r--r-- 1 vm vm 77739 2024-03-07 14:51:30 bcm2712d0-rpi-5-b.dtb -rw-r--r-- 1 vm vm 52476 2024-03-15 14:59:34 bootcode.bin -rw-r--r-- 1 vm vm 154 2024-03-15 15:06:52 cmdline.txt -rw-r--r-- 1 vm vm 1179 2024-03-15 14:59:38 config.txt -rw-r--r-- 1 vm vm 7303 2024-03-15 14:59:34 fixup.dat -rw-r--r-- 1 vm vm 5434 2024-03-15 14:59:34 fixup4.dat 〜 省略 〜 -rw-r--r-- 1 vm vm 4825352 2024-03-15 14:59:34 start_db.elf -rw-r--r-- 1 vm vm 3727656 2024-03-15 14:59:34 start_x.elf
rootパーティション(rootfs)では、/usr/lib/raspberrypi-sys-mods ディレクトリなどには、この後に使われる各種ファイルも格納されているので、ここでその一覧を見ておく。重要そうなファイル行は赤着色している。
Raspberry Pi Imagerの場合とファイルの中身が違うものも多い。
$ ls -la /usr/lib/raspberrypi-sys-mods 合計 44 drwxr-xr-x 2 root root 4096 2024-03-16 00:00:17 ./ drwxr-xr-x 65 root root 4096 2024-03-16 00:00:46 ../ -rwxr-xr-x 1 root root 3227 2023-11-07 00:03:19 firstboot* -rwxr-xr-x 1 root root 445 2023-12-18 19:51:31 get_fw_loc* -rwxr-xr-x 1 root root 419 2022-01-06 17:45:24 i2cprobe* -rwxr-xr-x 1 root root 5486 2023-11-07 18:30:53 imager_custom* -rwxr-xr-x 1 root root 7319 2023-07-26 00:09:46 init_config* -rwxr-xr-x 1 root root 117 2023-08-31 20:35:11 regenerate_ssh_host_keys* -rwxr-xr-x 1 root root 339 2023-07-26 00:09:46 sshswitch* $ ls -la /usr/lib/userconf-pi 合計 16 drwxr-xr-x 2 root root 4096 2024-03-16 00:00:20 ./ drwxr-xr-x 65 root root 4096 2024-03-16 00:00:46 ../ -rwxr-xr-x 1 root root 768 2022-03-21 20:38:07 userconf* -rwxr-xr-x 1 root root 3521 2023-08-30 03:09:11 userconf-service*
(OSイメージファイル) カーネルパラメータの設定からfirstbootスクリプトが呼び出される
カーネルパラメータは前述した「Raspberry Pi Imager」の場合より大幅に少なく、firstrun.shスクリプトの実行が含まれていない。
/boot/cmdline.txt
console=serial0,115200 console=tty1 root=PARTUUID=662b4900-02 rootfstype=ext4 fsck.repair=yes rootwait quiet init=/usr/lib/raspberrypi-sys-mods/firstboot
カーネルパラメータのinitプロセス設定より、firstboot が実行される。
また、この部分はfirstbootが一度実行された後、次の記述により自動削除される。
/usr/lib/raspberrypi-sys-mods/firstboot より抜粋
sed -i 's| init=/usr/lib/raspberrypi-sys-mods/firstboot||' "$FWLOC/cmdline.txt"
(OSイメージファイル) firstbootスクリプトで行われること
/boot/custom.toml ファイルに記述された「設定情報」を、/usr/lib/raspberrypi-sys-mods/init_config スクリプトに引き渡すのが、firstbootの主な役割。
なお、「OSイメージファイル」には/boot/custom.tomlは含まれていないので、初回起動時までに新たに作成して/bootディレクトリに保存しておくこと。
/usr/lib/raspberrypi-sys-mods/firstboot より抜粋
〜 省略 〜 apply_custom () { CONFIG_FILE="$1" mount -o remount,rw / mount -o remount,rw "$FWLOC" if ! python3 -c "import toml" 2> /dev/null; then FAIL_REASON="custom.toml provided, but python3-toml is not installed\n$FAIL_REASON" else set -o pipefail /usr/lib/raspberrypi-sys-mods/init_config "$CONFIG_FILE" |& tee /run/firstboot.log | while read -r line; do MSG="$MSG\n$line" whiptail --infobox "$MSG" 20 60 done if [ "$?" -ne 0 ]; then mv /run/firstboot.log /var/log/firstboot.log FAIL_REASON="Failed to apply customisations from custom.toml\n\nLog file saved as /var/log/firstboot.log\n$FAIL_REASON" fi set +o pipefail fi rm -f "$CONFIG_FILE" mount -o remount,ro "$FWLOC" mount -o remount,ro / } main () { get_variables whiptail --infobox "Generating SSH keys..." 20 60 regenerate_ssh_host_keys if [ -f "$FWLOC/custom.toml" ]; then MSG="Applying customisations from custom.toml...\n" whiptail --infobox "$MSG" 20 60 apply_custom "$FWLOC/custom.toml" fi whiptail --infobox "Fix PARTUUID..." 20 60 fix_partuuid return 0 } 〜 省略 〜 main 〜 省略 〜
新規作成する custom.toml ファイルの書式例は次のようなものらしい(ここを参考にした)
/boot/custom.toml
config_version = 1 [system] hostname = "raspberrypi" [user] # If present, the default "rpi" user gets renamed to this "name" name = "rpi" # The password can be encrypted or plain. To encrypt, we can use "openssl passwd -5 raspberry" password = "$5$pN7oRnie.WDOHoJY$aWEYmKUytN/S/bxMza5ksBiurbSJmcvcysBKHSmYa45" password_encrypted = true [ssh] # ssh_import_id = "gh:user" # import public keys from github enabled = true password_authentication = false # We can also seed the ssh public keys configured for the default user: # authorized_keys = [ "ssh-rsa ... user@host", ... ] [wlan] ssid = "mywifi" password = "$5$pN7oRnie.WDOHoJY$aWEYmKUytN/S/bxMza5ksBiurbSJmcvcysBKHSmYa45" password_encrypted = true hidden = false # The country is written to /etc/default/crda # Reference: https://wireless.wiki.kernel.org/en/developers/Regulatory country = "JP" [locale] keymap = "jp" timezone = "Asia/Tokyo"
init_configスクリプトでは、custom.tomlの変数をセクションごとに取り出して、セクションごとの関数に渡し、その関数からimager_customスクリプトに変数を引き渡している。
/usr/lib/raspberrypi-sys-mods/init_config より抜粋
〜 省略 〜 imager_custom_path = os.path.join('/', 'usr', 'lib', 'raspberrypi-sys-mods', 'imager_custom') 〜 省略 〜 def config_ssh (ssh_config): ← 例として、ssh設定の関数を抜粋してみた if not ssh_config: return ssh_import_id = ssh_config.pop("ssh_import_id", None) import_ssh_id(ssh_import_id) cmd = (imager_custom_path, "enable_ssh") ssh_enabled = ssh_config.pop("enabled", False) ssh_password_authentication = ssh_config.pop("password_authentication", None) ssh_authorized_keys = ssh_config.pop("authorized_keys", []) if not ssh_enabled: cmd = cmd + ('-d',) if ssh_password_authentication is not None: cmd = cmd + ('-p' if ssh_password_authentication else '-k',) cmd = cmd + tuple(ssh_authorized_keys) try: subprocess.run(cmd, encoding='UTF-8', check=True) logging.info ("Configured SSH") 〜 省略 〜 try: config = toml.load(args.toml_file) ← tomlファイルを解析し、データをconfigディクショナリに格納する except toml.decoder.TomlDecodeError as err: logging.error ("Error parsing %s: %s", args.toml_file, err) sys.exit(1) 〜 省略 〜 supported_sections = ("system", "user", "ssh", "wlan", "locale") for s in supported_sections: section_config = config.pop(s, {}) ← tomlデータを格納したディクショナリconfigから、指定したセクション名 s のものを抽出 locals()[f"config_{s}"](section_config) ← 指定したセクション名の関数 (例:config_system)を実行する for key in section_config: logging.warning("Unknown key in [%s]: %s", s, key) 〜 省略 〜
(OSイメージファイル) SSH接続の有効化方法を詳しく見てみる
bootパーティション(bootfs)に空の(長さゼロの)sshというファイルを作るのではなく、imager_customスクリプト で実行されることをなぞってみる。
一つ前のセクションでinit_configスクリプトまで読み解いたが、init_configスクリプトの
subprocess.run("/usr/lib/raspberrypi-sys-mods/imager_custom enable_ssh", encoding='UTF-8', check=True)
によって処理がimager_customスクリプトに移る。そして、imager_customの中で次のようにsystemdでsshサービスを有効化している。
systemctl -q enable ssh
/usr/lib/raspberrypi-sys-mods/imager_custom から抜粋
〜 省略 〜 enable_ssh () ( ENABLE=1 KEY_ONLY_SED_STR='s/^[#\s]*PasswordAuthentication\s\+\S\+$/PasswordAuthentication no/' PASSAUTH_SED_STR='s/^[#\s]*PasswordAuthentication\s\+\S\+$/PasswordAuthentication yes/' for arg in "$@"; do if [ "$arg" = "-k" ] || [ "$arg" = "--key-only" ]; then sed -i "$KEY_ONLY_SED_STR" /etc/ssh/sshd_config elif [ "$arg" = "-p" ] || [ "$arg" = "--pass-auth" ]; then sed -i "$PASSAUTH_SED_STR" /etc/ssh/sshd_config elif [ "$arg" = "-d" ] || [ "$arg" = "--disabled" ]; then ENABLE=0 else add_ssh_keys "$arg" fi done if [ "$ENABLE" = 1 ]; then systemctl -q enable ssh fi ) 〜 省略 〜 command="$1"; shift case "$command" in set_hostname|import_ssh_id|enable_ssh|set_wlan_country|set_wlan|set_keymap|set_timezone) "$command" "$@" ;; *) echo "Unsupported command: $command" usage exit 1 ;; esac
(OSイメージファイル) Wifi接続の設定方法を詳しく見てみる
一つ前のセクションで読み解いたSSH有効化のときと同じく、init_configスクリプトからimager_customが呼び出される。
次に示すように、nmcli コマンドを使う正攻法ではなく、/etc/NetworkManager/system-connections/ ディレクトリにキーファイルを直接作成する方法が取られている。
/usr/lib/raspberrypi-sys-mods/imager_custom から抜粋
〜 省略 〜 set_wlan () ( HIDDEN="false" PLAIN=0 for arg in "$@"; do # shellcheck disable=SC2031 if [ "$arg" = "-h" ] || [ "$arg" = "--hidden" ]; then HIDDEN="true" elif [ "$arg" = "-p" ] || [ "$arg" = "--plain" ]; then PLAIN=1 elif [ -z "${SSID+set}" ]; then SSID="$arg" elif [ -z "${PASS+set}" ]; then PASS="$arg" elif [ -z "${COUNTRY+set}" ]; then COUNTRY="$arg" else usage set_wlan exit 1 fi done if [ -z "${SSID+set}" ]; then usage set_wlan exit 1 fi if [ -n "$COUNTRY" ]; then set_wlan_country "$COUNTRY" fi CONNFILE=/etc/NetworkManager/system-connections/preconfigured.nmconnection UUID=$(uuid -v4) cat <<- EOF >${CONNFILE} [connection] id=preconfigured uuid=${UUID} type=wifi [wifi] mode=infrastructure ssid=${SSID} hidden=${HIDDEN} [ipv4] method=auto [ipv6] addr-gen-mode=default method=auto [proxy] EOF if [ ! -z "${PASS}" ]; then cat <<- EOF >>${CONNFILE} [wifi-security] key-mgmt=wpa-psk psk=${PASS} EOF fi # NetworkManager will ignore nmconnection files with incorrect permissions, # to prevent Wi-Fi credentials accidentally being world-readable. chmod 600 ${CONNFILE} ) 〜 省略 〜
(OSイメージファイル) ユーザ名・パスワード設定方法を詳しく見てみる
init_configスクリプトの処理の流れを見ていくと、赤字のところが主な処理内容で、userconfスクリプトに「ユーザ名」「SHA512化したパスワード」を引き渡している。
/usr/lib/raspberrypi-sys-mods/init_config より抜粋
def config_user(user_config): name = user_config.pop("name", None) password = user_config.pop("password", None) is_encrypted = user_config.pop("password_encrypted", True) rename_user(name, password, is_encrypted) userconf_path = os.path.join('/', 'usr', 'lib', 'userconf-pi', 'userconf') def rename_user(name, password, is_encrypted=True): 〜 省略 〜 elif not is_encrypted: password = crypt.crypt(password, crypt.mksalt(crypt.METHOD_SHA512)) try: cmd = (userconf_path, name, password) subprocess.run(cmd, encoding='UTF-8', check=True)そして、userconfスクリプトでは、システムに登録された「最初のユーザ」(UID=1000)を変更すしている。
/usr/lib/userconf-pi/userconf
if [ $# -eq 3 ]; then FIRSTUSER="$1" FIRSTGROUP="$1" shift else ← 引数はnew_user,new_passwordの2個なので、こちらが実行される FIRSTUSER="$(getent passwd 1000 | cut -d: -f1)" ← UID=1000のユーザ名 FIRSTGROUP="$(getent group 1000 | cut -d: -f1)" ← GID=1000のグループ名 fi NEWNAME=$1 NEWPASS=$2 if [ "$FIRSTUSER" != "$NEWNAME" ]; then ← ユーザ名に変更があるなら、rename_user 関数に移る rename_user fi if [ -n "$NEWPASS" ]; then ← $NEWPASSが0文字以上なら、パスワード変更する echo "$NEWNAME:$NEWPASS" | chpasswd -e fi rename_user () { usermod -l "$NEWNAME" "$FIRSTUSER" ← 既存のユーザ名を、新しいユーザ名に変更 usermod -m -d "/home/$NEWNAME" "$NEWNAME" groupmod -n "$NEWNAME" "$FIRSTGROUP" for file in /etc/subuid /etc/subgid; do sed -i "s/^$FIRSTUSER:/$NEWNAME:/" "$file" done if [ -f /etc/sudoers.d/010_pi-nopasswd ]; then sed -i "s/^$FIRSTUSER /$NEWNAME /" /etc/sudoers.d/010_pi-nopasswd fi }
ちなみに/etc/passwdと/etc/groupの初期値は、$FIRSTUSER = "pi", $FIRSTGROUP = "pi" である。また、/etc/shadowの2番めのフィールドがパスワードロックの "!" となっている。
/etc/passwd
pi:x:1000:1000:,,,:/home/pi:/bin/bash
/etc/group
pi:x:1000:
/etc/shadow
pi:!:19797:0:99999:7:::
(OSイメージファイル) custom.toml ファイルを作成し自動セットアップしてみた
OSイメージファイルをSDカードに書き込み、bootパーティション(bootfs)に次の内容の custom.toml ファイルを新規作成保存した。
/boot/custom.toml
config_version = 1 [system] hostname = "raspberrypi" [user] # If present, the default "rpi" user gets renamed to this "name" name = "pi" # The password can be encrypted or plain. To encrypt, we can use "openssl passwd -5 raspberry" password = "●パスワードを平文で記入●" password_encrypted = false [ssh] # ssh_import_id = "gh:user" # import public keys from github enabled = true password_authentication = true # We can also seed the ssh public keys configured for the default user: # authorized_keys = [ "ssh-rsa ... user@host", ... ] [wlan] ssid = "●WifiルータのSSID名●" password = "●Wifiパスワードを平文で記入●" password_encrypted = false hidden = false # The country is written to /etc/default/crda # Reference: https://wireless.wiki.kernel.org/en/developers/Regulatory country = "JP" [locale] keymap = "jp" timezone = "Asia/Tokyo"
初回電源投入後、数回リブートを繰り返し、5分程度でWifi接続されsshdも稼働し正常起動した。
/bootディレクトリに置かれていた各種セットアップファイルが、正常起動後にどうなったか確認してみる
/boot 直下に置かれていた cmdline.txtとconfig.txt は、/boot/firmware ディレクトリに移動されるとともに、cmdline.txt から firstboot スクリプトを起動するカーネルパラメータのinit設定がなくなっている。
init設定がなくなったのは、正常にfirstbootスクリプトが処理終了し、自己削除したためだ。
$ ls -la /boot total 73274 drwxr-xr-x 3 root root 4096 Mar 16 00:07 . drwxr-xr-x 18 root root 4096 Mar 16 00:08 .. -rw-r--r-- 1 root root 92 Mar 15 23:59 cmdline.txt -rw-r--r-- 1 root root 204639 Mar 7 23:51 config-6.6.20+rpt-rpi-v6 -rw-r--r-- 1 root root 210131 Mar 7 23:51 config-6.6.20+rpt-rpi-v7 -rw-r--r-- 1 root root 227912 Mar 7 23:51 config-6.6.20+rpt-rpi-v7l -rw-r--r-- 1 root root 236765 Mar 7 23:51 config-6.6.20+rpt-rpi-v8 -rw-r--r-- 1 root root 91 Mar 15 23:59 config.txt drwxr-xr-x 3 root root 6144 Jan 1 1970 firmware -rw-r--r-- 1 root root 10446553 Mar 16 00:06 initrd.img-6.6.20+rpt-rpi-v6 -rw-r--r-- 1 root root 10595497 Mar 16 00:07 initrd.img-6.6.20+rpt-rpi-v7 -rw-r--r-- 1 root root 10693834 Mar 16 00:07 initrd.img-6.6.20+rpt-rpi-v7l -rw-r--r-- 1 root root 10578299 Mar 16 00:07 initrd.img-6.6.20+rpt-rpi-v8 lrwxrwxrwx 1 root root 18 Mar 16 00:07 issue.txt -> firmware/issue.txt lrwxrwxrwx 1 root root 17 Mar 15 23:59 overlays -> firmware/overlays -rw-r--r-- 1 root root 83 Mar 7 23:51 System.map-6.6.20+rpt-rpi-v6 -rw-r--r-- 1 root root 83 Mar 7 23:51 System.map-6.6.20+rpt-rpi-v7 -rw-r--r-- 1 root root 83 Mar 7 23:51 System.map-6.6.20+rpt-rpi-v7l -rw-r--r-- 1 root root 83 Mar 7 23:51 System.map-6.6.20+rpt-rpi-v8 -rw-r--r-- 1 root root 7091784 Mar 7 23:51 vmlinuz-6.6.20+rpt-rpi-v6 -rw-r--r-- 1 root root 7427672 Mar 7 23:51 vmlinuz-6.6.20+rpt-rpi-v7 -rw-r--r-- 1 root root 7853280 Mar 7 23:51 vmlinuz-6.6.20+rpt-rpi-v7l -rw-r--r-- 1 root root 9259827 Mar 7 23:51 vmlinuz-6.6.20+rpt-rpi-v8 $ ls -la /boot/firmware/ total 95036 drwxr-xr-x 3 root root 6144 Jan 1 1970 . drwxr-xr-x 3 root root 4096 Mar 16 00:07 .. -rwxr-xr-x 1 root root 29275 Mar 7 23:51 bcm2708-rpi-b.dtb -rwxr-xr-x 1 root root 29578 Mar 7 23:51 bcm2708-rpi-b-plus.dtb -rwxr-xr-x 1 root root 28937 Mar 7 23:51 bcm2708-rpi-b-rev1.dtb -rwxr-xr-x 1 root root 29018 Mar 7 23:51 bcm2708-rpi-cm.dtb -rwxr-xr-x 1 root root 28888 Mar 7 23:51 bcm2708-rpi-zero.dtb -rwxr-xr-x 1 root root 30755 Mar 7 23:51 bcm2708-rpi-zero-w.dtb -rwxr-xr-x 1 root root 31272 Mar 7 23:51 bcm2709-rpi-2-b.dtb -rwxr-xr-x 1 root root 31195 Mar 7 23:51 bcm2709-rpi-cm2.dtb -rwxr-xr-x 1 root root 31401 Mar 7 23:51 bcm2710-rpi-2-b.dtb -rwxr-xr-x 1 root root 33593 Mar 7 23:51 bcm2710-rpi-3-b.dtb -rwxr-xr-x 1 root root 34228 Mar 7 23:51 bcm2710-rpi-3-b-plus.dtb -rwxr-xr-x 1 root root 31312 Mar 7 23:51 bcm2710-rpi-cm3.dtb -rwxr-xr-x 1 root root 32570 Mar 7 23:51 bcm2710-rpi-zero-2.dtb -rwxr-xr-x 1 root root 32570 Mar 7 23:51 bcm2710-rpi-zero-2-w.dtb -rwxr-xr-x 1 root root 54813 Mar 7 23:51 bcm2711-rpi-400.dtb -rwxr-xr-x 1 root root 54809 Mar 7 23:51 bcm2711-rpi-4-b.dtb -rwxr-xr-x 1 root root 55449 Mar 7 23:51 bcm2711-rpi-cm4.dtb -rwxr-xr-x 1 root root 38349 Mar 7 23:51 bcm2711-rpi-cm4-io.dtb -rwxr-xr-x 1 root root 52228 Mar 7 23:51 bcm2711-rpi-cm4s.dtb -rwxr-xr-x 1 root root 77739 Mar 7 23:51 bcm2712d0-rpi-5-b.dtb -rwxr-xr-x 1 root root 77755 Mar 7 23:51 bcm2712-rpi-5-b.dtb -rwxr-xr-x 1 root root 77699 Mar 7 23:51 bcm2712-rpi-cm5-cm4io.dtb -rwxr-xr-x 1 root root 77691 Mar 7 23:51 bcm2712-rpi-cm5-cm5io.dtb -rwxr-xr-x 1 root root 52476 Mar 15 23:59 bootcode.bin -rwxr-xr-x 1 root root 132 Jan 1 1980 cmdline.txt -rwxr-xr-x 1 root root 1179 Mar 15 23:59 config.txt -rwxr-xr-x 1 root root 3204 Mar 15 23:59 fixup4cd.dat -rwxr-xr-x 1 root root 5434 Mar 15 23:59 fixup4.dat -rwxr-xr-x 1 root root 8423 Mar 15 23:59 fixup4db.dat -rwxr-xr-x 1 root root 8425 Mar 15 23:59 fixup4x.dat -rwxr-xr-x 1 root root 3204 Mar 15 23:59 fixup_cd.dat -rwxr-xr-x 1 root root 7303 Mar 15 23:59 fixup.dat -rwxr-xr-x 1 root root 10268 Mar 15 23:59 fixup_db.dat -rwxr-xr-x 1 root root 10268 Mar 15 23:59 fixup_x.dat -rwxr-xr-x 1 root root 10446553 Mar 16 00:07 initramfs -rwxr-xr-x 1 root root 10595497 Mar 16 00:07 initramfs7 -rwxr-xr-x 1 root root 10693834 Mar 16 00:07 initramfs7l -rwxr-xr-x 1 root root 10578299 Mar 16 00:07 initramfs8 -rwxr-xr-x 1 root root 145 Mar 16 00:07 issue.txt -rwxr-xr-x 1 root root 7427672 Mar 15 23:59 kernel7.img -rwxr-xr-x 1 root root 7853280 Mar 15 23:59 kernel7l.img -rwxr-xr-x 1 root root 9259827 Mar 15 23:59 kernel8.img -rwxr-xr-x 1 root root 7091784 Mar 15 23:59 kernel.img -rwxr-xr-x 1 root root 1594 Mar 15 23:59 LICENCE.broadcom drwxr-xr-x 2 root root 28672 Mar 15 23:59 overlays -rwxr-xr-x 1 root root 808892 Mar 15 23:59 start4cd.elf -rwxr-xr-x 1 root root 3753480 Mar 15 23:59 start4db.elf -rwxr-xr-x 1 root root 2256224 Mar 15 23:59 start4.elf -rwxr-xr-x 1 root root 3004040 Mar 15 23:59 start4x.elf -rwxr-xr-x 1 root root 808892 Mar 15 23:59 start_cd.elf -rwxr-xr-x 1 root root 4825352 Mar 15 23:59 start_db.elf -rwxr-xr-x 1 root root 2980544 Mar 15 23:59 start.elf -rwxr-xr-x 1 root root 3727656 Mar 15 23:59 start_x.elf
メモリー、ディスク、サービスの一覧は
ソースコード
$ free -h -t total used free shared buff/cache available Mem: 427Mi 91Mi 295Mi 948Ki 88Mi 336Mi Swap: 99Mi 0B 99Mi Total: 527Mi 91Mi 395Mi $ df -h Filesystem Size Used Avail Use% Mounted on udev 81M 0 81M 0% /dev tmpfs 43M 940K 42M 3% /run /dev/mmcblk0p2 3.0G 1.7G 1.2G 59% / tmpfs 214M 0 214M 0% /dev/shm tmpfs 5.0M 8.0K 5.0M 1% /run/lock /dev/mmcblk0p1 510M 95M 416M 19% /boot/firmware tmpfs 43M 0 43M 0% /run/user/1000 $ sudo systemctl list-unit-files -t service | grep -e enabled alsa-utils.service masked enabled apparmor.service enabled enabled avahi-daemon.service enabled enabled bluetooth.service enabled enabled console-setup.service enabled enabled cron.service enabled enabled cryptdisks-early.service masked enabled cryptdisks.service masked enabled dphys-swapfile.service enabled enabled e2scrub_reap.service enabled enabled fake-hwclock.service enabled enabled getty@.service enabled enabled hciuart.service enabled enabled hwclock.service masked enabled ifupdown-wait-online.service disabled enabled keyboard-setup.service enabled enabled ModemManager.service enabled enabled networking.service enabled enabled NetworkManager-dispatcher.service enabled enabled NetworkManager-wait-online.service enabled enabled NetworkManager.service enabled enabled nfs-common.service masked enabled nftables.service disabled enabled paxctld.service disabled enabled pigpiod.service disabled enabled rc-local.service enabled-runtime enabled rc.service masked enabled rcS.service masked enabled regenerate_ssh_host_keys.service disabled enabled rpcbind.service disabled enabled rpi-display-backlight.service enabled enabled rpi-eeprom-update.service enabled enabled rsync.service disabled enabled serial-getty@.service disabled enabled ssh.service enabled enabled sshswitch.service enabled enabled sudo.service masked enabled systemd-fsck-root.service enabled-runtime enabled systemd-network-generator.service disabled enabled systemd-networkd-wait-online@.service disabled enabled systemd-networkd.service disabled enabled systemd-pstore.service enabled enabled systemd-remount-fs.service enabled-runtime enabled systemd-sysext.service disabled enabled systemd-timesyncd.service enabled enabled triggerhappy.service enabled enabled udisks2.service enabled enabled userconfig.service disabled enabled wpa_supplicant-nl80211@.service disabled enabled wpa_supplicant-wired@.service disabled enabled wpa_supplicant.service enabled enabled wpa_supplicant@.service disabled enabled x11-common.service masked enabled
完全手動設定で、SSHとWifiを設定する方法
Raspberry Piを初回電源投入(起動)した後、Wifiやsshが動いていないことがわかった場合、ここで書く方法で「手動での有効化」を行うことができる。
SSHを有効化
cmdline.txtに黄色着色した部分を追加し、systemdのkernel-command-lineで実行するスクリプトファイルを指定する。(この作業をする前に、/boot/firstrun.sh ファイルが存在しないことを確認してから行うこと)
/boot/cmdline.txt に黄色着色部を追記する
console=serial0,115200 console=tty1 root=PARTUUID=6b2ecde3-02 rootfstype=ext4 fsck.repair=yes rootwait quiet systemd.run=/boot/firstrun.sh systemd.run_success_action=reboot systemd.unit=kernel-command-line.target
fstab設定によって/bootディレクトリにマウントされるbootパーティション(bootfs)に、firstrun.sh を次の内容で新規作成する。
/boot/firstrun.sh を新規作成する
#!/bin/bash systemctl -q enable ssh # 処理後に、追加した処理設定を削除する(または、この記載をなくして起動後に手動削除) rm -f /boot/firstrun.sh sed -i 's| systemd.run.*||g' /boot/cmdline.txt exit 0
Wifi接続を有効化
NetwormManagerのキーファイルを作成する。
/etc/NetworkManager/system-connections/SSID名.nmconnection
[connection] id=●SSID名称(キーファイルの拡張子除いたファイル名)● uuid=●自動生成したUUID● type=wifi [wifi] mode=infrastructure ssid=●SSID名● [wifi-security] key-mgmt=wpa-psk psk=●パスワード● [ipv4] method=auto [ipv6] addr-gen-mode=default method=auto [proxy]