#! /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