123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866 |
- #!/bin/sh
- #
- # PiLC bootstrap
- #
- # Copyright 2016 Michael Buesch <m@bues.ch>
- #
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 2 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License along
- # with this program; if not, write to the Free Software Foundation, Inc.,
- # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- #
- basedir="$(dirname "$0")"
- [ "$(echo "$basedir" | cut -c1)" = '/' ] || basedir="$PWD/$basedir"
- # The repository root is basedir.
- basedir="$basedir/.."
- die()
- {
- echo "=== $*" >&2
- exit 1
- }
- info()
- {
- echo "--- $*"
- }
- # print the first of its arguments.
- first()
- {
- echo "$1"
- }
- # print the last of its arguments.
- last()
- {
- while [ $# -gt 1 ]; do shift; done
- echo "$1"
- }
- # $1=program_name
- have_program()
- {
- which "$1" >/dev/null 2>&1
- }
- # $1=program_name, ($2=description)
- assert_program()
- {
- local bin="$1"
- local desc="$2"
- [ -n "$desc" ] || desc="$bin"
- have_program "$bin" || die "$bin not found. Please install $desc."
- }
- term_signal()
- {
- die "Terminating signal received"
- }
- cleanup()
- {
- info "Cleaning up..."
- for mp in "$mp_shm" "$mp_proc" "$mp_sys" "$mp_bootimgfile" "$mp_rootimgfile"; do
- [ -n "$mp" -a -d "$mp" ] &&\
- umount "$mp" >/dev/null 2>&1
- done
- for mp in "$mp_bootimgfile" "$mp_rootimgfile"; do
- [ -n "$mp" -a -d "$mp" ] &&\
- rmdir "$mp" >/dev/null 2>&1
- done
- }
- boot_config_file()
- {
- cat <<EOF
- # For more options and information see
- # http://www.raspberrypi.org/documentation/configuration/config-txt.md
- # Some settings may impact device functionality. See link above for details
- # uncomment if you get no picture on HDMI for a default "safe" mode
- #hdmi_safe=1
- # uncomment this if your display has a black border of unused pixels visible
- # and your display can output without overscan
- #disable_overscan=1
- # uncomment the following to adjust overscan. Use positive numbers if console
- # goes off screen, and negative if there is too much border
- #overscan_left=16
- #overscan_right=16
- #overscan_top=16
- #overscan_bottom=16
- # uncomment to force a console size. By default it will be display's size minus
- # overscan.
- #framebuffer_width=1280
- #framebuffer_height=720
- # uncomment if hdmi display is not detected and composite is being output
- #hdmi_force_hotplug=1
- # uncomment to force a specific HDMI mode (this will force VGA)
- #hdmi_group=1
- #hdmi_mode=1
- # uncomment to force a HDMI mode rather than DVI. This can make audio work in
- # DMT (computer monitor) modes
- #hdmi_drive=2
- # uncomment to increase signal to HDMI, if you have interference, blanking, or
- # no display
- #config_hdmi_boost=4
- # uncomment for composite PAL
- #sdtv_mode=2
- #uncomment to overclock the arm. 700 MHz is the default.
- #arm_freq=800
- # Uncomment some or all of these to enable the optional hardware interfaces
- dtparam=i2c_arm=on
- dtparam=i2c_vc=on
- #dtparam=i2s=on
- #dtparam=spi=on
- # RV3029 RTC
- dtoverlay=rv3029-rtc
- # Uncomment this to enable the lirc-rpi module
- #dtoverlay=lirc-rpi
- # Additional overlays and parameters are documented /boot/overlays/README
- # Enable audio (loads snd_bcm2835)
- dtparam=audio=on
- EOF
- }
- pilc_bootstrap_first_stage()
- {
- echo "Running first stage..."
- [ "$(id -u)" = "0" ] || die "Permission denied. Must be root."
- # Check host tools (first/third stage).
- assert_program debootstrap
- assert_program git
- assert_program chroot
- assert_program rsync
- assert_program parted
- assert_program mkfs.vfat
- assert_program mkfs.ext4
- assert_program 7z
- [ -x "$opt_qemu" ] ||\
- die "The qemu binary '$opt_qemu' is not executable."
- # debootstrap first stage.
- if [ $opt_skip_debootstrap1 -eq 0 ]; then
- info "Running debootstrap first stage..."
- debootstrap --arch="$opt_arch" --foreign --verbose \
- --keyring="$basedir/pilc/raspbian.public.key.gpg" \
- "$opt_suite" "$opt_target_dir" "$opt_mirror" \
- || die "debootstrap failed"
- mkdir -p "$opt_target_dir/usr/share/keyrings" ||\
- die "Failed to create keyrings dir."
- cp /usr/share/keyrings/debian-archive-keyring.gpg \
- "$opt_target_dir/usr/share/keyrings/debian-archive-keyring.gpg" ||\
- die "Failed to copy debian-archive-keyring.gpg."
- fi
- [ -d "$opt_target_dir" ] ||\
- die "Target directory '$opt_target_dir' does not exist."
- # Copy qemu.
- local qemu_bin="$opt_target_dir/$opt_qemu"
- if ! [ -x "$qemu_bin" ]; then
- info "Copying qemu binary from '$opt_qemu' to '$qemu_bin'..."
- mkdir -p "$(dirname "$qemu_bin")" ||\
- die "Failed to make qemu base directory."
- cp "$opt_qemu" "$qemu_bin" ||\
- die "Failed to copy qemu binary."
- fi
- info "Copying rv3029 kernel module..."
- local rv3029_dir="$opt_target_dir/tmp/rv3029"
- mkdir -p "$rv3029_dir" ||\
- die "Failed to make rv3029 directory."
- cp "$basedir/pilc/kernel/rtc-rv3029c2.c" "$rv3029_dir/" ||\
- die "Failed to copy rv3029 source code."
- cp "$basedir/pilc/kernel/Makefile.kbuild" "$rv3029_dir/Makefile" ||\
- die "Failed to copy rv3029 Makefile."
- info "Copying PiLC bootstrap script..."
- cp "$basedir/pilc/pilc-bootstrap.sh" "$opt_target_dir/" ||\
- die "Failed to copy bootstrap script."
- info "Checking out awlsim..."
- local awlsim_dir="$opt_target_dir/tmp/awlsim"
- local checkout_dir="$awlsim_dir/src"
- rm -rf "$awlsim_dir"
- mkdir -p "$awlsim_dir" || die "mkdir failed"
- git clone --no-checkout "$basedir/.git" "$checkout_dir" ||\
- die "Failed to clone"
- (
- cd "$checkout_dir" ||\
- die "Failed to cd"
- git checkout -b __build "$opt_branch" ||\
- die "Failed to check out branch."
- rm -r ".git" ||\
- die "Failed to remove .git directory."
- ) || die
- # Second stage will mount a few filesystems.
- # Keep track to umount them in cleanup.
- mp_proc="$opt_target_dir/proc"
- mp_sys="$opt_target_dir/sys"
- mp_shm="$opt_target_dir/dev/shm"
- }
- pilc_bootstrap_second_stage()
- {
- info "Running second stage ($opt_arch)..."
- [ -x /pilc-bootstrap.sh ] ||\
- die "Second stage does not contain the bootstrap script."
- # Set up environment.
- export LC_ALL=C
- export LANGUAGE=C
- export LANG=C
- # debootstrap second stage.
- if [ $opt_skip_debootstrap2 -eq 0 ]; then
- info "Running debootstrap second stage..."
- /debootstrap/debootstrap --verbose --second-stage ||\
- die "Debootstrap second stage failed."
- fi
- info "Mounting /proc..."
- mkdir -p /proc ||\
- die "Failed to create /proc mountpoint."
- mount -t proc proc /proc ||\
- die "Mounting /proc failed."
- info "Mounting /sys..."
- mkdir -p /sys ||\
- die "Failed to create /sys mountpoint."
- mount -t sysfs sysfs /sys ||\
- die "Mounting /sys failed."
- info "Mounting /dev/shm..."
- mkdir -p /dev/shm ||\
- die "Failed to create /dev/shm mountpoint."
- mount -t tmpfs tmpfs /dev/shm ||\
- die "Mounting /dev/shm failed."
- info "Writing apt configuration (mirror = $opt_mirror)..."
- echo "deb $opt_mirror $opt_suite main firmware" > /etc/apt/sources.list ||\
- die "Failed to set sources.list"
- echo 'Acquire { Languages "none"; };' > /etc/apt/apt.conf.d/99no-translations ||\
- die "Failed to set apt.conf.d"
- info "Creating /etc/fstab"
- mkdir -p /config ||\
- die "Failed to create /config"
- cat > /etc/fstab <<EOF
- proc /proc proc auto,defaults 0 0
- debugfs /sys/kernel/debug debugfs auto,defaults 0 0
- configfs /config configfs auto,defaults 0 0
- tmpfs /tmp tmpfs auto,mode=1777 0 0
- /dev/mmcblk0p2 / ext4 auto,noatime,errors=remount-ro 0 1
- /dev/mmcblk0p1 /boot vfat auto,noatime 0 0
- EOF
- info "Writing misc /etc stuff..."
- echo "PiLC" > /etc/hostname ||\
- die "Failed to set hostname"
- printf 'PiLC GNU/Linux (based on Raspbian) \\n \\l\n\n' > /etc/issue ||\
- die "Failed to create /etc/issue"
- printf 'PiLC GNU/Linux (based on Raspbian)\n' > /etc/issue.net ||\
- die "Failed to create /etc/issue.net"
- sed -i -e 's|PRETTY_NAME=.*|PRETTY_NAME="PiLC"|' \
- /etc/os-release ||\
- die "Failed to set os-release PRETTY_NAME."
- sed -i -e 's|NAME=.*|NAME="PiLC"|' \
- /etc/os-release ||\
- die "Failed to set os-release NAME."
- sed -i -e 's|ID=.*|ID=pilc|' \
- /etc/os-release ||\
- die "Failed to set os-release ID."
- sed -i -e 's|ID_LIKE=.*|ID_LIKE=raspbian|' \
- /etc/os-release ||\
- die "Failed to set os-release ID_LIKE."
- sed -i -e 's|HOME_URL=.*|HOME_URL="https://bues.ch/h/pilc"|' \
- /etc/os-release ||\
- die "Failed to set os-release HOME_URL."
- sed -i -e 's|SUPPORT_URL=.*|SUPPORT_URL="https://bues.ch/h/pilc"|' \
- /etc/os-release ||\
- die "Failed to set os-release SUPPORT_URL."
- sed -i -e 's|BUG_REPORT_URL=.*|BUG_REPORT_URL="https://bues.ch/h/pilc"|' \
- /etc/os-release ||\
- die "Failed to set os-release BUG_REPORT_URL."
- sed -i -e 's|#FSCKFIX=no|FSCKFIX=yes|' \
- /etc/default/rcS ||\
- die "Failed to set FSCKFIX=yes"
- info "Updating packages..."
- cat <<EOF | debconf-set-selections
- debconf debconf/priority select high
- debconf debconf/frontend select Noninteractive
- locales locales/locales_to_be_generated multiselect en_US.UTF-8 UTF-8
- locales locales/default_environment_locale select None
- EOF
- [ $? -eq 0 ] || die "Failed to configure debconf settings"
- apt-get -y update ||\
- die "apt-get update failed"
- apt-get -y dist-upgrade ||\
- die "apt-get dist-upgrade failed"
- info "Installing packages..."
- apt-get -y install \
- aptitude \
- build-essential \
- console-setup \
- cython \
- cython3 \
- dbus \
- debconf-utils \
- devscripts \
- git \
- htop \
- i2c-tools \
- linux-headers-rpi-rpfv \
- linux-image-rpi-rpfv \
- linux-headers-rpi2-rpfv \
- linux-image-rpi2-rpfv \
- locales \
- nano \
- openssh-server \
- openssh-blacklist \
- openssh-blacklist-extra \
- pypy \
- python \
- python-all-dev \
- python-setuptools \
- python3 \
- python3-all-dev \
- python3-setuptools \
- raspberrypi-bootloader-nokernel \
- screen \
- sudo \
- systemd \
- tmux \
- vim ||\
- die "apt-get install failed"
- apt-get install --reinstall libc6-dev ||\
- die "Failed to reinstall"
- cat <<EOF | debconf-set-selections
- debconf debconf/frontend select Dialog
- locales locales/default_environment_locale select en_US.UTF-8
- EOF
- [ $? -eq 0 ] || die "Failed to configure debconf settings"
- dpkg-reconfigure -u locales ||\
- die "Failed to reconfigure locales"
- apt-get -y clean ||\
- die "apt-get clean failed"
- info "Removing ssh keys..."
- if [ -e "$(first /etc/ssh/ssh_host_*_key*)" ]; then
- rm /etc/ssh/ssh_host_*_key* ||\
- die "Failed to remove ssh keys."
- fi
- echo 1 > /etc/ssh/sshd_not_to_be_run ||\
- die "Failed to create /etc/ssh/sshd_not_to_be_run"
- echo 1 > /etc/ssh/ssh_create_keys ||\
- die "Failed to create /etc/ssh/ssh_create_keys"
- info "Creating /etc/rc.local..."
- cat > /etc/rc.local <<EOF
- #!/bin/sh -e
- #
- # rc.local
- #
- # This script is executed at the end of each multiuser runlevel.
- # Make sure that the script will "exit 0" on success or any other
- # value on error.
- #
- # In order to enable or disable this script just change the execution
- # bits.
- #
- set -e
- if [ -e /etc/ssh/ssh_create_keys ]; then
- /bin/rm -f /etc/ssh/ssh_host_*_key*
- LC_ALL=C LANGUAGE=C LANG=C /usr/sbin/dpkg-reconfigure openssh-server
- /bin/rm /etc/ssh/sshd_not_to_be_run
- /bin/rm /etc/ssh/ssh_create_keys
- /etc/init.d/ssh start
- fi
- exit 0
- EOF
- [ $? -eq 0 ] || die "Failed to create /etc/rc.local"
- info "Creating /etc/modules-load.d/i2c.conf..."
- cat > /etc/modules-load.d/i2c.conf <<EOF
- i2c-dev
- i2c-bcm2708
- at24
- rtc-rv3029c2
- EOF
- [ $? -eq 0 ] || die "Failed to create /etc/modules-load.d/i2c.conf"
- info "Creating users/groups..."
- userdel -f pi
- groupdel pi
- rm -rf /home/pi
- groupadd -g 1000 pi ||\
- die "Failed to create group pi."
- useradd -u 1000 -d /home/pi -m -g pi\
- -G pi,lp,dialout,cdrom,floppy,audio,dip,src,video,plugdev,netdev\
- -s /bin/bash\
- pi ||\
- die "Failed to create user pi."
- printf 'raspberry\nraspberry\n' | passwd pi ||\
- die "Failed to set 'pi' password."
- echo 'pi ALL=(ALL:ALL) ALL' > "/etc/sudoers.d/00-pi" ||\
- die "Failed to create /etc/sudoers.d/00-pi"
- info "Building updated rv3029 kernel module..."
- (
- cd /tmp/rv3029 ||\
- die "Failed to cd to rv3029 build dir"
- for moddir in /lib/modules/*; do
- [ -d "$moddir" ] || die "Invalid moddir '$moddir'"
- make KBUILD_DIR="$moddir/build" MODNAME=rtc-rv3029c2 \
- CFLAGS=-DCONFIG_RTC_DRV_RV3029_HWMON \
- clean ||\
- die "rv3029: Failed to clean"
- make KBUILD_DIR="$moddir/build" MODNAME=rtc-rv3029c2 \
- CFLAGS=-DCONFIG_RTC_DRV_RV3029_HWMON ||\
- die "rv3029: Failed to build"
- cp rtc-rv3029c2.ko "$moddir/kernel/drivers/rtc/" ||\
- die "rv3029: Failed to install kernel module"
- depmod "$(basename "$moddir")" ||\
- die "Failed to run depmod"
- done
- ) || die
- rm -r /tmp/rv3029 ||\
- die "Failed to remove rv3029 build dir."
- info "Building awlsim..."
- (
- cd /tmp/awlsim/src ||\
- die "Failed to cd"
- if [ $opt_cython -eq 0 ]; then
- # Disable cython
- sed -i -e '/Package: cython/,/^$/ d' \
- debian/control ||\
- die "Failed to patch control file"
- sed -i -e 's/export NOCYTHON=0/export NOCYTHON=1/' \
- debian/rules ||\
- die "Failed to patch rules file"
- fi
- debuild -uc -us -b -d || die "debuild failed"
- info "Built awlsim files:"
- ls .. || die "Failed to list results"
- info "Installing awlsim..."
- # Core
- dpkg -i ../python-awlsim_*.deb ||\
- die "Failed to install python-awlsim"
- dpkg -i ../python3-awlsim_*.deb ||\
- die "Failed to install python3-awlsim"
- dpkg -i ../pypy-awlsim_*.deb ||\
- die "Failed to install pypy-awlsim"
- if [ $opt_cython -ne 0 ]; then
- dpkg -i ../cython-awlsim_*.deb ||\
- die "Failed to install cython-awlsim"
- dpkg -i ../cython3-awlsim_*.deb ||\
- die "Failed to install cython3-awlsim"
- fi
- # hardware: dummy
- dpkg -i ../python-awlsimhw-dummy_*.deb ||\
- die "Failed to install python-awlsimhw-dummy"
- dpkg -i ../python3-awlsimhw-dummy_*.deb ||\
- die "Failed to install python3-awlsimhw-dummy"
- dpkg -i ../pypy-awlsimhw-dummy_*.deb ||\
- die "Failed to install pypy-awlsimhw-dummy"
- if [ $opt_cython -ne 0 ]; then
- dpkg -i ../cython-awlsimhw-dummy_*.deb ||\
- die "Failed to install cython-awlsimhw-dummy"
- dpkg -i ../cython3-awlsimhw-dummy_*.deb ||\
- die "Failed to install cython3-awlsimhw-dummy"
- fi
- # hardware: linuxcnc
- dpkg -i ../python-awlsimhw-linuxcnc_*.deb ||\
- die "Failed to install python-awlsimhw-linuxcnc"
- dpkg -i ../python3-awlsimhw-linuxcnc_*.deb ||\
- die "Failed to install python3-awlsimhw-linuxcnc"
- if [ $opt_cython -ne 0 ]; then
- dpkg -i ../cython-awlsimhw-linuxcnc_*.deb ||\
- die "Failed to install cython-awlsimhw-linuxcnc"
- dpkg -i ../cython3-awlsimhw-linuxcnc_*.deb ||\
- die "Failed to install cython3-awlsimhw-linuxcnc"
- fi
- # hardware: profibus
- dpkg -i ../python-awlsimhw-profibus_*.deb ||\
- die "Failed to install python-awlsimhw-profibus"
- dpkg -i ../python3-awlsimhw-profibus_*.deb ||\
- die "Failed to install python3-awlsimhw-profibus"
- dpkg -i ../pypy-awlsimhw-profibus_*.deb ||\
- die "Failed to install pypy-awlsimhw-profibus"
- if [ $opt_cython -ne 0 ]; then
- dpkg -i ../cython-awlsimhw-profibus_*.deb ||\
- die "Failed to install cython-awlsimhw-profibus"
- dpkg -i ../cython3-awlsimhw-profibus_*.deb ||\
- die "Failed to install cython3-awlsimhw-profibus"
- fi
- # Executables
- dpkg -i ../awlsim-server_*.deb ||\
- die "Failed to install awlsim-server"
- dpkg -i ../awlsim-client_*.deb ||\
- die "Failed to install awlsim-client"
- dpkg -i ../awlsim-symtab_*.deb ||\
- die "Failed to install awlsim-symtab"
- dpkg -i ../awlsim-test_*.deb ||\
- die "Failed to install awlsim-test"
- dpkg -i ../awlsim-linuxcnc-hal_*.deb ||\
- die "Failed to install awlsim-linuxcnc-hal"
- # GUI
- mkdir -p /home/pi/awlsim-gui ||\
- die "mkdir /home/pi/awlsim-gui failed"
- cp ../python*-awlsim-gui_*.deb ../awlsim-gui_*.deb \
- /home/pi/awlsim-gui/ ||\
- die "Failed to copy awlsim-gui"
- cp examples/EXAMPLE.awlpro /home/pi/ ||\
- die "Failed to copy EXAMPLE.awlpro."
- #TODO run the testsuite
- #TODO install unit via package
- info "Installing awlsim service unit..."
- local awlsim_prefix=/usr
- local site="$awlsim_prefix/lib/python3/dist-packages"
- cat awlsim-server.service.in |\
- sed -e 's|@USER@|pi|g' \
- -e 's|@GROUP@|pi|g' \
- -e "s|@PREFIX@|$awlsim_prefix|g" \
- -e "s|@PYTHON_SITE@|$site|g" >\
- /etc/systemd/system/awlsim-server.service ||\
- die "Failed to create awlsim-server.service"
- systemctl enable awlsim-server.service ||\
- die "Failed to enable awlsim-server-service"
- ) || die
- rm -r /tmp/awlsim ||\
- die "Failed to remove awlsim checkout."
- info "Extending pi user environment..."
- cat >> /home/pi/.bashrc <<EOF
- # PiLC
- for __i in /opt/awlsim/lib/python*/site-packages/; do
- export PYTHONPATH="\$PYTHONPATH:\$__i"
- done
- export PATH="\$PATH:/opt/awlsim/bin"
- EOF
- [ $? -eq 0 ] || die "Failed to extend /home/pi/.bashrc"
- info "Configuring network..."
- cat > /etc/network/interfaces.d/lo <<EOF
- auto lo
- iface lo inet loopback
- EOF
- [ $? -eq 0 ] || die "Failed to create /etc/network/interfaces.d/lo"
- cat > /etc/network/interfaces.d/eth0 <<EOF
- allow-hotplug eth0
- iface eth0 inet dhcp
- iface eth0 inet6 auto
- EOF
- [ $? -eq 0 ] || die "Failed to create /etc/network/interfaces.d/eth0"
- info "Stopping processes..."
- for i in dbus ssh atd; do
- /etc/init.d/$i stop
- done
- info "Umounting /dev/shm..."
- umount /dev/shm || die "Failed to umount /dev/shm"
- info "Umounting /sys..."
- umount /sys || die "Failed to umount /sys"
- info "Umounting /proc..."
- umount /proc || die "Failed to umount /proc"
- }
- pilc_bootstrap_third_stage()
- {
- info "Running third stage..."
- info "Removing PiLC bootstrap script..."
- rm "$opt_target_dir/pilc-bootstrap.sh" ||\
- die "Failed to remove bootstrap script."
- info "Configuring boot..."
- cat > "$opt_target_dir/boot/cmdline.txt" <<EOF
- dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet
- EOF
- [ $? -eq 0 ] || die "Failed to create /boot/cmdline.txt"
- boot_config_file > "$opt_target_dir/boot/config.txt" ||\
- die "Failed to create /boot/config.txt"
- cp "$basedir/pilc/kernel/rv3029.dtb" \
- "$opt_target_dir/boot/overlays/rv3029-rtc-overlay.dtb" ||\
- die "Failed to copy rv3029 dt overlay"
- local img="$(first "$opt_target_dir/boot/"vmlinuz-*-rpi)"
- if [ -e "$img" ]; then
- mv "$img" "$opt_target_dir/boot/kernel.img" ||\
- die "Failed to create kernel.img"
- fi
- local img="$(first "$opt_target_dir/boot/"initrd.img-*-rpi)"
- if [ -e "$img" ]; then
- mv "$img" "$opt_target_dir/boot/initrd.img" ||\
- die "Failed to create initrd.img"
- fi
- local img="$(first "$opt_target_dir/boot/"vmlinuz-*-rpi2)"
- if [ -e "$img" ]; then
- mv "$img" "$opt_target_dir/boot/kernel7.img" ||\
- die "Failed to create kernel7.img"
- fi
- local img="$(first "$opt_target_dir/boot/"initrd.img-*-rpi2)"
- if [ -e "$img" ]; then
- mv "$img" "$opt_target_dir/boot/initrd7.img" ||\
- die "Failed to create initrd7.img"
- fi
- # Prepare image paths.
- local target_dir="$(readlink -m "${opt_target_dir}")"
- [ -n "$target_dir" ] || die "Failed to resolve target dir."
- local imgfile="${target_dir}.img"
- local bootimgfile="${imgfile}.boot"
- mp_bootimgfile="${bootimgfile}.mp"
- local rootimgfile="${imgfile}.root"
- mp_rootimgfile="${rootimgfile}.mp"
- rm -f "$rootimgfile" "$bootimgfile"
- rmdir "$mp_bootimgfile" "$mp_rootimgfile" 2>/dev/null
- info "Creating boot image..."
- mkfs.vfat -F 32 -i 7771B0BB -n boot -C "$bootimgfile" \
- $(expr \( 64 \* 1024 \) - \( 4 \* 1024 \) ) ||\
- die "Failed to create boot partition file system."
- mkdir "$mp_bootimgfile" ||\
- die "Failed to make boot partition mount point."
- mount -o loop "$bootimgfile" "$mp_bootimgfile" ||\
- die "Failed to mount boot partition."
- rsync -aHAX --inplace \
- "$target_dir/boot/" "$mp_bootimgfile/" ||\
- die "Failed to copy boot files."
- umount "$mp_bootimgfile" ||\
- die "Failed to umount boot partition."
- rmdir "$mp_bootimgfile" ||\
- die "Failed to remove boot partition mount point."
- info "Creating root image..."
- mkfs.ext4 "$rootimgfile" $(expr \( 1391 - 64 \) \* 1024 ) ||\
- die "Failed to create root filesystem."
- mkdir "$mp_rootimgfile" ||\
- die "Failed to make root partition mount point."
- mount -o loop "$rootimgfile" "$mp_rootimgfile" ||\
- die "Failed to mount root partition."
- rsync -aHAX --inplace \
- --exclude='boot/*' \
- --exclude='proc/*' \
- --exclude='sys/*' \
- --exclude='dev/shm/*' \
- --exclude="$(basename "$opt_qemu")" \
- "$target_dir/" "$mp_rootimgfile/" ||\
- die "Failed to copy root files."
- umount "$mp_rootimgfile" ||\
- die "Failed to umount root partition."
- rmdir "$mp_rootimgfile" ||\
- die "Failed to remove root partition mount point."
- info "Creating image '$imgfile'..."
- dd if=/dev/zero of="$imgfile" bs=1M count=1391 conv=sparse ||\
- die "Failed to create image file."
- parted "$imgfile" <<EOF
- unit b
- mklabel msdos
- mkpart primary fat32 $(expr 4 \* 1024 \* 1024) $(expr 64 \* 1024 \* 1024 - 1)
- mkpart primary ext4 $(expr 64 \* 1024 \* 1024) 100%
- EOF
- [ $? -eq 0 ] || die "Failed to create partitions."
- info "Integrating boot image..."
- dd if="$bootimgfile" of="$imgfile"\
- seek=4 bs=1M conv=notrunc,sparse ||\
- die "Failed to integrate boot partition."
- rm "$bootimgfile" ||\
- die "Failed to delete boot partition image."
- info "Integrating root image..."
- dd if="$rootimgfile" of="$imgfile"\
- seek=64 bs=1M conv=notrunc,sparse ||\
- die "Failed to integrate root partition."
- rm "$rootimgfile" ||\
- die "Failed to delete root partition image."
- info "Compressing image..."
- local imgfile_zip="${imgfile}.7z"
- rm -f "$imgfile_zip"
- 7z -mx=9 a "$imgfile_zip" "$imgfile" ||\
- die "Failed to compress partition image."
- }
- usage()
- {
- echo "pilc-bootstrap.sh [OPTIONS] TARGET_DIR"
- echo
- echo "Options:"
- echo " --branch|-b BRANCH Select the awlsim branch."
- echo " Default: $default_branch"
- echo " --no-cython|-C Do not build Cython modules."
- echo " Default: Build cython modules"
- echo " --mirror|-m URL Select the mirror."
- echo " Default: $default_mirror"
- echo " --suite|-s SUITE Select the suite."
- echo " Default: $default_suite"
- echo " --arch|-a ARCH Select the default arch."
- echo " Default: $default_arch"
- echo " --qemu-bin|-q PATH Select qemu-user-static binary."
- echo " Default: $default_qemu"
- echo
- echo " --skip-debootstrap1|-1 Skip debootstrap first stage."
- echo " --skip-debootstrap2|-2 Skip debootstrap second stage."
- }
- # canonicalize basedir
- basedir="$(readlink -e "$basedir")"
- [ -n "$basedir" ] || die "Failed to canonicalize base directory."
- # Mountpoints. Will be umounted on cleanup.
- mp_shm=
- mp_proc=
- mp_sys=
- mp_bootimgfile=
- mp_rootimgfile=
- trap term_signal TERM INT
- if [ -z "$__PILC_BOOTSTRAP_SECOND_STAGE__" ]; then
- # First stage
- trap cleanup EXIT
- default_branch="master"
- default_mirror="http://mirrordirector.raspbian.org/raspbian/"
- default_suite="jessie"
- default_arch="armhf"
- default_qemu="/usr/bin/qemu-arm-static"
- opt_target_dir=
- opt_branch="$default_branch"
- opt_cython=1
- opt_mirror="$default_mirror"
- opt_suite="$default_suite"
- opt_arch="$default_arch"
- opt_qemu="$default_qemu"
- opt_skip_debootstrap1=0
- opt_skip_debootstrap2=0
- while [ $# -ge 1 ]; do
- case "$1" in
- --help|-h)
- usage
- exit 0
- ;;
- --branch|-b)
- shift
- opt_branch="$1"
- [ -n "$opt_branch" ] || die "No branch given"
- ;;
- --no-cython|-C)
- opt_cython=0
- ;;
- --mirror|-m)
- shift
- opt_mirror="$1"
- [ -n "$opt_mirror" ] || die "No mirror given"
- ;;
- --suite|-s)
- shift
- opt_suite="$1"
- [ -n "$opt_suite" ] || die "No suite given"
- ;;
- --arch|-a)
- shift
- opt_arch="$1"
- [ -n "$opt_arch" ] || die "No arch given"
- ;;
- --qemu-bin|-q)
- shift
- opt_qemu="$1"
- [ -x "$opt_qemu" ] || die "No valid qemu binary given"
- ;;
- --skip-debootstrap1|-1)
- opt_skip_debootstrap1=1
- ;;
- --skip-debootstrap2|-2)
- opt_skip_debootstrap2=1
- ;;
- *)
- opt_target_dir="$*"
- break
- ;;
- esac
- shift
- done
- [ -n "$opt_target_dir" ] ||\
- die "No TARGET_DIR"
- [ -d "$opt_target_dir" -o ! -e "$opt_target_dir" ] ||\
- die "$opt_target_dir is not a directory"
- # Run first stage.
- pilc_bootstrap_first_stage
- info "Starting second stage."
- # Export options for use by second stage.
- export opt_target_dir
- export opt_branch
- export opt_cython
- export opt_mirror
- export opt_suite
- export opt_arch
- export opt_qemu
- export opt_skip_debootstrap1
- export opt_skip_debootstrap2
- export __PILC_BOOTSTRAP_SECOND_STAGE__=1
- chroot "$opt_target_dir" "/pilc-bootstrap.sh" ||\
- die "Chroot failed."
- # Run third stage.
- pilc_bootstrap_third_stage
- info ""
- info "Successfully bootstrapped PiLC."
- exit 0
- else
- # Run second stage
- pilc_bootstrap_second_stage
- exit 0
- fi
|