0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ラズパイのconfigをImagerを使わずにやってみる

0
Posted at

みなさん、rpi-imagerを使ってラズパイにイメージを書いたことはありますか?
基本的にはこれ以外を選択する方が珍しいと思いますが、最近(バグなのか)ネットワークの設定やユーザーの設定が正常に書き込まれないため、手動でファイルシステムを書くことで様々な設定を実現したいと思います。

前提

Host machineがLinuxである想定で記事が書かれています。
Windowsだと、正常に動作しない可能性があります。

まずは

イメージをSDカードに書きます。
設定項目は「適用しない」で、完全にまっさらなものを書きます。

とりあえずScriptのヘルパーを定義

適切にパスや、ユーザー名、パスワード、ホスト名を書き換えましょう。

#!/bin/bash
set -e # Exit on error

# Configuration variables
PATH_TO_ROOTFS="${PATH_TO_ROOTFS:-/mnt/rootfs}"
PATH_TO_BOOTFS="${PATH_TO_BOOTFS:-/mnt/bootfs}"
USERNAME="${USERNAME:-raspi}"
PASSWORD="${PASSWORD:-raspberry}"
WIFI_SSID="${WIFI_SSID:-rotarymars}"
WIFI_PASSWORD="${WIFI_PASSWORD:-rotarymars1234}"
WIFI_COUNTRY="${WIFI_COUNTRY:-JP}"
PI_HOSTNAME="${PI_HOSTNAME:-raspberrypi}"

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# Helper functions
print_success() {
  echo -e "${GREEN}[✓]${NC} $1"
}

print_error() {
  echo -e "${RED}[✗]${NC} $1"
}

print_info() {
  echo -e "${YELLOW}[i]${NC} $1"
}

# Check if running as root
if [ "$EUID" -ne 0 ]; then
  print_error "This script must be run as root (use sudo)"
  exit 1
fi

# Check if paths exist
if [ ! -d "$PATH_TO_ROOTFS" ]; then
  print_error "Root filesystem not found at $PATH_TO_ROOTFS"
  exit 1
fi

if [ ! -d "$PATH_TO_BOOTFS" ]; then
  print_error "Boot filesystem not found at $PATH_TO_BOOTFS"
  exit 1
fi

print_info "Starting Raspberry Pi configuration..."
echo "Root FS: $PATH_TO_ROOTFS"
echo "Boot FS: $PATH_TO_BOOTFS"
echo "Hostname: $PI_HOSTNAME"
echo "Username: $USERNAME"
echo "WiFi SSID: $WIFI_SSID"
echo ""

ユーザーの設定

# ========================================
# 1. Configure User Account
# ========================================
print_info "Configuring user account: $USERNAME"

# Encrypt password
ENCRYPTED=$(openssl passwd -6 "$PASSWORD")

# Check if user already exists in passwd
if grep -q "^$USERNAME:" "${PATH_TO_ROOTFS}/etc/passwd" 2>/dev/null; then
  print_info "User $USERNAME already exists in passwd, skipping..."
else
  echo "$USERNAME:x:1001:1001:New User,,,:/home/$USERNAME:/bin/bash" >>"${PATH_TO_ROOTFS}/etc/passwd"
  print_success "Added user to /etc/passwd"
fi

# Check if user already exists in shadow
if grep -q "^$USERNAME:" "${PATH_TO_ROOTFS}/etc/shadow" 2>/dev/null; then
  print_info "User $USERNAME already exists in shadow, skipping..."
else
  echo "$USERNAME:$ENCRYPTED:19000:0:99999:7:::" >>"${PATH_TO_ROOTFS}/etc/shadow"
  print_success "Added user to /etc/shadow"
fi

# Check if group already exists
if grep -q "^$USERNAME:" "${PATH_TO_ROOTFS}/etc/group" 2>/dev/null; then
  print_info "Group $USERNAME already exists, skipping..."
else
  echo "$USERNAME:x:1001:" >>"${PATH_TO_ROOTFS}/etc/group"
  print_success "Added group to /etc/group"
fi

# Add to sudo group if not already there
if grep "^sudo:.*$USERNAME" "${PATH_TO_ROOTFS}/etc/group" >/dev/null 2>&1; then
  print_info "User already in sudo group, skipping..."
else
  sed -i "s/^\(sudo:x:27:.*\)/\1,$USERNAME/" "${PATH_TO_ROOTFS}/etc/group"
  print_success "Added user to sudo group"
