1
0
Fork 0
This repository has been archived on 2023-03-27. You can view files and clone it, but cannot push or open issues or pull requests.
raspberrypi-build/build.sh

418 lines
8.5 KiB
Bash
Raw Normal View History

2016-04-11 06:21:07 +00:00
#!/bin/bash -e
2017-07-03 00:52:41 +00:00
export IMG_NAME='BarnacleOS'
export HOSTNAME='barnacleos'
export USERNAME='user'
export PASSWORD='password'
2017-07-02 11:07:37 +00:00
export BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
2017-07-02 11:08:24 +00:00
export DEPLOY_DIR="$BASE_DIR/deploy"
2017-07-03 00:17:20 +00:00
export ROOTFS_DIR="$BASE_DIR/rootfs"
2017-07-03 00:24:50 +00:00
export MOUNT_DIR="$BASE_DIR/mnt"
2017-07-02 11:07:37 +00:00
2017-07-03 00:55:48 +00:00
export IMG_DATE="$(date +%Y-%m-%d)"
2017-07-02 13:18:10 +00:00
2017-07-03 00:55:48 +00:00
export IMG_FILE="$DEPLOY_DIR/$IMG_DATE-${IMG_NAME}.img"
export ZIP_FILE="$DEPLOY_DIR/$IMG_DATE-${IMG_NAME}.zip"
2017-07-02 18:01:01 +00:00
2017-07-02 11:07:37 +00:00
export QUILT_NO_DIFF_INDEX=1
export QUILT_NO_DIFF_TIMESTAMPS=1
2017-07-02 11:10:54 +00:00
export QUILT_REFRESH_ARGS='-p ab'
2017-07-02 11:07:37 +00:00
# dependencies_check
# $@ Dependnecy files to check
#
# Each dependency is in the form of a tool to test for, optionally followed by
# a : and the name of a package if the package on a Debian-ish system is not
# named for the tool (i.e., qemu-user-static).
dependencies_check() {
local missing
if [[ -f "$1" ]]; then
for dep in $(cat "$1"); do
if ! hash ${dep%:*} 2>/dev/null; then
missing="${missing:+$missing }${dep#*:}"
fi
done
fi
if [[ "$missing" ]]; then
tput setaf 1 # Red color
echo 'Reqired dependencies not installed.'
echo 'This can be resolved on Debian/Raspbian systems by installing the following packages:'
for package_name in $missing; do
echo " * $package_name"
done
tput sgr0 # No color
false
fi
}
2017-07-03 01:04:47 +00:00
on_chroot() {
capsh --drop=cap_setfcap "--chroot=$ROOTFS_DIR/" -- "$@"
}
2017-07-03 06:48:36 +00:00
apply_patches() {
pushd "$ROOTFS_DIR" > /dev/null
2017-07-04 19:44:58 +00:00
export QUILT_PATCHES="$BASE_DIR/patches"
2017-07-03 06:48:36 +00:00
quilt upgrade
RC=0
2017-07-04 19:44:58 +00:00
quilt push "$1" || RC=$?
2017-07-03 06:48:36 +00:00
case "$RC" in
0|2)
;;
*)
false
;;
esac
popd > /dev/null
}
2017-07-03 01:04:47 +00:00
unmount() {
if [ -z "$1" ]; then
2017-07-03 11:17:27 +00:00
local DIR=$PWD
else
2017-07-03 11:17:27 +00:00
local DIR=$1
fi
while mount | grep -q "$DIR"; do
2017-07-03 11:17:27 +00:00
local LOCS=$(mount | grep "$DIR" | cut -f 3 -d ' ' | sort -r)
for loc in $LOCS; do
umount "$loc"
done
done
}
unmount_image() {
sync
sleep 1
2017-07-03 11:17:27 +00:00
local LOOP_DEVICES=$(losetup -j "$1" | cut -f1 -d ':')
for LOOP_DEV in $LOOP_DEVICES; do
if [ -n "$LOOP_DEV" ]; then
local MOUNTED_DIR=$(mount | grep "$(basename "$LOOP_DEV")" | head -n 1 | cut -f 3 -d ' ')
if [ -n "$MOUNTED_DIR" ] && [ "$MOUNTED_DIR" != "/" ]; then
unmount "$(dirname "$MOUNTED_DIR")"
fi
2017-07-03 11:17:27 +00:00
sleep 1
2017-07-03 11:17:27 +00:00
losetup -d "$LOOP_DEV"
fi
done
}
2017-07-03 11:51:22 +00:00
##
# Prepare environment.
#
2017-07-03 06:28:10 +00:00
if [ "$(id -u)" != '0' ]; then
echo 'Please run as root' 1>&2
exit 1
fi
2017-07-03 00:56:30 +00:00
2017-07-03 06:28:10 +00:00
dependencies_check "$BASE_DIR/depends"
2017-07-03 00:58:19 +00:00
2017-07-03 06:28:10 +00:00
mkdir -p "$DEPLOY_DIR"
mkdir -p "$MOUNT_DIR"
2017-07-02 11:07:37 +00:00
2017-07-03 06:40:57 +00:00
cd "$BASE_DIR"
2017-07-02 11:30:26 +00:00
2017-07-03 11:51:22 +00:00
##
# Bootstrap a basic Debian system.
#
2017-07-03 06:42:46 +00:00
if [ ! -d "$ROOTFS_DIR" ]; then
ARCH="$(dpkg --print-architecture)"
if [ "$ARCH" != 'armhf' ]; then
BOOTSTRAP_CMD='qemu-debootstrap'
else
BOOTSTRAP_CMD='debootstrap'
fi
capsh --drop=cap_setfcap -- -c "$BOOTSTRAP_CMD \
--components=main,contrib,non-free \
--arch armhf \
--keyring ./files/raspberrypi.gpg \
jessie \
$ROOTFS_DIR \
http://mirrordirector.raspbian.org/raspbian/" || rmdir "$ROOTFS_DIR/debootstrap"
fi
2017-07-04 19:44:58 +00:00
##
# Prepare for Quilt patching.
#
rm -rf "$ROOTFS_DIR/.pc"
mkdir "$ROOTFS_DIR/.pc"
2017-07-05 07:19:20 +00:00
##
# Prevent services to start after package installation in chroot environment.
#
install -m 744 files/policy-rc.d "$ROOTFS_DIR/usr/sbin/policy-rc.d"
2017-07-03 11:51:22 +00:00
##
# Mount virtual file systems.
#
2017-07-03 09:53:52 +00:00
mount --bind /dev "$ROOTFS_DIR/dev"
mount --bind /dev/pts "$ROOTFS_DIR/dev/pts"
mount -t proc /proc "$ROOTFS_DIR/proc"
mount --bind /sys "$ROOTFS_DIR/sys"
2017-07-03 09:48:00 +00:00
2017-07-05 07:09:58 +00:00
##
2017-07-05 07:33:27 +00:00
# Add /etc/fstab and /etc/mtab
2017-07-05 07:09:58 +00:00
#
2017-07-05 07:33:27 +00:00
install -m 644 files/fstab "$ROOTFS_DIR/etc/fstab"
ln -nsf /proc/mounts "$ROOTFS_DIR/etc/mtab"
2017-07-05 07:09:58 +00:00
2017-07-03 11:51:22 +00:00
##
# Prepare package manager.
#
2017-07-03 06:42:46 +00:00
install -m 644 files/sources.list "$ROOTFS_DIR/etc/apt/"
on_chroot apt-key add - < files/raspberrypi.gpg.key
2017-07-03 06:42:46 +00:00
install -m 644 files/raspberrypi-kernel-and-bootloader "$ROOTFS_DIR/etc/apt/preferences.d/"
2017-07-05 08:02:03 +00:00
install -m 644 files/50raspi "$ROOTFS_DIR/etc/apt/apt.conf.d/"
on_chroot << EOF
2017-07-03 06:42:46 +00:00
apt-get update
apt-get dist-upgrade -y
EOF
2017-07-05 07:26:31 +00:00
##
# Install kernel and bootloader.
2017-07-05 07:26:31 +00:00
#
on_chroot << EOF
apt-get install -y raspberrypi-kernel raspberrypi-bootloader
EOF
2017-07-05 07:26:31 +00:00
##
# Prepare Raspberry Pi boot partition.
#
2017-07-05 07:26:31 +00:00
install -m 644 files/cmdline.txt "$ROOTFS_DIR/boot/"
install -m 644 files/config.txt "$ROOTFS_DIR/boot/"
2017-07-05 07:22:54 +00:00
##
# This script is executed at the end of each multiuser runlevel.
#
install -m 755 files/rc.local "$ROOTFS_DIR/etc/rc.local"
2017-07-05 07:31:01 +00:00
##
# Install SSH server
#
on_chroot << EOF
apt-get install -y ssh
EOF
apply_patches '01-no-root-login.diff'
2017-07-03 11:51:22 +00:00
##
# ?????
2017-07-03 11:51:22 +00:00
#
on_chroot << EOF
apt-get install -y raspberrypi-sys-mods
2017-07-03 06:42:46 +00:00
EOF
2017-07-05 07:44:31 +00:00
##
# Configure network.
#
2017-07-05 08:03:30 +00:00
install -m 644 files/resolv.conf "$ROOTFS_DIR/etc/"
install -m 644 files/interfaces "$ROOTFS_DIR/etc/network/interfaces"
install -m 644 files/ipv6.conf "$ROOTFS_DIR/etc/modprobe.d/ipv6.conf"
2017-07-03 06:42:46 +00:00
echo $HOSTNAME > "$ROOTFS_DIR/etc/hostname"
chmod 644 "$ROOTFS_DIR/etc/hostname"
2017-07-03 08:41:53 +00:00
echo "127.0.1.1 $HOSTNAME" >>"$ROOTFS_DIR/etc/hosts"
2017-07-03 06:42:46 +00:00
2017-07-05 07:44:31 +00:00
##
# Add user.
#
2017-07-05 08:12:25 +00:00
on_chroot << EOF
apt-get install -y sudo
EOF
2017-07-05 09:00:08 +00:00
apply_patches '02-bashrc.diff'
apply_patches '03-useradd.diff'
2017-07-05 07:38:56 +00:00
on_chroot << EOF
2017-07-03 06:42:46 +00:00
if ! id -u $USERNAME >/dev/null 2>&1; then
adduser --disabled-password --gecos "" $USERNAME
fi
echo "$USERNAME:$PASSWORD" | chpasswd
passwd -d root
2017-07-05 07:48:04 +00:00
adduser $USERNAME sudo
2017-07-03 06:42:46 +00:00
EOF
2017-07-05 07:44:31 +00:00
##
# Configure time zone.
#
on_chroot << EOF
2017-07-03 06:42:46 +00:00
debconf-set-selections <<SELEOF
tzdata tzdata/Areas select Etc
tzdata tzdata/Zones/Etc select UTC
SELEOF
2017-07-05 07:50:44 +00:00
apt-get install -y tzdata
2017-07-03 06:42:46 +00:00
EOF
2017-07-05 07:44:31 +00:00
##
# Install additional packages which maybe can be removed safely.
#
on_chroot << EOF
2017-07-06 00:47:09 +00:00
apt-get install -y ca-certificates
2017-07-03 06:42:46 +00:00
EOF
2017-07-05 07:45:40 +00:00
##
# Enable swap.
#
on_chroot << EOF
apt-get install -y dphys-swapfile
EOF
2017-07-05 09:00:08 +00:00
apply_patches '04-swap.diff'
2017-07-05 07:45:40 +00:00
2017-07-05 07:47:28 +00:00
##
# Configure environment.
#
2017-07-05 09:00:08 +00:00
apply_patches '05-path.diff'
2017-07-03 06:42:46 +00:00
2017-07-03 11:40:59 +00:00
##
# Wi-Fi firmware and tools.
#
on_chroot << EOF
2017-07-05 08:17:46 +00:00
apt-get install -y wpasupplicant wireless-tools crda
2017-07-03 06:42:46 +00:00
EOF
2017-07-03 11:38:42 +00:00
##
2017-07-03 11:40:59 +00:00
# DHCP client.
2017-07-03 11:38:42 +00:00
#
on_chroot << EOF
2017-07-04 08:45:25 +00:00
apt-get install -y dhcpcd5
EOF
2017-07-03 11:40:59 +00:00
2017-07-04 13:37:52 +00:00
##
# Save fake hardware clock time for more realistic time after startup.
#
2017-07-05 07:53:08 +00:00
on_chroot << EOF
2017-07-05 08:14:11 +00:00
apt-get install -y fake-hwclock ntp
2017-07-05 07:53:08 +00:00
systemctl disable hwclock.sh
fake-hwclock save
EOF
2017-07-04 13:37:52 +00:00
2017-07-03 11:38:42 +00:00
##
# Unmount virtual file systems.
#
2017-07-04 16:34:06 +00:00
umount "$ROOTFS_DIR/sys"
umount "$ROOTFS_DIR/proc"
umount "$ROOTFS_DIR/dev/pts"
umount "$ROOTFS_DIR/dev"
2017-07-03 11:38:42 +00:00
2017-07-04 19:44:58 +00:00
##
# Cleanup after Quilt patching.
#
rm -rf "$ROOTFS_DIR/.pc"
2017-07-05 07:19:20 +00:00
##
# Allow services to start.
#
rm -f "$ROOTFS_DIR/usr/sbin/policy-rc.d"
2017-07-03 11:38:42 +00:00
##
# Prepare image file systems.
#
2017-07-03 06:42:46 +00:00
rm -f "$IMG_FILE"
BOOT_SIZE=$(du --apparent-size -s "$ROOTFS_DIR/boot" --block-size=1 | cut -f 1)
TOTAL_SIZE=$(du --apparent-size -s "$ROOTFS_DIR" --exclude var/cache/apt/archives --block-size=1 | cut -f 1)
IMG_SIZE=$((BOOT_SIZE + TOTAL_SIZE + (800 * 1024 * 1024)))
truncate -s $IMG_SIZE "$IMG_FILE"
fdisk -H 255 -S 63 "$IMG_FILE" <<EOF
o
n
8192
+$((BOOT_SIZE * 2 / 512))
p
t
c
n
8192
p
w
EOF
PARTED_OUT=$(parted -s "$IMG_FILE" unit b print)
BOOT_OFFSET=$(echo "$PARTED_OUT" | grep -e '^ 1' | xargs echo -n \
| cut -d" " -f 2 | tr -d B)
BOOT_LENGTH=$(echo "$PARTED_OUT" | grep -e '^ 1' | xargs echo -n \
| cut -d" " -f 4 | tr -d B)
ROOT_OFFSET=$(echo "$PARTED_OUT" | grep -e '^ 2' | xargs echo -n \
| cut -d" " -f 2 | tr -d B)
ROOT_LENGTH=$(echo "$PARTED_OUT" | grep -e '^ 2' | xargs echo -n \
| cut -d" " -f 4 | tr -d B)
BOOT_DEV=$(losetup --show -f -o $BOOT_OFFSET --sizelimit $BOOT_LENGTH "$IMG_FILE")
ROOT_DEV=$(losetup --show -f -o $ROOT_OFFSET --sizelimit $ROOT_LENGTH "$IMG_FILE")
mkdosfs -n boot -F 32 -v $BOOT_DEV > /dev/null
2017-07-04 22:15:25 +00:00
mkfs.ext4 -O ^huge_file $ROOT_DEV > /dev/null
2017-07-03 06:42:46 +00:00
2017-07-03 11:38:42 +00:00
##
# Mount image file systems.
#
2017-07-03 09:54:24 +00:00
mkdir -p "$MOUNT_DIR"
2017-07-03 06:42:46 +00:00
mount -v $ROOT_DEV "$MOUNT_DIR" -t ext4
2017-07-03 09:54:24 +00:00
mkdir -p "$MOUNT_DIR/boot"
2017-07-03 06:42:46 +00:00
mount -v $BOOT_DEV "$MOUNT_DIR/boot" -t vfat
2017-07-03 11:38:42 +00:00
##
# Copy root file system to image file systems.
#
2017-07-03 06:42:46 +00:00
rsync -aHAXx --exclude var/cache/apt/archives "$ROOTFS_DIR/" "$MOUNT_DIR/"
2017-07-03 11:31:42 +00:00
##
# Store file system UUIDs to configuration files.
#
2017-07-03 06:42:46 +00:00
IMGID="$(fdisk -l "$IMG_FILE" | sed -n 's/Disk identifier: 0x\([^ ]*\)/\1/p')"
BOOT_PARTUUID="$IMGID-01"
ROOT_PARTUUID="$IMGID-02"
sed -i "s/BOOTDEV/PARTUUID=$BOOT_PARTUUID/" "$MOUNT_DIR/etc/fstab"
sed -i "s/ROOTDEV/PARTUUID=$ROOT_PARTUUID/" "$MOUNT_DIR/etc/fstab"
sed -i "s/ROOTDEV/PARTUUID=$ROOT_PARTUUID/" "$MOUNT_DIR/boot/cmdline.txt"
2017-07-03 11:31:42 +00:00
##
2017-07-03 11:24:44 +00:00
# Unmount all file systems and minimize image file for distribution.
2017-07-03 11:31:42 +00:00
#
2017-07-04 22:57:29 +00:00
ROOT_DEV=$(mount | grep "$MOUNT_DIR " | cut -f1 -d ' ')
2017-07-04 22:50:09 +00:00
umount "$MOUNT_DIR/boot"
umount "$MOUNT_DIR"
2017-07-03 06:42:46 +00:00
zerofree -v "$ROOT_DEV"
unmount_image "$IMG_FILE"
2017-07-03 11:31:42 +00:00
##
2017-07-03 11:24:44 +00:00
# Create zip archive with image file for distribution.
2017-07-03 11:31:42 +00:00
#
2017-07-03 06:42:46 +00:00
rm -f "$ZIP_FILE"
pushd $(dirname "$IMG_FILE") > /dev/null
zip "$ZIP_FILE" $(basename "$IMG_FILE")
popd > /dev/null