#!/bin/sh ################################################################################ # This file is part of OpenELEC - http://www.openelec.tv # Copyright (C) 2009-2014 Stephan Raue (stephan@openelec.tv) # Copyright (C) 2010-2011 Roman Weber (roman@openelec.tv) # Copyright (C) 2012 Yann Cézard (eesprit@free.fr) # # OpenELEC 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. # # OpenELEC 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 OpenELEC. If not, see . ################################################################################ # create directories /bin/busybox mkdir -p /dev /bin/busybox mkdir -p /proc /bin/busybox mkdir -p /sys /bin/busybox mkdir -p /tmp /bin/busybox mkdir -p /flash /bin/busybox mkdir -p /sysroot /bin/busybox mkdir -p /storage # mount all needed special filesystems /bin/busybox mount -t devtmpfs devtmpfs /dev /bin/busybox mount -t proc proc /proc /bin/busybox mount -t sysfs sysfs /sys # common functions . /functions # set needed variables MODULE_DIR=/lib/modules UPDATE_ROOT=/storage/.update UPDATE_DIR="$UPDATE_ROOT" UPDATE_KERNEL="KERNEL" UPDATE_SYSTEM="SYSTEM" IMAGE_KERNEL="KERNEL" IMAGE_SYSTEM="SYSTEM" BOOT_STEP="start" MD5_FAILED="0" RUN_FSCK="yes" RUN_FSCK_DISKS="" NBD_DEVS="0" FLASH_FREE_MIN="5" INSTALLED_MEMORY=`cat /proc/meminfo | grep 'MemTotal:' | awk '{print $2}'` SYSTEM_TORAM_LIMIT=1024000 LIVE="no" # hide kernel log messages on console echo '1 4 1 7' > /proc/sys/kernel/printk # set ondemand up_threshold if [ -e /sys/devices/system/cpu/cpufreq/ondemand/up_threshold ] ; then echo 50 > /sys/devices/system/cpu/cpufreq/ondemand/up_threshold fi # run platform_init script if exists if [ -f "./platform_init" ]; then ./platform_init fi # clear screen and hide cursor clear hidecursor # parse command line arguments for arg in $(cat /proc/cmdline); do case $arg in BOOT_IMAGE=*) IMAGE_KERNEL="${arg#*=}" ;; SYSTEM_IMAGE=*) IMAGE_SYSTEM="${arg#*=}" ;; boot=*) boot="${arg#*=}" case $boot in ISCSI=*|NBD=*|NFS=*) UPDATE_DISABLED=yes FLASH_NETBOOT=yes ;; /dev/*|LABEL=*|UUID=*) RUN_FSCK_DISKS="$RUN_FSCK_DISKS $boot" ;; esac ;; disk=*) disk="${arg#*=}" case $disk in ISCSI=*|NBD=*|NFS=*) STORAGE_NETBOOT=yes ;; /dev/*|LABEL=*|UUID=*) RUN_FSCK_DISKS="$RUN_FSCK_DISKS $disk" ;; esac ;; wol_mac=*) wol_mac="${arg#*=}" ;; wol_wait=*) wol_wait="${arg#*=}" ;; textmode) INIT_UNIT="--unit=textmode.target" ;; installer) INIT_UNIT="--unit=installer.target" ;; debugging) DEBUG=yes ;; progress) PROGRESS=yes INIT_ARGS="$INIT_ARGS --show-status=1" ;; nofsck) RUN_FSCK=no ;; nosplash) SPLASH=no ;; noram) SYSTEM_TORAM=no ;; live) LIVE=yes ;; overlay) OVERLAY=yes ;; setfbres=*) SWITCH_FRAMEBUFFER="${arg#*=}" SWITCH_FRAMEBUFFER="${SWITCH_FRAMEBUFFER//,/ }" ;; break=*) BREAK="${arg#*=}" ;; esac done if test "$DEBUG" = "yes"; then exec 3>&1 else exec 3>/dev/null fi SILENT_OUT=3 progress() { if test "$PROGRESS" = "yes"; then echo "### $1 ###" fi } debug_shell() { echo "### Starting debugging shell... type exit to quit ###" showcursor sh /dev/tty1 2>&1 } error() { # Display fatal error message # $1:action which caused error, $2:message echo "*** Error in $BOOT_STEP: $1: $2 ***" debug_shell } break_after() { # Start debug shell after boot step $1 case $BREAK in all|*$1*) debug_shell ;; esac } # Mount handlers # All handlers take the following parameters: # $1:target, $2:mountpoint, $3:mount options, [$4:fs type] mount_common() { # Common mount handler, handles block devices and filesystem images MOUNT_OPTIONS="-o $3" [ -n "$4" ] && MOUNT_OPTIONS="-t $4 $MOUNT_OPTIONS" for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do ERR_ENV=1 mount $MOUNT_OPTIONS $1 $2 >&$SILENT_OUT 2>&1 [ "$?" -eq "0" ] && ERR_ENV=0 && break usleep 1000000 done [ "$ERR_ENV" -ne "0" ] && error "mount_common" "Could not mount $1" } get_iscsistart_options() { # Convert kernel commandline ISCSI= options to iscsistart options IFS_SAVE="$IFS" IFS=, for arg in $1; do val="${arg#*=}" case "$arg" in iscsi_initiator=*) option="-i" ;; iscsi_target_name=*) option="-t" ;; iscsi_target_ip=*) option="-a" ;; iscsi_target_port=*) option="-p" ;; iscsi_target_group=*) option="-g" ;; iscsi_username=*) option="-u" ;; iscsi_password=*) option="-w" ;; iscsi_in_username=*) option="-U" ;; iscsi_in_password=*) option="-W" ;; esac echo "$option $val" done IFS="$IFS_SAVE" } mount_iscsi() { # Mount iSCSI target ISCSI_DEV="${1##*,}" ISCSI_OPTIONS="${1%,*}" if [ ! -f "/sbin/iscsistart" ]; then error "iscsistart" "iSCSI support not available" fi if [ "$ISCSI_OPTIONS" = "auto" ]; then progress "Network configuration based on iBFT" /sbin/iscsistart -N >&$SILENT_OUT 2>&1 || \ error "iscsistart" "Unable to configure network" progress "iSCSI auto connect based on iBFT" /sbin/iscsistart -b >&$SILENT_OUT 2>&1 || \ error "iscsistart" "Unable to auto connect" else /sbin/iscsistart $(get_iscsistart_options "$ISCSI_OPTIONS") >&$SILENT_OUT 2>&1 || \ error "iscsistart" "Unable to connect to ISCSI target" fi mount_common "$ISCSI_DEV" "$2" "$3" "$4" } mount_nbd() { # Mount NBD device NBD_SERVER="${1%%:*}" NBD_PORT="${1#*:}" NBD_DEV="/dev/nbd$NBD_DEVS" nbd-client $NBD_SERVER $NBD_PORT $NBD_DEV >&$SILENT_OUT 2>&1 || \ error "nbd-client" "Could not connect to NBD server $1" mount_common "$NBD_DEV" "$2" "$3" "$4" NBD_DEVS=$(( ${NBD_DEVS} + 1 )) } mount_nfs() { # Mount NFS export NFS_EXPORT="${1%%,*}" NFS_OPTIONS="${1#*,}" [ "$NFS_OPTIONS" = "$1" ] && NFS_OPTIONS= mount_common "$NFS_EXPORT" "$2" "$3,nolock,soft,timeo=3,retrans=2,rsize=32768,wsize=32768,$NFS_OPTIONS" "nfs" } mount_ubifs() { mount_common "$1" "$2" "$3" "ubifs" } mount_part() { # Mount a local or network filesystem # $1:[TYPE=]target, $2:mountpoint, $3:mount options, [$4:fs type] progress "mount filesystem $1 ..." MOUNT_TARGET="${1#*=}" case $1 in /dev/ubi*) MOUNT_CMD="mount_ubifs" MOUNT_TARGET="$1" RUN_FSCK="no" ;; LABEL=*|UUID=*|/*) MOUNT_CMD="mount_common" MOUNT_TARGET="$1" ;; ISCSI=*) MOUNT_CMD="mount_iscsi" ;; NBD=*) MOUNT_CMD="mount_nbd" ;; NFS=*) MOUNT_CMD="mount_nfs" ;; *) error "mount_part" "Unknown filesystem $1" ;; esac $MOUNT_CMD "$MOUNT_TARGET" "$2" "$3" "$4" } update_file() { if [ -f "$UPDATE_DIR/$2" -a -f "$3" ]; then mount -o remount,rw /flash StartProgress percent "Updating $1... " "$3" $(stat -t "$UPDATE_DIR/$2" | awk '{print $2}') # use dd here with conv=fsync so that all writes are non-buffered # ensuring accurate progress - take the sync hit during the # transfer, rather than when flushing file buffers after the progress # meter declares the transfer already complete dd if=$UPDATE_DIR/$2 of=$3 bs=1M conv=fsync 2>/dev/null StopProgress # loopback file needs writable /flash all the time if [ "${disk%%=*}" != "FILE" ]; then mount -o remount,ro /flash fi sync fi } update_partition() { local result if [ -f "$UPDATE_DIR/$2" -a -b "$3" ]; then StartProgress spinner "Updating $1... " result="$(dd if="$UPDATE_DIR/$2" of="$3" conv=fsync 2>&1)" StopProgress "done" echo "${result}" fi } update_bootloader() { local result export BOOT_ROOT="/flash" export SYSTEM_ROOT="/sysroot" mount_part "/flash/$IMAGE_SYSTEM" "/sysroot" "ro,loop" if [ -f $SYSTEM_ROOT/usr/share/bootloader/update.sh ]; then StartProgress spinner "Updating Bootloader... " result="$(sh $SYSTEM_ROOT/usr/share/bootloader/update.sh 2>&1)" sync StopProgress "done" [ -n "${result}" ] && echo "${result}" fi umount /sysroot } load_modules() { progress "Loading kernel modules" [ ! -f "/etc/modules" ] && return for module in $(cat /etc/modules); do progress "Loading kernel module $module" insmod "$MODULE_DIR/$module.ko" || \ progress "... Failed to load kernel module $module, skipping" done } load_splash() { local set_default_res=no local vres if [ ! "$SPLASH" = "no" ]; then progress "Loading bootsplash" # load uvesafb module if needed if [ -f "$MODULE_DIR/uvesafb.ko" -a ! -e /dev/fb0 ]; then progress "Loading kernel module uvesafb.ko" insmod "$MODULE_DIR/uvesafb.ko" && \ set_default_res=yes || \ progress "... Failed to load kernel module uvesafb, skipping" fi if [ -e /dev/fb0 ]; then # Set framebuffer to a custom resolution and/or fallback to default resolution (1024x768-32), if required. if [ ! "$SWITCH_FRAMEBUFFER" = "no" ]; then if [ "$SWITCH_FRAMEBUFFER" = "1080" ]; then SWITCH_FRAMEBUFFER="1920 1080 1920 1080 32" elif [ "$SWITCH_FRAMEBUFFER" = "720" ]; then SWITCH_FRAMEBUFFER="1280 720 1280 720 32" fi # Try setting a custom framebuffer resolution if [ ! "${SWITCH_FRAMEBUFFER:-yes}" = "yes" ]; then fbset -g $SWITCH_FRAMEBUFFER 2>/dev/null && set_default_res=no fi # Set a default resolution if required if [ "$set_default_res" = "yes" ]; then fbset -g 1024 768 1024 768 32 fi fi # Select splash image based on current native resolution if [ -z "$SPLASHIMAGE" ]; then vres="$(fbset | awk '/geometry/ { print $3 }')" if [ -n "$vres" -a -f /splash/splash-$vres.png ]; then SPLASHIMAGE="/splash/splash-$vres.png" else SPLASHIMAGE="/splash/splash-1080.png" fi fi # load splash if [ -f /flash/oemsplash.png ]; then SPLASHIMAGE="/flash/oemsplash.png" elif [ -f /splash/splash.conf ]; then . /splash/splash.conf fi ply-image $SPLASHIMAGE > /dev/null 2>&1 fi fi } do_reboot() { echo "System reboots now..." # syncing filesystem sync # unmount filesystems if /bin/busybox mountpoint -q /flash ; then /bin/busybox umount /flash fi if /bin/busybox mountpoint -q /storage ; then /bin/busybox umount /storage fi usleep 2000000 /bin/busybox reboot } force_fsck() { echo "Filesystem corruption has been detected!" echo "To prevent an automatic repair attempt continuing," echo "press any key or power off your system within the next 120 seconds" echo "" read -t120 -n1 # The exit status is 0 if input is available # The exit status is greater than 128 if the timeout is exceeded if [ "$?" -ne "0" -o "$?" -gt "128" ] ; then echo "Repairing filesystem..." echo "" /sbin/fsck -T -M -y $RUN_FSCK_DISKS FSCK_RET="$?" if [ "$(( $FSCK_RET & 8 ))" = 8 ] ; then # fubar echo "Forced fsck failed. Your system is broken beyond repair" echo "Please re-install @DISTRONAME@" echo "" echo "Press enter to shutdown now" echo "" read fubar poweroff fi do_reboot else echo "Shutting down..." sleep 5 sync poweroff fi } check_disks() { if [ "$RUN_FSCK" = "yes" -a -n "$RUN_FSCK_DISKS" ]; then progress "Checking disk(s): $RUN_FSCK_DISKS" /sbin/fsck -T -M -p -a $RUN_FSCK_DISKS > /dev/null 2>&1 FSCK_RET="$?" # FSCK_RET is the bit-wise OR of the exit codes for each filesystem that is checked. if [ "$(( $FSCK_RET & 4 ))" = 4 ] ; then # errors left force_fsck elif [ "$(( $FSCK_RET & 2 ))" = 2 ] ; then # reboot needed echo "Filesystem repaired, reboot needed..." do_reboot elif [ "$(( $FSCK_RET & 1 ))" = 1 ] ; then # filesystem errors corrected progress "Filesystem errors corrected , continuing..." elif [ "$(( $FSCK_RET & 0 ))" = 0 ] ; then # no errors found progress "No filesystem errors found, continuing..." fi fi } wakeonlan() { if [ "$STORAGE_NETBOOT" = "yes" ]; then wol_ip=${disk%:*} wol_ip=${wol_ip#*=} elif [ "$FLASH_NETBOOT" = "yes" ]; then wol_ip=${boot%:*} wol_ip=${wol_ip#*=} else return 0 fi if [ -n "$wol_ip" -a -n "$wol_mac" -a -n "$wol_wait" ]; then progress "Sending Magic Packet (WOL) if needed" if ! ping -q -c 2 "$wol_ip" &>/dev/null; then ether-wake "$wol_mac" StartProgress countdown "WOL magic packet sent to $wol_ip, waiting $wol_wait seconds... " $wol_wait "done" fi fi } mount_flash() { progress "Mounting flash" wakeonlan mount_part "$boot" "/flash" "ro,noatime" } mount_storage() { progress "Mounting storage" if [ "$LIVE" = "yes" ]; then # mount tmpfs and exit early. disk=xx is not allowed in live mode mount -t tmpfs none /storage return fi wakeonlan if [ -n "$disk" ]; then if [ -n "$OVERLAY" ]; then OVERLAY_DIR=`cat /sys/class/net/eth0/address | tr -d :` mount_part "$disk" "/storage" "rw,noatime" mkdir -p /storage/$OVERLAY_DIR umount /storage # split $disk into $target,$options so we can append $OVERLAY_DIR options="${disk#*,}" target="${disk%%,*}" if [ "$options" = "$disk" ]; then disk="$target/$OVERLAY_DIR" else disk="$target/$OVERLAY_DIR,$options" fi fi mount_part "$disk" "/storage" "rw,noatime" else # /storage should always be writable mount -t tmpfs none /storage fi } do_cleanup() { StartProgress spinner "Cleaning up... " if [ -d $UPDATE_ROOT/.tmp/mnt ]; then if mountpoint -q $UPDATE_ROOT/.tmp/mnt ; then # busybox umount deletes loop device automatically umount $UPDATE_ROOT/.tmp/mnt fi [ -n $LOOP ] && losetup -d $LOOP &>/dev/null fi [ -f "$UPDATE_TAR" ] && rm -f "$UPDATE_TAR" &>/dev/null [ -f "$UPDATE_IMG_GZ" ] && rm -f "$UPDATE_IMG_GZ" &>/dev/null [ -f "$UPDATE_IMG" ] && rm -f "$UPDATE_IMG" &>/dev/null rm -rf $UPDATE_ROOT/.tmp &>/dev/null rm -rf $UPDATE_ROOT/[0-9a-zA-Z]* &>/dev/null sync StopProgress "done" } check_update() { progress "Checking for updates" UPDATE_TAR=`ls -1 "$UPDATE_DIR"/*.tar 2>/dev/null | head -n 1` UPDATE_IMG_GZ=`ls -1 "$UPDATE_DIR"/*.img.gz 2>/dev/null | head -n 1` UPDATE_IMG=`ls -1 "$UPDATE_DIR"/*.img 2>/dev/null | head -n 1` if ! [ -f "$UPDATE_DIR/$UPDATE_KERNEL" -a -f "$UPDATE_DIR/$UPDATE_SYSTEM" ] && ! [ -f "$UPDATE_TAR" -o -f "$UPDATE_IMG_GZ" -o -f "$UPDATE_IMG" ]; then return 0 fi if [ "$UPDATE_DISABLED" = "yes" ] ; then echo "Updating is not supported on netboot" do_cleanup StartProgress countdown "Normal startup in 10s... " 10 "NOW" return 0 fi # remove temporary folder if exist from previous run rm -fr "$UPDATE_DIR/.tmp" &>/dev/null echo "UPGRADE IN PROGRESS" echo "" echo "Please do not reboot or turn off your @DISTRONAME@ device!" echo "" if [ -f "$UPDATE_TAR" ] ; then echo "Found new .tar archive" StartProgress spinner "Extracting contents of archive... " mkdir -p $UPDATE_DIR/.tmp &>/dev/null tar -xf "$UPDATE_TAR" -C $UPDATE_DIR/.tmp &>/dev/null mv $UPDATE_DIR/.tmp/*/target/* $UPDATE_DIR &>/dev/null sync StopProgress "done" elif [ -f "$UPDATE_IMG_GZ" -o -f "$UPDATE_IMG" ] ; then mkdir -p $UPDATE_DIR/.tmp/mnt &>/dev/null IMG_FILE="$UPDATE_DIR/.tmp/update.img" GZRESULT="0" if [ -f "$UPDATE_IMG_GZ" ]; then echo "Found new compressed image file" StartProgress spinner "Decompressing image file... " gunzip -d -c "$UPDATE_IMG_GZ" 1>$IMG_FILE 2>/tmp/gzresult.txt || GZRESULT="1" sync [ "${GZRESULT}" -eq "0" ] && StopProgress "OK" || StopProgress "FAILED" if [ "${GZRESULT}" -eq "1" ]; then echo "Failed to decompress image file!" echo "gunzip result: '$(cat /tmp/gzresult.txt)'" do_cleanup StartProgress countdown "Normal startup in 30s... " 30 "NOW" return 0 fi else echo "Found new image file" mv "$UPDATE_IMG" $IMG_FILE fi LOOP=$(losetup -f) LOOP_NUM=$(echo $LOOP | sed 's|/dev/loop||') mknod $LOOP b 7 $LOOP_NUM &>/dev/null losetup $LOOP $IMG_FILE # check for MBR partititon OFFSET=$(fdisk -u -l $LOOP 2>/dev/null | awk '/^[ ]*Device/{part=1; next}; part{if ($2 == "*") {print $3} else {print $2} ; exit}') if [ -z "$OFFSET" ]; then # check for GPT partititon OFFSET=$(fdisk -u -l $LOOP 2>/dev/null | awk '/^Number/{part=1; next}; part{print $2; exit}') if [ -z "$OFFSET" ]; then echo "Could not find a valid system partition in image file!" do_cleanup StartProgress countdown "Normal startup in 10s... " 10 "NOW" return 0 fi fi SECTOR_SIZE=$(cat /sys/devices/virtual/block/loop${LOOP_NUM}/queue/hw_sector_size) losetup -d $LOOP sync OFFSET=$(($OFFSET * $SECTOR_SIZE)) # use losetup because busybox mount does not support the -o offset option echo "Mounting system partition..." losetup -o $OFFSET $LOOP $IMG_FILE mount -o ro,loop $LOOP $UPDATE_DIR/.tmp/mnt # don't make temporary files but instead copy # directly from mountpoint to /flash UPDATE_DIR=$UPDATE_ROOT/.tmp/mnt UPDATE_KERNEL=$(basename $IMAGE_KERNEL) fi sync if [ ! -f "$UPDATE_DIR/$UPDATE_KERNEL" -o ! -f "$UPDATE_DIR/$UPDATE_SYSTEM" ] ; then echo "Missing ${UPDATE_KERNEL} or ${UPDATE_SYSTEM}!" do_cleanup StartProgress countdown "Normal startup in 10s... " 10 "NOW" return 0 fi # check md5 sums if .nocheck doesn't exist if [ ! -f "$UPDATE_DIR/.nocheck" ]; then if [ -f "$UPDATE_DIR/${UPDATE_KERNEL}.md5" -a -f "$UPDATE_DIR/${UPDATE_SYSTEM}.md5" ] ; then # *.md5 size-check if [ ! -s "$UPDATE_DIR/${UPDATE_KERNEL}.md5" -o ! -s "$UPDATE_DIR/${UPDATE_SYSTEM}.md5" ] ; then echo "Zero-sized .md5 file!" MD5_FAILED="1" else sed "s#target/KERNEL#$UPDATE_DIR/$UPDATE_KERNEL#g" "$UPDATE_DIR/${UPDATE_KERNEL}.md5" >"$UPDATE_ROOT/${UPDATE_KERNEL}.check.md5" sed "s#target#$UPDATE_DIR#g" "$UPDATE_DIR/${UPDATE_SYSTEM}.md5" >"$UPDATE_ROOT/${UPDATE_SYSTEM}.check.md5" StartProgress spinner "Checking ${UPDATE_KERNEL}.md5... " if md5sum -sc "$UPDATE_ROOT/${UPDATE_KERNEL}.check.md5"; then StopProgress "OK" else StopProgress "FAILED" MD5_FAILED="1" fi StartProgress spinner "Checking ${UPDATE_SYSTEM}.md5... " if md5sum -sc "$UPDATE_ROOT/${UPDATE_SYSTEM}.check.md5"; then StopProgress "OK" else StopProgress "FAILED" MD5_FAILED="1" fi fi else echo "Missing ${UPDATE_KERNEL}.md5 or ${UPDATE_SYSTEM}.md5!" MD5_FAILED="1" fi if [ "$MD5_FAILED" -eq "1" ]; then echo "md5 check failed!" do_cleanup StartProgress countdown "Normal startup in 30s... " 30 "NOW" return 0 fi fi # get sizes FLASH_FREE=$(df /flash/ | awk '/[0-9]%/{print $4}') FLASH_FREE=$(( $FLASH_FREE * 1024 )) # Disregard kernel size if it's a a block device, which is the case on Amlogic/WeTek devices if [ ! -b $IMAGE_KERNEL ]; then OLD_KERNEL=$(stat -t "/flash/$IMAGE_KERNEL" | awk '{print $2}') else OLD_KERNEL="0" fi OLD_SYSTEM=$(stat -t "/flash/$IMAGE_SYSTEM" | awk '{print $2}') NEW_KERNEL=$(stat -t "$UPDATE_DIR/$UPDATE_KERNEL" | awk '{print $2}') NEW_SYSTEM=$(stat -t "$UPDATE_DIR/$UPDATE_SYSTEM" | awk '{print $2}') # old KERNEL+SYSTEM+free space - new KERNEL+SYSTEM must be higher then 5MB # at least 5MB free after update TMP_SIZE=$(($OLD_KERNEL+$OLD_SYSTEM+$FLASH_FREE-$NEW_KERNEL-$NEW_SYSTEM)) FLASH_FREE_MIN=$(($FLASH_FREE_MIN*1024*1024)) if [ $TMP_SIZE -ge $FLASH_FREE_MIN ]; then echo "Checking size: OK" else echo "Checking size: FAILED" echo "" echo "Your System (FAT) partition is too small for this update," echo "and there is not enough space for the update to be installed!" echo "" echo "You must re-install your system using the disk image of a" echo "current release, or you must re-size your existing partitions" echo "so that the System (FAT) partition is at least 512MB in size." echo "" do_cleanup StartProgress countdown "Normal startup in 60s... " 60 "NOW" return 0 fi # all ok, update if [ -b $IMAGE_KERNEL ]; then update_partition "Kernel" "$UPDATE_KERNEL" "$IMAGE_KERNEL" else update_file "Kernel" "$UPDATE_KERNEL" "/flash/$IMAGE_KERNEL" fi update_file "System" "$UPDATE_SYSTEM" "/flash/$IMAGE_SYSTEM" update_bootloader do_cleanup do_reboot } prepare_sysroot() { progress "Preparing system" if [ "$SYSTEM_TORAM" = "no" -o "$INSTALLED_MEMORY" -lt "$SYSTEM_TORAM_LIMIT" ]; then mount_part "/flash/$IMAGE_SYSTEM" "/sysroot" "ro,loop" else cp /flash/$IMAGE_SYSTEM /dev/$IMAGE_SYSTEM mount_part "/dev/$IMAGE_SYSTEM" "/sysroot" "ro,loop" fi mount --move /flash /sysroot/flash mount --move /storage /sysroot/storage if [ ! -d "/sysroot/lib/modules/$(uname -r)/" -a -f "/sysroot/usr/lib/systemd/systemd" ]; then echo "" echo "NEVER TOUCH boot= in extlinux.conf / cmdline.txt!" echo "If you don't know what you are doing," echo "your installation is now broken." echo "" StartProgress countdown "Normal startup in 60s... " 60 "NOW" fi [ -f "/sysroot/usr/lib/systemd/systemd" ] || error "final_check" "Could not find systemd!" } if [ "${boot%%=*}" = "FILE" ]; then error "check arguments" "boot argument can't be FILE type..." fi # main boot sequence for BOOT_STEP in \ load_modules \ check_disks \ mount_flash \ load_splash \ mount_storage \ check_update \ prepare_sysroot; do $BOOT_STEP [ -n "$DEBUG" ] && break_after $BOOT_STEP done BOOT_STEP=final # log if booting from usb / removable storage STORAGE=$(cat /proc/mounts | grep " /sysroot/storage " | awk '{print $1}' | awk -F '/' '{print $3}') FLASH=$(cat /proc/mounts | grep " /sysroot/flash " | awk '{print $1}' | awk -F '/' '{print $3}') for i in $STORAGE $FLASH ; do if [ -n "$i" ] ; then removable="/sys/class/block/*/$i/../removable" if [ -e $removable ] ; then if [ "$(cat $removable 2>/dev/null)" = "1" ] ; then echo "### BIG FAT WARNING" > /dev/kmsg echo "### $i is removable. suspend/resume may not work" > /dev/kmsg fi fi fi done # move some special filesystems /bin/busybox mount --move /dev /sysroot/dev /bin/busybox mount --move /proc /sysroot/proc /bin/busybox mount --move /sys /sysroot/sys /bin/busybox rm -fr /tmp # tell OE settings addon to disable updates if [ "$UPDATE_DISABLED" = "yes" ] ; then echo "" > /sysroot/dev/.update_disabled fi # swap can not be used over nfs.(see scripts/mount-swap) if [ "$STORAGE_NETBOOT" = "yes" ] ; then echo "" > /sysroot/dev/.storage_netboot fi if [ -f /sysroot/storage/.please_resize_me ] ; then INIT_UNIT="--unit=fs-resize.target" fi BACKUP_FILE=`ls -1 /sysroot/storage/.restore/??????????????.tar 2>/dev/null | head -n 1` if [ -f "$BACKUP_FILE" ] ; then INIT_UNIT="--unit=backup-restore.target" fi if [ -f /sysroot/storage/.cache/reset_oe -o -f /sysroot/storage/.cache/reset_xbmc ] ; then INIT_UNIT="--unit=factory-reset.target" fi # switch to new sysroot and start real init exec /bin/busybox switch_root /sysroot /usr/lib/systemd/systemd $INIT_ARGS $INIT_UNIT error "switch_root" "Error in initramfs. Could not switch to new root"