fi

# Create home directory
if [ -d "${PATH_TO_ROOTFS}/home/$USERNAME" ]; then
  print_info "Home directory already exists, skipping..."
else
  mkdir -p "${PATH_TO_ROOTFS}/home/$USERNAME"
  cp -r "${PATH_TO_ROOTFS}/etc/skel/." "${PATH_TO_ROOTFS}/home/$USERNAME/" 2>/dev/null || true
  chown -R 1001:1001 "${PATH_TO_ROOTFS}/home/$USERNAME"
  chmod 700 "${PATH_TO_ROOTFS}/home/$USERNAME"
  print_success "Created home directory with proper permissions"
fi

RaspberrypiではDebianベースのOSを採用しており、上記のようにファイルに書き込みをしてあげるだけでユーザーを作成することができます。
このスクリプトでは自動的にsudoグループに追加されるので、気を付けてください。

ホスト名の設定

# ========================================
# 2. Configure Hostname
# ========================================
print_info "Setting hostname to '$PI_HOSTNAME'..."

# Set hostname in /etc/hostname
echo "$PI_HOSTNAME" > "${PATH_TO_ROOTFS}/etc/hostname"
print_success "Set hostname in /etc/hostname"

# Update /etc/hosts
if [ -f "${PATH_TO_ROOTFS}/etc/hosts" ]; then
    # Replace any existing 127.0.1.1 entry
    if grep -q "^127.0.1.1" "${PATH_TO_ROOTFS}/etc/hosts"; then
        sed -i "s/^127.0.1.1.*/127.0.1.1\t$PI_HOSTNAME/" "${PATH_TO_ROOTFS}/etc/hosts"
        print_success "Updated hostname in /etc/hosts"
    else
        # Add 127.0.1.1 entry if it doesn't exist
        echo -e "127.0.1.1\t$PI_HOSTNAME" >> "${PATH_TO_ROOTFS}/etc/hosts"
        print_success "Added hostname to /etc/hosts"
    fi
fi

/etc/hostsの中身を書き換えることで、ホスト名を変えることができます。

ホスト名とは、その危機に接続するための名前に相当します。たとえば、raspiという名前が設定されている場合は、raspi.localでIPを検索できるようになります。

WiFi設定

# ========================================
# 3. Configure WiFi
# ========================================
print_info "Configuring WiFi network: $WIFI_SSID"

# Method 1: wpa_supplicant.conf in boot (for older Raspberry Pi OS)
WPA_CONF="${PATH_TO_BOOTFS}/wpa_supplicant.conf"

# Create wpa_supplicant.conf (overwrite if exists)
cat >"$WPA_CONF" <<WPAEOF
country=$WIFI_COUNTRY
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

WPAEOF

# Generate and append the network configuration
wpa_passphrase "$WIFI_SSID" "$WIFI_PASSWORD" >> "$WPA_CONF"
chmod 600 "$WPA_CONF"
print_success "Created wpa_supplicant.conf in boot partition"

# Method 2: Configure in rootfs for newer systems
if [ -d "${PATH_TO_ROOTFS}/etc/wpa_supplicant" ]; then
    WPA_CONF_ROOTFS="${PATH_TO_ROOTFS}/etc/wpa_supplicant/wpa_supplicant.conf"
    cat >"$WPA_CONF_ROOTFS" <<WPAEOF
country=$WIFI_COUNTRY
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

WPAEOF
    wpa_passphrase "$WIFI_SSID" "$WIFI_PASSWORD" >> "$WPA_CONF_ROOTFS"
    chmod 600 "$WPA_CONF_ROOTFS"
    print_success "Created wpa_supplicant.conf in rootfs"
fi

# Method 3: NetworkManager configuration (for Raspberry Pi OS Bookworm and newer)
NM_DIR="${PATH_TO_ROOTFS}/etc/NetworkManager/system-connections"
if [ -d "${PATH_TO_ROOTFS}/etc/NetworkManager" ]; then
    mkdir -p "$NM_DIR"

    # Generate PSK hash for NetworkManager
    PSK=$(wpa_passphrase "$WIFI_SSID" "$WIFI_PASSWORD" | grep '^\spsk=' | cut -d= -f2)

    # Generate UUID (use uuidgen if available, otherwise create one)
    if command -v uuidgen &> /dev/null; then
        UUID=$(uuidgen)
    else
        UUID=$(cat /proc/sys/kernel/random/uuid 2>/dev/null || echo "$(date +%s)-$(shuf -i 1000-9999 -n 1)")
    fi

    cat >"${NM_DIR}/${WIFI_SSID}.nmconnection" <<NMEOF
