|
| 1 | +#!/bin/bash |
| 2 | + |
| 3 | +apt-get -q -y install mmdebstrap qemu-user-static binfmt-support fdisk gdisk dosfstools systemd-container |
| 4 | + |
| 5 | +MNTROOT=`mktemp -d` |
| 6 | +MNTFIRM=`mktemp -d` |
| 7 | + |
| 8 | +#DEVFILE=/dev/mmcblk0 |
| 9 | +echo "Input the device name of an SD card or a USB MSD" |
| 10 | +echo -n "for example, /dev/mmcblk0, /dev/sdc, etc.: " |
| 11 | +read DEVFILE |
| 12 | +#DEVFILE=/dev/loop2 |
| 13 | +#rm $IMGFILE |
| 14 | +#dd if=/dev/zero of=$IMGFILE count=1 seek=`expr 4096 \* 1024 - 1` |
| 15 | +#losetup -P $DEVFILE $IMGFILE |
| 16 | +#losetup -l |
| 17 | +for i in ${DEVFILE}[0-9] ${DEVFILE}p[0-9] /dev/null; do |
| 18 | + umount -qf $i >/dev/null 2>&1 |
| 19 | +done |
| 20 | +dd of=${DEVFILE} if=/dev/zero bs=1MiB count=256 |
| 21 | +sync |
| 22 | +while [ -b ${DEVFILE}1 -o -b ${DEVFILE}p1 ]; do |
| 23 | + partprobe $DEVFILE |
| 24 | + sleep 1 |
| 25 | +done |
| 26 | + |
| 27 | +echo -n "Select partition type (msdos or gpt). USB MSD > 2TB needs gpt: " |
| 28 | +read PARTTYPE |
| 29 | + |
| 30 | +echo -n "Swap partition size in GB, 0 means no swap partition: " |
| 31 | +read SWAPGB |
| 32 | + |
| 33 | +if [ $PARTTYPE = msdos ]; then |
| 34 | + fdisk $DEVFILE <<EOF |
| 35 | +o |
| 36 | +n |
| 37 | +p |
| 38 | +1 |
| 39 | +
|
| 40 | ++256M |
| 41 | +a |
| 42 | +t |
| 43 | +c |
| 44 | +n |
| 45 | +p |
| 46 | +2 |
| 47 | +
|
| 48 | +-${SWAPGB}GiB |
| 49 | +p |
| 50 | +w |
| 51 | +EOF |
| 52 | +elif [ $PARTTYPE = gpt ]; then |
| 53 | + gdisk $DEVFILE <<EOF |
| 54 | +2 |
| 55 | +n |
| 56 | +1 |
| 57 | +
|
| 58 | +256M |
| 59 | +EF00 |
| 60 | +n |
| 61 | +2 |
| 62 | +
|
| 63 | +-${SWAPGB}GiB |
| 64 | +8300 |
| 65 | +p |
| 66 | +w |
| 67 | +y |
| 68 | +EOF |
| 69 | +else |
| 70 | + echo "Unknown partition type!" |
| 71 | + exit 1 |
| 72 | +fi |
| 73 | + |
| 74 | +while [ ! -b ${DEVFILE}1 -a ! -b ${DEVFILE}p1 ]; do |
| 75 | + partprobe $DEVFILE |
| 76 | + sleep 1 |
| 77 | +done |
| 78 | +if [ -b ${DEVFILE}p1 ]; then |
| 79 | + PARTCHAR=p |
| 80 | +elif [ -b ${DEVFILE}1 ]; then |
| 81 | + PARTCHAR="" |
| 82 | +else |
| 83 | + echo "Unknown device name for the partition 1!" |
| 84 | + exit 1 |
| 85 | +fi |
| 86 | + |
| 87 | +if [ "$SWAPGB" -gt 0 ]; then |
| 88 | + if [ $PARTTYPE = msdos ]; then |
| 89 | + fdisk $DEVFILE <<EOF |
| 90 | +n |
| 91 | +p |
| 92 | +3 |
| 93 | +
|
| 94 | +
|
| 95 | +t |
| 96 | +3 |
| 97 | +82 |
| 98 | +p |
| 99 | +w |
| 100 | +EOF |
| 101 | + elif [ $PARTTYPE = gpt ]; then |
| 102 | + gdisk $DEVFILE <<EOF |
| 103 | +n |
| 104 | +3 |
| 105 | +
|
| 106 | +
|
| 107 | +8200 |
| 108 | +p |
| 109 | +w |
| 110 | +y |
| 111 | +EOF |
| 112 | + fi |
| 113 | + while [ ! -b ${DEVFILE}${PARTCHAR}3 ]; do |
| 114 | + partprobe $DEVFILE |
| 115 | + sleep 1 |
| 116 | + done |
| 117 | + mkswap -f -L RASPISWAP ${DEVFILE}${PARTCHAR}3 |
| 118 | +fi |
| 119 | + |
| 120 | +echo "(btrfs may not work as initramfs is not well supported on Raspberry Pi OS.)" |
| 121 | +echo -n "Filesystem type of the root partition (ext4 or btrfs): " |
| 122 | +read FSTYPE |
| 123 | +dd of=${DEVFILE}${PARTCHAR}2 if=/dev/zero count=512 |
| 124 | +eval mkfs.${FSTYPE} -L RASPIROOT ${DEVFILE}${PARTCHAR}2 |
| 125 | +ROOTPARTUUID=`blkid -s PARTUUID -o value ${DEVFILE}${PARTCHAR}2` |
| 126 | + |
| 127 | +echo -n "Debian Suite (buster, bullseye or sid): " |
| 128 | +read MMSUITE |
| 129 | +cat <<EOF |
| 130 | +Explanation of architectures: |
| 131 | +armel for Raspberry Pi Zero, Zero W and 1, |
| 132 | +armhf for Raspberry Pi 2, |
| 133 | +arm64 for Raspberry Pi 3 and 4. |
| 134 | +EOF |
| 135 | +#echo -n 'Architecture ("armel", "armhf", "arm64", or "armhf,arm64"): ' |
| 136 | +echo -n 'Architecture ("armel", "armhf", or "arm64"): ' |
| 137 | +read MMARCH |
| 138 | +echo |
| 139 | +echo "As defined at https://www.debian.org/doc/debian-policy/ch-archive.html#s-priorities" |
| 140 | +echo -n "select installed package coverage (apt, required, important, or standard): " |
| 141 | +read MMVARIANT |
| 142 | + |
| 143 | +RASPIFIRMWARE=wireless-regdb,rpi-eeprom,raspberrypi-bootloader,libraspberrypi-bin,bluez-firmware,firmware-atheros,firmware-brcm80211,firmware-libertas,firmware-misc-nonfree,firmware-realtek,raspberrypi-archive-keyring |
| 144 | + |
| 145 | +KERNELPKG=raspberrypi-kernel |
| 146 | +echo "Selected kernel package is $KERNELPKG." |
| 147 | + |
| 148 | +echo |
| 149 | +echo -n "Choose network configurator (ifupdown, network-manager, systemd-networkd, none): " |
| 150 | +read NETWORK |
| 151 | + |
| 152 | +if [ $NETWORK = ifupdown ]; then |
| 153 | + NETPKG=ifupdown,isc-dhcp-client,crda |
| 154 | +elif [ $NETWORK = network-manager ]; then |
| 155 | + NETPKG=network-manager,crda |
| 156 | +elif [ $NETWORK = systemd-networkd ]; then |
| 157 | + NETPKG=systemd |
| 158 | +else |
| 159 | + NETPKG=iproute2,iw |
| 160 | +fi |
| 161 | + |
| 162 | +if [ $FSTYPE = btrfs ]; then |
| 163 | + mount -o ssd,async,lazytime,discard,noatime,autodefrag,nobarrier,commit=3600,compress-force=lzo ${DEVFILE}${PARTCHAR}2 ${MNTROOT} |
| 164 | +elif [ $FSTYPE = ext4 ]; then |
| 165 | + mount -o async,lazytime,discard,noatime,nobarrier,journal_async_commit,commit=3600,delalloc,noauto_da_alloc,data=writeback ${DEVFILE}${PARTCHAR}2 ${MNTROOT} |
| 166 | +fi |
| 167 | +mmdebstrap --architectures=$MMARCH --variant=$MMVARIANT --components="main contrib non-free" --include=${KERNELPKG},debian-archive-keyring,systemd-sysv,udev,kmod,e2fsprogs,btrfs-progs,locales,tzdata,apt-utils,whiptail,wpasupplicant,${NETPKG},${RASPIFIRMWARE},firmware-linux-free,firmware-misc-nonfree,keyboard-configuration,console-setup,fake-hwclock "$MMSUITE" ${MNTROOT} - <<EOF |
| 168 | +deb http://archive.raspberrypi.org/debian/ buster main |
| 169 | +deb http://deb.debian.org/debian $MMSUITE main contrib non-free |
| 170 | +EOF |
| 171 | + |
| 172 | +mkfs.vfat -v -F 32 -n RASPIFIRM ${DEVFILE}${PARTCHAR}1 |
| 173 | +mount -o async,discard,lazytime,noatime ${DEVFILE}${PARTCHAR}1 ${MNTFIRM} |
| 174 | +cp -Rp ${MNTROOT}/boot/* ${MNTFIRM} |
| 175 | +rm -rf ${MNTROOT}/boot/* |
| 176 | +umount ${MNTFIRM} |
| 177 | +mount -o async,discard,lazytime,noatime ${DEVFILE}${PARTCHAR}1 ${MNTROOT}/boot |
| 178 | + |
| 179 | +echo -n "Choose hostname: " |
| 180 | +read YOURHOSTNAME |
| 181 | +echo "$YOURHOSTNAME" >${MNTROOT}/etc/hostname |
| 182 | +if [ ${FSTYPE} = btrfs ]; then |
| 183 | + cat >${MNTROOT}/etc/fstab <<EOF |
| 184 | +LABEL=RASPIROOT / ${FSTYPE} rw,async,lazytime,discard,compress-force=lzo 0 1 |
| 185 | +LABEL=RASPIFIRM /boot vfat rw,async,lazytime,discard 0 2 |
| 186 | +EOF |
| 187 | +else |
| 188 | + cat >${MNTROOT}/etc/fstab <<EOF |
| 189 | +LABEL=RASPIROOT / ${FSTYPE} rw,async,lazytime,discard 0 1 |
| 190 | +LABEL=RASPIFIRM /boot vfat rw,async,lazytime,discard 0 2 |
| 191 | +EOF |
| 192 | +fi |
| 193 | +if [ "$SWAPGB" -gt 0 ]; then |
| 194 | + echo 'LABEL=RASPISWAP none swap sw,discard 0 0' >>${MNTROOT}/etc/fstab |
| 195 | +fi |
| 196 | + |
| 197 | +if [ $NETWORK != none ]; then |
| 198 | + echo "IPv4 DHCP is assumed." |
| 199 | + echo -n "Name of the primary network interface (eth0, wlan0): " |
| 200 | + read NETIF |
| 201 | + |
| 202 | + if [ $NETIF = wlan0 ]; then |
| 203 | + echo "As https://wiki.archlinux.org/index.php/Network_configuration/Wireless#Respecting_the_regulatory_domain" |
| 204 | + echo -n "Choose your wireless regulatory domain (hit Enter if unsuer): " |
| 205 | + read REGDOM |
| 206 | + echo -n "Your Wireless LAN SSID: " |
| 207 | + read SSID |
| 208 | + echo -n "Your Wireless LAN passphrease: " |
| 209 | + read PSK |
| 210 | + fi |
| 211 | + |
| 212 | + if [ $NETWORK = ifupdown ]; then |
| 213 | + NETCONFIG="Network configurations can be changed by /etc/network/interfaces" |
| 214 | + cat >>${MNTROOT}/etc/network/interfaces <<EOF |
| 215 | +auto $NETIF |
| 216 | +iface $NETIF inet dhcp |
| 217 | +EOF |
| 218 | + if [ "$NETIF" = wlan0 ]; then |
| 219 | + NETCONFIG="${NETCONFIG} and /etc/default/crda" |
| 220 | + cat >>${MNTROOT}/etc/network/interfaces <<EOF |
| 221 | + wpa-ssid $SSID |
| 222 | + wpa-psk $PSK |
| 223 | +EOF |
| 224 | + if [ -n "$REGDOM" ]; then |
| 225 | + echo "REGDOMAIN=$REGDOM" >>${MNTROOT}/etc/default/crda |
| 226 | + fi |
| 227 | + fi |
| 228 | + echo "/etc/network/interfaces is" |
| 229 | + cat ${MNTROOT}/etc/network/interfaces |
| 230 | + elif [ $NETWORK = network-manager ]; then |
| 231 | + NETCONFIG="Network configurations can be changed by nmtui" |
| 232 | + if [ "$NETIF" = wlan0 ]; then |
| 233 | + NETCONFIG="${NETCONFIG} and /etc/default/crda" |
| 234 | + #UUID=`uuidgen` |
| 235 | + cat >>"${MNTROOT}/etc/NetworkManager/system-connections/${SSID}.nmconnection" <<EOF |
| 236 | +[connection] |
| 237 | +id=$SSID |
| 238 | +type=wifi |
| 239 | +permissions= |
| 240 | +
|
| 241 | +[wifi] |
| 242 | +mac-address-blacklist= |
| 243 | +mode=infrastructure |
| 244 | +ssid=$SSID |
| 245 | +
|
| 246 | +[wifi-security] |
| 247 | +key-mgmt=wpa-psk |
| 248 | +psk=$PSK |
| 249 | +
|
| 250 | +[ipv4] |
| 251 | +dns-search= |
| 252 | +method=auto |
| 253 | +
|
| 254 | +[ipv6] |
| 255 | +addr-gen-mode=stable-privacy |
| 256 | +dns-search= |
| 257 | +method=auto |
| 258 | +
|
| 259 | +[proxy] |
| 260 | +EOF |
| 261 | + chmod 600 "${MNTROOT}/etc/NetworkManager/system-connections/${SSID}.nmconnection" |
| 262 | + if [ -n "$REGDOM" ]; then |
| 263 | + echo "REGDOMAIN=$REGDOM" >>${MNTROOT}/etc/default/crda |
| 264 | + fi |
| 265 | + fi |
| 266 | + elif [ $NETWORK = systemd-networkd ]; then |
| 267 | + NETCONFIG="Network configurations can be changed by /etc/systemd/network/${NETIF}.network" |
| 268 | + cat >${MNTROOT}/etc/systemd/network/${NETIF}.network <<EOF |
| 269 | +[Match] |
| 270 | +Name=${NETIF} |
| 271 | +
|
| 272 | +[Network] |
| 273 | +DHCP=yes |
| 274 | +EOF |
| 275 | + systemd-nspawn -q -D ${MNTROOT} -a systemctl enable systemd-networkd |
| 276 | + if [ $NETIF = wlan0 ]; then |
| 277 | + NETCONFIG="${NETCONFIG} and /etc/wpa_supplicant/wpa_supplicant-wlan0.conf" |
| 278 | + if [ -n "$REGDOM" ]; then |
| 279 | + echo "country=$REGDOM" >${MNTROOT}/etc/wpa_supplicant/wpa_supplicant-wlan0.conf |
| 280 | + fi |
| 281 | + cat >>${MNTROOT}/etc/wpa_supplicant/wpa_supplicant-wlan0.conf <<EOF |
| 282 | +network={ |
| 283 | + ssid="${SSID}" |
| 284 | + scan_ssid=1 |
| 285 | + key_mgmt=WPA-PSK |
| 286 | + psk="${PSK}" |
| 287 | +} |
| 288 | +EOF |
| 289 | + systemd-nspawn -q -D ${MNTROOT} -a systemctl enable wpa_supplicant@wlan0 |
| 290 | + fi |
| 291 | + fi |
| 292 | +fi |
| 293 | + |
| 294 | +set -x |
| 295 | +#systemd-nspawn -q -D ${MNTROOT} -a pam-auth-update |
| 296 | +systemd-nspawn -q -D ${MNTROOT} -a passwd root |
| 297 | +systemd-nspawn -q -D ${MNTROOT} -a dpkg-reconfigure tzdata |
| 298 | +systemd-nspawn -q -D ${MNTROOT} -a dpkg-reconfigure locales |
| 299 | +systemd-nspawn -q -D ${MNTROOT} -a dpkg-reconfigure keyboard-configuration |
| 300 | +systemd-nspawn -q -D ${MNTROOT} -a fake-hwclock save |
| 301 | + |
| 302 | + |
| 303 | +mkdir -p ${MNTROOT}/etc/systemd/sleep.conf.d |
| 304 | +cat >${MNTROOT}/etc/systemd/sleep.conf.d/nosleep.conf <<'EOF' |
| 305 | +[Sleep] |
| 306 | +#AllowSuspend=no |
| 307 | +#AllowHibernation=no |
| 308 | +#AllowSuspendThenHibernate=no |
| 309 | +#AllowHybridSleep=no |
| 310 | +EOF |
| 311 | + |
| 312 | + |
| 313 | + |
| 314 | +if [ "$MMSUITE" != buster ]; then |
| 315 | + systemd-nspawn -q -D ${MNTROOT} -a apt-get -y --purge --autoremove purge python2.7-minimal |
| 316 | +fi |
| 317 | +set +x |
| 318 | + |
| 319 | + |
| 320 | +if [ $NETWORK = network-manager -o $NETWORK = systemd-networkd ]; then |
| 321 | + systemd-nspawn -q -D ${MNTROOT} -a apt-get -y --purge --autoremove purge ifupdown |
| 322 | + rm -f ${MNTROOT}/etc/network/interfaces |
| 323 | +fi |
| 324 | + |
| 325 | +cat >>${MNTROOT}/root/.profile <<EOF |
| 326 | +echo "$NETCONFIG" |
| 327 | +EOF |
| 328 | + |
| 329 | +cat >>${MNTROOT}/boot/config.txt <<EOF |
| 330 | +disable_overscan=1 |
| 331 | +disable_fw_kms_setup=1 |
| 332 | +dtparam=audio=on,watchdog=on |
| 333 | +EOF |
| 334 | + |
| 335 | +if echo $MMARCH | fgrep -q arm64; then |
| 336 | + cat >>${MNTROOT}/boot/config.txt <<EOF |
| 337 | +hdmi_enable_4kp60=1 |
| 338 | +dtoverlay=vc4-kms-v3d-pi4 |
| 339 | +arm_64bit=1 |
| 340 | +EOF |
| 341 | +fi |
| 342 | + |
| 343 | +cat >>${MNTROOT}/boot/cmdline.txt <<EOF |
| 344 | +root=PARTUUID=${ROOTPARTUUID} rootfstype=$FSTYPE fsck.repair=yes rootwait |
| 345 | +EOF |
| 346 | +cat ${MNTROOT}/boot/cmdline.txt |
| 347 | + |
| 348 | + |
| 349 | +umount ${MNTROOT}/boot |
| 350 | +umount ${MNTROOT} |
| 351 | +rm -rf ${MNTROOT} ${MNTFIRM} |
0 commit comments