InstallPrawnOS.sh 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. #!/bin/bash
  2. #See the block of "echos" in main() for description of this script
  3. # This file is part of PrawnOS (http://www.prawnos.com)
  4. # Copyright (c) 2018 Hal Emmerich <hal@halemmerich.com>
  5. # PrawnOS is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License version 2
  7. # as published by the Free Software Foundation.
  8. # PrawnOS is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. # You should have received a copy of the GNU General Public License
  13. # along with PrawnOS. If not, see <https://www.gnu.org/licenses/>.
  14. RESOURCES=/InstallResources
  15. # Grab the boot device, which is either /dev/sda for usb or /dev/mmcblk0 for an sd card
  16. BOOT_DEVICE=$(mount | head -n 1 | cut -d '2' -f 1)
  17. main() {
  18. echo "---------------------------------------------------------------------------------------------------------------------"
  19. echo "PrawnOS Install or Expand Script"
  20. echo "Installation sets up the internal emmc partitions, root encryption, and copies the filesystem from the"
  21. echo "current boot device to the target device. The target device cannot be the current boot device"
  22. echo
  23. echo "Expansion simply targets the booted device, and expands the filesystem to fill the entire thing instead of just 2GB."
  24. echo "Because of this, root encryption cannot be setup"
  25. echo
  26. echo "For installation, this script can be quit and re-ran at any point."
  27. echo "Unfortunately for expansion this is not the case"
  28. echo "---------------------------------------------------------------------------------------------------------------------"
  29. echo
  30. echo "Expand or Install?: "
  31. echo "The currently booted device is ${BOOT_DEVICE}"
  32. while true; do
  33. read -p "[I]nstall or [E]xpand?" IE
  34. case $IE in
  35. [Ii]* ) install; break;;
  36. [Ee]* ) expand; break;;
  37. * ) echo "Please answer I or E";;
  38. esac
  39. done
  40. }
  41. #Now to pick the install target: internal, sd, or usb
  42. #if target is usb, and boot device is usb, target is sdb
  43. #and whether to enable crypto
  44. install() {
  45. echo "Pick an install target. This can be the Internal Emmc, an SD card, or a USB device"
  46. echo "Please ensure you have only have the booted device and the desired target device inserted."
  47. echo "The currently booted device is ${BOOT_DEVICE}"
  48. while true; do
  49. read -p "[I]nternal Emmc, [S]D card, or [U]SB device?: " ISU
  50. case $ISU in
  51. [Ii]* ) TARGET=/dev/mmcblk2p; break;;
  52. [Ss]* ) TARGET=/dev/mmcblk0p; break;;
  53. [Uu]* ) TARGET=USB; break;;
  54. * ) echo "Please answer I, S, or U";;
  55. esac
  56. done
  57. if [[ $TARGET == "USB" ]]
  58. then
  59. if [[ $BOOT_DEVICE == "/dev/sda" ]]
  60. then
  61. TARGET=/dev/sdb
  62. else
  63. TARGET=/dev/sda
  64. fi
  65. fi
  66. if [[ $TARGET == $BOOT_DEVICE ]]
  67. then
  68. echo "Can't install to booted device, please ensure you have *only* the booted device and target device inserted"
  69. exit
  70. fi
  71. #cut off the "p" if we are using an sd card or internal emmc, doesn't change TARGET if we are using usb
  72. TARGET_NO_P=$(echo $TARGET | cut -d 'p' -f 1)
  73. if [ ! -e $TARGET_NO_P ];
  74. then
  75. echo "${TARGET_NO_P} does not exist, have you plugged in your target sd card or usb device?"
  76. exit 1
  77. fi
  78. #Now on to the installation, basically copy InstallToInternal.sh
  79. while true; do
  80. read -p "This will ERASE ALL DATA ON ${TARGET_NO_P} and reboot when finished, do you want to continue? [y/N]" yn
  81. case $yn in
  82. [Yy]* ) break;;
  83. [Nn]* ) exit;;
  84. * ) echo "Please answer y or n";;
  85. esac
  86. done
  87. umount ${TARGET}1 || /bin/true
  88. umount ${TARGET}2 || /bin/true
  89. if [[ $TARGET == "/dev/mmcblk2p" ]]
  90. then
  91. emmc_partition
  92. else
  93. external_partition $TARGET_NO_P
  94. fi
  95. KERNEL_PARTITION=${TARGET}1
  96. ROOT_PARTITION=${TARGET}2
  97. CRYPTO=false
  98. echo Writing kernel partition
  99. dd if=/dev/zero of=$KERNEL_PARTITION bs=512 count=65536
  100. dd if=${BOOT_DEVICE}1 of=$KERNEL_PARTITION conv=notrunc
  101. #Handle full disk encryption
  102. echo "Would you like to setup full disk encrytion using LUKs/DmCrypt?"
  103. select yn in "Yes" "No"
  104. do
  105. case $yn,$REPLY in
  106. Yes,*|*,Yes )
  107. CRYPTO=true
  108. # Since iteration count is based on cpu power, and the rk3288 isn't as fast as a usual
  109. # desktop cpu, manually supply -i 15000 for security at the cost of a slightly slower unlock
  110. echo "Enter the password you would like to use to unlock the encrypted root partition at boot"
  111. cryptsetup -q -y -s 512 luksFormat -i 15000 $ROOT_PARTITION || exit 1
  112. echo "Now unlock the newly created encrypted root partition so we can mount it and install the filesystem"
  113. cryptsetup luksOpen $ROOT_PARTITION luksroot || exit 1
  114. ROOT_PARTITION=/dev/mapper/luksroot
  115. break
  116. ;;
  117. No,*|*,No )
  118. break
  119. ;;
  120. * )
  121. echo "Invalid Option, please enter Yes or No, 1 or 2"
  122. ;;
  123. esac
  124. done
  125. echo Writing Filesystem, this will take about 4 minutes...
  126. mkfs.ext4 -F -b 1024 $ROOT_PARTITION
  127. mkdir -p /mnt/mmc/
  128. mount $ROOT_PARTITION /mnt/mmc
  129. rsync -ah --info=progress2 --info=name0 --numeric-ids -x / /mnt/mmc/
  130. #Remove the live-fstab and install a base fstab
  131. rm /mnt/mmc/etc/fstab
  132. echo "${ROOT_PARTITION} / ext4 defaults,noatime 0 1" > /mnt/mmc/etc/fstab
  133. umount $ROOT_PARTITION
  134. echo Running fsck
  135. e2fsck -p -f $ROOT_PARTITION
  136. if [[ $CRYPTO == "true" ]]
  137. then
  138. # unmount and close encrypted storage
  139. # let things settle, otherwise cryptsetup complainssss
  140. sleep 2
  141. cryptsetup luksClose luksroot
  142. fi
  143. echo "Please remove the booted device after power off is complete"
  144. while true; do
  145. read -p "Reboot? [y/N]" re
  146. case $re in
  147. [Yy]* ) reboot;;
  148. [Nn]* ) exit;;
  149. * ) echo "Please answer y or n";;
  150. esac
  151. done
  152. }
  153. #Setup partition map on internal emmc
  154. emmc_partition() {
  155. #disable dmesg, writing the partition map tries to write the the first gpt table, which is unmodifiable
  156. dmesg -D
  157. echo Writing partition map to internal emmc
  158. DISK_SZ="$(blockdev --getsz /dev/mmcblk2)"
  159. echo Total disk size is: $DISK_SZ
  160. if [ $DISK_SZ = 30785536 ]
  161. then
  162. echo Detected Emmc Type 1
  163. sfdisk /dev/mmcblk2 < $RESOURCES/mmc.partmap
  164. elif [ $DISK_SZ = 30777344 ]
  165. then
  166. echo Detected Emmc Type 2
  167. sfdisk /dev/mmcblk2 < $RESOURCES/mmc_type2.partmap
  168. else
  169. echo ERROR! Not a known EMMC type, please open an issue on github or send SolidHal an email with the Total disk size reported above
  170. echo Try a fallback value? This will allow installation to continue, at the cost of a very small amoutnt of disk space. This may not work.
  171. select yn in "Yes" "No"
  172. do
  173. case $yn,$REPLY in
  174. Yes,*|*,Yes )
  175. echo Trying Emmc Type 2
  176. sfdisk /dev/mmcblk2 < $RESOURCES/mmc_type2.partmap
  177. break
  178. ;;
  179. * )
  180. echo "Invalid Option, please enter Yes or No, 1 or 2"
  181. ;;
  182. esac
  183. done
  184. fi
  185. dmesg -E
  186. }
  187. #Setup partition map for external bootable device, aka usb or sd card
  188. external_partition() {
  189. EXTERNAL_TARGET=$1
  190. kernel_start=8192
  191. kernel_size=65536
  192. root_start=$(($kernel_start + $kernel_size))
  193. #wipe the partition map, cgpt doesn't like anything weird in the primary or backup partition maps
  194. sgdisk -Z $EXTERNAL_TARGET
  195. partprobe $EXTERNAL_TARGET
  196. #make the base gpt partition map
  197. parted --script $EXTERNAL_TARGET mklabel gpt
  198. cgpt create $EXTERNAL_TARGET
  199. #must use cgpt to make the kernel partition, as we need the -S, -T, and -P variables
  200. cgpt add -i 1 -t kernel -b $kernel_start -s $kernel_size -l Kernel -S 1 -T 5 -P 10 $EXTERNAL_TARGET
  201. #Now the main filesystem
  202. #cgpt doesn't seem to handle this part correctly
  203. sgdisk -N 2 $EXTERNAL_TARGET
  204. #Set the type to "data"
  205. sgdisk -t 2:0700 $EXTERNAL_TARGET
  206. #Name it "properly" - Probably not required, but looks nice
  207. sgdisk -c 2:Root $EXTERNAL_TARGET
  208. #Reload the partition mapping
  209. partprobe $EXTERNAL_TARGET
  210. }
  211. #simply expand to fill the current boot device
  212. expand() {
  213. if [[ $BOOT_DEVICE == "/dev/mmcblk2" ]]
  214. then
  215. echo "Can't expand to fill internal emmc, install will have done this already"
  216. exit
  217. fi
  218. #Make the boot partition fille the whole drive
  219. #Delete the partition
  220. sgdisk -d 2 $BOOT_DEVICE
  221. #Make new partition map entry, with full size
  222. sgdisk -N 2 $BOOT_DEVICE
  223. #Set the type to "data"
  224. sgdisk -t 2:0700 $BOOT_DEVICE
  225. #Name it "properly" - Probably not required, but looks nice
  226. sgdisk -c 2:Root $BOOT_DEVICE
  227. #Reload the partition mapping
  228. partprobe $BOOT_DEVICE
  229. #Force the filesystem to fill the new partition
  230. resize2fs -f ${BOOT_DEVICE}2
  231. echo "/dev/${BOOT_DEVICE}2 / ext4 defaults,noatime 0 1" > /etc/fstab
  232. }
  233. #call the main function, script technically starts here
  234. #Organized this way so that main can come before the functions it calls
  235. main "$@"; exit