[connection]
id=$WIFI_SSID
uuid=$UUID
type=wifi
autoconnect=true
autoconnect-priority=999

[wifi]
mode=infrastructure
ssid=$WIFI_SSID

[wifi-security]
key-mgmt=wpa-psk
psk=$PSK

[ipv4]
method=auto

[ipv6]
method=auto
addr-gen-mode=stable-privacy
NMEOF

    chmod 600 "${NM_DIR}/${WIFI_SSID}.nmconnection"
    print_success "Created NetworkManager connection"
fi
# Method 4: dhcpcd configuration (for additional compatibility)
if [ -f "${PATH_TO_ROOTFS}/etc/dhcpcd.conf" ]; then
    if ! grep -q "interface wlan0" "${PATH_TO_ROOTFS}/etc/dhcpcd.conf"; then
        cat >>"${PATH_TO_ROOTFS}/etc/dhcpcd.conf" <<'DHCPEOF'

# WiFi configuration
interface wlan0
env ifwireless=1
env wpa_supplicant_driver=nl80211,wext
DHCPEOF
        print_success "Updated dhcpcd.conf for WiFi"
    fi
fi

print_success "WiFi configuration complete (multiple methods configured)"

# Method 5: Set WiFi Regulatory Domain
print_info "Setting WiFi regulatory domain to $WIFI_COUNTRY..."

# Configure regulatory domain in /etc/default/crda
if [ -d "${PATH_TO_ROOTFS}/etc/default" ]; then
    if [ -f "${PATH_TO_ROOTFS}/etc/default/crda" ]; then
        if grep -q "^REGDOMAIN=" "${PATH_TO_ROOTFS}/etc/default/crda"; then
            sed -i "s/^REGDOMAIN=.*/REGDOMAIN=$WIFI_COUNTRY/" "${PATH_TO_ROOTFS}/etc/default/crda"
        else
            echo "REGDOMAIN=$WIFI_COUNTRY" >> "${PATH_TO_ROOTFS}/etc/default/crda"
        fi
        print_success "Set REGDOMAIN in /etc/default/crda"
    else
        echo "REGDOMAIN=$WIFI_COUNTRY" > "${PATH_TO_ROOTFS}/etc/default/crda"
        print_success "Created /etc/default/crda with REGDOMAIN=$WIFI_COUNTRY"
    fi
fi

# Create a combined systemd service for WiFi setup
WIFI_SERVICE="${PATH_TO_ROOTFS}/etc/systemd/system/wifi-setup.service"
if [ -d "${PATH_TO_ROOTFS}/etc/systemd/system" ]; then
    cat >"$WIFI_SERVICE" <<WIFIEOF
[Unit]
Description=WiFi Setup (Unblock and Set Region)
Before=network-pre.target
After=sys-subsystem-net-devices-wlan0.device
Wants=network-pre.target

[Service]
Type=oneshot
ExecStart=/usr/sbin/rfkill unblock wifi
ExecStart=/usr/sbin/iw reg set $WIFI_COUNTRY
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
WIFIEOF

    # Enable the service
    mkdir -p "${PATH_TO_ROOTFS}/etc/systemd/system/multi-user.target.wants" 2>/dev/null || true
    ln -sf "../wifi-setup.service" "${PATH_TO_ROOTFS}/etc/systemd/system/multi-user.target.wants/wifi-setup.service" 2>/dev/null || true
    print_success "Created WiFi setup service (rfkill unblock + regulatory domain)"
fi

Method 1、2、3、4、5といくつかありますが、すべてやっておけばつながるでしょうという感じです(実際どれを抜くとつながらなくなるのかはよく分かりません)。

SSHを有効化する

# ========================================
# 4. Enable SSH
# ========================================
print_info "Enabling SSH..."

# Create ssh file in boot partition to enable SSH
touch "${PATH_TO_BOOTFS}/ssh"
print_success "SSH enabled (created /boot/ssh)"

touchしておしまいです。簡単ですね。

UARTを有効化する

この記事のように、有線でRaspberrypiのコンソールをたたくことができます。
Bluetoothが無効になるので、必要な人は設定しないようにしましょう。

