434 lines
13 KiB
Bash
434 lines
13 KiB
Bash
#! /bin/bash
|
|
|
|
# Set globals
|
|
TMPDIR=/var/tmp/manjaro-arm-installer
|
|
PROFILES=/var/tmp/manjaro-arm-installer/profiles
|
|
ARCH='aarch64'
|
|
|
|
|
|
# Functions
|
|
msg() {
|
|
ALL_OFF="\e[1;0m"
|
|
BOLD="\e[1;1m"
|
|
GREEN="${BOLD}\e[1;32m"
|
|
local mesg=$1; shift
|
|
printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
|
|
}
|
|
|
|
|
|
usage_build_installer() {
|
|
echo "Usage: ${0##*/} [options]"
|
|
echo ' -h This help'
|
|
echo ''
|
|
echo ''
|
|
exit $1
|
|
}
|
|
|
|
get_timer(){
|
|
echo $(date +%s)
|
|
}
|
|
|
|
# $1: start timer
|
|
elapsed_time(){
|
|
echo $(echo $1 $(get_timer) | awk '{ printf "%0.2f",($2-$1)/60 }')
|
|
}
|
|
|
|
show_elapsed_time(){
|
|
msg "Time %s: %s minutes..." "$1" "$(elapsed_time $2)"
|
|
}
|
|
|
|
getarmprofiles () {
|
|
if ls $PROFILES/arm-profiles/* 1> /dev/null 2>&1; then
|
|
cd $PROFILES/arm-profiles
|
|
git pull
|
|
else
|
|
sudo mkdir -p $PROFILES
|
|
sudo chmod 777 $PROFILES
|
|
cd $PROFILES
|
|
git clone https://gitlab.com/Strit/arm-profiles.git
|
|
fi
|
|
|
|
}
|
|
|
|
create_install() {
|
|
if [[ "$DEVICE" = "oc1" ]] || [[ "$DEVICE" = "rpi2" ]] || [[ "$DEVICE" = "xu4" ]]; then
|
|
ARCH='armv7h'
|
|
else
|
|
ARCH='aarch64'
|
|
fi
|
|
|
|
msg "Creating install for $DEVICE..."
|
|
|
|
# backup host mirrorlist
|
|
#sudo mv /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist-orig
|
|
|
|
# Create arm mirrlorlist
|
|
#echo "Server = http://mirrors.dotsrc.org/manjaro-arm/stable/\$arch/\$repo/" > mirrorlist
|
|
#sudo mv mirrorlist /etc/pacman.d/mirrorlist
|
|
|
|
# create chroot on SD card
|
|
# sudo pacstrap -G -c -C $LIBDIR/pacman.conf.$ARCH $TMPDIR/root base manjaro-arm-keyring
|
|
|
|
# Enable cross architecture Chrooting
|
|
#if [[ "$DEVICE" = "oc1" ]] || [[ "$DEVICE" = "rpi2" ]] || [[ "$DEVICE" = "xu4" ]]; then
|
|
# sudo cp /usr/bin/qemu-arm-static $TMPDIR/root/usr/bin/
|
|
#else
|
|
# sudo cp /usr/bin/qemu-aarch64-static $TMPDIR/root/usr/bin/
|
|
#fi
|
|
|
|
# fetch and extract rootfs
|
|
msg "Downloading latest $ARCH rootfs..."
|
|
cd $TMPDIR
|
|
wget https://www.strits.dk/files/Manjaro-ARM-$ARCH-latest.tar.gz
|
|
|
|
msg "Extracting $ARCH rootfs..."
|
|
sudo bsdtar -xpf $TMPDIR/Manjaro-ARM-$ARCH-latest.tar.gz -C $TMPDIR/root
|
|
|
|
msg "Setting up keyrings..."
|
|
sudo systemd-nspawn -D $TMPDIR/root pacman-key --init 1> /dev/null 2>&1
|
|
sudo systemd-nspawn -D $TMPDIR/root pacman-key --populate archlinuxarm manjaro manjaro-arm 1> /dev/null 2>&1
|
|
|
|
msg "Installing packages for $EDITION on $DEVICE..."
|
|
# Install device and editions specific packages
|
|
sudo systemd-nspawn -D $TMPDIR/root pacman -S base $PKG_DEVICE $PKG_EDITION lsb-release --needed --noconfirm
|
|
|
|
# restore original mirrorlist to host system
|
|
sudo mv /etc/pacman.d/mirrorlist-orig /etc/pacman.d/mirrorlist
|
|
sudo pacman -Syy
|
|
|
|
msg "Enabling services..."
|
|
# Enable services
|
|
sudo systemd-nspawn -D $TMPDIR/root systemctl enable systemd-networkd.service getty.target haveged.service dhcpcd.service 1> /dev/null 2>&1
|
|
sudo systemd-nspawn -D $TMPDIR/root systemctl enable $SRV_EDITION 1> /dev/null 2>&1
|
|
|
|
if [[ "$DEVICE" = "oc1" ]] || [[ "$DEVICE" = "oc2" ]]; then
|
|
sudo systemd-nspawn -D $TMPDIR/root systemctl enable amlogic.service 1> /dev/null 2>&1
|
|
fi
|
|
|
|
msg "Applying overlay for $EDITION..."
|
|
sudo cp -ap $PROFILES/arm-profiles/overlays/$EDITION/* $TMPDIR/root/
|
|
|
|
msg "Setting up users..."
|
|
#setup users
|
|
echo "$USER" > $TMPDIR/user
|
|
echo "$PASSWORD" >> $TMPDIR/password
|
|
echo "$PASSWORD" >> $TMPDIR/password
|
|
echo "$ROOTPASSWORD" >> $TMPDIR/rootpassword
|
|
echo "$ROOTPASSWORD" >> $TMPDIR/rootpassword
|
|
sudo systemd-nspawn -D $TMPDIR/root passwd root < $TMPDIR/rootpassword 1> /dev/null 2>&1
|
|
sudo systemd-nspawn -D $TMPDIR/root useradd -m -g users -G wheel,storage,network,power -s /bin/bash $(cat $TMPDIR/user) 1> /dev/null 2>&1
|
|
sudo systemd-nspawn -D $TMPDIR/root passwd $(cat $TMPDIR/user) < $TMPDIR/password 1> /dev/null 2>&1
|
|
|
|
|
|
msg "Enabling user services..."
|
|
if [[ "$EDITION" = "minimal" ]] || [[ "$EDITION" = "server" ]]; then
|
|
echo "No user services for $EDITION edition"
|
|
else
|
|
sudo systemd-nspawn -D $TMPDIR/root --user $(cat $TMPDIR/user) systemctl --user enable pulseaudio.service 1> /dev/null 2>&1
|
|
fi
|
|
|
|
msg "Setting up system settings..."
|
|
#system setup
|
|
sudo systemd-nspawn -D $TMPDIR/root chmod u+s /usr/bin/ping 1> /dev/null 2>&1
|
|
sudo systemd-nspawn -D $TMPDIR/root update-ca-trust 1> /dev/null 2>&1
|
|
|
|
msg "Doing device specific setups for $DEVICE..."
|
|
if [[ "$DEVICE" = "rpi2" ]] || [[ "$DEVICE" = "rpi3" ]]; then
|
|
echo "dtparam=audio=on" | sudo tee --append $TMPDIR/root/boot/config.txt
|
|
echo "hdmi_drive=2" | sudo tee --append $TMPDIR/root/boot/config.txt
|
|
echo "audio_pwm_mode=2" | sudo tee --append $TMPDIR/root/boot/config.txt
|
|
echo "/dev/mmcblk0p1 /boot vfat defaults 0 0" | sudo tee --append $TMPDIR/root/etc/fstab
|
|
elif [[ "$DEVICE" = "oc1" ]] || [[ "$DEVICE" = "oc2" ]]; then
|
|
echo "No device setups for $DEVICE..."
|
|
elif [[ "$DEVICE" = "rock64" ]] || [[ "$DEVICE" = "rockpro64" ]]; then
|
|
echo "No device setups for $DEVICE..."
|
|
elif [[ "$DEVICE" = "pinebook" ]]; then
|
|
sudo systemd-nspawn -D $TMPDIR/root systemctl enable pinebook-post-install.service 1> /dev/null 2>&1
|
|
sudo systemd-nspawn -D $TMPDIR/root --user $(cat $TMPDIR/user) systemctl --user enable pinebook-user.service 1> /dev/null 2>&1
|
|
else
|
|
echo ""
|
|
fi
|
|
|
|
msg "Cleaning install for unwanted files..."
|
|
if [[ "$DEVICE" = "oc1" ]] || [[ "$DEVICE" = "rpi2" ]] || [[ "$DEVICE" = "xu4" ]]; then
|
|
sudo rm $TMPDIR/root/usr/bin/qemu-arm-static
|
|
else
|
|
sudo rm $TMPDIR/root/usr/bin/qemu-aarch64-static
|
|
fi
|
|
sudo rm -rf $TMPDIR/root/var/cache/pacman/pkg/*
|
|
sudo rm -rf $TMPDIR/root/var/log/*
|
|
|
|
# Remove temp files on host
|
|
sudo rm -rf $TMPDIR/user $TMPDIR/password $TMPDIR/rootpassword
|
|
sudo rm -rf $TMPDIR/Manjaro-ARM-$ARCH-latest.tar.gz
|
|
|
|
msg "$DEVICE $EDITION install complete"
|
|
}
|
|
|
|
prepare_card () {
|
|
msg "Getting $SDCARD ready for $DEVICE..."
|
|
# For Raspberry Pi devices
|
|
if [[ "$DEVICE" = "rpi2" ]] || [[ "$DEVICE" = "rpi3" ]]; then
|
|
#partition with boot and root
|
|
sudo parted -s $SDCARD mklabel msdos
|
|
sudo parted -s $SDCARD mkpart primary fat32 0% 100M
|
|
START=`cat /sys/block/$DEV_NAME/${DEV_NAME}1/start`
|
|
SIZE=`cat /sys/block/$DEV_NAME/${DEV_NAME}1/size`
|
|
END_SECTOR=$(expr $START + $SIZE)
|
|
sudo parted -s $SDCARD mkpart primary ext4 "${END_SECTOR}s" 100%
|
|
sudo partprobe $SDCARD
|
|
sudo mkfs.vfat "${SDCARD}1"
|
|
sudo mkfs.ext4 "${SDCARD}2"
|
|
|
|
#Mount SD card
|
|
mkdir -p $TMPDIR/root
|
|
mkdir -p $TMPDIR/boot
|
|
sudo mount ${SDCARD}1 $TMPDIR/boot
|
|
sudo mount ${SDCARD}2 $TMPDIR/root
|
|
|
|
# For Odroid devices
|
|
elif [[ "$DEVICE" = "oc1" ]] || [[ "$DEVICE" = "oc2" ]] || [[ "$DEVICE" = "xu4" ]]; then
|
|
#Clear first 8mb
|
|
sudo dd if=/dev/zero of=${SDCARD} bs=1M count=8
|
|
|
|
#partition with a single root partition
|
|
sudo parted -s $SDCARD mklabel msdos
|
|
sudo parted -s $SDCARD mkpart primary ext4 0% 100%
|
|
sudo partprobe $SDCARD
|
|
sudo mkfs.ext4 -O ^metadata_csum,^64bit ${SDCARD}1
|
|
|
|
#Mount SD card
|
|
mkdir -p $TMPDIR/root
|
|
sudo chmod 777 -R $TMPDIR/root
|
|
sudo mount ${SDCARD}1 $TMPDIR/root
|
|
|
|
# For pinebook device
|
|
elif [[ "$DEVICE" = "pinebook" ]]; then
|
|
|
|
#Clear first 8mb
|
|
sudo dd if=/dev/zero of=${SDCARD} bs=1M count=8
|
|
|
|
#partition with a single root partition
|
|
sudo parted -s $SDCARD mklabel msdos
|
|
sudo parted -s $SDCARD mkpart primary ext4 0% 100%
|
|
sudo partprobe $SDCARD
|
|
sudo mkfs.ext4 -O ^metadata_csum,^64bit ${SDCARD}1
|
|
|
|
# Mount SD card
|
|
mkdir -p $TMPDIR/root
|
|
sudo chmod 777 -R $TMPDIR/root
|
|
sudo mount ${SDCARD}1 $TMPDIR/root
|
|
|
|
# For rockpro64 device
|
|
elif [[ "$DEVICE" = "rockpro64" ]]; then
|
|
|
|
#Clear first 8mb
|
|
sudo dd if=/dev/zero of=${SDCARD} bs=1M count=8
|
|
|
|
#partition with a single root partition
|
|
sudo parted -s $SDCARD mklabel msdos
|
|
sudo parted -s $SDCARD mkpart primary ext4 0% 100%
|
|
sudo partprobe $SDCARD
|
|
sudo mkfs.ext4 -O ^metadata_csum,^64bit ${SDCARD}1
|
|
|
|
# Mount SD card
|
|
mkdir -p $TMPDIR/root
|
|
sudo chmod 777 -R $TMPDIR/root
|
|
sudo mount ${SDCARD}1 $TMPDIR/root
|
|
fi
|
|
}
|
|
|
|
cleanup () {
|
|
msg "Writing bootloader and cleaning up after install..."
|
|
# For Raspberry Pi devices
|
|
if [[ "$DEVICE" = "rpi2" ]] || [[ "$DEVICE" = "rpi3" ]]; then
|
|
#copy rootfs contents over to the FS
|
|
sudo mv $TMPDIR/root/boot/* $TMPDIR/boot
|
|
|
|
#clean up
|
|
sudo umount $TMPDIR/root
|
|
sudo umount $TMPDIR/boot
|
|
sudo rm -r $TMPDIR/root $TMPDIR/boot
|
|
sudo partprobe $SDCARD
|
|
|
|
# For Odroid devices
|
|
elif [[ "$DEVICE" = "oc1" ]] || [[ "$DEVICE" = "oc2" ]] || [[ "$DEVICE" = "xu4" ]]; then
|
|
#flash bootloader
|
|
cd $TMPDIR/root/boot/
|
|
sudo ./sd_fusing.sh $SDCARD
|
|
cd ~
|
|
|
|
#clean up
|
|
sudo umount $TMPDIR/root
|
|
sudo rm -r $TMPDIR/root
|
|
sudo partprobe $SDCARD
|
|
|
|
# For pinebook device
|
|
elif [[ "$DEVICE" = "pinebook" ]]; then
|
|
#flash bootloader
|
|
sudo dd if=$TMPDIR/root/boot/u-boot-sunxi-with-spl-$DEVICE.bin of=${SDCARD} bs=8k seek=1
|
|
|
|
#clean up
|
|
sudo umount $TMPDIR/root
|
|
sudo rm -r $TMPDIR/root
|
|
sudo partprobe $SDCARD
|
|
|
|
|
|
# For rockpro64 device
|
|
elif [[ "$DEVICE" = "rockpro64" ]]; then
|
|
#flash bootloader
|
|
sudo dd if=$TMPDIR/root/boot/idbloader.img of=${SDCARD} seek=64 conv=notrunc
|
|
sudo dd if=$TMPDIR/root/boot/uboot.img of=${SDCARD} seek=16384 conv=notrunc
|
|
sudo dd if=$TMPDIR/root/boot/trust.img of=${SDCARD} seek=24576 conv=notrunc
|
|
|
|
#clean up
|
|
sudo umount $TMPDIR/root
|
|
sudo rm -r $TMPDIR/root
|
|
sudo partprobe $SDCARD
|
|
|
|
fi
|
|
}
|
|
|
|
# Asking for user input!
|
|
#read -p 'What device is this for? [Options: rpi3, oc2 and pinebook] ' DEVICE
|
|
#read -p 'What edition do you want? [Options: minimal, lxqt and kde] ' EDITION
|
|
#read -p 'What is the path to the SD card? (example: /dev/sdb)? ' SDCARD
|
|
#read -p 'What username do you want? ' USER
|
|
#read -sp "What password should $USER have? " PASSWORD
|
|
#read -sp "
|
|
#What password should the root user have? " ROOTPASSWORD
|
|
#echo "
|
|
#" #to fix next line from being in the password line
|
|
#echo "Device = $DEVICE"
|
|
#echo "Edition = $EDITION"
|
|
#echo "Path to SD Card = $SDCARD"
|
|
#echo "Username = $USER"
|
|
|
|
|
|
# Using ncurses to ask for user input for variables
|
|
DEVICE=$(dialog --clear --title "Manjaro-ARM Installer" \
|
|
--menu "Choose a device:" 20 51 4 \
|
|
"rpi3" "Raspberry Pi 3" \
|
|
"oc2" "Odroid C2" \
|
|
"pinebook" "PineBook" 3>&1 1>&2 2>&3 3>&-)
|
|
|
|
|
|
#The if statement makes sure that the user has put in something in the previous prompt. If not (left blank or pressed cancel) the script will end
|
|
if [ ! -z "$DEVICE" ]
|
|
then
|
|
EDITION=$(dialog --clear --title "Manjaro-ARM Installer" \
|
|
--menu "Choose an edition:" 20 50 4 \
|
|
"minimal" "Minimal Edition (Just CLI)" \
|
|
"lxqt" "Full LXQT Desktop and apps (lightweight)" \
|
|
"kde" "Full KDE Desktop (Heavy)" 3>&1 1>&2 2>&3 3>&-)
|
|
|
|
else
|
|
clear
|
|
exit 1
|
|
fi
|
|
|
|
|
|
if [ ! -z "$EDITION" ]
|
|
then
|
|
USER=$(dialog --clear --title "Manjaro-ARM Installer" \
|
|
--inputbox "Enter username:" 8 50 \
|
|
3>&1 1>&2 2>&3 3>&-)
|
|
else
|
|
clear
|
|
exit 1
|
|
fi
|
|
|
|
|
|
|
|
|
|
if [ ! -z "$USER" ]
|
|
then
|
|
PASSWORD=$(dialog --clear --title "Manjaro-ARM Installer" \
|
|
--passwordbox "Enter Password:" 8 50 \
|
|
3>&1 1>&2 2>&3 3>&- \
|
|
)
|
|
else
|
|
clear
|
|
exit 1
|
|
fi
|
|
|
|
|
|
|
|
if [ ! -z "$PASSWORD" ]
|
|
then
|
|
ROOTPASSWORD=$(dialog --clear --title "Manjaro-ARM Installer" \
|
|
--passwordbox "Enter Root Password:" 8 50 \
|
|
3>&1 1>&2 2>&3 3>&- \
|
|
)
|
|
else
|
|
clear
|
|
exit 1
|
|
fi
|
|
|
|
|
|
|
|
|
|
if [ ! -z "$ROOTPASSWORD" ]
|
|
then
|
|
|
|
# simple command to put the results of lsblk (just the names of the devices) into an array and make that array populate the options
|
|
let i=0
|
|
W=()
|
|
while read -r line; do
|
|
let i=$i+1
|
|
W+=($line "")
|
|
done < <( lsblk -adn -o NAME )
|
|
SDCARD=$(dialog --title "Manjaro-ARM Installer" \
|
|
--menu "Chose your SDCard" 20 50 4 \
|
|
"${W[@]}" 3>&2 2>&1 1>&3)
|
|
|
|
# add /dev/ to the selected option above
|
|
SDCARD=/dev/$SDCARD
|
|
else
|
|
clear
|
|
exit 1
|
|
fi
|
|
|
|
|
|
# List all the responses upon completion (remove this for production)
|
|
clear
|
|
echo "Device = $DEVICE"
|
|
echo "Edition = $EDITION"
|
|
echo "User name = $USER"
|
|
echo "Password = ********** ($PASSWORD)" #password is here for testing purposes
|
|
echo "Root Password = ********** ($ROOTPASSWORD)" #password is here for testing purposes
|
|
echo "SDCard = $SDCARD"
|
|
|
|
if [[ "$DEVICE" = "oc1" ]] || [[ "$DEVICE" = "rpi2" ]] || [[ "$DEVICE" = "xu4" ]]; then
|
|
ARCH='armv7h'
|
|
else
|
|
ARCH='aarch64'
|
|
fi
|
|
|
|
# get the profiles
|
|
getarmprofiles
|
|
|
|
#Package lists
|
|
PKG_DEVICE=$(grep "^[^#;]" $PROFILES/arm-profiles/devices/$DEVICE | awk '{print $1}')
|
|
PKG_EDITION=$(grep "^[^#;]" $PROFILES/arm-profiles/editions/$EDITION | awk '{print $1}')
|
|
SRV_EDITION=$(grep "^[^#;]" $PROFILES/arm-profiles/services/$EDITION | awk '{print $1}')
|
|
|
|
# Remove '/dev/' from the name
|
|
DEV_NAME=`echo "$SDCARD" | cut -d "/" -f 3`
|
|
|
|
# Get size of SDCard (final sector)
|
|
SECTOR_SIZE=`cat /sys/block/${DEV_NAME}/size`
|
|
|
|
# Set the ending sector that the partition should be resized too
|
|
END_SECTOR=`expr $SECTOR_SIZE - 1`
|
|
|
|
|
|
# Commands
|
|
timer_start=$(get_timer)
|
|
|
|
prepare_card
|
|
create_install
|
|
cleanup
|
|
show_elapsed_time "${FUNCNAME}" "${timer_start}"
|
|
sync
|