install.sh 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703
  1. #!/usr/bin/env bash
  2. #-
  3. # Copyright © 2010-2025
  4. # Waldemar Brodkorb <wbx@openadk.org>
  5. # Thorsten Glaser <tg@mirbsd.org>
  6. #
  7. # Provided that these terms and disclaimer and all copyright notices
  8. # are retained or reproduced in an accompanying document, permission
  9. # is granted to deal in this work without restriction, including un‐
  10. # limited rights to use, publicly perform, distribute, sell, modify,
  11. # merge, give away, or sublicence.
  12. #
  13. # This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to
  14. # the utmost extent permitted by applicable law, neither express nor
  15. # implied; without malicious intent or gross negligence. In no event
  16. # may a licensor, author or contributor be held liable for indirect,
  17. # direct, other damage, loss, or other issues arising in any way out
  18. # of dealing in the work, even if advised of the possibility of such
  19. # damage or existence of a defect, except proven that it results out
  20. # of said person’s immediate fault when using the work as intended.
  21. #
  22. # Alternatively, this work may be distributed under the terms of the
  23. # General Public License, any version, as published by the Free Soft-
  24. # ware Foundation.
  25. #-
  26. # Prepare a USB stick or CF/SD/MMC card or hard disc for installation
  27. # of OpenADK
  28. ADK_TOPDIR=$(pwd)
  29. HOST=$(gcc -dumpmachine)
  30. me=$0
  31. case :$PATH: in
  32. (*:$ADK_TOPDIR/host_$HOST/usr/bin:*) ;;
  33. (*) export PATH=$PATH:$ADK_TOPDIR/host_$HOST/usr/bin ;;
  34. esac
  35. test -n "$KSH_VERSION" || exec mksh "$me" "$@"
  36. if test -z "$KSH_VERSION"; then
  37. echo >&2 Fatal error: could not run myself with mksh!
  38. exit 255
  39. fi
  40. ### run with mksh from here onwards ###
  41. me=${me##*/}
  42. if (( USER_ID )); then
  43. print -u2 Installation is only possible as root!
  44. exit 1
  45. fi
  46. ADK_TOPDIR=$(realpath .)
  47. ostype=$(uname -s)
  48. fs=ext4
  49. cfgfs=1
  50. datafssz=0
  51. noformat=0
  52. quiet=0
  53. serial=0
  54. speed=115200
  55. panicreboot=10
  56. keep=0
  57. grub=0
  58. paragon_ext=0
  59. datapartcontent=""
  60. function usage {
  61. cat >&2 <<EOF
  62. Syntax: $me [-f filesystem] [-c cfgfssize] [-d datafssize] [-D datafscontent] [-k] [-n] [-g]
  63. [-p panictime] [±q] [-s serialspeed] [±t] <target> <device> <archive>
  64. Partition sizes are in MiB. Filesystem type is currently ignored (ext4).
  65. To keep filesystem on data partition use -k.
  66. Use -n to not format boot/root partition.
  67. Defaults: -c 1 -p 10 -s 115200; -t = enable serial console
  68. EOF
  69. exit $1
  70. }
  71. while getopts "c:d:D:ef:ghknp:qs:tx:" ch; do
  72. case $ch {
  73. (c) if (( (cfgfs = OPTARG) < 0 || cfgfs > 16 )); then
  74. print -u2 "$me: -c $OPTARG out of bounds"
  75. exit 1
  76. fi ;;
  77. (d) if (( (datafssz = OPTARG) < 0 )); then
  78. print -u2 "$me: -d $OPTARG out of bounds"
  79. exit 1
  80. fi ;;
  81. (e) paragon_ext=1 ;;
  82. (f) if [[ $OPTARG != @(ext2|ext3|ext4|xfs) ]]; then
  83. print -u2 "$me: filesystem $OPTARG invalid"
  84. exit 1
  85. fi
  86. fs=$OPTARG ;;
  87. (h) usage 0 ;;
  88. (k) keep=1 ;;
  89. (g) grub=1 ;;
  90. (p) if (( (panicreboot = OPTARG) < 0 || panicreboot > 300 )); then
  91. print -u2 "$me: -p $OPTARG out of bounds"
  92. exit 1
  93. fi ;;
  94. (q) quiet=1 ;;
  95. (+q) quiet=0 ;;
  96. (s) if [[ $OPTARG != @(96|192|384|576|1152)00 ]]; then
  97. print -u2 "$me: serial speed $OPTARG invalid"
  98. exit 1
  99. fi
  100. speed=$OPTARG ;;
  101. (n) noformat=1 ;;
  102. (t) serial=1 ;;
  103. (+t) serial=0 ;;
  104. (D) if [[ ! -d $OPTARG ]]; then
  105. print -u2 "$me: -D $OPTARG must be an existing directory"
  106. exit 1
  107. fi
  108. datapartcontent=$OPTARG;;
  109. (*) usage 1 ;;
  110. }
  111. done
  112. shift $((OPTIND - 1))
  113. (( $# == 3 )) || usage 1
  114. f=0
  115. case $ostype {
  116. (Linux)
  117. tools="bc mkfs.ext4 mkfs.vfat tune2fs partprobe"
  118. ;;
  119. (*)
  120. print -u2 Sorry, not ported to the OS "'$ostype'" yet.
  121. exit 1
  122. ;;
  123. }
  124. for tool in $tools; do
  125. print -n Checking if $tool is installed...
  126. if whence -p $tool >/dev/null; then
  127. print " okay"
  128. else
  129. print " failed"
  130. f=1
  131. fi
  132. done
  133. (( f )) && exit 1
  134. target=$1
  135. tgt=$2
  136. src=$3
  137. case $target {
  138. (atmel-ngw100|banana-pro|banana-pro-zero|orange-pi0|pcengines-apu|phytec-imx6|phytec-wega|raspberry-pi|raspberry-pi0|raspberry-pi2|raspberry-pi3|raspberry-pi3-64|raspberry-pi4|raspberry-pi4-64|raspberry-pi5|rockpi4-plus|solidrun-imx6|solidrun-clearfog|imgtec-ci20|hp-jornada|default) ;;
  139. (*)
  140. print -u2 "Unknown target '$target', exiting"
  141. exit 1 ;;
  142. }
  143. if [[ ! -b $tgt ]]; then
  144. print -u2 "'$tgt' is not a block device, exiting"
  145. exit 1
  146. fi
  147. if [[ ! -f $src ]]; then
  148. print -u2 "'$src' is not a file, exiting"
  149. exit 1
  150. fi
  151. (( quiet )) || print "Installing $src on $tgt."
  152. case $ostype {
  153. (Linux)
  154. basedev=$tgt
  155. if [[ "$tgt" == *"nvme0n1"* ]] || [[ "$tgt" == *"mmcblk"* ]]; then
  156. partitionsep="p"
  157. else
  158. partitionsep=""
  159. fi
  160. if [[ $basedev = /dev/loop* ]]; then
  161. (( quiet )) || print "${tgt} is a loop device"
  162. partitionsep=p
  163. fi
  164. rootpart=${basedev}${partitionsep}1
  165. datapart=${basedev}${partitionsep}2
  166. if [[ $target = raspberry-pi || $target = raspberry-pi0 || $target = raspberry-pi2 || $target = raspberry-pi3 || $target = raspberry-pi3-64 || $target = raspberry-pi4 || $target = raspberry-pi4-64 || $target = raspberry-pi5 ]]; then
  167. bootpart=${basedev}${partitionsep}1
  168. rootpart=${basedev}${partitionsep}2
  169. datapart=${basedev}${partitionsep}3
  170. fi
  171. match=\'${basedev}${partitionsep}\''+([0-9])'
  172. function mount_fs {
  173. (( quiet )) || print "Mounting filesystem on ${1}..."
  174. mount -t "$3" "$1" "$2"
  175. }
  176. function umount_fs {
  177. (( quiet )) || print "Unmounting filesystem on ${1}..."
  178. umount "$1"
  179. }
  180. function create_fs {
  181. (( quiet )) || print "Creating filesystem on ${1}..."
  182. mkfs.$3 "$1"
  183. }
  184. function tune_fs {
  185. tune2fs -c 0 -i 0 "$1"
  186. }
  187. ;;
  188. }
  189. mount |&
  190. while read -p dev rest; do
  191. eval [[ \$dev = $match ]] || continue
  192. print -u2 "Block device $tgt is in use, please umount first."
  193. exit 1
  194. done
  195. if (( !quiet )); then
  196. print "WARNING: This will overwrite $basedev - type Yes to continue!"
  197. read x
  198. [[ $x = Yes ]] || exit 0
  199. fi
  200. if ! T=$(mktemp -d /tmp/openadk.XXXXXXXXXX); then
  201. print -u2 Error creating temporary directory.
  202. exit 1
  203. fi
  204. R=$T/rootmnt
  205. B=$T/bootmnt
  206. D=$T/datamnt
  207. mkdir -p "$R" "$B" "$D"
  208. # get disk size
  209. dksz=$(dkgetsz "$tgt")
  210. # partition layouts:
  211. # n̲a̲m̲e̲ p̲a̲r̲t̲#̲0̲ p̲̲a̲r̲t̲#̲1̲ p̲̲a̲r̲t̲#̲2̲ p̲̲a̲r̲t̲#̲3̲
  212. # default: 0x83(system) 0x83(?data) -(unused) 0x88(cfgfs)
  213. # raspberry: 0x0B(boot) 0x83(system) 0x83(?data) 0x88(cfgfs)
  214. syspartno=0
  215. # sizes:
  216. # boot(raspberry) - fixed (100 MiB)
  217. # cfgfs - fixed (parameter, max. 16 MiB)
  218. # data - flexible (parameter)
  219. # system - everything else
  220. if [[ $target = raspberry-pi || $target = raspberry-pi0 || $target = raspberry-pi2 || $target = raspberry-pi3 || $target = raspberry-pi3-64 || $target = raspberry-pi4 || $target = raspberry-pi4-64 || $target = raspberry-pi5 || $target = phytec-wega ]]; then
  221. syspartno=1
  222. bootfssz=100
  223. if (( grub )); then
  224. print -u2 "Cannot combine GRUB with $target"
  225. rm -rf "$T"
  226. exit 1
  227. fi
  228. else
  229. bootfssz=0
  230. fi
  231. heads=64
  232. secs=32
  233. (( cyls = dksz / heads / secs ))
  234. if (( cyls < (bootfssz + cfgfs + datafssz + 2) )); then
  235. print -u2 "Size of $tgt is $dksz, this looks fishy?"
  236. rm -rf "$T"
  237. exit 1
  238. fi
  239. if stat -qs .>/dev/null 2>&1; then
  240. statcmd='stat -f %z' # BSD stat (or so we assume)
  241. else
  242. statcmd='stat -c %s' # GNU stat
  243. fi
  244. if (( grub )); then
  245. tar -xOf "$src" boot/grub/core.img >"$T/core.img"
  246. integer coreimgsz=$($statcmd "$T/core.img")
  247. else
  248. coreimgsz=65024
  249. fi
  250. if (( coreimgsz < 1024 )); then
  251. print -u2 core.img is probably too small: $coreimgsz
  252. rm -rf "$T"
  253. exit 1
  254. fi
  255. if (( coreimgsz > 65024 )); then
  256. print -u2 core.img is larger than 64K-512: $coreimgsz
  257. rm -rf "$T"
  258. exit 1
  259. fi
  260. (( coreendsec = (coreimgsz + 511) / 512 ))
  261. if [[ $basedev = /dev/svnd+([0-9]) ]]; then
  262. # BSD svnd0 mode: protect sector #1
  263. corestartsec=2
  264. (( ++coreendsec ))
  265. corepatchofs=$((0x614))
  266. else
  267. corestartsec=1
  268. corepatchofs=$((0x414))
  269. fi
  270. # partition offset: at least coreendsec+1 but aligned on a multiple of secs
  271. #(( partofs = ((coreendsec / secs) + 1) * secs ))
  272. # we just use 2048 all the time, since some loaders are longer
  273. partofs=2048
  274. if [[ $target = raspberry-pi || $target = raspberry-pi0 || $target = raspberry-pi2 || $target = raspberry-pi3 || $target = raspberry-pi3-64 || $target = raspberry-pi4 || $target = raspberry-pi4-64 || $target = raspberry-pi5 || $target = phytec-wega || $target = rockpi4-plus ]]; then
  275. (( spartofs = partofs + (100 * 2048) ))
  276. else
  277. spartofs=$partofs
  278. fi
  279. (( quiet )) || if (( grub )); then
  280. print Preparing MBR and GRUB2...
  281. else
  282. print Preparing MBR...
  283. fi
  284. dd if=/dev/zero of="$T/firsttrack" count=$partofs 2>/dev/null
  285. # add another MiB to clear the first partition
  286. dd if=/dev/zero bs=1048576 count=1 >>"$T/firsttrack" 2>/dev/null
  287. echo $corestartsec $coreendsec | mksh "$ADK_TOPDIR/scripts/bootgrub.mksh" \
  288. -A -g $((cyls - bootfssz - cfgfs - datafssz)):$heads:$secs -M 1:0x83 \
  289. -O $spartofs | dd of="$T/firsttrack" conv=notrunc 2>/dev/null
  290. (( grub )) && dd if="$T/core.img" of="$T/firsttrack" conv=notrunc \
  291. seek=$corestartsec 2>/dev/null
  292. # set partition where it can find /boot/grub
  293. (( grub )) && print -n '\0\0\0\0' | \
  294. dd of="$T/firsttrack" conv=notrunc bs=1 seek=$corepatchofs 2>/dev/null
  295. # create cfgfs partition (mostly taken from bootgrub.mksh)
  296. set -A thecode
  297. typeset -Uui8 thecode
  298. mbrpno=0
  299. set -A g_code $cyls $heads $secs
  300. (( psz = g_code[0] * g_code[1] * g_code[2] ))
  301. (( pofs = (cyls - cfgfs) * g_code[1] * g_code[2] ))
  302. set -A o_code # g_code equivalent for partition offset
  303. (( o_code[2] = pofs % g_code[2] + 1 ))
  304. (( o_code[1] = pofs / g_code[2] ))
  305. (( o_code[0] = o_code[1] / g_code[1] + 1 ))
  306. (( o_code[1] = o_code[1] % g_code[1] + 1 ))
  307. # boot flag; C/H/S offset
  308. thecode[mbrpno++]=0x00
  309. (( thecode[mbrpno++] = o_code[1] - 1 ))
  310. (( cylno = o_code[0] > 1024 ? 1023 : o_code[0] - 1 ))
  311. (( thecode[mbrpno++] = o_code[2] | ((cylno & 0x0300) >> 2) ))
  312. (( thecode[mbrpno++] = cylno & 0x00FF ))
  313. # partition type; C/H/S end
  314. (( thecode[mbrpno++] = 0x88 ))
  315. (( thecode[mbrpno++] = g_code[1] - 1 ))
  316. (( cylno = g_code[0] > 1024 ? 1023 : g_code[0] - 1 ))
  317. (( thecode[mbrpno++] = g_code[2] | ((cylno & 0x0300) >> 2) ))
  318. (( thecode[mbrpno++] = cylno & 0x00FF ))
  319. # partition offset, size (LBA)
  320. (( thecode[mbrpno++] = pofs & 0xFF ))
  321. (( thecode[mbrpno++] = (pofs >> 8) & 0xFF ))
  322. (( thecode[mbrpno++] = (pofs >> 16) & 0xFF ))
  323. (( thecode[mbrpno++] = (pofs >> 24) & 0xFF ))
  324. (( pssz = psz - pofs ))
  325. (( thecode[mbrpno++] = pssz & 0xFF ))
  326. (( thecode[mbrpno++] = (pssz >> 8) & 0xFF ))
  327. (( thecode[mbrpno++] = (pssz >> 16) & 0xFF ))
  328. (( thecode[mbrpno++] = (pssz >> 24) & 0xFF ))
  329. # write partition table entry
  330. ostr=
  331. curptr=0
  332. while (( curptr < 16 )); do
  333. ostr=$ostr\\0${thecode[curptr++]#8#}
  334. done
  335. print -n "$ostr" | \
  336. dd of="$T/firsttrack" conv=notrunc bs=1 seek=$((0x1EE)) 2>/dev/null
  337. if (( datafssz )); then
  338. # create data partition (copy of the above :)
  339. set -A thecode
  340. typeset -Uui8 thecode
  341. mbrpno=0
  342. set -A g_code $cyls $heads $secs
  343. (( psz = (cyls - cfgfs) * g_code[1] * g_code[2] ))
  344. (( pofs = (cyls - cfgfs - datafssz) * g_code[1] * g_code[2] ))
  345. set -A o_code # g_code equivalent for partition offset
  346. (( o_code[2] = pofs % g_code[2] + 1 ))
  347. (( o_code[1] = pofs / g_code[2] ))
  348. (( o_code[0] = o_code[1] / g_code[1] + 1 ))
  349. (( o_code[1] = o_code[1] % g_code[1] + 1 ))
  350. # boot flag; C/H/S offset
  351. thecode[mbrpno++]=0x00
  352. (( thecode[mbrpno++] = o_code[1] - 1 ))
  353. (( cylno = o_code[0] > 1024 ? 1023 : o_code[0] - 1 ))
  354. (( thecode[mbrpno++] = o_code[2] | ((cylno & 0x0300) >> 2) ))
  355. (( thecode[mbrpno++] = cylno & 0x00FF ))
  356. # partition type; C/H/S end
  357. (( thecode[mbrpno++] = 0x83 ))
  358. (( thecode[mbrpno++] = g_code[1] - 1 ))
  359. (( cylno = (g_code[0] - cfgfs) > 1024 ? 1023 : g_code[0] - cfgfs - 1 ))
  360. (( thecode[mbrpno++] = g_code[2] | ((cylno & 0x0300) >> 2) ))
  361. (( thecode[mbrpno++] = cylno & 0x00FF ))
  362. # partition offset, size (LBA)
  363. (( thecode[mbrpno++] = pofs & 0xFF ))
  364. (( thecode[mbrpno++] = (pofs >> 8) & 0xFF ))
  365. (( thecode[mbrpno++] = (pofs >> 16) & 0xFF ))
  366. (( thecode[mbrpno++] = (pofs >> 24) & 0xFF ))
  367. (( pssz = psz - pofs ))
  368. (( thecode[mbrpno++] = pssz & 0xFF ))
  369. (( thecode[mbrpno++] = (pssz >> 8) & 0xFF ))
  370. (( thecode[mbrpno++] = (pssz >> 16) & 0xFF ))
  371. (( thecode[mbrpno++] = (pssz >> 24) & 0xFF ))
  372. # write partition table entry
  373. ostr=
  374. curptr=0
  375. while (( curptr < 16 )); do
  376. ostr=$ostr\\0${thecode[curptr++]#8#}
  377. done
  378. print -n "$ostr" | \
  379. dd of="$T/firsttrack" conv=notrunc bs=1 seek=$((0x1CE)) 2>/dev/null
  380. fi
  381. if [[ $target = raspberry-pi || $target = raspberry-pi0 || $target = raspberry-pi2 || $target = raspberry-pi3 || $target = raspberry-pi3-64 || $target = raspberry-pi4 || $target = raspberry-pi4-64 || $target = raspberry-pi5 || $target = phytec-wega ]]; then
  382. # move system and data partition from #0/#1 to #1/#2
  383. dd if="$T/firsttrack" bs=1 skip=$((0x1BE)) count=32 of="$T/x" 2>/dev/null
  384. dd of="$T/firsttrack" conv=notrunc bs=1 seek=$((0x1CE)) if="$T/x" 2>/dev/null
  385. # create boot partition (copy of the above :)
  386. set -A thecode
  387. typeset -Uui8 thecode
  388. mbrpno=0
  389. set -A g_code $cyls $heads $secs
  390. psz=$spartofs
  391. pofs=$partofs
  392. set -A o_code # g_code equivalent for partition offset
  393. (( o_code[2] = pofs % g_code[2] + 1 ))
  394. (( o_code[1] = pofs / g_code[2] ))
  395. (( o_code[0] = o_code[1] / g_code[1] + 1 ))
  396. (( o_code[1] = o_code[1] % g_code[1] + 1 ))
  397. # boot flag; C/H/S offset
  398. thecode[mbrpno++]=0x00
  399. (( thecode[mbrpno++] = o_code[1] - 1 ))
  400. (( cylno = o_code[0] > 1024 ? 1023 : o_code[0] - 1 ))
  401. (( thecode[mbrpno++] = o_code[2] | ((cylno & 0x0300) >> 2) ))
  402. (( thecode[mbrpno++] = cylno & 0x00FF ))
  403. # partition type; C/H/S end
  404. (( thecode[mbrpno++] = 0x0B ))
  405. (( thecode[mbrpno++] = g_code[1] - 1 ))
  406. (( cylno = (spartofs / 2048) > 1024 ? 1023 : (spartofs / 2048) - 1 ))
  407. (( thecode[mbrpno++] = g_code[2] | ((cylno & 0x0300) >> 2) ))
  408. (( thecode[mbrpno++] = cylno & 0x00FF ))
  409. # partition offset, size (LBA)
  410. (( thecode[mbrpno++] = pofs & 0xFF ))
  411. (( thecode[mbrpno++] = (pofs >> 8) & 0xFF ))
  412. (( thecode[mbrpno++] = (pofs >> 16) & 0xFF ))
  413. (( thecode[mbrpno++] = (pofs >> 24) & 0xFF ))
  414. (( pssz = psz - pofs ))
  415. (( thecode[mbrpno++] = pssz & 0xFF ))
  416. (( thecode[mbrpno++] = (pssz >> 8) & 0xFF ))
  417. (( thecode[mbrpno++] = (pssz >> 16) & 0xFF ))
  418. (( thecode[mbrpno++] = (pssz >> 24) & 0xFF ))
  419. # write partition table entry
  420. ostr=
  421. curptr=0
  422. while (( curptr < 16 )); do
  423. ostr=$ostr\\0${thecode[curptr++]#8#}
  424. done
  425. print -n "$ostr" | \
  426. dd of="$T/firsttrack" conv=notrunc bs=1 seek=$((0x1BE)) 2>/dev/null
  427. fi
  428. # disk signature
  429. rnddev=/dev/urandom
  430. [[ -c /dev/arandom ]] && rnddev=/dev/arandom
  431. dd if=$rnddev bs=4 count=1 2>/dev/null | \
  432. dd of="$T/firsttrack" conv=notrunc bs=1 seek=$((0x1B8)) 2>/dev/null
  433. print -n '\0\0' | \
  434. dd of="$T/firsttrack" conv=notrunc bs=1 seek=$((0x1BC)) 2>/dev/null
  435. partuuid=$(dd if="$T/firsttrack" bs=1 count=4 skip=$((0x1B8)) 2>/dev/null | \
  436. hexdump -e '1/4 "%08x"')-0$((syspartno+1))
  437. ((keep)) || if (( datafssz )); then
  438. (( quiet )) || print Cleaning out data partition...
  439. dd if=/dev/zero of="$tgt" bs=1048576 count=1 seek=$((cyls - cfgfs - datafssz)) > /dev/null 2>&1
  440. fi
  441. (( quiet )) || print Cleaning out root partition...
  442. dd if=/dev/zero bs=1048576 of="$tgt" count=1 seek=$((spartofs / 2048)) > /dev/null 2>&1
  443. (( quiet )) || if (( grub )); then
  444. print Writing MBR and GRUB2 to target device... system PARTUUID=$partuuid
  445. else
  446. print Writing MBR to target device... system PARTUUID=$partuuid
  447. fi
  448. dd if="$T/firsttrack" of="$tgt" > /dev/null 2>&1
  449. if [[ $ostype = Linux ]]; then
  450. echo partprobe $tgt
  451. partprobe -s $tgt
  452. sync
  453. fdisk -l $tgt
  454. ls -la ${tgt}*
  455. fi
  456. fwdir=$(dirname "$src")
  457. case $target {
  458. (rockpi4-plus)
  459. dd if="$fwdir/idbloader.img" of="$tgt" bs=512 seek=64 > /dev/null 2>&1
  460. dd if="$fwdir/u-boot.itb" of="$tgt" bs=512 seek=16384 > /dev/null 2>&1
  461. ;;
  462. (imgtec-ci20)
  463. dd if="$fwdir/u-boot-spl.bin" of="$tgt" obs=512 seek=1 > /dev/null 2>&1
  464. dd if="$fwdir/u-boot-dtb.img" of="$tgt" obs=1k seek=14 > /dev/null 2>&1
  465. ;;
  466. (banana-pro|banana-pro-zero|orange-pi0)
  467. dd if="$fwdir/u-boot-sunxi-with-spl.bin" of="$tgt" bs=1024 seek=8 > /dev/null 2>&1
  468. ;;
  469. (solidrun-clearfog)
  470. dd if="$fwdir/u-boot-with-spl.kwb" of="$tgt" bs=512 seek=1 > /dev/null 2>&1
  471. ;;
  472. (solidrun-imx6|phytec-imx6)
  473. dd if="$fwdir/SPL" of="$tgt" bs=1024 seek=1 > /dev/null 2>&1
  474. dd if="$fwdir/u-boot.img" of="$tgt" bs=1024 seek=69 > /dev/null 2>&1
  475. ;;
  476. (raspberry-pi|raspberry-pi0|raspberry-pi2|raspberry-pi3|raspberry-pi3-64|raspberry-pi4|raspberry-pi4-64|raspberry-pi5)
  477. (( noformat )) || create_fs "$bootpart" ADKBOOT vfat
  478. ;;
  479. (phytec-wega)
  480. (( noformat )) || create_fs "$bootpart" ADKBOOT ext4
  481. ;;
  482. }
  483. case $target {
  484. (atmel-ngw100)
  485. (( noformat )) || create_fs "$rootpart" ADKROOT ext2
  486. (( noformat )) || tune_fs "$rootpart"
  487. ;;
  488. (*)
  489. (( noformat )) || create_fs "$rootpart" ADKROOT ext4
  490. (( noformat )) || tune_fs "$rootpart"
  491. }
  492. (( quiet )) || print Extracting installation archive...
  493. mount_fs "$rootpart" "$R" ext4
  494. gzip -dc "$src" | (cd "$R"; tar -xpf -)
  495. if (( datafssz )); then
  496. mkdir -m0755 "$R"/data
  497. ((keep)) || create_fs "$datapart" ADKDATA ext4
  498. ((keep)) || tune_fs "$datapart"
  499. case $target {
  500. (raspberry-pi|raspberry-pi0|raspberry-pi2|raspberry-pi3|raspberry-pi3-64|raspberry-pi4|raspberry-pi4-64|raspberry-pi5|phytec-wega)
  501. echo "/dev/mmcblk0p3 /data ext4 rw 0 0" >> "$R"/etc/fstab
  502. ;;
  503. (banana-pro|orange-pi0|solidrun-clearfog|rockpi4-plus)
  504. echo "/dev/mmcblk0p2 /data ext4 rw 0 0" >> "$R"/etc/fstab
  505. ;;
  506. (solidrun-imx6|phytec-imx6)
  507. echo "/dev/mmcblk1p2 /data ext4 rw 0 0" >> "$R"/etc/fstab
  508. ;;
  509. }
  510. if [[ -d $datapartcontent ]]; then
  511. mount_fs "$datapart" "$D" ext4
  512. # strip trailing slash
  513. case $datapartcontent in
  514. *[!/]*/) datapartcontent=${datapartcontent%"${x##*[!/]}"};;
  515. esac
  516. cp -R $datapartcontent/* "$D"
  517. fi
  518. fi
  519. (( quiet )) || print Finishing up with bootloader and kernel ...
  520. case $target {
  521. (raspberry-pi|raspberry-pi0|raspberry-pi2|raspberry-pi3|raspberry-pi3-64|raspberry-pi4|raspberry-pi4-64|raspberry-pi5)
  522. mount_fs "$bootpart" "$B" vfat
  523. for x in "$R"/boot/*; do
  524. [[ -e "$x" ]] && mv -f "$R"/boot/* "$B/"
  525. break
  526. done
  527. for x in "$fwdir"/*.dtb; do
  528. [[ -e "$x" ]] && cp "$fwdir"/*.dtb "$B/"
  529. break
  530. done
  531. # use static dtoverlay, rename to *.dtb
  532. mkdir "$B/"overlays
  533. for x in "$fwdir"/overlays/*.dtbo; do
  534. y=$(basename ${x} .dtbo)
  535. [[ -e "$x" ]] && cp "$fwdir"/overlays/${y}.dtbo "$B/"overlays/${y}.dtbo
  536. done
  537. for x in "$fwdir"/overlays/*.dtb; do
  538. y=$(basename ${x} .dtb)
  539. [[ -e "$x" ]] && cp "$fwdir"/overlays/${y}.dtb "$B/"overlays/${y}.dtb
  540. done
  541. umount_fs "$B"
  542. ;;
  543. (phytec-wega)
  544. mount_fs "$bootpart" "$B" ext4
  545. for x in "$R"/boot/*; do
  546. [[ -e "$x" ]] && mv -f "$R"/boot/* "$B/"
  547. break
  548. done
  549. for x in "$fwdir"/*.dtb; do
  550. [[ -e "$x" ]] && cp "$fwdir"/*.dtb "$B/"
  551. break
  552. done
  553. umount_fs "$B"
  554. ;;
  555. (rockpi4-plus)
  556. for x in "$fwdir"/*.dtb; do
  557. [[ -e "$x" ]] && cp "$fwdir"/*.dtb "$R/boot/"
  558. break
  559. done
  560. mkimage -A arm64 -O linux -T script -C none -a 0 -e 0 \
  561. -n "RockPI4-Plus" \
  562. -d $fwdir/boot.script.rockpi4 $R/boot/boot.scr.uimg
  563. ;;
  564. (solidrun-clearfog)
  565. for x in "$fwdir"/*.dtb; do
  566. [[ -e "$x" ]] && cp "$fwdir"/*.dtb "$R/boot/"
  567. break
  568. done
  569. mkimage -A arm -O linux -T script -C none -a 0 -e 0 \
  570. -n "SolidrunClearfog" \
  571. -d $fwdir/boot.script.clearfog $R/boot/boot.scr.uimg
  572. ;;
  573. (solidrun-imx6)
  574. for x in "$fwdir"/*.dtb; do
  575. [[ -e "$x" ]] && cp "$fwdir"/*.dtb "$R/boot/"
  576. break
  577. done
  578. mkimage -A arm -O linux -T script -C none -a 0 -e 0 \
  579. -n "SolidrunImx6" \
  580. -d $fwdir/boot.script.imx6 $R/boot/boot.scr.uimg
  581. ;;
  582. (phytec-imx6)
  583. for x in "$fwdir"/*.dtb; do
  584. [[ -e "$x" ]] && cp "$fwdir"/*.dtb "$R/boot/"
  585. break
  586. done
  587. mkimage -A arm -O linux -T script -C none -a 0 -e 0 \
  588. -n "PhytecImx6" \
  589. -d $fwdir/boot.script.phytec $R/boot/boot.scr.uimg
  590. ;;
  591. (orange-pi0)
  592. for x in "$fwdir"/*.dtb; do
  593. [[ -e "$x" ]] && cp "$fwdir"/*.dtb "$R/boot/"
  594. break
  595. done
  596. mkimage -A arm -O linux -T script -C none -a 0 -e 0 \
  597. -n "OrangePI Zero" \
  598. -d $fwdir/boot.script.opi $R/boot/boot.scr.uimg
  599. ;;
  600. (banana-pro)
  601. for x in "$fwdir"/*.dtb; do
  602. [[ -e "$x" ]] && cp "$fwdir"/*.dtb "$R/boot/"
  603. break
  604. done
  605. mkimage -A arm -O linux -T script -C none -a 0 -e 0 \
  606. -n "BananaPro" \
  607. -d $fwdir/boot.script.bpi $R/boot/boot.scr.uimg
  608. ;;
  609. (banana-pro-zero)
  610. for x in "$fwdir"/*.dtb; do
  611. [[ -e "$x" ]] && cp "$fwdir"/*.dtb "$R/boot/"
  612. break
  613. done
  614. mkimage -A arm -O linux -T script -C none -a 0 -e 0 \
  615. -n "BananaProZero" \
  616. -d $fwdir/boot.script.bpizero $R/boot/boot.scr.uimg
  617. ;;
  618. }
  619. cd "$R"
  620. dd if=$rnddev bs=16 count=1 >>etc/.rnd 2>/dev/null
  621. (( quiet )) || print Fixing up permissions...
  622. chown 0:0 tmp
  623. chmod 1777 tmp
  624. [[ -f usr/bin/sudo ]] && chmod 4755 usr/bin/sudo
  625. if (( grub )); then
  626. (( quiet )) || print Configuring GRUB2 bootloader...
  627. mkdir -p boot/grub
  628. (
  629. print set default=0
  630. print set timeout=1
  631. if (( serial )); then
  632. print serial --unit=0 --speed=$speed
  633. print terminal_output serial
  634. print terminal_input serial
  635. consargs="console=ttyS0,$speed console=tty0"
  636. else
  637. print terminal_output console
  638. print terminal_input console
  639. consargs="console=tty0"
  640. fi
  641. print
  642. print 'menuentry "GNU/Linux (OpenADK)" {'
  643. linuxargs="root=PARTUUID=$partuuid $consargs rootwait"
  644. (( panicreboot )) && linuxargs="$linuxargs panic=$panicreboot"
  645. print "\tlinux /boot/kernel $linuxargs"
  646. print '}'
  647. ) >boot/grub/grub.cfg
  648. fi
  649. (( quiet )) || print Finishing up...
  650. cd "$ADK_TOPDIR"
  651. umount_fs "$R"
  652. if (( datafssz )); then
  653. umount_fs $datapart
  654. fi
  655. rm -rf "$T"
  656. exit 0