ファイルの末尾に追加するだけです。

# ========================================
# 5. Enable UART
# ========================================
print_info "Enabling UART..."

CONFIG_FILE="${PATH_TO_BOOTFS}/config.txt"

if [ -f "$CONFIG_FILE" ]; then
  # Check if enable_uart is already set
  if grep -q "^enable_uart=" "$CONFIG_FILE"; then
    sed -i 's/^enable_uart=.*/enable_uart=1/' "$CONFIG_FILE"
    print_success "Updated enable_uart in config.txt"
  else
    echo "" >>"$CONFIG_FILE"
    echo "# Enable UART" >>"$CONFIG_FILE"
    echo "enable_uart=1" >>"$CONFIG_FILE"
    print_success "Added enable_uart to config.txt"
  fi

  # Also disable Bluetooth to free up the hardware UART (optional but recommended)
  if ! grep -q "^dtoverlay=disable-bt" "$CONFIG_FILE"; then
    echo "dtoverlay=disable-bt" >>"$CONFIG_FILE"
    print_success "Disabled Bluetooth to free hardware UART"
  fi
else
  print_error "config.txt not found at $CONFIG_FILE"
fi

コンソールの設定

# ========================================
# 6. Additional Serial Console Configuration
# ========================================
print_info "Configuring serial console..."

CMDLINE_FILE="${PATH_TO_BOOTFS}/cmdline.txt"

if [ -f "$CMDLINE_FILE" ]; then
  # Backup original cmdline.txt
  cp "$CMDLINE_FILE" "${CMDLINE_FILE}.backup" 2>/dev/null || true

  # Check if console=serial0 is already present
  if ! grep -q "console=serial0" "$CMDLINE_FILE"; then
    sed -i '1s/^/console=serial0,115200 /' "$CMDLINE_FILE"
    print_success "Added serial console to cmdline.txt"
  else
    print_info "Serial console already configured in cmdline.txt"
  fi
else
  print_info "cmdline.txt not found (may not be needed for this OS version)"
fi

最後に

全部を載せたものをいかに貼り付けます。
今までのものと、最後にサマリーを出力します。

すべてのコード
#!/bin/bash
set -e # Exit on error

# Configuration variables
PATH_TO_ROOTFS="${PATH_TO_ROOTFS:-/media/rotarymars/rootfs}"
PATH_TO_BOOTFS="${PATH_TO_BOOTFS:-/media/rotarymars/bootfs}"
USERNAME="${USERNAME:-robo}"
PASSWORD="${PASSWORD:-techno}"
WIFI_SSID="${WIFI_SSID:-rotarymars}"
WIFI_PASSWORD="${WIFI_PASSWORD:-rotarymars}"
WIFI_COUNTRY="${WIFI_COUNTRY:-JP}"
PI_HOSTNAME="${PI_HOSTNAME:-roboberry}"

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# Helper functions
print_success() {
  echo -e "${GREEN}[✓]${NC} $1"
}

print_error() {
  echo -e "${RED}[✗]${NC} $1"
}

print_info() {
  echo -e "${YELLOW}[i]${NC} $1"
}

# Check if running as root
if [ "$EUID" -ne 0 ]; then
  print_error "This script must be run as root (use sudo)"
  exit 1
fi

# Check if paths exist
if [ ! -d "$PATH_TO_ROOTFS" ]; then
  print_error "Root filesystem not found at $PATH_TO_ROOTFS"
  exit 1
fi

if [ ! -d "$PATH_TO_BOOTFS" ]; then
  print_error "Boot filesystem not found at $PATH_TO_BOOTFS"
  exit 1
fi

print_info "Starting Raspberry Pi configuration..."
echo "Root FS: $PATH_TO_ROOTFS"
echo "Boot FS: $PATH_TO_BOOTFS"
echo "Hostname: $PI_HOSTNAME"
echo "Username: $USERNAME"
echo "WiFi SSID: $WIFI_SSID"
echo ""

# ========================================
# 1. Configure User Account
# ========================================
print_info "Configuring user account: $USERNAME"

# Encrypt password
ENCRYPTED=$(openssl passwd -6 "$PASSWORD")

# Check if user already exists in passwd
if grep -q "^$USERNAME:" "${PATH_TO_ROOTFS}/etc/passwd" 2>/dev/null; then
  print_info "User $USERNAME already exists in passwd, skipping..."
