pilc-bootstrap.sh 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866
  1. #!/bin/sh
  2. #
  3. # PiLC bootstrap
  4. #
  5. # Copyright 2016 Michael Buesch <m@bues.ch>
  6. #
  7. # This program is free software; you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation; either version 2 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License along
  18. # with this program; if not, write to the Free Software Foundation, Inc.,
  19. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20. #
  21. basedir="$(dirname "$0")"
  22. [ "$(echo "$basedir" | cut -c1)" = '/' ] || basedir="$PWD/$basedir"
  23. # The repository root is basedir.
  24. basedir="$basedir/.."
  25. die()
  26. {
  27. echo "=== $*" >&2
  28. exit 1
  29. }
  30. info()
  31. {
  32. echo "--- $*"
  33. }
  34. # print the first of its arguments.
  35. first()
  36. {
  37. echo "$1"
  38. }
  39. # print the last of its arguments.
  40. last()
  41. {
  42. while [ $# -gt 1 ]; do shift; done
  43. echo "$1"
  44. }
  45. # $1=program_name
  46. have_program()
  47. {
  48. which "$1" >/dev/null 2>&1
  49. }
  50. # $1=program_name, ($2=description)
  51. assert_program()
  52. {
  53. local bin="$1"
  54. local desc="$2"
  55. [ -n "$desc" ] || desc="$bin"
  56. have_program "$bin" || die "$bin not found. Please install $desc."
  57. }
  58. term_signal()
  59. {
  60. die "Terminating signal received"
  61. }
  62. cleanup()
  63. {
  64. info "Cleaning up..."
  65. for mp in "$mp_shm" "$mp_proc" "$mp_sys" "$mp_bootimgfile" "$mp_rootimgfile"; do
  66. [ -n "$mp" -a -d "$mp" ] &&\
  67. umount "$mp" >/dev/null 2>&1
  68. done
  69. for mp in "$mp_bootimgfile" "$mp_rootimgfile"; do
  70. [ -n "$mp" -a -d "$mp" ] &&\
  71. rmdir "$mp" >/dev/null 2>&1
  72. done
  73. }
  74. boot_config_file()
  75. {
  76. cat <<EOF
  77. # For more options and information see
  78. # http://www.raspberrypi.org/documentation/configuration/config-txt.md
  79. # Some settings may impact device functionality. See link above for details
  80. # uncomment if you get no picture on HDMI for a default "safe" mode
  81. #hdmi_safe=1
  82. # uncomment this if your display has a black border of unused pixels visible
  83. # and your display can output without overscan
  84. #disable_overscan=1
  85. # uncomment the following to adjust overscan. Use positive numbers if console
  86. # goes off screen, and negative if there is too much border
  87. #overscan_left=16
  88. #overscan_right=16
  89. #overscan_top=16
  90. #overscan_bottom=16
  91. # uncomment to force a console size. By default it will be display's size minus
  92. # overscan.
  93. #framebuffer_width=1280
  94. #framebuffer_height=720
  95. # uncomment if hdmi display is not detected and composite is being output
  96. #hdmi_force_hotplug=1
  97. # uncomment to force a specific HDMI mode (this will force VGA)
  98. #hdmi_group=1
  99. #hdmi_mode=1
  100. # uncomment to force a HDMI mode rather than DVI. This can make audio work in
  101. # DMT (computer monitor) modes
  102. #hdmi_drive=2
  103. # uncomment to increase signal to HDMI, if you have interference, blanking, or
  104. # no display
  105. #config_hdmi_boost=4
  106. # uncomment for composite PAL
  107. #sdtv_mode=2
  108. #uncomment to overclock the arm. 700 MHz is the default.
  109. #arm_freq=800
  110. # Uncomment some or all of these to enable the optional hardware interfaces
  111. dtparam=i2c_arm=on
  112. dtparam=i2c_vc=on
  113. #dtparam=i2s=on
  114. #dtparam=spi=on
  115. # RV3029 RTC
  116. dtoverlay=rv3029-rtc
  117. # Uncomment this to enable the lirc-rpi module
  118. #dtoverlay=lirc-rpi
  119. # Additional overlays and parameters are documented /boot/overlays/README
  120. # Enable audio (loads snd_bcm2835)
  121. dtparam=audio=on
  122. EOF
  123. }
  124. pilc_bootstrap_first_stage()
  125. {
  126. echo "Running first stage..."
  127. [ "$(id -u)" = "0" ] || die "Permission denied. Must be root."
  128. # Check host tools (first/third stage).
  129. assert_program debootstrap
  130. assert_program git
  131. assert_program chroot
  132. assert_program rsync
  133. assert_program parted
  134. assert_program mkfs.vfat
  135. assert_program mkfs.ext4
  136. assert_program 7z
  137. [ -x "$opt_qemu" ] ||\
  138. die "The qemu binary '$opt_qemu' is not executable."
  139. # debootstrap first stage.
  140. if [ $opt_skip_debootstrap1 -eq 0 ]; then
  141. info "Running debootstrap first stage..."
  142. debootstrap --arch="$opt_arch" --foreign --verbose \
  143. --keyring="$basedir/pilc/raspbian.public.key.gpg" \
  144. "$opt_suite" "$opt_target_dir" "$opt_mirror" \
  145. || die "debootstrap failed"
  146. mkdir -p "$opt_target_dir/usr/share/keyrings" ||\
  147. die "Failed to create keyrings dir."
  148. cp /usr/share/keyrings/debian-archive-keyring.gpg \
  149. "$opt_target_dir/usr/share/keyrings/debian-archive-keyring.gpg" ||\
  150. die "Failed to copy debian-archive-keyring.gpg."
  151. fi
  152. [ -d "$opt_target_dir" ] ||\
  153. die "Target directory '$opt_target_dir' does not exist."
  154. # Copy qemu.
  155. local qemu_bin="$opt_target_dir/$opt_qemu"
  156. if ! [ -x "$qemu_bin" ]; then
  157. info "Copying qemu binary from '$opt_qemu' to '$qemu_bin'..."
  158. mkdir -p "$(dirname "$qemu_bin")" ||\
  159. die "Failed to make qemu base directory."
  160. cp "$opt_qemu" "$qemu_bin" ||\
  161. die "Failed to copy qemu binary."
  162. fi
  163. info "Copying rv3029 kernel module..."
  164. local rv3029_dir="$opt_target_dir/tmp/rv3029"
  165. mkdir -p "$rv3029_dir" ||\
  166. die "Failed to make rv3029 directory."
  167. cp "$basedir/pilc/kernel/rtc-rv3029c2.c" "$rv3029_dir/" ||\
  168. die "Failed to copy rv3029 source code."
  169. cp "$basedir/pilc/kernel/Makefile.kbuild" "$rv3029_dir/Makefile" ||\
  170. die "Failed to copy rv3029 Makefile."
  171. info "Copying PiLC bootstrap script..."
  172. cp "$basedir/pilc/pilc-bootstrap.sh" "$opt_target_dir/" ||\
  173. die "Failed to copy bootstrap script."
  174. info "Checking out awlsim..."
  175. local awlsim_dir="$opt_target_dir/tmp/awlsim"
  176. local checkout_dir="$awlsim_dir/src"
  177. rm -rf "$awlsim_dir"
  178. mkdir -p "$awlsim_dir" || die "mkdir failed"
  179. git clone --no-checkout "$basedir/.git" "$checkout_dir" ||\
  180. die "Failed to clone"
  181. (
  182. cd "$checkout_dir" ||\
  183. die "Failed to cd"
  184. git checkout -b __build "$opt_branch" ||\
  185. die "Failed to check out branch."
  186. rm -r ".git" ||\
  187. die "Failed to remove .git directory."
  188. ) || die
  189. # Second stage will mount a few filesystems.
  190. # Keep track to umount them in cleanup.
  191. mp_proc="$opt_target_dir/proc"
  192. mp_sys="$opt_target_dir/sys"
  193. mp_shm="$opt_target_dir/dev/shm"
  194. }
  195. pilc_bootstrap_second_stage()
  196. {
  197. info "Running second stage ($opt_arch)..."
  198. [ -x /pilc-bootstrap.sh ] ||\
  199. die "Second stage does not contain the bootstrap script."
  200. # Set up environment.
  201. export LC_ALL=C
  202. export LANGUAGE=C
  203. export LANG=C
  204. # debootstrap second stage.
  205. if [ $opt_skip_debootstrap2 -eq 0 ]; then
  206. info "Running debootstrap second stage..."
  207. /debootstrap/debootstrap --verbose --second-stage ||\
  208. die "Debootstrap second stage failed."
  209. fi
  210. info "Mounting /proc..."
  211. mkdir -p /proc ||\
  212. die "Failed to create /proc mountpoint."
  213. mount -t proc proc /proc ||\
  214. die "Mounting /proc failed."
  215. info "Mounting /sys..."
  216. mkdir -p /sys ||\
  217. die "Failed to create /sys mountpoint."
  218. mount -t sysfs sysfs /sys ||\
  219. die "Mounting /sys failed."
  220. info "Mounting /dev/shm..."
  221. mkdir -p /dev/shm ||\
  222. die "Failed to create /dev/shm mountpoint."
  223. mount -t tmpfs tmpfs /dev/shm ||\
  224. die "Mounting /dev/shm failed."
  225. info "Writing apt configuration (mirror = $opt_mirror)..."
  226. echo "deb $opt_mirror $opt_suite main firmware" > /etc/apt/sources.list ||\
  227. die "Failed to set sources.list"
  228. echo 'Acquire { Languages "none"; };' > /etc/apt/apt.conf.d/99no-translations ||\
  229. die "Failed to set apt.conf.d"
  230. info "Creating /etc/fstab"
  231. mkdir -p /config ||\
  232. die "Failed to create /config"
  233. cat > /etc/fstab <<EOF
  234. proc /proc proc auto,defaults 0 0
  235. debugfs /sys/kernel/debug debugfs auto,defaults 0 0
  236. configfs /config configfs auto,defaults 0 0
  237. tmpfs /tmp tmpfs auto,mode=1777 0 0
  238. /dev/mmcblk0p2 / ext4 auto,noatime,errors=remount-ro 0 1
  239. /dev/mmcblk0p1 /boot vfat auto,noatime 0 0
  240. EOF
  241. info "Writing misc /etc stuff..."
  242. echo "PiLC" > /etc/hostname ||\
  243. die "Failed to set hostname"
  244. printf 'PiLC GNU/Linux (based on Raspbian) \\n \\l\n\n' > /etc/issue ||\
  245. die "Failed to create /etc/issue"
  246. printf 'PiLC GNU/Linux (based on Raspbian)\n' > /etc/issue.net ||\
  247. die "Failed to create /etc/issue.net"
  248. sed -i -e 's|PRETTY_NAME=.*|PRETTY_NAME="PiLC"|' \
  249. /etc/os-release ||\
  250. die "Failed to set os-release PRETTY_NAME."
  251. sed -i -e 's|NAME=.*|NAME="PiLC"|' \
  252. /etc/os-release ||\
  253. die "Failed to set os-release NAME."
  254. sed -i -e 's|ID=.*|ID=pilc|' \
  255. /etc/os-release ||\
  256. die "Failed to set os-release ID."
  257. sed -i -e 's|ID_LIKE=.*|ID_LIKE=raspbian|' \
  258. /etc/os-release ||\
  259. die "Failed to set os-release ID_LIKE."
  260. sed -i -e 's|HOME_URL=.*|HOME_URL="https://bues.ch/h/pilc"|' \
  261. /etc/os-release ||\
  262. die "Failed to set os-release HOME_URL."
  263. sed -i -e 's|SUPPORT_URL=.*|SUPPORT_URL="https://bues.ch/h/pilc"|' \
  264. /etc/os-release ||\
  265. die "Failed to set os-release SUPPORT_URL."
  266. sed -i -e 's|BUG_REPORT_URL=.*|BUG_REPORT_URL="https://bues.ch/h/pilc"|' \
  267. /etc/os-release ||\
  268. die "Failed to set os-release BUG_REPORT_URL."
  269. sed -i -e 's|#FSCKFIX=no|FSCKFIX=yes|' \
  270. /etc/default/rcS ||\
  271. die "Failed to set FSCKFIX=yes"
  272. info "Updating packages..."
  273. cat <<EOF | debconf-set-selections
  274. debconf debconf/priority select high
  275. debconf debconf/frontend select Noninteractive
  276. locales locales/locales_to_be_generated multiselect en_US.UTF-8 UTF-8
  277. locales locales/default_environment_locale select None
  278. EOF
  279. [ $? -eq 0 ] || die "Failed to configure debconf settings"
  280. apt-get -y update ||\
  281. die "apt-get update failed"
  282. apt-get -y dist-upgrade ||\
  283. die "apt-get dist-upgrade failed"
  284. info "Installing packages..."
  285. apt-get -y install \
  286. aptitude \
  287. build-essential \
  288. console-setup \
  289. cython \
  290. cython3 \
  291. dbus \
  292. debconf-utils \
  293. devscripts \
  294. git \
  295. htop \
  296. i2c-tools \
  297. linux-headers-rpi-rpfv \
  298. linux-image-rpi-rpfv \
  299. linux-headers-rpi2-rpfv \
  300. linux-image-rpi2-rpfv \
  301. locales \
  302. nano \
  303. openssh-server \
  304. openssh-blacklist \
  305. openssh-blacklist-extra \
  306. pypy \
  307. python \
  308. python-all-dev \
  309. python-setuptools \
  310. python3 \
  311. python3-all-dev \
  312. python3-setuptools \
  313. raspberrypi-bootloader-nokernel \
  314. screen \
  315. sudo \
  316. systemd \
  317. tmux \
  318. vim ||\
  319. die "apt-get install failed"
  320. apt-get install --reinstall libc6-dev ||\
  321. die "Failed to reinstall"
  322. cat <<EOF | debconf-set-selections
  323. debconf debconf/frontend select Dialog
  324. locales locales/default_environment_locale select en_US.UTF-8
  325. EOF
  326. [ $? -eq 0 ] || die "Failed to configure debconf settings"
  327. dpkg-reconfigure -u locales ||\
  328. die "Failed to reconfigure locales"
  329. apt-get -y clean ||\
  330. die "apt-get clean failed"
  331. info "Removing ssh keys..."
  332. if [ -e "$(first /etc/ssh/ssh_host_*_key*)" ]; then
  333. rm /etc/ssh/ssh_host_*_key* ||\
  334. die "Failed to remove ssh keys."
  335. fi
  336. echo 1 > /etc/ssh/sshd_not_to_be_run ||\
  337. die "Failed to create /etc/ssh/sshd_not_to_be_run"
  338. echo 1 > /etc/ssh/ssh_create_keys ||\
  339. die "Failed to create /etc/ssh/ssh_create_keys"
  340. info "Creating /etc/rc.local..."
  341. cat > /etc/rc.local <<EOF
  342. #!/bin/sh -e
  343. #
  344. # rc.local
  345. #
  346. # This script is executed at the end of each multiuser runlevel.
  347. # Make sure that the script will "exit 0" on success or any other
  348. # value on error.
  349. #
  350. # In order to enable or disable this script just change the execution
  351. # bits.
  352. #
  353. set -e
  354. if [ -e /etc/ssh/ssh_create_keys ]; then
  355. /bin/rm -f /etc/ssh/ssh_host_*_key*
  356. LC_ALL=C LANGUAGE=C LANG=C /usr/sbin/dpkg-reconfigure openssh-server
  357. /bin/rm /etc/ssh/sshd_not_to_be_run
  358. /bin/rm /etc/ssh/ssh_create_keys
  359. /etc/init.d/ssh start
  360. fi
  361. exit 0
  362. EOF
  363. [ $? -eq 0 ] || die "Failed to create /etc/rc.local"
  364. info "Creating /etc/modules-load.d/i2c.conf..."
  365. cat > /etc/modules-load.d/i2c.conf <<EOF
  366. i2c-dev
  367. i2c-bcm2708
  368. at24
  369. rtc-rv3029c2
  370. EOF
  371. [ $? -eq 0 ] || die "Failed to create /etc/modules-load.d/i2c.conf"
  372. info "Creating users/groups..."
  373. userdel -f pi
  374. groupdel pi
  375. rm -rf /home/pi
  376. groupadd -g 1000 pi ||\
  377. die "Failed to create group pi."
  378. useradd -u 1000 -d /home/pi -m -g pi\
  379. -G pi,lp,dialout,cdrom,floppy,audio,dip,src,video,plugdev,netdev\
  380. -s /bin/bash\
  381. pi ||\
  382. die "Failed to create user pi."
  383. printf 'raspberry\nraspberry\n' | passwd pi ||\
  384. die "Failed to set 'pi' password."
  385. echo 'pi ALL=(ALL:ALL) ALL' > "/etc/sudoers.d/00-pi" ||\
  386. die "Failed to create /etc/sudoers.d/00-pi"
  387. info "Building updated rv3029 kernel module..."
  388. (
  389. cd /tmp/rv3029 ||\
  390. die "Failed to cd to rv3029 build dir"
  391. for moddir in /lib/modules/*; do
  392. [ -d "$moddir" ] || die "Invalid moddir '$moddir'"
  393. make KBUILD_DIR="$moddir/build" MODNAME=rtc-rv3029c2 \
  394. CFLAGS=-DCONFIG_RTC_DRV_RV3029_HWMON \
  395. clean ||\
  396. die "rv3029: Failed to clean"
  397. make KBUILD_DIR="$moddir/build" MODNAME=rtc-rv3029c2 \
  398. CFLAGS=-DCONFIG_RTC_DRV_RV3029_HWMON ||\
  399. die "rv3029: Failed to build"
  400. cp rtc-rv3029c2.ko "$moddir/kernel/drivers/rtc/" ||\
  401. die "rv3029: Failed to install kernel module"
  402. depmod "$(basename "$moddir")" ||\
  403. die "Failed to run depmod"
  404. done
  405. ) || die
  406. rm -r /tmp/rv3029 ||\
  407. die "Failed to remove rv3029 build dir."
  408. info "Building awlsim..."
  409. (
  410. cd /tmp/awlsim/src ||\
  411. die "Failed to cd"
  412. if [ $opt_cython -eq 0 ]; then
  413. # Disable cython
  414. sed -i -e '/Package: cython/,/^$/ d' \
  415. debian/control ||\
  416. die "Failed to patch control file"
  417. sed -i -e 's/export NOCYTHON=0/export NOCYTHON=1/' \
  418. debian/rules ||\
  419. die "Failed to patch rules file"
  420. fi
  421. debuild -uc -us -b -d || die "debuild failed"
  422. info "Built awlsim files:"
  423. ls .. || die "Failed to list results"
  424. info "Installing awlsim..."
  425. # Core
  426. dpkg -i ../python-awlsim_*.deb ||\
  427. die "Failed to install python-awlsim"
  428. dpkg -i ../python3-awlsim_*.deb ||\
  429. die "Failed to install python3-awlsim"
  430. dpkg -i ../pypy-awlsim_*.deb ||\
  431. die "Failed to install pypy-awlsim"
  432. if [ $opt_cython -ne 0 ]; then
  433. dpkg -i ../cython-awlsim_*.deb ||\
  434. die "Failed to install cython-awlsim"
  435. dpkg -i ../cython3-awlsim_*.deb ||\
  436. die "Failed to install cython3-awlsim"
  437. fi
  438. # hardware: dummy
  439. dpkg -i ../python-awlsimhw-dummy_*.deb ||\
  440. die "Failed to install python-awlsimhw-dummy"
  441. dpkg -i ../python3-awlsimhw-dummy_*.deb ||\
  442. die "Failed to install python3-awlsimhw-dummy"
  443. dpkg -i ../pypy-awlsimhw-dummy_*.deb ||\
  444. die "Failed to install pypy-awlsimhw-dummy"
  445. if [ $opt_cython -ne 0 ]; then
  446. dpkg -i ../cython-awlsimhw-dummy_*.deb ||\
  447. die "Failed to install cython-awlsimhw-dummy"
  448. dpkg -i ../cython3-awlsimhw-dummy_*.deb ||\
  449. die "Failed to install cython3-awlsimhw-dummy"
  450. fi
  451. # hardware: linuxcnc
  452. dpkg -i ../python-awlsimhw-linuxcnc_*.deb ||\
  453. die "Failed to install python-awlsimhw-linuxcnc"
  454. dpkg -i ../python3-awlsimhw-linuxcnc_*.deb ||\
  455. die "Failed to install python3-awlsimhw-linuxcnc"
  456. if [ $opt_cython -ne 0 ]; then
  457. dpkg -i ../cython-awlsimhw-linuxcnc_*.deb ||\
  458. die "Failed to install cython-awlsimhw-linuxcnc"
  459. dpkg -i ../cython3-awlsimhw-linuxcnc_*.deb ||\
  460. die "Failed to install cython3-awlsimhw-linuxcnc"
  461. fi
  462. # hardware: profibus
  463. dpkg -i ../python-awlsimhw-profibus_*.deb ||\
  464. die "Failed to install python-awlsimhw-profibus"
  465. dpkg -i ../python3-awlsimhw-profibus_*.deb ||\
  466. die "Failed to install python3-awlsimhw-profibus"
  467. dpkg -i ../pypy-awlsimhw-profibus_*.deb ||\
  468. die "Failed to install pypy-awlsimhw-profibus"
  469. if [ $opt_cython -ne 0 ]; then
  470. dpkg -i ../cython-awlsimhw-profibus_*.deb ||\
  471. die "Failed to install cython-awlsimhw-profibus"
  472. dpkg -i ../cython3-awlsimhw-profibus_*.deb ||\
  473. die "Failed to install cython3-awlsimhw-profibus"
  474. fi
  475. # Executables
  476. dpkg -i ../awlsim-server_*.deb ||\
  477. die "Failed to install awlsim-server"
  478. dpkg -i ../awlsim-client_*.deb ||\
  479. die "Failed to install awlsim-client"
  480. dpkg -i ../awlsim-symtab_*.deb ||\
  481. die "Failed to install awlsim-symtab"
  482. dpkg -i ../awlsim-test_*.deb ||\
  483. die "Failed to install awlsim-test"
  484. dpkg -i ../awlsim-linuxcnc-hal_*.deb ||\
  485. die "Failed to install awlsim-linuxcnc-hal"
  486. # GUI
  487. mkdir -p /home/pi/awlsim-gui ||\
  488. die "mkdir /home/pi/awlsim-gui failed"
  489. cp ../python*-awlsim-gui_*.deb ../awlsim-gui_*.deb \
  490. /home/pi/awlsim-gui/ ||\
  491. die "Failed to copy awlsim-gui"
  492. cp examples/EXAMPLE.awlpro /home/pi/ ||\
  493. die "Failed to copy EXAMPLE.awlpro."
  494. #TODO run the testsuite
  495. #TODO install unit via package
  496. info "Installing awlsim service unit..."
  497. local awlsim_prefix=/usr
  498. local site="$awlsim_prefix/lib/python3/dist-packages"
  499. cat awlsim-server.service.in |\
  500. sed -e 's|@USER@|pi|g' \
  501. -e 's|@GROUP@|pi|g' \
  502. -e "s|@PREFIX@|$awlsim_prefix|g" \
  503. -e "s|@PYTHON_SITE@|$site|g" >\
  504. /etc/systemd/system/awlsim-server.service ||\
  505. die "Failed to create awlsim-server.service"
  506. systemctl enable awlsim-server.service ||\
  507. die "Failed to enable awlsim-server-service"
  508. ) || die
  509. rm -r /tmp/awlsim ||\
  510. die "Failed to remove awlsim checkout."
  511. info "Extending pi user environment..."
  512. cat >> /home/pi/.bashrc <<EOF
  513. # PiLC
  514. for __i in /opt/awlsim/lib/python*/site-packages/; do
  515. export PYTHONPATH="\$PYTHONPATH:\$__i"
  516. done
  517. export PATH="\$PATH:/opt/awlsim/bin"
  518. EOF
  519. [ $? -eq 0 ] || die "Failed to extend /home/pi/.bashrc"
  520. info "Configuring network..."
  521. cat > /etc/network/interfaces.d/lo <<EOF
  522. auto lo
  523. iface lo inet loopback
  524. EOF
  525. [ $? -eq 0 ] || die "Failed to create /etc/network/interfaces.d/lo"
  526. cat > /etc/network/interfaces.d/eth0 <<EOF
  527. allow-hotplug eth0
  528. iface eth0 inet dhcp
  529. iface eth0 inet6 auto
  530. EOF
  531. [ $? -eq 0 ] || die "Failed to create /etc/network/interfaces.d/eth0"
  532. info "Stopping processes..."
  533. for i in dbus ssh atd; do
  534. /etc/init.d/$i stop
  535. done
  536. info "Umounting /dev/shm..."
  537. umount /dev/shm || die "Failed to umount /dev/shm"
  538. info "Umounting /sys..."
  539. umount /sys || die "Failed to umount /sys"
  540. info "Umounting /proc..."
  541. umount /proc || die "Failed to umount /proc"
  542. }
  543. pilc_bootstrap_third_stage()
  544. {
  545. info "Running third stage..."
  546. info "Removing PiLC bootstrap script..."
  547. rm "$opt_target_dir/pilc-bootstrap.sh" ||\
  548. die "Failed to remove bootstrap script."
  549. info "Configuring boot..."
  550. cat > "$opt_target_dir/boot/cmdline.txt" <<EOF
  551. dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet
  552. EOF
  553. [ $? -eq 0 ] || die "Failed to create /boot/cmdline.txt"
  554. boot_config_file > "$opt_target_dir/boot/config.txt" ||\
  555. die "Failed to create /boot/config.txt"
  556. cp "$basedir/pilc/kernel/rv3029.dtb" \
  557. "$opt_target_dir/boot/overlays/rv3029-rtc-overlay.dtb" ||\
  558. die "Failed to copy rv3029 dt overlay"
  559. local img="$(first "$opt_target_dir/boot/"vmlinuz-*-rpi)"
  560. if [ -e "$img" ]; then
  561. mv "$img" "$opt_target_dir/boot/kernel.img" ||\
  562. die "Failed to create kernel.img"
  563. fi
  564. local img="$(first "$opt_target_dir/boot/"initrd.img-*-rpi)"
  565. if [ -e "$img" ]; then
  566. mv "$img" "$opt_target_dir/boot/initrd.img" ||\
  567. die "Failed to create initrd.img"
  568. fi
  569. local img="$(first "$opt_target_dir/boot/"vmlinuz-*-rpi2)"
  570. if [ -e "$img" ]; then
  571. mv "$img" "$opt_target_dir/boot/kernel7.img" ||\
  572. die "Failed to create kernel7.img"
  573. fi
  574. local img="$(first "$opt_target_dir/boot/"initrd.img-*-rpi2)"
  575. if [ -e "$img" ]; then
  576. mv "$img" "$opt_target_dir/boot/initrd7.img" ||\
  577. die "Failed to create initrd7.img"
  578. fi
  579. # Prepare image paths.
  580. local target_dir="$(readlink -m "${opt_target_dir}")"
  581. [ -n "$target_dir" ] || die "Failed to resolve target dir."
  582. local imgfile="${target_dir}.img"
  583. local bootimgfile="${imgfile}.boot"
  584. mp_bootimgfile="${bootimgfile}.mp"
  585. local rootimgfile="${imgfile}.root"
  586. mp_rootimgfile="${rootimgfile}.mp"
  587. rm -f "$rootimgfile" "$bootimgfile"
  588. rmdir "$mp_bootimgfile" "$mp_rootimgfile" 2>/dev/null
  589. info "Creating boot image..."
  590. mkfs.vfat -F 32 -i 7771B0BB -n boot -C "$bootimgfile" \
  591. $(expr \( 64 \* 1024 \) - \( 4 \* 1024 \) ) ||\
  592. die "Failed to create boot partition file system."
  593. mkdir "$mp_bootimgfile" ||\
  594. die "Failed to make boot partition mount point."
  595. mount -o loop "$bootimgfile" "$mp_bootimgfile" ||\
  596. die "Failed to mount boot partition."
  597. rsync -aHAX --inplace \
  598. "$target_dir/boot/" "$mp_bootimgfile/" ||\
  599. die "Failed to copy boot files."
  600. umount "$mp_bootimgfile" ||\
  601. die "Failed to umount boot partition."
  602. rmdir "$mp_bootimgfile" ||\
  603. die "Failed to remove boot partition mount point."
  604. info "Creating root image..."
  605. mkfs.ext4 "$rootimgfile" $(expr \( 1391 - 64 \) \* 1024 ) ||\
  606. die "Failed to create root filesystem."
  607. mkdir "$mp_rootimgfile" ||\
  608. die "Failed to make root partition mount point."
  609. mount -o loop "$rootimgfile" "$mp_rootimgfile" ||\
  610. die "Failed to mount root partition."
  611. rsync -aHAX --inplace \
  612. --exclude='boot/*' \
  613. --exclude='proc/*' \
  614. --exclude='sys/*' \
  615. --exclude='dev/shm/*' \
  616. --exclude="$(basename "$opt_qemu")" \
  617. "$target_dir/" "$mp_rootimgfile/" ||\
  618. die "Failed to copy root files."
  619. umount "$mp_rootimgfile" ||\
  620. die "Failed to umount root partition."
  621. rmdir "$mp_rootimgfile" ||\
  622. die "Failed to remove root partition mount point."
  623. info "Creating image '$imgfile'..."
  624. dd if=/dev/zero of="$imgfile" bs=1M count=1391 conv=sparse ||\
  625. die "Failed to create image file."
  626. parted "$imgfile" <<EOF
  627. unit b
  628. mklabel msdos
  629. mkpart primary fat32 $(expr 4 \* 1024 \* 1024) $(expr 64 \* 1024 \* 1024 - 1)
  630. mkpart primary ext4 $(expr 64 \* 1024 \* 1024) 100%
  631. EOF
  632. [ $? -eq 0 ] || die "Failed to create partitions."
  633. info "Integrating boot image..."
  634. dd if="$bootimgfile" of="$imgfile"\
  635. seek=4 bs=1M conv=notrunc,sparse ||\
  636. die "Failed to integrate boot partition."
  637. rm "$bootimgfile" ||\
  638. die "Failed to delete boot partition image."
  639. info "Integrating root image..."
  640. dd if="$rootimgfile" of="$imgfile"\
  641. seek=64 bs=1M conv=notrunc,sparse ||\
  642. die "Failed to integrate root partition."
  643. rm "$rootimgfile" ||\
  644. die "Failed to delete root partition image."
  645. info "Compressing image..."
  646. local imgfile_zip="${imgfile}.7z"
  647. rm -f "$imgfile_zip"
  648. 7z -mx=9 a "$imgfile_zip" "$imgfile" ||\
  649. die "Failed to compress partition image."
  650. }
  651. usage()
  652. {
  653. echo "pilc-bootstrap.sh [OPTIONS] TARGET_DIR"
  654. echo
  655. echo "Options:"
  656. echo " --branch|-b BRANCH Select the awlsim branch."
  657. echo " Default: $default_branch"
  658. echo " --no-cython|-C Do not build Cython modules."
  659. echo " Default: Build cython modules"
  660. echo " --mirror|-m URL Select the mirror."
  661. echo " Default: $default_mirror"
  662. echo " --suite|-s SUITE Select the suite."
  663. echo " Default: $default_suite"
  664. echo " --arch|-a ARCH Select the default arch."
  665. echo " Default: $default_arch"
  666. echo " --qemu-bin|-q PATH Select qemu-user-static binary."
  667. echo " Default: $default_qemu"
  668. echo
  669. echo " --skip-debootstrap1|-1 Skip debootstrap first stage."
  670. echo " --skip-debootstrap2|-2 Skip debootstrap second stage."
  671. }
  672. # canonicalize basedir
  673. basedir="$(readlink -e "$basedir")"
  674. [ -n "$basedir" ] || die "Failed to canonicalize base directory."
  675. # Mountpoints. Will be umounted on cleanup.
  676. mp_shm=
  677. mp_proc=
  678. mp_sys=
  679. mp_bootimgfile=
  680. mp_rootimgfile=
  681. trap term_signal TERM INT
  682. if [ -z "$__PILC_BOOTSTRAP_SECOND_STAGE__" ]; then
  683. # First stage
  684. trap cleanup EXIT
  685. default_branch="master"
  686. default_mirror="http://mirrordirector.raspbian.org/raspbian/"
  687. default_suite="jessie"
  688. default_arch="armhf"
  689. default_qemu="/usr/bin/qemu-arm-static"
  690. opt_target_dir=
  691. opt_branch="$default_branch"
  692. opt_cython=1
  693. opt_mirror="$default_mirror"
  694. opt_suite="$default_suite"
  695. opt_arch="$default_arch"
  696. opt_qemu="$default_qemu"
  697. opt_skip_debootstrap1=0
  698. opt_skip_debootstrap2=0
  699. while [ $# -ge 1 ]; do
  700. case "$1" in
  701. --help|-h)
  702. usage
  703. exit 0
  704. ;;
  705. --branch|-b)
  706. shift
  707. opt_branch="$1"
  708. [ -n "$opt_branch" ] || die "No branch given"
  709. ;;
  710. --no-cython|-C)
  711. opt_cython=0
  712. ;;
  713. --mirror|-m)
  714. shift
  715. opt_mirror="$1"
  716. [ -n "$opt_mirror" ] || die "No mirror given"
  717. ;;
  718. --suite|-s)
  719. shift
  720. opt_suite="$1"
  721. [ -n "$opt_suite" ] || die "No suite given"
  722. ;;
  723. --arch|-a)
  724. shift
  725. opt_arch="$1"
  726. [ -n "$opt_arch" ] || die "No arch given"
  727. ;;
  728. --qemu-bin|-q)
  729. shift
  730. opt_qemu="$1"
  731. [ -x "$opt_qemu" ] || die "No valid qemu binary given"
  732. ;;
  733. --skip-debootstrap1|-1)
  734. opt_skip_debootstrap1=1
  735. ;;
  736. --skip-debootstrap2|-2)
  737. opt_skip_debootstrap2=1
  738. ;;
  739. *)
  740. opt_target_dir="$*"
  741. break
  742. ;;
  743. esac
  744. shift
  745. done
  746. [ -n "$opt_target_dir" ] ||\
  747. die "No TARGET_DIR"
  748. [ -d "$opt_target_dir" -o ! -e "$opt_target_dir" ] ||\
  749. die "$opt_target_dir is not a directory"
  750. # Run first stage.
  751. pilc_bootstrap_first_stage
  752. info "Starting second stage."
  753. # Export options for use by second stage.
  754. export opt_target_dir
  755. export opt_branch
  756. export opt_cython
  757. export opt_mirror
  758. export opt_suite
  759. export opt_arch
  760. export opt_qemu
  761. export opt_skip_debootstrap1
  762. export opt_skip_debootstrap2
  763. export __PILC_BOOTSTRAP_SECOND_STAGE__=1
  764. chroot "$opt_target_dir" "/pilc-bootstrap.sh" ||\
  765. die "Chroot failed."
  766. # Run third stage.
  767. pilc_bootstrap_third_stage
  768. info ""
  769. info "Successfully bootstrapped PiLC."
  770. exit 0
  771. else
  772. # Run second stage
  773. pilc_bootstrap_second_stage
  774. exit 0
  775. fi