組み込みProgrammerのチラシの裏

Install Raspberry Pi 3 #3-1

| Comments

SDカードにssh, userconf.txtのファイルを書き込むとHeadlessでインストール可能。 この仕組みをどうやって実現しているのか確認した。

  • Raspberry : Raspberry pi 3 2023-10-10(bookworm)
  • 環境 : Mac

ssh

sshファイルがあれば、sshdを有効化する。 起動時にsystemdからsshswitch.serviceが起動する。

/lib/systemd/system/sshswitch.service

1
2
3
  5 [Service]
  6 Type=oneshot
  7 ExecStart=/usr/lib/raspberrypi-sys-mods/sshswitch

ここで、sshswitchを実行する。

/usr/lib/raspberrypi-sys-mods/sshswitch

1
2
3
4
5
6
7
8
9
10
 10 FOUND=0
 11 for file in "$FWLOC/ssh" "$FWLOC/ssh.txt"; do
 12   [ -e "$file" ] || continue
 13   FOUND=1
 14   rm -f "$file"
 15 done
 16
 17 if [ "$FOUND" = "1" ]; then
 18   systemctl enable --now --no-block ssh
 19 fi

SDカードにssh(ssh.txtでも動きそう)がある場合、sshを有効化していた。

wpa_supplicant.conf

bookworm以降のRaspberry piでは、wpa_supplicantを使用しなくなった。 しかし、SDカードのwpa_supplicant.confをコピーする処理は残っていた。

起動時にsystemdからraspberrypi-net-mods.serviceが起動する。

/lib/systemd/system/raspberrypi-net-mods.service

1
2
3
4
  7 [Service]
  8 Type=oneshot
  9 RemainAfterExit=yes
 10 ExecStart=/usr/lib/raspberrypi-net-mods/wpa_copy

ここで、wpa_copyを実行する。

/usr/lib/raspberrypi-net-mods/wpa_copy

1
2
3
4
5
6
7
  1 #!/bin/sh
  2
  3 mv /boot/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant.conf
  4 chmod 600 /etc/wpa_supplicant/wpa_supplicant.conf
  5 REGDOMAIN=$(sed -n 's/^\s*country=\(..\)$/\1/p' /etc/wpa_supplicant/wpa_supplicant.conf)
  6 [ -n "$REGDOMAIN" ] && raspi-config nonint do_wifi_country "$REGDOMAIN"
  7 raspi-config nonint do_netconf 1

SDカードにwpa_supplicant.confがある場合、コピーし、raspi-configで設定していた。

userconf

起動時にsystemdからuserconfig.serviceが起動する。

/lib/systemd/system/userconfig.service

1
2
3
  5 [Service]
  6 Type=oneshot
  7 ExecStart=/usr/lib/userconf-pi/userconf-service

ここで、userconf-serviceを実行する。

/usr/lib/userconf-pi/userconf-service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 41 for BOOT_CONF_FILE in "$FWLOC/userconf" "$FWLOC/userconf.txt"; do
 42     if [ ! -f "$BOOT_CONF_FILE" ]; then
 43         continue
 44     fi
 45     LINE="$(head -n1 "$BOOT_CONF_FILE" | dos2unix)"
 46     NEW_USER="$(echo "$LINE" | cut -f1 -d:)"
 47     NEW_PASS="$(echo "$LINE" | cut -f2 -d:)"
 56 done
...
 58 if [ "$INTERACTIVE" = "True" ]; then
107 elif [ -n "$NEW_USER" ] && [ -n "$NEW_PASS" ]; then
108     /usr/lib/userconf-pi/userconf "$NEW_USER" "$NEW_PASS"
109     rm "$BOOT_CONF_FILE"
110 fi
111
112 rm -f "$FWLOC/failed_userconf" "$FWLOC/failed_userconf.txt"

SDカードにuserconf(userconf.txtでも動きそう)がある場合、ユーザー・パスワードを読み取り、userconfを実行。

/usr/lib/userconf-pi/userconf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
  3 rename_user () {
  4     usermod -l "$NEWNAME" "$FIRSTUSER"
  5     usermod -m -d "/home/$NEWNAME" "$NEWNAME"
  6     groupmod -n "$NEWNAME" "$FIRSTGROUP"
  7     for file in /etc/subuid /etc/subgid; do
  8         sed -i "s/^$FIRSTUSER:/$NEWNAME:/" "$file"
  9     done
 10     if [ -f /etc/sudoers.d/010_pi-nopasswd ]; then
 11         sed -i "s/^$FIRSTUSER /$NEWNAME /" /etc/sudoers.d/010_pi-nopasswd
 12     fi
 13 }
...
 15 if [ $# -eq 3 ]; then
 19 else
 20     FIRSTUSER="$(getent passwd 1000 | cut -d: -f1)"
 21     FIRSTGROUP="$(getent group 1000 | cut -d: -f1)"
 22 fi
 23
 24 NEWNAME=$1
 25 NEWPASS=$2
 26
 27 if [ "$FIRSTUSER" != "$NEWNAME" ]; then
 28     rename_user
 29 fi

ユーザー・パスワードからusermod,groupmodなどを駆使し、uid=1000,gid=1000のユーザーを作成していた。

Comments