else
  echo "$USERNAME:x:1001:1001:New User,,,:/home/$USERNAME:/bin/bash" >>"${PATH_TO_ROOTFS}/etc/passwd"
  print_success "Added user to /etc/passwd"
fi

# Check if user already exists in shadow
if grep -q "^$USERNAME:" "${PATH_TO_ROOTFS}/etc/shadow" 2>/dev/null; then
  print_info "User $USERNAME already exists in shadow, skipping..."
else
  echo "$USERNAME:$ENCRYPTED:19000:0:99999:7:::" >>"${PATH_TO_ROOTFS}/etc/shadow"
  print_success "Added user to /etc/shadow"
fi

# Check if group already exists
if grep -q "^$USERNAME:" "${PATH_TO_ROOTFS}/etc/group" 2>/dev/null; then
  print_info "Group $USERNAME already exists, skipping..."
else
  echo "$USERNAME:x:1001:" >>"${PATH_TO_ROOTFS}/etc/group"
  print_success "Added group to /etc/group"
fi

# Add to sudo group if not already there
if grep "^sudo:.*$USERNAME" "${PATH_TO_ROOTFS}/etc/group" >/dev/null 2>&1; then
  print_info "User already in sudo group, skipping..."
else
  sed -i "s/^\(sudo:x:27:.*\)/\1,$USERNAME/" "${PATH_TO_ROOTFS}/etc/group"
  print_success "Added user to sudo group"
fi

# Create home directory
if [ -d "${PATH_TO_ROOTFS}/home/$USERNAME" ]; then
  print_info "Home directory already exists, skipping..."
else
  mkdir -p "${PATH_TO_ROOTFS}/home/$USERNAME"
  cp -r "${PATH_TO_ROOTFS}/etc/skel/." "${PATH_TO_ROOTFS}/home/$USERNAME/" 2>/dev/null || true
  chown -R 1001:1001 "${PATH_TO_ROOTFS}/home/$USERNAME"
  chmod 700 "${PATH_TO_ROOTFS}/home/$USERNAME"
  print_success "Created home directory with proper permissions"
fi

# ========================================
# 2. Configure Hostname
# ========================================
print_info "Setting hostname to '$PI_HOSTNAME'..."

# Set hostname in /etc/hostname
echo "$PI_HOSTNAME" > "${PATH_TO_ROOTFS}/etc/hostname"
print_success "Set hostname in /etc/hostname"

# Update /etc/hosts
if [ -f "${PATH_TO_ROOTFS}/etc/hosts" ]; then
    # Replace any existing 127.0.1.1 entry
    if grep -q "^127.0.1.1" "${PATH_TO_ROOTFS}/etc/hosts"; then
        sed -i "s/^127.0.1.1.*/127.0.1.1\t$PI_HOSTNAME/" "${PATH_TO_ROOTFS}/etc/hosts"
        print_success "Updated hostname in /etc/hosts"
    else
        # Add 127.0.1.1 entry if it doesn't exist
        echo -e "127.0.1.1\t$PI_HOSTNAME" >> "${PATH_TO_ROOTFS}/etc/hosts"
        print_success "Added hostname to /etc/hosts"
    fi
fi

# ========================================
# 3. Configure WiFi
# ========================================
print_info "Configuring WiFi network: $WIFI_SSID"

# Method 1: wpa_supplicant.conf in boot (for older Raspberry Pi OS)
WPA_CONF="${PATH_TO_BOOTFS}/wpa_supplicant.conf"

# Create wpa_supplicant.conf (overwrite if exists)
cat >"$WPA_CONF" <<WPAEOF
country=$WIFI_COUNTRY
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

WPAEOF

# Generate and append the network configuration
wpa_passphrase "$WIFI_SSID" "$WIFI_PASSWORD" >> "$WPA_CONF"
chmod 600 "$WPA_CONF"
print_success "Created wpa_supplicant.conf in boot partition"

# Method 2: Configure in rootfs for newer systems
if [ -d "${PATH_TO_ROOTFS}/etc/wpa_supplicant" ]; then
    WPA_CONF_ROOTFS="${PATH_TO_ROOTFS}/etc/wpa_supplicant/wpa_supplicant.conf"
    cat >"$WPA_CONF_ROOTFS" <<WPAEOF
country=$WIFI_COUNTRY
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

