How to configure Debian/arm using Ubuntu/intel
Configuring a Raspberry Pi for headless operation without having to connect a keyboard and a screen, involves the following step
- Download the latest Raspbian image
- copy the Raspbian image to sdcard
- setup Wifi
- change pasword for pi
- enable sshd
- adduser for me,
- modify group
- add me to sudo
- add athorized ssh keys for me on my laptop so i can login without password
- set timezone
- set hostname
- set keyboard
- run raspi-config to configure various other stuff
Dependent on what it will be used for, there is still more to do, quite a few of the above steps needs to be done on the sdcard before you can access the Raspberry Pi remotely.
I have automated this proces by writing a small shell-script rpido
rpido -? usage: rpido <options> cmd -h name sets /etc/hostname on rpi -s start shell on raspian -w write raspian to sdcard cmd chroot rpi cmd installs files from template configures wifi and sshd, and authorized keys
which takes care of the bulk of this.
To create a configured sdcard for a new RPI, I would typically do
- install a sd card on my laptop
- run: rpido -w -h newtoy -s
- check things are fine, exit
- move the sdcard to the RPI
This will download and install the latest raspbian to the sdcard, configure all the things mentioned above and set the hostname to newtoy, and finally drop you into a root-shell on the sdcard, where you could run raspi-config.
Yes I can execute arm-binaries on my ubuntu laptop, in a chroot environment on the filesystem on sdcard, check my shell-script below for how it is done.
#!/bin/bash # URL=$(curl -s https://downloads.raspberrypi.org/raspbian_lite_latest | awk -F\" '/http/ { print $2}') LATEST=$(basename $URL .zip) zipfile=DIST/$LATEST.zip RPI_ROOT=sdcard VERBOSE=1 vecho() { [ $VERBOSE -lt 1 ] || echo $* >/dev/stderr; } vvecho() { [ $VERBOSE -lt 2 ] || echo $* >/dev/stderr; } SUDO() { vecho SUDO $* sudo $* } set_SD() { for d in /dev/sd[a-f] ;do if sudo gdisk -l $d 2>/dev/null| grep "^Model:.*SD/MMC">/dev/null; then SD=$(basename $d) break; fi done } loopdev_SD() { [ -f "$LATEST.img" ] || unzip -x $zipfile $LATEST.img LOOP=$(sudo losetup -f) SUDO losetup -P $LOOP $LATEST.img SD=$(basename ${LOOP}p) } is_mounted() { mount | grep $(realpath $1) >/dev/null } unmount_SD() { for i in /sys/block/${SD}/${SD}?;do SUDO umount /dev/$(basename $i) 2>/dev/null done } mount_SD() { unmount_SD mkdir -p $RPI_ROOT SUDO mount /dev/${SD}2 $RPI_ROOT SUDO mount /dev/${SD}1 $RPI_ROOT/boot } write_SD() { unmount_SD unzip -p $zipfile $LATEST.img | sudo dd of=/dev/${SD} bs=4M } unmount_all() { [ ! -z "$RPI_ROOT" ] || return 1 [ -z "$keep_mount" ] || return 0 FULLPATH=$(realpath ${RPI_ROOT}) LOOP=$(mount | grep "/dev/loop[0-9]*p2.*$FULLPATH" | sed 's/p2.*$//') # SUDO rm -f ${RPI_ROOT}/usr/bin/qemu-arm-static for p in $(mount | grep $FULLPATH | cut -f3 -d' ' | sort -Vr); do SUDO umount $p done for d in $LOOP; do SUDO losetup -d $d #SUDO rm -f ${d}* done } usage() { unmount_all set +x [ $# == 0 ] || echo $* echo "usage: rpido <options> cmd" echo " -w write raspian to sdcard" echo " -h name sets /etc/hostname on rpi" echo " -s start shell on raspian" echo " cmd chroot rpi cmd" echo "installs files from template" echo "configures wifi and sshd, and authorized keys" exit } while getopts ?h:kqsvw opt;do case $opt in h) hostname=$OPTARG ;; k) keep_mount=y ;; q) VERBOSE=0 ;; s) rpi_shell=y ;; v) VERBOSE=$(($VERBOSE+1)) ;; w) write_sd=y ;; *) usage ;; esac done shift $(($OPTIND-1)) [ $VERBOSE -lt 2 ] || set -x if [ "$rpi_shell" = y ]; then CMD="bash -i" else CMD="$*" fi [ -f $zipfile ] || curl --create-dirs -o $zipfile $URL set_SD if [ -z "$SD" ];then loopdev_SD else [ -z "$write_sd" ] || write_SD fi mount_SD if [ -z "${RPI_ROOT}" -o ! -f "$RPI_ROOT/etc/rpi-issue" -o ! -f "$RPI_ROOT/boot/issue.txt" ]; then usage raspbian root not as expected fi SUDO rsync -a template/. $RPI_ROOT [ -z "$hostname" ] || echo $hostname | sudo tee $RPI_ROOT/etc/hostname >/dev/null if [ ! -z "$CMD" ]; then SUDO rsync /usr/bin/qemu-arm-static ${RPI_ROOT}/usr/bin/ for f in proc dev sys;do is_mounted $RPI_ROOT/$f || SUDO mount --bind /$f $RPI_ROOT/$f done SUDO chroot ${RPI_ROOT} $CMD fi unmount_all sync
The current content of template is:
$ find template/ template/ template/etc template/etc/default template/etc/default/keyboard template/etc/shadow template/etc/wpa_supplicant template/etc/wpa_supplicant/wpa_supplicant.conf template/etc/passwd template/etc/timezone template/etc/gshadow template/etc/group template/etc/sudoers.d template/etc/sudoers.d/010_peter-nopasswd template/home template/home/peter template/home/peter/.bashrc template/home/peter/.ssh template/home/peter/.ssh/authorized_keys template/boot template/boot/ssh
You probably have to install some tools on your ubuntu first, I would suggest:
sudo apt-get install gdisk realpath qemu-user-static zip rsync xz-utils file curl
Features:
- rpido always checks for the latest version of Raspian lite. It is much more effcient to download a new up-to-date version than to try to upgrade an earlier version at hand.
- if there is no sd-card installed, rpido will use a file-based loop mounted filesystem, much faster for debugging and trying out stuff,
- -k is a debugging option wich will leave the filesystem mounted, hence you can easily dive into it again with a simple chroot
- Even though the script is not running as root, there is a lot of sudo which can really do a lot of harm, so be sure to do a backup before, for me it only takes one command
sudo zfs snapshot -r t470@20181027 # and to restore f.ex. the root filesystem to this snapshot sudo zfs rollback t470/ROOT/ubuntu-18.04-t470@20181027
If you are still wondering how I manage to run arm-binaries on an intel laptop the secret-sauce is line 108-112 in the above script
And finally I would recommend that the bash prompt shows whether you are root by color, like this little example of rpido use demonstrates:
peter@t470:~> ./rpido -s
SUDO losetup -P /dev/loop14 sdcard
SUDO mount /dev/loop14p2 sdcard
SUDO mount /dev/loop14p1 sdcard/boot
SUDO rsync -a template/. adcard
SUDO rsync /usr/bin/qemu-arm-static sdcard/usr/bin/
SUDO mount –bind /proc sdcard/proc
SUDO mount –bind /dev sdcard/dev
SUDO mount –bind /sys sdcard/sys
SUDO chroot sdcard bash -i
root@raspberrypi:/# cat ~peter/.bashrc
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~peter/bin
RED=$(tput setaf 1)
BLUE=$(tput setaf 4)
NORMAL=$(tput sgr0)
HOSTNAME=$(cat /etc/hostname)
if [ $(id -u) -eq 0 ]; then # you are root, make the prompt red
PS1=”\[${RED}\]\u@${HOSTNAME}:\W#\[${NORMAL}\] ”
else
PS1=”\[${BLUE}\]\u@${HOSTNAME}:\W>\[${NORMAL}\] ”
fi
root@raspberrypi:/# exit
SUDO umount sdcard/sys
SUDO umount adcard/proc
SUDO umount adcard/dev
SUDO umount sdcard/boot
SUDO umount sdcard
SUDO losetup -d /dev/loop14
peter@t470:~>
You must be logged in to post a comment.