Install Alpine Linux on a Raspberry PI using macOS

May 5, 2019

The software and hardware used for this HOWTO are:

  1. Alpine Linux 3.8.4, armhf
  2. Raspberry Pi 3 Model B, and:
    1. USB keyboard
    2. TV with HDMI input and an HDMI cable
    3. MicroUSB 5V adapter as close to 2.5A as you can find (I used a 2A phone charger.)
  3. macOS Mojave 10.14.4 (diskutil)
  4. Samsung 32GB microSD
  5. Vivitar microSD card reader

Step 1. Partition the microSD with your Mac and unzip install.

Use Note to self: 3.9.3 is packaged with the golang programs compiled by 1.11 allocate an unreasonable amount of virtual memory issue. armhf 3.8.4 or arm7 3.9.3 (armhf 3.9.3 won't boot on a Pi).

Make sure you know for sure which disk is the microSD. If you're not sure, don't follow these steps—you could lose all the data on your Mac.

diskutil list
diskutil partitionDisk disk2 MBR FAT32 VOL1 256MB "Free Space" VOL2 R

export U=http://dl-cdn.alpinelinux.org/alpine/v3.8/releases/armhf
export F=alpine-rpi-3.8.4-armhf.tar.gz
curl $U/$F -o ~/Downloads/$F
curl $U/$F.sha256 -o ~/Downloads/$F.sha256
cd ~/Downloads/
shasum -c alpine-rpi-3.8.4-armhf.tar.gz.sha256

cd /Volumes/VOL1
tar xzvf ~/Downloads/alpine-rpi-3.8.4-armhf.tar.gz

cat>usercfg.txt<<EOF
# On the Pi, the GPU and the CPU share RAM.  This is a headless install, so 
# give the GPU the least amount of RAM it can get by with (16MB).
# This also triggers the Pi to use a cutdown version of the firmware (start_cd.elf).
gpu_mem=16

# Turn off audio and bluetooth.  (Note "dt" stands for device tree.)
dtparam=audio=off,pi3-disable-bt

# Enable mini UART as serial port (/dev/ttyS0).  
# Also, fixes VideoCore IV (aka the GPU or the VPU) frequency to 250MHz.
enable_uart=1
EOF

cd ~
# unmount microSD and remove microSD card reader from the Mac

Step 2. Create a Linux and a Linux swap partition on the Raspberry Pi.

The macOS diskutil listFilesystems diskutil does not provide the Linux format partition type.

# Put the microSD in the Raspberry Pi, then plug in keyboard, TV and the power supply.
# username = root (you won't need a password)
fdisk /dev/mmcblk0
# Use the following inputs:
# echo a     # Mark the DOS partition as bootable.
# echo 1 
# echo n     # new partition ... 
# echo p     # ... is a primary partition
# echo 2     # ... is the 2nd partition
# echo       # ... with a default first sector
# echo +30G  # ... and is 30GB big. (This leaves 1.1GB for the swap partition.)
# echo n     # new partition ...
# echo p     # ... is a primary partition
# echo 3     # ... is the 3rd partition
# echo       # ... with a default first sector
# echo       # ... and a default last sector
# echo t     # the partition type ... 
# echo 3     # ... of the third partition
# echo 82    # ... is Linux swap
# echo p     # print the partition table ...
# echo w     # ... and if it looks good, write it to disk
# ignore "Resource busy" warning

reboot

Configure The key step here is to edit the apk repositories manually and to type in the repository path correctly.the Pi as suits your environment—the config I used is listed below.

# login as root again

setup-alpine
# us                # keyboard
# us
# tallis            # hostname
# eth0
# 192.168.30.11     # static IP
# 255.255.255.0     # netmask
# 192.168.30.1      # gateway
# done
# no                # no manual network config
# eventarelli.com   # domain
# 192.168.30.1      # DNS server
# s3cr3t            # new root password
# s3cr3t
# US/Eastern        # timezone
# none              # no proxy
# e                 # edit apk repositories file manually
#                   # delete existing line "/media/..." and replace with:
#                   # http://dl-cdn.alpinelinux.org/alpine/v3.8/main 
#                   # :wq
# openssh
# chrony
# none              # don't store configs
# none              # don't create an apk cache

mkswap /dev/mmcblk0p3

apk add e2fsprogs
# you should see five packages installed: libuuid, libblkid, libcom_err, e2fsprogs-libs, and e2fsprogs.
mkfs.ext4 /dev/mmcblk0p2

Step 3: Install Alpine on the Linux partition and bind mount /boot directory.

Edit the cmdline.txt After the Linux partition is setup, the Pi still boots from the DOS partition, which means it loads the kernel, initramfs, and modloop images from the DOS /boot directory. When the kernel boots, it reads command line options from cmdline.txt (which you can check with dmesg | grep command), and sets the root filesystem to be the Linux partition. We bind mount the Linux /boot to the DOS /boot so any Alpine upgrade that affects the contents of the /boot directory (for example, a new kernel) will be written to the DOS partition. on the DOS partition (mmcblk0p1) to configure the kernel to use the Linux partition (mmcblk0p2) as the root file system.

mkdir /stage
mount /dev/mmcblk0p2 /stage
setup-disk -m sys /stage
# ignore all extlinux errors, the Pi doesn't need that program
# ignore note that you might need to "fix the MBR".

echo /dev/mmcblk0p1 /media/mmcblk0p1 vfat defaults 0 0 >> /stage/etc/fstab

# point root to 2nd partition
mount -o remount,rw /media/mmcblk0p1
sed -i '$ s/$/ root=\/dev\/mmcblk0p2/' /media/mmcblk0p1/cmdline.txt
cat /media/mmcblk0p1/cmdline.txt
modules=loop,squashfs,sd-mod,usb-storage quiet dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2


echo /media/mmcblk0p1/boot /boot none defaults,bind 0 0 >> /stage/etc/fstab

reboot

Resources

Links

https://wiki.alpinelinux.org/wiki/Raspberry_Pi
Concise explanation of installing Alpine Linux on the Pi, including the usercfg.txt as well as the bind mount.
https://pi3g.com/2019/01/10/alpine-boot-process-on-the-raspberry-pi/
bind mount, among other things. Great resource.
https://wiki.alpinelinux.org/wiki/Raspberry_Pi_Zero_W_-_Installation
usercfg.txt for headless mode
https://www.raspberrypi.org/documentation/configuration/device-tree.md
dtparam
https://www.raspberrypi.org/documentation/configuration/uart.md
enable_uart=1
https://wiki.alpinelinux.org/wiki/Alpine_setup_scripts
answerfile
https://blog.w1r3.net/2018/04/16/automated-provisioning-using-apkovl.html
apkovl