WPAEOF
    wpa_passphrase "$WIFI_SSID" "$WIFI_PASSWORD" >> "$WPA_CONF_ROOTFS"
    chmod 600 "$WPA_CONF_ROOTFS"
    print_success "Created wpa_supplicant.conf in rootfs"
fi

# Method 3: NetworkManager configuration (for Raspberry Pi OS Bookworm and newer)
NM_DIR="${PATH_TO_ROOTFS}/etc/NetworkManager/system-connections"
if [ -d "${PATH_TO_ROOTFS}/etc/NetworkManager" ]; then
    mkdir -p "$NM_DIR"

    # Generate PSK hash for NetworkManager
    PSK=$(wpa_passphrase "$WIFI_SSID" "$WIFI_PASSWORD" | grep '^\spsk=' | cut -d= -f2)

    # Generate UUID (use uuidgen if available, otherwise create one)
    if command -v uuidgen &> /dev/null; then
        UUID=$(uuidgen)
    else
        UUID=$(cat /proc/sys/kernel/random/uuid 2>/dev/null || echo "$(date +%s)-$(shuf -i 1000-9999 -n 1)")
    fi

    cat >"${NM_DIR}/${WIFI_SSID}.nmconnection" <<NMEOF
[connection]
id=$WIFI_SSID
uuid=$UUID
type=wifi
autoconnect=true
autoconnect-priority=999

[wifi]
mode=infrastructure
ssid=$WIFI_SSID

[wifi-security]
key-mgmt=wpa-psk
psk=$PSK

[ipv4]
method=auto

[ipv6]
method=auto
addr-gen-mode=stable-privacy
NMEOF

    chmod 600 "${NM_DIR}/${WIFI_SSID}.nmconnection"
    print_success "Created NetworkManager connection"
fi

# Method 4: dhcpcd configuration (for additional compatibility)
if [ -f "${PATH_TO_ROOTFS}/etc/dhcpcd.conf" ]; then
    if ! grep -q "interface wlan0" "${PATH_TO_ROOTFS}/etc/dhcpcd.conf"; then
        cat >>"${PATH_TO_ROOTFS}/etc/dhcpcd.conf" <<'DHCPEOF'

# WiFi configuration
interface wlan0
env ifwireless=1
env wpa_supplicant_driver=nl80211,wext
DHCPEOF
        print_success "Updated dhcpcd.conf for WiFi"
    fi
fi

print_success "WiFi configuration complete (multiple methods configured)"

# Method 5: Set WiFi Regulatory Domain
print_info "Setting WiFi regulatory domain to $WIFI_COUNTRY..."

# Configure regulatory domain in /etc/default/crda
if [ -d "${PATH_TO_ROOTFS}/etc/default" ]; then
    if [ -f "${PATH_TO_ROOTFS}/etc/default/crda" ]; then
        if grep -q "^REGDOMAIN=" "${PATH_TO_ROOTFS}/etc/default/crda"; then
            sed -i "s/^REGDOMAIN=.*/REGDOMAIN=$WIFI_COUNTRY/" "${PATH_TO_ROOTFS}/etc/default/crda"
        else
            echo "REGDOMAIN=$WIFI_COUNTRY" >> "${PATH_TO_ROOTFS}/etc/default/crda"
        fi
        print_success "Set REGDOMAIN in /etc/default/crda"
    else
        echo "REGDOMAIN=$WIFI_COUNTRY" > "${PATH_TO_ROOTFS}/etc/default/crda"
        print_success "Created /etc/default/crda with REGDOMAIN=$WIFI_COUNTRY"
    fi
fi

# Create a combined systemd service for WiFi setup
WIFI_SERVICE="${PATH_TO_ROOTFS}/etc/systemd/system/wifi-setup.service"
if [ -d "${PATH_TO_ROOTFS}/etc/systemd/system" ]; then
    cat >"$WIFI_SERVICE" <<WIFIEOF
[Unit]
Description=WiFi Setup (Unblock and Set Region)
Before=network-pre.target
After=sys-subsystem-net-devices-wlan0.device
Wants=network-pre.target

[Service]
Type=oneshot
ExecStart=/usr/sbin/rfkill unblock wifi
ExecStart=/usr/sbin/iw reg set $WIFI_COUNTRY
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
WIFIEOF

    # Enable the service
    mkdir -p "${PATH_TO_ROOTFS}/etc/systemd/system/multi-user.target.wants" 2>/dev/null || true
    ln -sf "../wifi-setup.service" "${PATH_TO_ROOTFS}/etc/systemd/system/multi-user.target.wants/wifi-setup.service" 2>/dev/null || true
    print_success "Created WiFi setup service (rfkill unblock + regulatory domain)"
