install.sh 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  1. #!/usr/bin/env bash
  2. #-
  3. # Copyright © 2010-2023
  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. (Darwin)
  120. tools="bc diskutil"
  121. if [[ $paragon_ext == 0 ]]; then
  122. export PATH=/usr/local/opt/e2fsprogs/sbin:/usr/local/opt/e2fsprogs/bin:$PATH
  123. tools="$tools fuse-ext2 umount mkfs.ext4 tune2fs"
  124. fi
  125. ;;
  126. (*)
  127. print -u2 Sorry, not ported to the OS "'$ostype'" yet.
  128. exit 1
  129. ;;
  130. }
  131. for tool in $tools; do
  132. print -n Checking if $tool is installed...
  133. if whence -p $tool >/dev/null; then
  134. print " okay"
  135. else
  136. print " failed"
  137. f=1
  138. fi
  139. done
  140. (( f )) && exit 1
  141. target=$1
  142. tgt=$2
  143. src=$3
  144. case $target {
  145. (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|default) ;;
  146. (*)
  147. print -u2 "Unknown target '$target', exiting"
  148. exit 1 ;;
  149. }
  150. if [[ ! -b $tgt ]]; then
  151. print -u2 "'$tgt' is not a block device, exiting"
  152. exit 1
  153. fi
  154. if [[ ! -f $src ]]; then
  155. print -u2 "'$src' is not a file, exiting"
  156. exit 1
  157. fi
  158. (( quiet )) || print "Installing $src on $tgt."
  159. case $ostype {
  160. (Darwin)
  161. R=/Volumes/ADKROOT; diskutil unmount $R || umount $R
  162. B=/Volumes/ADKBOOT; diskutil unmount $B || umount $B
  163. D=/Volumes/ADKDATA; diskutil unmount $D || umount $D
  164. basedev=$tgt
  165. rootpart=${basedev}s1
  166. datapart=${basedev}s2
  167. 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
  168. bootpart=${basedev}s1
  169. rootpart=${basedev}s2
  170. datapart=${basedev}s3
  171. fi
  172. match=\'${basedev}\''?(s+([0-9]))'
  173. function mount_fs {
  174. if [[ $paragon_ext == 0 && $3 = ext4 ]]; then
  175. mkdir -p $2
  176. fuse-ext2 "$1" "$2" -o rw+
  177. fi
  178. }
  179. function umount_fs {
  180. (( quiet )) || print "Unmounting filesystem on ${1}..."
  181. if [[ $paragon_ext == 0 ]]; then
  182. umount "$1" || diskutil unmount "$1" || true
  183. rmdir $2 || true
  184. else
  185. diskutil unmount "$1"
  186. fi
  187. }
  188. function create_fs {
  189. (( quiet )) || printf "Creating filesystem on ${1}"
  190. if [[ $paragon_ext == 0 && $3 = ext4 ]]; then
  191. mkfs.ext4 -L "$2" "$1"
  192. else
  193. if [[ $3 = ext4 ]]; then
  194. fstype=UFSD_EXTFS4
  195. fi
  196. if [[ $3 = vfat ]]; then
  197. fstype=fat32
  198. fi
  199. diskutil eraseVolume $fstype "$2" "$1"
  200. fi
  201. }
  202. function tune_fs {
  203. if [[ $paragon_ext == 0 && $3 = ext4 ]]; then
  204. tune2fs -c 0 -i 0 "$1"
  205. fi
  206. }
  207. ;;
  208. (Linux)
  209. basedev=$tgt
  210. if [[ "$tgt" == *"nvme0n1"* ]] || [[ "$tgt" == *"mmcblk"* ]]; then
  211. partitionsep="p"
  212. else
  213. partitionsep=""
  214. fi
  215. if [[ $basedev = /dev/loop* ]]; then
  216. (( quiet )) || print "${tgt} is a loop device"
  217. partitionsep=p
  218. fi
  219. rootpart=${basedev}${partitionsep}1
  220. datapart=${basedev}${partitionsep}2
  221. 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
  222. bootpart=${basedev}${partitionsep}1
  223. rootpart=${basedev}${partitionsep}2
  224. datapart=${basedev}${partitionsep}3
  225. fi
  226. match=\'${basedev}${partitionsep}\''+([0-9])'
  227. function mount_fs {
  228. (( quiet )) || print "Mounting filesystem on ${1}..."
  229. mount -t "$3" "$1" "$2"
  230. }
  231. function umount_fs {
  232. (( quiet )) || print "Unmounting filesystem on ${1}..."
  233. umount "$1"
  234. }
  235. function create_fs {
  236. (( quiet )) || print "Creating filesystem on ${1}..."
  237. mkfs.$3 "$1"
  238. }
  239. function tune_fs {
  240. tune2fs -c 0 -i 0 "$1"
  241. }
  242. ;;
  243. }
  244. mount |&
  245. while read -p dev rest; do
  246. eval [[ \$dev = $match ]] || continue
  247. print -u2 "Block device $tgt is in use, please umount first."
  248. exit 1
  249. done
  250. if (( !quiet )); then
  251. print "WARNING: This will overwrite $basedev - type Yes to continue!"
  252. read x
  253. [[ $x = Yes ]] || exit 0
  254. fi
  255. if ! T=$(mktemp -d /tmp/openadk.XXXXXXXXXX); then
  256. print -u2 Error creating temporary directory.
  257. exit 1
  258. fi
  259. if [[ $ostype != Darwin ]]; then
  260. R=$T/rootmnt
  261. B=$T/bootmnt
  262. D=$T/datamnt
  263. mkdir -p "$R" "$B" "$D"
  264. fi
  265. # get disk size
  266. dksz=$(dkgetsz "$tgt")
  267. # partition layouts:
  268. # n̲a̲m̲e̲ p̲a̲r̲t̲#̲0̲ p̲̲a̲r̲t̲#̲1̲ p̲̲a̲r̲t̲#̲2̲ p̲̲a̲r̲t̲#̲3̲
  269. # default: 0x83(system) 0x83(?data) -(unused) 0x88(cfgfs)
  270. # raspberry: 0x0B(boot) 0x83(system) 0x83(?data) 0x88(cfgfs)
  271. syspartno=0
  272. # sizes:
  273. # boot(raspberry) - fixed (100 MiB)
  274. # cfgfs - fixed (parameter, max. 16 MiB)
  275. # data - flexible (parameter)
  276. # system - everything else
  277. 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
  278. syspartno=1
  279. bootfssz=100
  280. if (( grub )); then
  281. print -u2 "Cannot combine GRUB with $target"
  282. rm -rf "$T"
  283. exit 1
  284. fi
  285. else
  286. bootfssz=0
  287. fi
  288. heads=64
  289. secs=32
  290. (( cyls = dksz / heads / secs ))
  291. if (( cyls < (bootfssz + cfgfs + datafssz + 2) )); then
  292. print -u2 "Size of $tgt is $dksz, this looks fishy?"
  293. rm -rf "$T"
  294. exit 1
  295. fi
  296. if stat -qs .>/dev/null 2>&1; then
  297. statcmd='stat -f %z' # BSD stat (or so we assume)
  298. else
  299. statcmd='stat -c %s' # GNU stat
  300. fi
  301. if (( grub )); then
  302. tar -xOf "$src" boot/grub/core.img >"$T/core.img"
  303. integer coreimgsz=$($statcmd "$T/core.img")
  304. else
  305. coreimgsz=65024
  306. fi
  307. if (( coreimgsz < 1024 )); then
  308. print -u2 core.img is probably too small: $coreimgsz
  309. rm -rf "$T"
  310. exit 1
  311. fi
  312. if (( coreimgsz > 65024 )); then
  313. print -u2 core.img is larger than 64K-512: $coreimgsz
  314. rm -rf "$T"
  315. exit 1
  316. fi
  317. (( coreendsec = (coreimgsz + 511) / 512 ))
  318. if [[ $basedev = /dev/svnd+([0-9]) ]]; then
  319. # BSD svnd0 mode: protect sector #1
  320. corestartsec=2
  321. (( ++coreendsec ))
  322. corepatchofs=$((0x614))
  323. else
  324. corestartsec=1
  325. corepatchofs=$((0x414))
  326. fi
  327. # partition offset: at least coreendsec+1 but aligned on a multiple of secs
  328. #(( partofs = ((coreendsec / secs) + 1) * secs ))
  329. # we just use 2048 all the time, since some loaders are longer
  330. partofs=2048
  331. 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
  332. (( spartofs = partofs + (100 * 2048) ))
  333. else
  334. spartofs=$partofs
  335. fi
  336. (( quiet )) || if (( grub )); then
  337. print Preparing MBR and GRUB2...
  338. else
  339. print Preparing MBR...
  340. fi
  341. dd if=/dev/zero of="$T/firsttrack" count=$partofs 2>/dev/null
  342. # add another MiB to clear the first partition
  343. dd if=/dev/zero bs=1048576 count=1 >>"$T/firsttrack" 2>/dev/null
  344. echo $corestartsec $coreendsec | mksh "$ADK_TOPDIR/scripts/bootgrub.mksh" \
  345. -A -g $((cyls - bootfssz - cfgfs - datafssz)):$heads:$secs -M 1:0x83 \
  346. -O $spartofs | dd of="$T/firsttrack" conv=notrunc 2>/dev/null
  347. (( grub )) && dd if="$T/core.img" of="$T/firsttrack" conv=notrunc \
  348. seek=$corestartsec 2>/dev/null
  349. # set partition where it can find /boot/grub
  350. (( grub )) && print -n '\0\0\0\0' | \
  351. dd of="$T/firsttrack" conv=notrunc bs=1 seek=$corepatchofs 2>/dev/null
  352. # create cfgfs partition (mostly taken from bootgrub.mksh)
  353. set -A thecode
  354. typeset -Uui8 thecode
  355. mbrpno=0
  356. set -A g_code $cyls $heads $secs
  357. (( psz = g_code[0] * g_code[1] * g_code[2] ))
  358. (( pofs = (cyls - cfgfs) * g_code[1] * g_code[2] ))
  359. set -A o_code # g_code equivalent for partition offset
  360. (( o_code[2] = pofs % g_code[2] + 1 ))
  361. (( o_code[1] = pofs / g_code[2] ))
  362. (( o_code[0] = o_code[1] / g_code[1] + 1 ))
  363. (( o_code[1] = o_code[1] % g_code[1] + 1 ))
  364. # boot flag; C/H/S offset
  365. thecode[mbrpno++]=0x00
  366. (( thecode[mbrpno++] = o_code[1] - 1 ))
  367. (( cylno = o_code[0] > 1024 ? 1023 : o_code[0] - 1 ))
  368. (( thecode[mbrpno++] = o_code[2] | ((cylno & 0x0300) >> 2) ))
  369. (( thecode[mbrpno++] = cylno & 0x00FF ))
  370. # partition type; C/H/S end
  371. (( thecode[mbrpno++] = 0x88 ))
  372. (( thecode[mbrpno++] = g_code[1] - 1 ))
  373. (( cylno = g_code[0] > 1024 ? 1023 : g_code[0] - 1 ))
  374. (( thecode[mbrpno++] = g_code[2] | ((cylno & 0x0300) >> 2) ))
  375. (( thecode[mbrpno++] = cylno & 0x00FF ))
  376. # partition offset, size (LBA)
  377. (( thecode[mbrpno++] = pofs & 0xFF ))
  378. (( thecode[mbrpno++] = (pofs >> 8) & 0xFF ))
  379. (( thecode[mbrpno++] = (pofs >> 16) & 0xFF ))
  380. (( thecode[mbrpno++] = (pofs >> 24) & 0xFF ))
  381. (( pssz = psz - pofs ))
  382. (( thecode[mbrpno++] = pssz & 0xFF ))
  383. (( thecode[mbrpno++] = (pssz >> 8) & 0xFF ))
  384. (( thecode[mbrpno++] = (pssz >> 16) & 0xFF ))
  385. (( thecode[mbrpno++] = (pssz >> 24) & 0xFF ))
  386. # write partition table entry
  387. ostr=
  388. curptr=0
  389. while (( curptr < 16 )); do
  390. ostr=$ostr\\0${thecode[curptr++]#8#}
  391. done
  392. print -n "$ostr" | \
  393. dd of="$T/firsttrack" conv=notrunc bs=1 seek=$((0x1EE)) 2>/dev/null
  394. if (( datafssz )); then
  395. # create data partition (copy of the above :)
  396. set -A thecode
  397. typeset -Uui8 thecode
  398. mbrpno=0
  399. set -A g_code $cyls $heads $secs
  400. (( psz = (cyls - cfgfs) * g_code[1] * g_code[2] ))
  401. (( pofs = (cyls - cfgfs - datafssz) * g_code[1] * g_code[2] ))
  402. set -A o_code # g_code equivalent for partition offset
  403. (( o_code[2] = pofs % g_code[2] + 1 ))
  404. (( o_code[1] = pofs / g_code[2] ))
  405. (( o_code[0] = o_code[1] / g_code[1] + 1 ))
  406. (( o_code[1] = o_code[1] % g_code[1] + 1 ))
  407. # boot flag; C/H/S offset
  408. thecode[mbrpno++]=0x00
  409. (( thecode[mbrpno++] = o_code[1] - 1 ))
  410. (( cylno = o_code[0] > 1024 ? 1023 : o_code[0] - 1 ))
  411. (( thecode[mbrpno++] = o_code[2] | ((cylno & 0x0300) >> 2) ))
  412. (( thecode[mbrpno++] = cylno & 0x00FF ))
  413. # partition type; C/H/S end
  414. (( thecode[mbrpno++] = 0x83 ))
  415. (( thecode[mbrpno++] = g_code[1] - 1 ))
  416. (( cylno = (g_code[0] - cfgfs) > 1024 ? 1023 : g_code[0] - cfgfs - 1 ))
  417. (( thecode[mbrpno++] = g_code[2] | ((cylno & 0x0300) >> 2) ))
  418. (( thecode[mbrpno++] = cylno & 0x00FF ))
  419. # partition offset, size (LBA)
  420. (( thecode[mbrpno++] = pofs & 0xFF ))
  421. (( thecode[mbrpno++] = (pofs >> 8) & 0xFF ))
  422. (( thecode[mbrpno++] = (pofs >> 16) & 0xFF ))
  423. (( thecode[mbrpno++] = (pofs >> 24) & 0xFF ))
  424. (( pssz = psz - pofs ))
  425. (( thecode[mbrpno++] = pssz & 0xFF ))
  426. (( thecode[mbrpno++] = (pssz >> 8) & 0xFF ))
  427. (( thecode[mbrpno++] = (pssz >> 16) & 0xFF ))
  428. (( thecode[mbrpno++] = (pssz >> 24) & 0xFF ))
  429. # write partition table entry
  430. ostr=
  431. curptr=0
  432. while (( curptr < 16 )); do
  433. ostr=$ostr\\0${thecode[curptr++]#8#}
  434. done
  435. print -n "$ostr" | \
  436. dd of="$T/firsttrack" conv=notrunc bs=1 seek=$((0x1CE)) 2>/dev/null
  437. fi
  438. 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
  439. # move system and data partition from #0/#1 to #1/#2
  440. dd if="$T/firsttrack" bs=1 skip=$((0x1BE)) count=32 of="$T/x" 2>/dev/null
  441. dd of="$T/firsttrack" conv=notrunc bs=1 seek=$((0x1CE)) if="$T/x" 2>/dev/null
  442. # create boot partition (copy of the above :)
  443. set -A thecode
  444. typeset -Uui8 thecode
  445. mbrpno=0
  446. set -A g_code $cyls $heads $secs
  447. psz=$spartofs
  448. pofs=$partofs
  449. set -A o_code # g_code equivalent for partition offset
  450. (( o_code[2] = pofs % g_code[2] + 1 ))
  451. (( o_code[1] = pofs / g_code[2] ))
  452. (( o_code[0] = o_code[1] / g_code[1] + 1 ))
  453. (( o_code[1] = o_code[1] % g_code[1] + 1 ))
  454. # boot flag; C/H/S offset
  455. thecode[mbrpno++]=0x00
  456. (( thecode[mbrpno++] = o_code[1] - 1 ))
  457. (( cylno = o_code[0] > 1024 ? 1023 : o_code[0] - 1 ))
  458. (( thecode[mbrpno++] = o_code[2] | ((cylno & 0x0300) >> 2) ))
  459. (( thecode[mbrpno++] = cylno & 0x00FF ))
  460. # partition type; C/H/S end
  461. (( thecode[mbrpno++] = 0x0B ))
  462. (( thecode[mbrpno++] = g_code[1] - 1 ))
  463. (( cylno = (spartofs / 2048) > 1024 ? 1023 : (spartofs / 2048) - 1 ))
  464. (( thecode[mbrpno++] = g_code[2] | ((cylno & 0x0300) >> 2) ))
  465. (( thecode[mbrpno++] = cylno & 0x00FF ))
  466. # partition offset, size (LBA)
  467. (( thecode[mbrpno++] = pofs & 0xFF ))
  468. (( thecode[mbrpno++] = (pofs >> 8) & 0xFF ))
  469. (( thecode[mbrpno++] = (pofs >> 16) & 0xFF ))
  470. (( thecode[mbrpno++] = (pofs >> 24) & 0xFF ))
  471. (( pssz = psz - pofs ))
  472. (( thecode[mbrpno++] = pssz & 0xFF ))
  473. (( thecode[mbrpno++] = (pssz >> 8) & 0xFF ))
  474. (( thecode[mbrpno++] = (pssz >> 16) & 0xFF ))
  475. (( thecode[mbrpno++] = (pssz >> 24) & 0xFF ))
  476. # write partition table entry
  477. ostr=
  478. curptr=0
  479. while (( curptr < 16 )); do
  480. ostr=$ostr\\0${thecode[curptr++]#8#}
  481. done
  482. print -n "$ostr" | \
  483. dd of="$T/firsttrack" conv=notrunc bs=1 seek=$((0x1BE)) 2>/dev/null
  484. fi
  485. # disk signature
  486. rnddev=/dev/urandom
  487. [[ -c /dev/arandom ]] && rnddev=/dev/arandom
  488. dd if=$rnddev bs=4 count=1 2>/dev/null | \
  489. dd of="$T/firsttrack" conv=notrunc bs=1 seek=$((0x1B8)) 2>/dev/null
  490. print -n '\0\0' | \
  491. dd of="$T/firsttrack" conv=notrunc bs=1 seek=$((0x1BC)) 2>/dev/null
  492. partuuid=$(dd if="$T/firsttrack" bs=1 count=4 skip=$((0x1B8)) 2>/dev/null | \
  493. hexdump -e '1/4 "%08x"')-0$((syspartno+1))
  494. ((keep)) || if (( datafssz )); then
  495. (( quiet )) || print Cleaning out data partition...
  496. dd if=/dev/zero of="$tgt" bs=1048576 count=1 seek=$((cyls - cfgfs - datafssz)) > /dev/null 2>&1
  497. fi
  498. (( quiet )) || print Cleaning out root partition...
  499. dd if=/dev/zero bs=1048576 of="$tgt" count=1 seek=$((spartofs / 2048)) > /dev/null 2>&1
  500. (( quiet )) || if (( grub )); then
  501. print Writing MBR and GRUB2 to target device... system PARTUUID=$partuuid
  502. else
  503. print Writing MBR to target device... system PARTUUID=$partuuid
  504. fi
  505. dd if="$T/firsttrack" of="$tgt" > /dev/null 2>&1
  506. if [[ $ostype = Linux ]]; then
  507. echo partprobe $tgt
  508. partprobe -s $tgt
  509. sync
  510. fdisk -l $tgt
  511. ls -la ${tgt}*
  512. fi
  513. fwdir=$(dirname "$src")
  514. case $target {
  515. (rockpi4-plus)
  516. dd if="$fwdir/idbloader.img" of="$tgt" bs=512 seek=64 > /dev/null 2>&1
  517. dd if="$fwdir/u-boot.itb" of="$tgt" bs=512 seek=16384 > /dev/null 2>&1
  518. ;;
  519. (imgtec-ci20)
  520. dd if="$fwdir/u-boot-spl.bin" of="$tgt" obs=512 seek=1 > /dev/null 2>&1
  521. dd if="$fwdir/u-boot-dtb.img" of="$tgt" obs=1k seek=14 > /dev/null 2>&1
  522. ;;
  523. (banana-pro|banana-pro-zero|orange-pi0)
  524. dd if="$fwdir/u-boot-sunxi-with-spl.bin" of="$tgt" bs=1024 seek=8 > /dev/null 2>&1
  525. ;;
  526. (solidrun-clearfog)
  527. dd if="$fwdir/u-boot-spl.kwb" of="$tgt" bs=512 seek=1 > /dev/null 2>&1
  528. ;;
  529. (solidrun-imx6|phytec-imx6)
  530. dd if="$fwdir/SPL" of="$tgt" bs=1024 seek=1 > /dev/null 2>&1
  531. dd if="$fwdir/u-boot.img" of="$tgt" bs=1024 seek=69 > /dev/null 2>&1
  532. ;;
  533. (raspberry-pi|raspberry-pi0|raspberry-pi2|raspberry-pi3|raspberry-pi3-64|raspberry-pi4|raspberry-pi4-64|raspberry-pi5)
  534. (( noformat )) || create_fs "$bootpart" ADKBOOT vfat
  535. ;;
  536. (phytec-wega)
  537. (( noformat )) || create_fs "$bootpart" ADKBOOT ext4
  538. ;;
  539. }
  540. case $target {
  541. (atmel-ngw100)
  542. (( noformat )) || create_fs "$rootpart" ADKROOT ext2
  543. (( noformat )) || tune_fs "$rootpart"
  544. ;;
  545. (*)
  546. (( noformat )) || create_fs "$rootpart" ADKROOT ext4
  547. (( noformat )) || tune_fs "$rootpart"
  548. }
  549. (( quiet )) || print Extracting installation archive...
  550. mount_fs "$rootpart" "$R" ext4
  551. xz -dc "$src" | (cd "$R"; tar -xpf -)
  552. if (( datafssz )); then
  553. mkdir -m0755 "$R"/data
  554. ((keep)) || create_fs "$datapart" ADKDATA ext4
  555. ((keep)) || tune_fs "$datapart"
  556. case $target {
  557. (raspberry-pi|raspberry-pi0|raspberry-pi2|raspberry-pi3|raspberry-pi3-64|raspberry-pi4|raspberry-pi4-64|raspberry-pi5|phytec-wega)
  558. echo "/dev/mmcblk0p3 /data ext4 rw 0 0" >> "$R"/etc/fstab
  559. ;;
  560. (banana-pro|orange-pi0|solidrun-clearfog|rockpi4-plus)
  561. echo "/dev/mmcblk0p2 /data ext4 rw 0 0" >> "$R"/etc/fstab
  562. ;;
  563. (solidrun-imx6|phytec-imx6)
  564. echo "/dev/mmcblk1p2 /data ext4 rw 0 0" >> "$R"/etc/fstab
  565. ;;
  566. }
  567. if [[ -d $datapartcontent ]]; then
  568. mount_fs "$datapart" "$D" ext4
  569. # strip trailing slash
  570. case $datapartcontent in
  571. *[!/]*/) datapartcontent=${datapartcontent%"${x##*[!/]}"};;
  572. esac
  573. cp -R $datapartcontent/* "$D"
  574. fi
  575. fi
  576. (( quiet )) || print Finishing up with bootloader and kernel ...
  577. case $target {
  578. (raspberry-pi|raspberry-pi0|raspberry-pi2|raspberry-pi3|raspberry-pi3-64|raspberry-pi4|raspberry-pi4-64|raspberry-pi5)
  579. mount_fs "$bootpart" "$B" vfat
  580. for x in "$R"/boot/*; do
  581. [[ -e "$x" ]] && mv -f "$R"/boot/* "$B/"
  582. break
  583. done
  584. for x in "$fwdir"/*.dtb; do
  585. [[ -e "$x" ]] && cp "$fwdir"/*.dtb "$B/"
  586. break
  587. done
  588. # use static dtoverlay, rename to *.dtb
  589. mkdir "$B/"overlays
  590. for x in "$fwdir"/overlays/*.dtbo; do
  591. y=$(basename ${x} .dtbo)
  592. [[ -e "$x" ]] && cp "$fwdir"/overlays/${y}.dtbo "$B/"overlays/${y}.dtbo
  593. done
  594. for x in "$fwdir"/overlays/*.dtb; do
  595. y=$(basename ${x} .dtb)
  596. [[ -e "$x" ]] && cp "$fwdir"/overlays/${y}.dtb "$B/"overlays/${y}.dtb
  597. done
  598. umount_fs "$B"
  599. ;;
  600. (phytec-wega)
  601. mount_fs "$bootpart" "$B" ext4
  602. for x in "$R"/boot/*; do
  603. [[ -e "$x" ]] && mv -f "$R"/boot/* "$B/"
  604. break
  605. done
  606. for x in "$fwdir"/*.dtb; do
  607. [[ -e "$x" ]] && cp "$fwdir"/*.dtb "$B/"
  608. break
  609. done
  610. umount_fs "$B"
  611. ;;
  612. (rockpi4-plus)
  613. for x in "$fwdir"/*.dtb; do
  614. [[ -e "$x" ]] && cp "$fwdir"/*.dtb "$R/boot/"
  615. break
  616. done
  617. mkimage -A arm64 -O linux -T script -C none -a 0 -e 0 \
  618. -n "RockPI4-Plus" \
  619. -d $fwdir/boot.script.rockpi4 $R/boot/boot.scr.uimg
  620. ;;
  621. (solidrun-clearfog)
  622. for x in "$fwdir"/*.dtb; do
  623. [[ -e "$x" ]] && cp "$fwdir"/*.dtb "$R/boot/"
  624. break
  625. done
  626. mkimage -A arm -O linux -T script -C none -a 0 -e 0 \
  627. -n "SolidrunClearfog" \
  628. -d $fwdir/boot.script.clearfog $R/boot/boot.scr.uimg
  629. ;;
  630. (solidrun-imx6)
  631. for x in "$fwdir"/*.dtb; do
  632. [[ -e "$x" ]] && cp "$fwdir"/*.dtb "$R/boot/"
  633. break
  634. done
  635. mkimage -A arm -O linux -T script -C none -a 0 -e 0 \
  636. -n "SolidrunImx6" \
  637. -d $fwdir/boot.script.imx6 $R/boot/boot.scr.uimg
  638. ;;
  639. (phytec-imx6)
  640. for x in "$fwdir"/*.dtb; do
  641. [[ -e "$x" ]] && cp "$fwdir"/*.dtb "$R/boot/"
  642. break
  643. done
  644. mkimage -A arm -O linux -T script -C none -a 0 -e 0 \
  645. -n "PhytecImx6" \
  646. -d $fwdir/boot.script.phytec $R/boot/boot.scr.uimg
  647. ;;
  648. (orange-pi0)
  649. for x in "$fwdir"/*.dtb; do
  650. [[ -e "$x" ]] && cp "$fwdir"/*.dtb "$R/boot/"
  651. break
  652. done
  653. mkimage -A arm -O linux -T script -C none -a 0 -e 0 \
  654. -n "OrangePI Zero" \
  655. -d $fwdir/boot.script.opi $R/boot/boot.scr.uimg
  656. ;;
  657. (banana-pro)
  658. for x in "$fwdir"/*.dtb; do
  659. [[ -e "$x" ]] && cp "$fwdir"/*.dtb "$R/boot/"
  660. break
  661. done
  662. mkimage -A arm -O linux -T script -C none -a 0 -e 0 \
  663. -n "BananaPro" \
  664. -d $fwdir/boot.script.bpi $R/boot/boot.scr.uimg
  665. ;;
  666. (banana-pro-zero)
  667. for x in "$fwdir"/*.dtb; do
  668. [[ -e "$x" ]] && cp "$fwdir"/*.dtb "$R/boot/"
  669. break
  670. done
  671. mkimage -A arm -O linux -T script -C none -a 0 -e 0 \
  672. -n "BananaProZero" \
  673. -d $fwdir/boot.script.bpizero $R/boot/boot.scr.uimg
  674. ;;
  675. }
  676. cd "$R"
  677. dd if=$rnddev bs=16 count=1 >>etc/.rnd 2>/dev/null
  678. (( quiet )) || print Fixing up permissions...
  679. chown 0:0 tmp
  680. chmod 1777 tmp
  681. [[ -f usr/bin/sudo ]] && chmod 4755 usr/bin/sudo
  682. if (( grub )); then
  683. (( quiet )) || print Configuring GRUB2 bootloader...
  684. mkdir -p boot/grub
  685. (
  686. print set default=0
  687. print set timeout=1
  688. if (( serial )); then
  689. print serial --unit=0 --speed=$speed
  690. print terminal_output serial
  691. print terminal_input serial
  692. consargs="console=ttyS0,$speed console=tty0"
  693. else
  694. print terminal_output console
  695. print terminal_input console
  696. consargs="console=tty0"
  697. fi
  698. print
  699. print 'menuentry "GNU/Linux (OpenADK)" {'
  700. linuxargs="root=PARTUUID=$partuuid $consargs rootwait"
  701. (( panicreboot )) && linuxargs="$linuxargs panic=$panicreboot"
  702. print "\tlinux /boot/kernel $linuxargs"
  703. print '}'
  704. ) >boot/grub/grub.cfg
  705. fi
  706. (( quiet )) || print Finishing up...
  707. cd "$ADK_TOPDIR"
  708. umount_fs "$R"
  709. if (( datafssz )); then
  710. umount_fs $datapart
  711. fi
  712. rm -rf "$T"
  713. exit 0