Install Alpine Linux 3.10.2 on a Raspberry PI using macOS
October 1, 2019
Changes from the last Alpine/Pi install post:
- Alpine Linux armv7 3.10.2 instead of armhf 3.8.4
- OSX Mojave 10.14.6 instead of 10.14.4 (which changed diskutil behavior)
- Document output of
- Deal with diskutil aligning partition to start on 1MiB boundary
- Setting up package mirror is much easier in this Alpine release, as you do not have to type in the URL.
- The chrony selection comes before you pick the mirror.
- Added a step 4 to add a non-privileged user so you can SSH to the server.
The software and hardware used for this HOWTO are:
- Alpine Linux 3.10.2, armv7
- Raspberry Pi 3 Model B, and:
- USB keyboard
- TV with HDMI input and an HDMI cable
- 5V 2.5A Switching Power Supply with 20AWG MicroUSB Cable
- macOS Mojave 10.14.6 (diskutil)
- Samsung 32GB microSD
- Vivitar microSD card reader
Step 1. Partition the microSD with your Mac and unzip install.
Make sure you know for sure which disk is the microSD. If you're not sure, stop.
You could lose all the data on your Mac.
$ diskutil list /dev/disk0 (internal, physical): #: TYPE NAME SIZE IDENTIFIER 0: GUID_partition_scheme *751.3 GB disk0 1: EFI EFI 209.7 MB disk0s1 2: Apple_APFS Container disk1 751.1 GB disk0s2 /dev/disk1 (synthesized): #: TYPE NAME SIZE IDENTIFIER 0: APFS Container Scheme - +751.1 GB disk1 Physical Store disk0s2 1: APFS Volume Macintosh HD 652.6 GB disk1s1 2: APFS Volume Preboot 42.1 MB disk1s2 3: APFS Volume Recovery 510.0 MB disk1s3 4: APFS Volume VM 3.2 GB disk1s4 /dev/disk2 (external, physical): #: TYPE NAME SIZE IDENTIFIER 0: FDisk_partition_scheme *31.4 GB disk2 1: DOS_FAT_32 VOL1 256.0 MB disk2s1
If you are totally sure you know which disk is the USB stick with the MicroSD (it was disk2 for me), run:
$ diskutil partitionDisk disk2 MBR FAT32 VOL1 256MB "Free Space" VOL2 R
Download armv7 3.10.2 and untar it onto the partition you just created:
cd /Volumes/VOL1 tar xzvf ~/Downloads/alpine-rpi-3.10.2-armv7.tar.gz
Create a usercfg.txt to suit what you will use the Raspberry PI for—mine will be a headless server. For more information on setting up the usercfg.txt, see links 3, 4, and 5 below.
$ 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 USB card reader in Finder and take out the microSD card.
Step 2. Create a Linux and a Linux swap partition on the Raspberry Pi.
Since OSX diskutil does not provide the Linux format partition type, so you have to make this partition using the Raspberry Pi. Put the microSD in the Raspberry Pi, then plug in keyboard, TV, ethernet cable and lastly the power supply.
Make the DOS partition bootable.
# username = root (you won't need a password) fdisk /dev/mmcblk0 # Use the following inputs: a # Mark the DOS partition as bootable. 1 p Disk /dev/mmcblk0: 29 GB, 31440502784 bytes, 61407232 sectors 3022 cylinders, 255 heads, 63 sectors/track Units: sectors of 1 * 512 = 512 bytes Device Boot StartCHS EndCHS StartLBA EndLBA Sectors Size Id Type /dev/mmcblk0p1 * 1023,254,63 1023,254,63 2048 502047 500000 244M b Win95 FAT32
Add the Linux partition. This the big difference from the previous blog post—you don't accept the default first sector (63), and instead add one to the EndLBA of the first partition and use that.
n # new partition ... p # ... is a primary partition 2 # ... is the 2nd partition 502048 # ... 1 + EndLBA of first partition +27G # ... This leaves 2GB for the swap partition. p # ... so you can read the EndLBA of the second partition.
Finally, add the swap partition.
n # new partition ... p # ... is a primary partition 3 # ... is the 3rd partition 57125152 # ... 1 + EndLBA of first partition # ... and a default last sector t # the partition type ... 3 # ... of the third partition 82 # ... is Linux swap p # print the partition table ... w # ... and if it looks good, write it to disk # ignore "Resource busy" warning reboot
Run setup-alpine. It has improved since 3.8.
# login as root again setup-alpine # us # keyboard # us # palestrina # hostname # eth0 # 192.168.30.12 # 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 # chrony # take the default # 1 # use the CDN mirror # openssh # none # don't store configs # none # don't create an apk cache
Create the filesystems.
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
When the kernel boots, it reads command line options from cmdline.txt (which you can
check with dmesg | grep
command), and sets the
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
Step 4: Add a non-privileged user
The default openSSH configuration won't let root connect with a password. Since I'm using this as a headless server, I want a user that I can use to login remotely via SSH. I also want to put that user in the wheel group and edit the sudo config so this user can become root.
# adduser mark Changing password for mark New password: Retype password: passwd: password for mark changed by root
Add user mark to the wheel group.
# # adduser mark wheel # groups mark mark wheel
Install sudo and let members of wheel to execute any command (with a password).
# apk add visudo # visudo # uncomment: %wheel ALL=(ALL) ALL
It's good to go—type
halt to shutdown Alpine and
then plug in the Pi to your server network.
- 1. 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.
- 2. https://pi3g.com/2019/01/10/alpine-boot-process-on-the-raspberry-pi/
- bind mount, among other things. Great resource.
- 3. https://wiki.alpinelinux.org/wiki/Raspberry_Pi_Zero_W_-_Installation
- usercfg.txt for headless mode
- 4. https://www.raspberrypi.org/documentation/configuration/device-tree.md
- 5. https://www.raspberrypi.org/documentation/configuration/uart.md
- 6. https://wiki.alpinelinux.org/wiki/Alpine_setup_scripts