fi

# ========================================
# 4. Enable SSH
# ========================================
print_info "Enabling SSH..."

# Create ssh file in boot partition to enable SSH
touch "${PATH_TO_BOOTFS}/ssh"
print_success "SSH enabled (created /boot/ssh)"

# ========================================
# 5. Enable UART
# ========================================
print_info "Enabling UART..."

CONFIG_FILE="${PATH_TO_BOOTFS}/config.txt"

if [ -f "$CONFIG_FILE" ]; then
  # Check if enable_uart is already set
  if grep -q "^enable_uart=" "$CONFIG_FILE"; then
    sed -i 's/^enable_uart=.*/enable_uart=1/' "$CONFIG_FILE"
    print_success "Updated enable_uart in config.txt"
  else
    echo "" >>"$CONFIG_FILE"
    echo "# Enable UART" >>"$CONFIG_FILE"
    echo "enable_uart=1" >>"$CONFIG_FILE"
    print_success "Added enable_uart to config.txt"
  fi

  # Also disable Bluetooth to free up the hardware UART (optional but recommended)
  if ! grep -q "^dtoverlay=disable-bt" "$CONFIG_FILE"; then
    echo "dtoverlay=disable-bt" >>"$CONFIG_FILE"
    print_success "Disabled Bluetooth to free hardware UART"
  fi
else
  print_error "config.txt not found at $CONFIG_FILE"
fi

# ========================================
# 6. Additional Serial Console Configuration
# ========================================
print_info "Configuring serial console..."

CMDLINE_FILE="${PATH_TO_BOOTFS}/cmdline.txt"

if [ -f "$CMDLINE_FILE" ]; then
  # Backup original cmdline.txt
  cp "$CMDLINE_FILE" "${CMDLINE_FILE}.backup" 2>/dev/null || true

  # Check if console=serial0 is already present
  if ! grep -q "console=serial0" "$CMDLINE_FILE"; then
    sed -i '1s/^/console=serial0,115200 /' "$CMDLINE_FILE"
    print_success "Added serial console to cmdline.txt"
  else
    print_info "Serial console already configured in cmdline.txt"
  fi
else
  print_info "cmdline.txt not found (may not be needed for this OS version)"
fi

# ========================================
# Summary
# ========================================
echo ""
print_success "Raspberry Pi configuration complete!"
echo ""
echo "Configuration summary:"
echo "  • Hostname set to '$PI_HOSTNAME' (accessible via $PI_HOSTNAME.local)"
echo "  • User '$USERNAME' created with sudo access"
echo "  • WiFi configured for network '$WIFI_SSID' (country: $WIFI_COUNTRY)"
echo "  • WiFi regulatory domain set to $WIFI_COUNTRY"
echo "  • SSH enabled"
echo "  • UART enabled (hardware serial)"
echo "  • Serial console configured"
echo "  • WiFi setup service enabled (unblock + region)"
echo ""
echo "You can now unmount the SD card and boot your Raspberry Pi."
echo "Default login: $USERNAME / $PASSWORD"
echo ""
echo "Connect via:"
echo "  • SSH: ssh $USERNAME@$PI_HOSTNAME.local"
echo "  • UART: screen /dev/ttyUSB0 115200"
echo ""
print_info "WiFi Troubleshooting:"
echo "If WiFi doesn't connect, try these steps on the Pi:"
echo "  1. Check WiFi status: iwconfig wlan0"
echo "  2. Check if interface is up: ip link show wlan0"
echo "  3. Scan for networks: sudo iwlist wlan0 scan | grep ESSID"
echo "  4. Check wpa_supplicant: sudo systemctl status wpa_supplicant"
echo "  5. Check NetworkManager: sudo systemctl status NetworkManager"
echo "  6. View logs: sudo journalctl -u wpa_supplicant -u NetworkManager"
echo "  7. Manual connect: sudo wpa_cli -i wlan0 reconfigure"
echo "  8. Check country code: sudo iw reg get"
echo ""
echo "To manually test WiFi configuration:"
echo "  sudo rfkill unblock wifi"
echo "  sudo ip link set wlan0 up"
echo "  sudo wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf"
echo "  sudo dhcpcd wlan0"
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?