Raspberry Pi
SD card
After getting an SD card adapter[1], I still could not[2] erase/format it on a MacBook:
$ diskutil eraseDisk HFS+ 32GB disk3 Started erase on disk3 Unmounting disk Error: -69877: Couldn't open device
Not even directly writing to the block device would work, apparently due to hardware issues[3]
$ pv < /dev/zero > /dev/disk3 -bash: /dev/disk3: Permission denied
Same for the character device:[4][5]
$ pv < /dev/zero > /dev/rdisk3s1
-bash: /dev/rdisk3s1: Permission denied
Headless Setup
Debian
While Debian does not seem to offer official images, we can use unofficial ones made by the Raspberry Pi image specs and the Debian image builder
https://people.debian.org/~gwolf/raspberrypi3/
The root
password is set to raspberry
.
Raspbian
The Raspberry Pi 3 Starter Kit came with a MicroSD card, pre-imaged with NOOBS, which appeared to boot and the RPI received a DHCP lease, but could not be logged into. But let's install a Debian based Raspbian Jessie Lite in the SD card instead:
sha1sum *raspbian-jessie-lite.zip # Verify the checksum!
unzip *raspbian-jessie-lite.zip
pv < *raspbian-jessie-lite.img | sudo dd of=/dev/sdb bs=1M
After the image has been written, the MicroSD card should look like this:
$ sudo fdisk -l /dev/sdb Disk /dev/sdb: 29.7 GiB, 31914983424 bytes, 62333952 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0xc20f799b Device Boot Start End Sectors Size Id Type /dev/sdb1 8192 137215 129024 63M c W95 FAT32 (LBA) /dev/sdb2 137216 62333951 62196736 29.7G 83 Linux
- The vfat partition contains the boot loader and some firmware blobs
- The ext4 partition contains the actual operating system.
We still have to solve the headless setup part. Mounting the ext4 partition reveals a Systemd based Debian system:
$ find etc/ -name "*ssh*" | xargs ls -dog [...] -rwxr-xr-x 1 4077 Apr 14 2016 etc/init.d/ssh lrwxrwxrwx 1 13 Feb 25 23:57 etc/rc2.d/K01ssh -> ../init.d/ssh lrwxrwxrwx 1 13 Feb 25 23:57 etc/rc3.d/K01ssh -> ../init.d/ssh lrwxrwxrwx 1 13 Feb 25 23:57 etc/rc4.d/K01ssh -> ../init.d/ssh lrwxrwxrwx 1 13 Feb 25 23:57 etc/rc5.d/K01ssh -> ../init.d/ssh lrwxrwxrwx 1 37 Nov 25 09:29 etc/systemd/system/multi-user.target.wants/sshswitch.service -> /lib/systemd/system/sshswitch.service
- In an SysV based system, we could just rename the K01ssh symlinks to e.g. S01ssh and then sshd should be started on the next boot.
- But since we have a systemd based system, we have to enable sshd with service files:
cd ../etc/systemd/system/ ln -s /lib/systemd/system/ssh.service cd ../multi-user.target.wants/ ln -s /lib/systemd/system/ssh.service
This should work, because /lib/systemd/system/ssh.service does really exists on that Raspbian image. But the easiest method would be to use its own sshswitch service, which is already active:
$ pwd ../etc/systemd/system/multi-user.target.wants $ cat ../../../../lib/systemd/system/sshswitch.service [Unit] Description=Turn on SSH if /boot/ssh is present ConditionPathExistsGlob=/boot/ssh{,.txt} After=regenerate_ssh_host_keys.service [Service] Type=oneshot ExecStart=/bin/sh -c "update-rc.d ssh enable && invoke-rc.d ssh start && rm -f /boot/ssh ; rm -f /boot/ssh.txt" [...]
This will enable and start sshd if /boot/ssh or /boot/ssh.txt is present. Once enabled, one can login via SSH.
Arch Linux ARM
To install Arch Linux instead, we also have to prepare the SD card:
fdisk /dev/sdf > 100 MB 0x0b (W95 FAT32) > 0x83 (Linux) mkfs.vfat -vn BOOT /dev/sdf1 # -F 32 needed?[6] mkfs.ext4 -vL root /dev/sdf2 mkdir /mnt/rpi-{boot,root} mount -t vfat /dev/sdf1 /mnt/rpi-boot mount -t ext4 /dev/sdf2 /mnt/rpi-root
Grab the correct image from the download site and install like:
wget http://os.archlinuxarm.org/os/ArchLinuxARM-rpi-3-latest.tar.gz{,.md5,.sig} md5sum -c ArchLinuxARM*.md5 gpg --recv-keys 68B3537F39A313B3E574D06777193F152BDBE6A6 gpg --verify ArchLinuxARM*.sig
Extract into the root, and move the /boot
contents to the first partition:
bsdtar -xpf ArchLinuxARM*tar.gz -C /mnt/rpi-root/ mv /mnt/rpi-root/boot/* /mnt/rpi-boot/ umount /mnt/rpi-{boot,root}
With that, Arch Linux should be able to boot.
NetBSD
Not exactly a headless setup, but close enough. The installation, in short:
wget https://cdn.netbsd.org/pub/NetBSD/NetBSD-8.0/evbarm-earmv7hf/binary/gzimg/armv7.img.gz # There's no checksum here :-\ gzip -dc armv7.img.gz | pv > /dev/sdX
Again, NetBSD doesn't seem to publish checksums for these images, so let's at least verify if our image made it to the SDcard correctly:
$ gzip -dc armv7.img.gz | wc -c && gzip -dc armv7.img.gz | sha256sum 1669922816 82a1e487c4d4109f19040f5f89868086da9c59215cdbfb53cf5bffd20f3767dd
$ pv -Ss 1669922816 /dev/sdX | sha256sum | grep 82a1e487c4d4109f19040f5f89868086da9c59215cdbfb53cf5bffd20f3767dd 82a1e487c4d4109f19040f5f89868086da9c59215cdbfb53cf5bffd20f3767dd
NetBSD will boot and will grow its filesystem to fill the entire SDcard and reboot again. We can setup a user account and then use SSH to login, so that we can continue in a headless fashion:
useradd -m -G wheel dummy passwd dummy
Postinst
Packages
Install missing packages:
apt-get install acl apt-listchanges atop attr autossh bc bzip2 ca-certificates curl deborphan debsums git haveged s-nail htop iftop iotop irqbalance ksh less libpam-tmpdir lsof mlocate netcat-openbsd openssh-server p7zip-full pbzip2 pigz pv pwgen rsync screen sharutils smartmontools strace sudo sysstat vim vnstat whois zsh
For x86 based systems:
firmware-iwlwifi i7z intel-microcode mcelog memtest86+ msr-tools
For desktop systems:
chromium flashplugin-nonfree gedit gnome-core gnome-themes gnome-tweak-tool icedove enigmail firefox libcanberra-gtk-module xul-ext-https-everywhere xul-ext-noscript xul-ext-refcontrol libreoffice-calc libreoffice-writer pidgin pidgin-otr rdesktop sox xtightvncviewer ekiga
Zram
Zram can be used, but with Debian/jessie, zramctl binary is not included in util-linux yet:
$ dpkg-architecture -q DEB_HOST_ARCH
armhf
$ wget http://ftp.us.debian.org/debian/pool/main/u/util-linux/util-linux_2.29.1-1_armhf.deb
$ dpkg -x util-linux_2.29.1-1_armhf.deb x
$ sudo mv x/sbin/zramctl /usr/local/sbin/
Then, as root:
modprobe zram && modprobe lz4_compress && sleep 1 && zramctl -a lz4 -f -s 512M && mkswap /dev/zram0 && swapon -p 2 /dev/zram0
WiFi
The RPI 3 supports 802.11n WiFi, but only the 2.4 GHz variant:[7][8]
$ cat /etc/wpa_supplicant/wpa_supplicant.conf [...] network={ disabled=0 ssid="ESSID" psk="passphrase" proto=WPA2 key_mgmt=WPA-PSK pairwise=CCMP group=CCMP }
Sensors
Instead of using lm-sensors, the RPI can be queried via its (pre-installed) libraspberrypi-bin tools:[9]
$ /opt/vc/bin/vcgencmd measure_temp temp=48.3'C
Miscellaneous
Disable Bluetooth, if not needed:
$ grep ^B /etc/default/bluetooth BLUETOOTH_ENABLED=0 $ systemctl disable bluetooth hciuart $ systemctl stop bluetooth hciuart
Enable periodic debsums verification:
$ grep ^C /etc/default/debsums CRON_CHECK=weekly
Enable sysstat collection:
$ grep ^ENA /etc/default/sysstat ENABLED="true"
Mount /tmp as tmpfs:
$ grep ^[A-Z] /etc/default/tmpfs RAMTMP=yes
View the kernel configuration, if needed:
$ sudo modprobe configs $ ls -go /proc/config.gz -r--r--r-- 1 31643 Mar 1 01:23 /proc/config.gz
Installing irqbalance may not help so much, because the board may not support it:[10]
$ cat /proc/interrupts CPU0 CPU1 CPU2 CPU3 16: 0 0 0 0 bcm2836-timer 0 Edge arch_timer 17: 1325340 2396930 2651875 1604640 bcm2836-timer 1 Edge arch_timer 23: 402 0 0 0 ARMCTRL-level 1 Edge 3f00b880.mailbox 24: 2 0 0 0 ARMCTRL-level 2 Edge VCHIQ doorbell 39: 1 0 0 0 ARMCTRL-level 41 Edge 46: 0 0 0 0 ARMCTRL-level 48 Edge bcm2708_fb dma 48: 54282 0 0 0 ARMCTRL-level 50 Edge DMA IRQ 50: 0 0 0 0 ARMCTRL-level 52 Edge DMA IRQ 62: 435446749 0 0 0 ARMCTRL-level 64 Edge dwc_otg, dwc_otg_pcd, dwc_otg_hcd:usb1[11][12] 79: 0 0 0 0 ARMCTRL-level 81 Edge 3f200000.gpio:bank0 80: 0 0 0 0 ARMCTRL-level 82 Edge 3f200000.gpio:bank1 86: 43862 0 0 0 ARMCTRL-level 88 Edge mmc0 92: 580497 0 0 0 ARMCTRL-level 94 Edge mmc1 FIQ[13]: usb_fiq IPI0: 0 0 0 0 CPU wakeup interrupts IPI1: 0 0 0 0 Timer broadcast interrupts IPI2: 20480575 37755008 26262138 26052578 Rescheduling interrupts IPI3: 1088 1058 1115 1068 Function call interrupts IPI4: 2767657 3219384 2344363 2403153 Single function call interrupts IPI5: 0 0 0 0 CPU stop interrupts IPI6: 0 0 0 0 IRQ work interrupts IPI7: 0 0 0 0 completion interrupts Err: 0
Kernel
To build a new kernel[14][15][16], we'll better cross-compile, otherwise the process may just take too long:
git clone git://github.com/raspberrypi/linux raspberrypi_linux-git # Add --depth=1 to omit some history. git clone git://github.com/raspberrypi/tools raspberrypi_tools-git git clone --depth 1 https://github.com/raspberrypi/firmware raspberrypi_firmware-git # Omit --depth=1 to get the full history.
Checkout a stable kernel release:
cd ../raspberrypi_linux-git git checkout rpi-4.12.y
aarch32
Adjust the PATH
variable accordingly:
export PATH=../arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin:$PATH # Linaro Cross Compiler[17] export PATH=/opt/ctng/tools/arm-unknown-linux-gnueabihf/bin:$PATH # Crosstool-NG
Create a viable kernel configuration:
export DIR=${TMPDIR:-/tmp}/aarch32 && [ -d $DIR ] && rm -rf $DIR && mkdir $DIR
make O=$DIR ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2709_defconfig
Compile with:
make -j4 O=$DIR ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs
Collect all the bits and install on our RPI:
export KERNEL=kernel7 INSTDIR=${TMPDIR:-/tmp}/aarch32_inst
rm -rf $INSTDIR && mkdir -p $INSTDIR/boot/overlays
make O=$DIR ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=$INSTDIR modules_install
scripts/mkknlimg $DIR/arch/arm/boot/zImage $INSTDIR/boot/$KERNEL.img
aarch64
Adjust the PATH
variable accordingly:
export PATH=../arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin:$PATH # Linaro Cross Compiler[17] export PATH=/opt/ctng/tools/aarch64-unknown-linux-gnueabi/bin:$PATH # Crosstool-NG
Create a viable kernel configuration:[18]
export DIR=${TMPDIR:-/tmp}/aarch64 && [ -d $DIR ] && rm -rf $DIR && mkdir $DIR
make O=$DIR ARCH=arm64 CROSS_COMPILE=aarch64-unknown-linux-gnueabi- bcmrpi3_defconfig
Compile with:
make -j4 O=$DIR ARCH=arm64 CROSS_COMPILE=aarch64-unknown-linux-gnueabi- Image.gz modules dtbs scripts/mkknlimg $DIR/arch/arm64/boot/Image.gz $DIR/arch/arm64/boot/kernel8.img
Collect all the bits and install onto the SD card:
export RPIROOT=/mnt/rpi-root RPIBOOT=/mnt/rpi-boot # Where the SD card is mounted sudo tar -C $RPIBOOT -cvf ~/backup_boot.tar . # Backup boot! sudo tar -C $RPIROOT/lib/modules -cvf ~/backup_modules.tar . # Backup modules! sudo cp -ivr ../raspberrypi_firmware-git/boot/* $RPIBOOT/ # This will populate $RPIBOOT; only needed once. sudo cp -iv $DIR/arch/arm64/boot/kernel8.img $RPIBOOT/kernel8.img sudo cp -iv $DIR/arch/arm64/boot/Image $RPIBOOT/kernel8.img sudo cp -iv $DIR/arch/arm64/boot/dts/broadcom/bcm{2710,2837}-rpi-3-b.dtb $RPIBOOT/ sudo mkdir -p $RPIBOOT/overlays sudo cp -iv $DIR/arch/arm64/boot/dts/overlays/* $RPIBOOT/overlays/ echo "kernel=kernel8.img" | sudo tee -a $RPIBOOT/config.txt # Should already be in place sudo env PATH=$PATH make O=$DIR ARCH=arm64 \ # The env PATH trick may (not) be necessary[19] CROSS_COMPILE=aarch64-unknown-linux-gnueabi- INSTALL_MOD_PATH=$RPIROOT modules_install sudo umount -v $RPIROOT $RPIBOOT
If things don't work out, we restore from backup:
sudo tar -C $RPIBOOT -xpf ~/backup_boot.tar sudo tar -C $RPIROOT/lib/modules -xpf ~/backup_modules.tar
Architecture
Model | CPU | Port |
---|---|---|
Raspberry Pi Model A+ | BCM2835 SoC 32-bit ARMv6 + VFPv2 | armel |
Raspberry Pi 1 Model B | (same) | (same) |
Raspberry Pi Model B+ | (same) | (same) |
Raspberry Pi 2 Model B | BCM2836 SoC 32-bit quad-core ARM Cortex-A7 (ARMv7) | armhf |
Raspberry Pi 3 Model B | BCM2837 SoC 64-bit quad-core ARM Cortex-A53 (ARMv8) | armhf / arm64 |
Links
- Enabling SSH on RPi without screen - keystrokes for raspi-config?
- Arch Linux: Raspberry Pi
- Kernel building
- Linux mainlining effort
- Raspberry Pi2 and Pi3 running pure Debian 9 (“Stretch”) and the Linux Mainline/Vanilla Kernel
- Zero Client: Boot kernel and root filesystem from network with a Raspberry Pi2 or Pi3
- Debian + Mainline Linux Kernel + u-boot Bootstrap Script and Tutorial for RPi2/3
References
- ↑ About the SD and SDXC card slot: Which SD card formats work in the SD card slot?
- ↑ Disk utility tip: Fix ‘couldn’t unmount disk’ errors
- ↑ “dd: /dev/disk4: Permission denied” error when making LiveUSB on Mac OS X
- ↑ Why is “/dev/rdisk” about 20 times faster than “/dev/disk” in Mac OS X
- ↑ Re: /dev/disk and /dev/rdisk behavior
- ↑ Raspberry Pi 3 64 bit Install: Make Filesystems
- ↑ Setting WiFi up via the command line
- ↑ Does Pi3 Wi-Fi support 5 GHz and does it need an extra antenna?
- ↑ Onboard hardware sensors
- ↑ rpi 2: Unable to change irq affinity
- ↑ Was this possibly related to: Disable GPE ACPI interrupts on boot?
- ↑ disable_gpe6F.service
- ↑ FIQ Handlers in the ARM Linux Kernel
- ↑ Kernel building
- ↑ Raspberry Pi Kernel Compilation
- ↑ Building and Deploying Raspberry PI Kernel
- ↑ 17.0 17.1 CrossbuildingQuickStart: Should I be cross-compiling?
- ↑ Build a 64-bit Kernel for your Raspberry Pi 3
- ↑ sudo changes PATH - why?