├── README.md └── installer.sh /README.md: -------------------------------------------------------------------------------- 1 | This script allows you to install [Arch Linux ARM for PinePhone / PineTab](https://github.com/dreemurrs-embedded/Pine64-Arch) with full disk encryption. 2 | -------------------------------------------------------------------------------- /installer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2020 - DanctNIX Community 4 | # 5 | # This script setup FDE on Arch Linux ARM for PinePhone 6 | # and PineTab. 7 | # 8 | # Inspired by: 9 | # https://github.com/sailfish-on-dontbeevil/flash-it 10 | 11 | set +e 12 | 13 | DOWNLOAD_SERVER="https://danctnix.arikawa-hi.me/rootfs/archarm-on-mobile" 14 | TMPMOUNT=$(mktemp -p . -d) 15 | 16 | # Parse arguments 17 | # https://stackoverflow.com/questions/192249/how-do-i-parse-command-line-arguments-in-bash 18 | POSITIONAL=() 19 | while [[ $# -gt 0 ]] 20 | do 21 | key="$1" 22 | 23 | case $key in 24 | -h|--help) 25 | echo "Arch Linux ARM for PP/PT Encrypted Setup" 26 | echo "" 27 | printf '%s\n' \ 28 | "This script will download the latest encrypted image for the" \ 29 | "PinePhone and PineTab. It downloads and create a image for the user" \ 30 | "to flash on their device or SD card." \ 31 | "" \ 32 | "usage: $0 " \ 33 | "" \ 34 | "Options:" \ 35 | "" \ 36 | " -h, --help Print this help and exit." \ 37 | "" \ 38 | "This command requires: parted, curl, sudo, wget, tar, unzip," \ 39 | "mkfs.ext4, mkfs.f2fs, losetup, unsquashfs." \ 40 | "" 41 | 42 | exit 0 43 | shift 44 | ;; 45 | *) # unknown argument 46 | POSITIONAL+=("$1") # save it in an array for later 47 | shift # past argument 48 | ;; 49 | esac 50 | done 51 | set -- "${POSITIONAL[@]}" # restore positional parameters 52 | 53 | # Helper functions 54 | # Error out if the given command is not found in PATH. 55 | function check_dependency { 56 | dependency=$1 57 | hash $dependency >/dev/null 2>&1 || { 58 | echo >&2 "${dependency} not found. Please make sure it is installed and on your PATH."; exit 1; 59 | } 60 | } 61 | 62 | function error { 63 | echo -e "\e[41m\e[5mERROR:\e[49m\e[25m $1" 64 | } 65 | 66 | # Check dependencies 67 | check_dependency "parted" 68 | check_dependency "cryptsetup" 69 | check_dependency "sudo" 70 | check_dependency "wget" 71 | check_dependency "tar" 72 | check_dependency "unsquashfs" 73 | check_dependency "mkfs.ext4" 74 | check_dependency "mkfs.f2fs" 75 | check_dependency "losetup" 76 | check_dependency "zstd" 77 | check_dependency "curl" 78 | 79 | # Image selection 80 | echo -e "\e[1mWhich image do you want to create?\e[0m" 81 | select OPTION in "PinePhone" "PineTab"; do 82 | case $OPTION in 83 | "PinePhone" ) DEVICE="pinephone"; break;; 84 | "PineTab" ) DEVICE="pinetab"; break;; 85 | esac 86 | done 87 | 88 | echo -e "\e[1mWhich environment would you like to install?\e[0m" 89 | select OPTION in "Phosh" "Plasma" "Sxmo" "Barebone"; do 90 | case $OPTION in 91 | "Phosh" ) USR_ENV="phosh"; break;; 92 | "Plasma" ) USR_ENV="plasma"; break;; 93 | "Sxmo" ) USR_ENV="sxmo"; break;; 94 | "Barebone" ) USR_ENV="barebone"; break;; 95 | esac 96 | done 97 | 98 | SQFSDATE=$(curl -s -f $DOWNLOAD_SERVER/version.txt || echo BAD) 99 | SQFSROOT="archlinux-$DEVICE-$USR_ENV-$SQFSDATE.sqfs" 100 | 101 | [ $SQFSDATE = "BAD" ] && { error "Failed to fetch for the latest version. The server may be down, please try again later." && exit 1; } 102 | 103 | # Filesystem selection 104 | echo -e "\e[1mWhich filesystem would you like to use?\e[0m" 105 | select OPTION in "ext4" "f2fs"; do 106 | case $OPTION in 107 | "ext4" ) FILESYSTEM="ext4"; break;; 108 | "f2fs" ) FILESYSTEM="f2fs"; break;; 109 | esac 110 | done 111 | 112 | # Select flash target 113 | echo -e "\e[1mWhich SD card do you want to flash?\e[0m" 114 | lsblk 115 | read -p "Device node (/dev/sdX): " DISK_IMAGE 116 | echo "Flashing image to: $DISK_IMAGE" 117 | echo "WARNING: All data will be erased! You have been warned!" 118 | echo "Some commands require root permissions, you might be asked to enter your sudo password." 119 | 120 | # Make sure people won't pick the wrong thing and ultimately erase the disk 121 | echo 122 | echo -e "\e[31m\e[1mARE YOU SURE \e[5m\e[4m${DISK_IMAGE}\e[24m\e[25m IS WHAT YOU PICKED?\e[39m\e[0m" 123 | read -p "Confirm device node: " CONFIRM_DISK_IMAGE 124 | [ "$DISK_IMAGE" != "$CONFIRM_DISK_IMAGE" ] && error "The device node mismatched. Aborting." && exit 1 125 | echo 126 | 127 | # Downloading images 128 | echo -e "\e[1mDownloading images...\e[0m" 129 | 130 | wget --quiet --show-progress -c -O $SQFSROOT $DOWNLOAD_SERVER/$SQFSROOT || { 131 | error "Root filesystem image download failed. Aborting." 132 | exit 2 133 | } 134 | 135 | # Checksum check, make sure the root image is the real deal. 136 | curl -s $DOWNLOAD_SERVER/$SQFSROOT.sha512sum | sha512sum -c || { error "Checksum does not match. Aborting." && rm $SQFSROOT && exit 1; } 137 | 138 | wget --quiet --show-progress -c -O arch-install-scripts.tar.zst "https://archlinux.org/packages/extra/any/arch-install-scripts/download/" || { 139 | error "arch-install-scripts download failed. Aborting." 140 | exit 2 141 | } 142 | 143 | tar --transform='s,^\([^/][^/]*/\)\+,,' -xf arch-install-scripts.tar.zst usr/bin/genfstab 144 | chmod +x genfstab 145 | 146 | [ ! -e "genfstab" ] && error "Failed to locate genfstab. Aborting." && exit 2 147 | 148 | [ $FILESYSTEM = "ext4" ] && MKFS="mkfs.ext4" 149 | [ $FILESYSTEM = "f2fs" ] && MKFS="mkfs.f2fs" 150 | 151 | sudo parted -a optimal ${DISK_IMAGE} mklabel msdos --script 152 | sudo parted -a optimal ${DISK_IMAGE} mkpart primary fat32 '0%' 256MB --script 153 | sudo parted -a optimal ${DISK_IMAGE} mkpart primary ext4 256MB 100% --script 154 | sudo parted ${DISK_IMAGE} set 1 boot on --script 155 | 156 | # The first partition is the boot partition and the second one the root 157 | PARTITIONS=$(lsblk $DISK_IMAGE -l | grep ' part ' | awk '{print $1}') 158 | BOOTPART=/dev/$(echo "$PARTITIONS" | sed -n '1p') 159 | ROOTPART=/dev/$(echo "$PARTITIONS" | sed -n '2p') 160 | 161 | ENCRYNAME=$(basename $(mktemp -p /dev/mapper/ -u)) 162 | ENCRYPART="/dev/mapper/$ENCRYNAME" 163 | 164 | echo "You'll now be asked to type in a new encryption key. DO NOT LOSE THIS!" 165 | 166 | # Generating LUKS header on a modern computer would make the container slow to unlock 167 | # on slower devices such as PinePhone. 168 | # 169 | # Unless you're happy with the phone taking an eternity to unlock, this is it for now. 170 | sudo cryptsetup -q -y -v luksFormat --pbkdf-memory=20721 --pbkdf-parallel=4 --pbkdf-force-iterations=4 $ROOTPART 171 | sudo cryptsetup open $ROOTPART $ENCRYNAME 172 | 173 | [ ! -e /dev/mapper/${ENCRYNAME} ] && error "Failed to locate rootfs mapper. Aborting." && exit 1 174 | 175 | sudo mkfs.vfat $BOOTPART 176 | sudo $MKFS $ENCRYPART 177 | 178 | sudo mount $ENCRYPART $TMPMOUNT 179 | sudo mkdir $TMPMOUNT/boot 180 | sudo mount $BOOTPART $TMPMOUNT/boot 181 | 182 | sudo unsquashfs -f -d $TMPMOUNT $SQFSROOT 183 | 184 | ./genfstab -U $TMPMOUNT | grep UUID | grep -v "swap" | sudo tee -a $TMPMOUNT/etc/fstab 185 | sudo sed -i "s:UUID=[0-9a-f-]*\s*/\s:/dev/mapper/cryptroot / :g" $TMPMOUNT/etc/fstab 186 | 187 | sudo dd if=${TMPMOUNT}/boot/u-boot-sunxi-with-spl-${DEVICE}-552.bin of=${DISK_IMAGE} bs=8k seek=1 188 | 189 | sudo umount -R $TMPMOUNT 190 | sudo cryptsetup close $ENCRYNAME 191 | 192 | 193 | echo -e "\e[1mCleaning up working directory...\e[0m" 194 | sudo rm -f arch-install-scripts.tar.zst || true 195 | sudo rm -f genfstab || true 196 | sudo rm -rf $TMPMOUNT || true 197 | 198 | echo -e "\e[32m\e[1mAll done! Please insert the card to your device and power on.\e[39m\e[0m" 199 | --------------------------------------------------------------------------------