Skip to content

Commit

Permalink
Optimize build script for Raspberry Pi 4 (#407)
Browse files Browse the repository at this point in the history
  • Loading branch information
meisenzahl committed Nov 13, 2020
1 parent 049e71e commit 8a1fde4
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 33 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ The following example uses Docker and assumes you have Docker correctly installe

4) When done, your image will be in the `builds` folder.

## Raspberry Pi 4

```
docker run --privileged -i -v /proc:/proc \
-v ${PWD}:/working_dir \
-w /working_dir \
debian:unstable \
./build-rpi.sh
```

## Further Information

More information about the concepts behind `live-build` and the technical decisions made to arrive at this set of tools to build an .iso can be found [on the wiki](https://github.com/elementary/os/wiki/Building-iso-Images).
77 changes: 44 additions & 33 deletions build-rpi.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,27 @@

# Install dependencies in host system
apt-get update
apt-get install -y --no-install-recommends ubuntu-keyring debootstrap qemu-user-static qemu-utils qemu-system-arm binfmt-support parted kpartx rsync dosfstools
apt-get install -y --no-install-recommends ubuntu-keyring debootstrap qemu-user-static qemu-utils qemu-system-arm binfmt-support parted kpartx rsync dosfstools xz-utils

# Make sure cross-running ARM ELF executables is enabled
update-binfmts --enable

rootdir=`pwd`
basedir=`pwd`/elementary-rpi
basedir=`pwd`/artifacts/elementary-rpi

# Size of .img file to build in MB. Approx 4GB required at this time, the rest is free space on /
size=5000
size=8000

export packages="elementary-minimal elementary-desktop elementary-standard"
export architecture="armhf"
export architecture="arm64"
export codename="focal"
export codename_latest="groovy"
export channel="daily"

version=6.0
YYYYMMDD="$(date +%Y%m%d)"
imagename=elementaryos-$version-$channel-rpi-$YYYYMMDD

mkdir -p ${basedir}
cd ${basedir}

Expand All @@ -30,6 +35,9 @@ cp /usr/bin/qemu-arm-static elementary-$architecture/usr/bin/
# Run the second stage of the bootstrap in QEMU
LANG=C chroot elementary-$architecture /debootstrap/debootstrap --second-stage

# Copy Raspberry Pi specific files
cp -r ${rootdir}/rpi/rootfs/writable/* elementary-${architecture}/

# Add the rest of the ubuntu repos
cat << EOF > elementary-$architecture/etc/apt/sources.list
deb http://ports.ubuntu.com/ubuntu-ports $codename main restricted universe multiverse
Expand All @@ -44,6 +52,11 @@ for f in ${rootdir}/etc/config/archives/*.pref; do cp -- "$f" "elementary-$archi
# Set codename/channel in added repos
sed -i "s/@CHANNEL/$channel/" elementary-$architecture/etc/apt/sources.list.d/*.list*
sed -i "s/@BASECODENAME/$codename/" elementary-$architecture/etc/apt/sources.list.d/*.list*
sed -i "s/@LATESTCODENAME/$codename_latest/" elementary-$architecture/etc/apt/sources.list.d/*.list*

# Set codename in added preferences
sed -i "s/@BASECODENAME/$codename/" elementary-$architecture/etc/apt/preferences.d/*.pref*
sed -i "s/@LATESTCODENAME/$codename_latest/" elementary-$architecture/etc/apt/preferences.d/*.pref*

echo "elementary" > elementary-$architecture/etc/hostname

Expand All @@ -60,8 +73,8 @@ EOF
cat << EOF > elementary-${architecture}/etc/fstab
# <file system> <mount point> <type> <options> <dump> <pass>
proc /proc proc nodev,noexec,nosuid 0 0
/dev/mmcblk0p2 / ext4 errors=remount-ro 0 1
/dev/mmcblk0p1 /boot/firmware vfat noauto 0 0
LABEL=writable / ext4 defaults,x-systemd.growfs 0 0
LABEL=system-boot /boot/firmware vfat defaults 0 1
EOF

export LC_ALL=C
Expand All @@ -88,21 +101,21 @@ LANG=C chroot elementary-$architecture /third-stage

# Create the disk and partition it
echo "Creating image file for Raspberry Pi"
dd if=/dev/zero of=${basedir}/elementary-rpi.img bs=1M count=$size
parted elementary-rpi.img --script -- mklabel msdos
parted elementary-rpi.img --script -- mkpart primary fat32 0 128
parted elementary-rpi.img --script -- mkpart primary ext4 128 -1
dd if=/dev/zero of=${basedir}/${imagename}.img bs=1M count=$size
parted ${imagename}.img --script -- mklabel msdos
parted ${imagename}.img --script -- mkpart primary fat32 0 256
parted ${imagename}.img --script -- mkpart primary ext4 256 -1

# Set the partition variables
loopdevice=`losetup -f --show ${basedir}/elementary-rpi.img`
loopdevice=`losetup -f --show ${basedir}/${imagename}.img`
device=`kpartx -va $loopdevice| sed -E 's/.*(loop[0-9])p.*/\1/g' | head -1`
device="/dev/mapper/${device}"
bootp=${device}p1
rootp=${device}p2

# Create file systems
mkfs.vfat $bootp
mkfs.ext4 $rootp
mkfs.vfat -n system-boot $bootp
mkfs.ext4 -L writable $rootp

# Create the dirs for the partitions and mount them
mkdir -p ${basedir}/bootp ${basedir}/root
Expand All @@ -112,36 +125,27 @@ mount $rootp ${basedir}/root
mkdir -p elementary-$architecture/boot/firmware
mount -o bind ${basedir}/bootp/ elementary-$architecture/boot/firmware

# RPi specific config files to configure bootloader
cat << EOF > elementary-$architecture/boot/firmware/config.txt
kernel=vmlinuz
initramfs initrd.img followkernel
enable_uart=1
dtparam=i2c_arm=on
dtparam=spi=on
EOF
# Copy Raspberry Pi specific files
cp -r ${rootdir}/rpi/rootfs/system-boot/* elementary-${architecture}/boot/firmware/

cat << EOF > elementary-$architecture/boot/firmware/cmdline.txt
net.ifnames=0 dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait fixrtc
EOF

# Install an RPi kernel and firmware
cat << EOF > elementary-$architecture/kernel
# Install Raspberry Pi specific packages
cat << EOF > elementary-$architecture/hardware
#!/bin/bash
apt-get --yes install linux-image-raspi linux-firmware-raspi2 u-boot-rpi
apt-get --yes install linux-image-raspi linux-firmware-raspi2 u-boot-rpi grub-efi-arm64 rpi-eeprom ubuntu-raspi-settings
cp /boot/vmlinuz /boot/firmware/vmlinuz
cp /boot/initrd.img /boot/firmware/initrd.img
# Copy device-tree blobs to fat32 partition
cp -r /lib/firmware/*-raspi/device-tree/* /boot/firmware/
cp -r /lib/firmware/*-raspi/device-tree/broadcom/* /boot/firmware/
cp -r /lib/firmware/*-raspi/device-tree/overlays /boot/firmware/
cp -r /usr/lib/*-raspi2/* /boot/firmware/
rm -f kernel
rm -f hardware
EOF

chmod +x elementary-$architecture/kernel
LANG=C chroot elementary-$architecture /kernel
chmod +x elementary-$architecture/hardware
LANG=C chroot elementary-$architecture /hardware

# Copy in any file overrides
cp -r ${rootdir}/etc/config/includes.chroot/* elementary-$architecture/
Expand Down Expand Up @@ -194,3 +198,10 @@ umount $rootp
kpartx -dv $loopdevice
losetup -d $loopdevice

echo "Compressing ${imagename}.img"
xz -z ${basedir}/${imagename}.img

cd "${basedir}"

md5sum ${imagename}.img.xz > ${imagename}.md5.txt
sha256sum ${imagename}.img.xz > ${imagename}.sha256.txt
1 change: 1 addition & 0 deletions rpi/rootfs/system-boot/cmdline.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
net.ifnames=0 dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=LABEL=writable rootfstype=ext4 elevator=deadline rootwait fixrtc
32 changes: 32 additions & 0 deletions rpi/rootfs/system-boot/config.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[pi4]
max_framebuffers=2

[all]
arm_64bit=1
kernel=vmlinuz
cmdline=cmdline.txt
initramfs initrd.img followkernel

# Enable the audio output, I2C and SPI interfaces on the GPIO header
dtparam=audio=on
dtparam=i2c_arm=on
dtparam=spi=on

# Enable the FKMS ("Fake" KMS) graphics overlay, enable the camera firmware
# and allocate 128Mb to the GPU memory
dtoverlay=vc4-fkms-v3d
gpu_mem=128
start_x=1

# Comment out the following line if the edges of the desktop appear outside
# the edges of your display
disable_overscan=1

# If you have issues with audio, you may try uncommenting the following line
# which forces the HDMI output into HDMI mode instead of DVI (which doesn't
# support audio output)
#hdmi_drive=2

# If you have a CM4, uncomment the following line to enable the USB2 outputs
# on the IO board (assuming your CM4 is plugged into such a board)
#dtoverlay=dwc2,dr_mode=host
37 changes: 37 additions & 0 deletions rpi/rootfs/writable/etc/apt/preferences.d/rpi.pref
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
Package: linux-firmware-raspi2
Pin: release n=@LATESTCODENAME
Pin-Priority: 990

Package: linux*-raspi*
Pin: release n=@LATESTCODENAME
Pin-Priority: 990

Package: ubuntu-raspi-settings
Pin: release n=@LATESTCODENAME
Pin-Priority: 990

Package: rpi-eeprom
Pin: release n=@LATESTCODENAME
Pin-Priority: 990

Package: libraspberrypi*
Pin: release n=@LATESTCODENAME
Pin-Priority: 990

Package: u-boot-rpi
Pin: release n=@LATESTCODENAME
Pin-Priority: 990

Package: grub*
Pin: release n=@LATESTCODENAME
Pin-Priority: 990

Explanation: Uninstall or do not install any Ubuntu-originated
Explanation: package versions other than those in the @BASECODENAME release
Package: *
Pin: release n=@BASECODENAME
Pin-Priority: 900

Package: *
Pin: release o=Ubuntu
Pin-Priority: -10
2 changes: 2 additions & 0 deletions rpi/rootfs/writable/etc/apt/sources.list.d/ubuntu-latest.list
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
deb http://ports.ubuntu.com/ubuntu-ports @LATESTCODENAME main restricted universe multiverse
deb http://ports.ubuntu.com/ubuntu-ports @LATESTCODENAME-updates main restricted universe multiverse
5 changes: 5 additions & 0 deletions rpi/rootfs/writable/etc/oem.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[OEM]
Manufacturer=Raspberry Pi Foundation
Product=Raspberry Pi
Logo=/etc/oem/logo.png
URL=https://www.raspberrypi.org/
Binary file added rpi/rootfs/writable/etc/oem/logo.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 8a1fde4

Please sign in to comment.