diff --git a/packages/sysutils/busybox/config/busybox-init.conf b/packages/sysutils/busybox/config/busybox-init.conf index 038f8b58e0..ae44b49bba 100644 --- a/packages/sysutils/busybox/config/busybox-init.conf +++ b/packages/sysutils/busybox/config/busybox-init.conf @@ -139,7 +139,7 @@ CONFIG_FEATURE_SEAMLESS_GZ=y # CONFIG_FEATURE_AR_LONG_FILENAMES is not set # CONFIG_FEATURE_AR_CREATE is not set # CONFIG_UNCOMPRESS is not set -# CONFIG_GUNZIP is not set +CONFIG_GUNZIP=y # CONFIG_BUNZIP2 is not set # CONFIG_UNLZMA is not set # CONFIG_FEATURE_LZMA_FAST is not set @@ -153,10 +153,10 @@ CONFIG_FEATURE_SEAMLESS_GZ=y # CONFIG_DPKG is not set # CONFIG_DPKG_DEB is not set # CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set -# CONFIG_GZIP is not set +CONFIG_GZIP=y # CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set CONFIG_GZIP_FAST=0 -# CONFIG_FEATURE_GZIP_LEVELS is not set +CONFIG_FEATURE_GZIP_LEVELS=y # CONFIG_LZOP is not set # CONFIG_LZOP_COMPR_HIGH is not set # CONFIG_RPM2CPIO is not set @@ -257,7 +257,7 @@ CONFIG_MD5SUM=y CONFIG_MKDIR=y # CONFIG_FEATURE_MKDIR_LONG_OPTIONS is not set # CONFIG_MKFIFO is not set -# CONFIG_MKNOD is not set +CONFIG_MKNOD=y CONFIG_MV=y # CONFIG_FEATURE_MV_LONG_OPTIONS is not set CONFIG_NICE=y @@ -577,14 +577,14 @@ CONFIG_FEATURE_FBSET_FANCY=y CONFIG_FEATURE_FBSET_READMODE=y # CONFIG_FDFLUSH is not set # CONFIG_FDFORMAT is not set -# CONFIG_FDISK is not set +CONFIG_FDISK=y # CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set -# CONFIG_FEATURE_FDISK_WRITABLE is not set +CONFIG_FEATURE_FDISK_WRITABLE=y # CONFIG_FEATURE_AIX_LABEL is not set # CONFIG_FEATURE_SGI_LABEL is not set # CONFIG_FEATURE_SUN_LABEL is not set # CONFIG_FEATURE_OSF_LABEL is not set -# CONFIG_FEATURE_GPT_LABEL is not set +CONFIG_FEATURE_GPT_LABEL=y # CONFIG_FEATURE_FDISK_ADVANCED is not set # CONFIG_FINDFS is not set # CONFIG_FLOCK is not set @@ -605,7 +605,7 @@ CONFIG_FEATURE_FBSET_READMODE=y # CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set # CONFIG_IPCRM is not set # CONFIG_IPCS is not set -# CONFIG_LOSETUP is not set +CONFIG_LOSETUP=y # CONFIG_LSPCI is not set # CONFIG_LSUSB is not set # CONFIG_MKSWAP is not set diff --git a/packages/sysutils/busybox/scripts/init b/packages/sysutils/busybox/scripts/init index 0f8bfc5651..9a81a70b6f 100755 --- a/packages/sysutils/busybox/scripts/init +++ b/packages/sysutils/busybox/scripts/init @@ -36,7 +36,9 @@ # set needed variables MODULE_DIR=/lib/modules - UPDATE_DIR=/storage/.update + UPDATE_ROOT=/storage/.update + UPDATE_DIR="$UPDATE_ROOT" + UPDATE_KERNEL="KERNEL" UPDATE_SYSTEM="SYSTEM" IMAGE_KERNEL="KERNEL" @@ -44,8 +46,6 @@ BOOT_STEP="start" MD5_FAILED="0" - MD5_NOCHECK="0" - SIZE_FAILED="0" RUN_FSCK="yes" RUN_FSCK_DISKS="" @@ -336,7 +336,7 @@ if [ -f "$UPDATE_DIR/$2" -a -f "$3" ]; then echo "updating $1..." mount -o remount,rw /flash - mv $UPDATE_DIR/$2 $3 2>/dev/null + cp $UPDATE_DIR/$2 $3 2>/dev/null # loopback file needs writable /flash all the time if [ "${disk%%=*}" != "FILE" ]; then mount -o remount,ro /flash @@ -549,115 +549,178 @@ fi } - check_update() { - progress "Checking for updates" - - UPDATE_TAR=`ls -1 "$UPDATE_DIR"/*.tar 2>/dev/null | head -n 1` - if [ -f "$UPDATE_DIR/$UPDATE_KERNEL" -a -f "$UPDATE_DIR/$UPDATE_SYSTEM" -o -f "$UPDATE_TAR" ] ; then - if [ "$UPDATE_DISABLED" = "yes" ] ; then - rm -rf $UPDATE_DIR/[0-9a-zA-Z]* &>/dev/null - echo "Updating not supported on netboot. normal startup in 10s..." - sync - usleep 10000000 - return 0 + do_cleanup() { + 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 - # check for .tar - if [ -f "$UPDATE_TAR" ] ; then - echo "Found new .tar archive. extracting..." - 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 - rm -f "$UPDATE_TAR" &>/dev/null - rm -rf $UPDATE_DIR/.tmp &>/dev/null - sync - if [ ! -f "$UPDATE_DIR/$UPDATE_KERNEL" -o ! -f "$UPDATE_DIR/$UPDATE_SYSTEM" ] ; then - echo "missing ${UPDATE_KERNEL} or ${UPDATE_SYSTEM}... normal startup in 10s" - sync - usleep 10000000 + [ -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 + } + + 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 not supported on netboot. normal startup in 10s..." + do_cleanup + sync + usleep 10000000 + return 0 + fi + + # remove temporary folder if exist from previous run + rm -fr "$UPDATE_DIR/.tmp" &>/dev/null + + if [ -f "$UPDATE_TAR" ] ; then + echo "Found new .tar archive. extracting..." + 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 + 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" + + if [ -f "$UPDATE_IMG_GZ" ]; then + echo "Found new .img.gz archive. extracting..." + gunzip -d -c "$UPDATE_IMG_GZ" > $IMG_FILE + else + echo "Found new .img file..." + mv "$UPDATE_IMG" $IMG_FILE + fi + + LOOP=$(losetup -f) + LOOP_NUM=$(echo $LOOP | sed 's|/dev/loop||') + mknod $LOOP b 7 $LOOP_NUM + losetup $LOOP $IMG_FILE + + # check for MBR partititon + OFFSET=$(fdisk -u -l $LOOP | 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 | awk '/^Number/{part=1; next}; part{print $2; exit}') + if [ -z "$OFFSET" ]; then + do_cleanup + error "img update" "Can't get system partition from image file" return 0 fi fi - if [ -f "$UPDATE_DIR/.nocheck" ] ; then - MD5_NOCHECK="1" - fi + SECTOR_SIZE=$(cat /sys/devices/virtual/block/loop${LOOP_NUM}/queue/hw_sector_size) + losetup -d $LOOP + sync - # check md5 sums if .nocheck doesn't exist - if [ "$MD5_NOCHECK" -eq "0" ] ; 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 -i 's#target#/storage/.update#g' "$UPDATE_DIR/${UPDATE_KERNEL}.md5" - sed -i 's#target#/storage/.update#g' "$UPDATE_DIR/${UPDATE_SYSTEM}.md5" + OFFSET=$(($OFFSET * $SECTOR_SIZE)) - echo "Checking ${UPDATE_KERNEL}.md5..." - md5sum -c "$UPDATE_DIR/${UPDATE_KERNEL}.md5" || MD5_FAILED="1" + # 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 - echo "Checking ${UPDATE_SYSTEM}.md5..." - md5sum -c "$UPDATE_DIR/${UPDATE_SYSTEM}.md5" || MD5_FAILED="1" - fi - else - echo "missing ${UPDATE_KERNEL}.md5 or ${UPDATE_SYSTEM}.md5..." + # 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}... normal startup in 10s" + do_cleanup + sync + usleep 10000000 + 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" - fi - fi - - # get sizes - FLASH_FREE=$(df /flash/ | awk '/[0-9]%/{print $4}') - FLASH_FREE=$(( $FLASH_FREE * 1024 )) - - OLD_KERNEL="0" - if [ ! -b $IMAGE_KERNEL ]; then - OLD_KERNEL=$(stat -t "/flash/$IMAGE_KERNEL" | awk '{print $2}') - 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" - SIZE_FAILED="1" - fi - - # update if size check is ok - if [ "$SIZE_FAILED" -eq "0" ] ; then - # update if md5 check is ok or .nocheck exists - if [ "$MD5_FAILED" -eq "0" -o "$MD5_NOCHECK" -eq "1" ] ; then - 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 - rm -rf $UPDATE_DIR/[0-9a-zA-Z]* &>/dev/null - do_reboot else - rm -rf $UPDATE_DIR/[0-9a-zA-Z]* &>/dev/null - echo "md5 check failed. normal startup in 30s..." - sync - usleep 30000000 + 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" + + echo "Checking ${UPDATE_KERNEL}.md5..." + md5sum -c "$UPDATE_ROOT/${UPDATE_KERNEL}.check.md5" || MD5_FAILED="1" + + echo "Checking ${UPDATE_SYSTEM}.md5..." + md5sum -c "$UPDATE_ROOT/${UPDATE_SYSTEM}.check.md5" || MD5_FAILED="1" fi else - rm -rf $UPDATE_DIR/[0-9a-zA-Z]* &>/dev/null - echo "size check failed. normal startup in 30s..." + echo "missing ${UPDATE_KERNEL}.md5 or ${UPDATE_SYSTEM}.md5..." + MD5_FAILED="1" + fi + + if [ "$MD5_FAILED" -eq "1" ]; then + echo "md5 check failed. normal startup in 30s..." + do_cleanup sync usleep 30000000 + return 0 fi fi + + # get sizes + FLASH_FREE=$(df /flash/ | awk '/[0-9]%/{print $4}') + FLASH_FREE=$(( $FLASH_FREE * 1024 )) + + OLD_KERNEL="0" + if [ ! -b $IMAGE_KERNEL ]; then + OLD_KERNEL=$(stat -t "/flash/$IMAGE_KERNEL" | awk '{print $2}') + 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" + do_cleanup + echo "size check failed. normal startup in 30s..." + sync + usleep 30000000 + 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() { diff --git a/scripts/mkimage b/scripts/mkimage index 2d7f310562..901da33790 100755 --- a/scripts/mkimage +++ b/scripts/mkimage @@ -145,6 +145,9 @@ EOF echo "image: copying files to part1..." mcopy $TARGET_IMG/$IMAGE_NAME.kernel "::/$KERNEL_NAME" mcopy $TARGET_IMG/$IMAGE_NAME.system ::/SYSTEM + mcopy $RELEASE_DIR/target/KERNEL.md5 "::/$KERNEL_NAME.md5" + mcopy $RELEASE_DIR/target/SYSTEM.md5 ::/SYSTEM.md5 + mmd EFI EFI/BOOT mcopy $ROOT/$TOOLCHAIN/share/syslinux/bootx64.efi ::/EFI/BOOT mcopy $ROOT/$TOOLCHAIN/share/syslinux/ldlinux.e64 ::/EFI/BOOT @@ -162,6 +165,9 @@ EOF echo "image: copying files to part1..." mcopy $TARGET_IMG/$IMAGE_NAME.kernel "::/$KERNEL_NAME" mcopy $TARGET_IMG/$IMAGE_NAME.system ::/SYSTEM + mcopy $RELEASE_DIR/target/KERNEL.md5 "::/$KERNEL_NAME.md5" + mcopy $RELEASE_DIR/target/SYSTEM.md5 ::/SYSTEM.md5 + mcopy $RELEASE_DIR/3rdparty/bootloader/bootcode.bin :: mcopy $RELEASE_DIR/3rdparty/bootloader/fixup.dat :: mcopy $RELEASE_DIR/3rdparty/bootloader/start.elf :: @@ -207,6 +213,8 @@ elif [ "$BOOTLOADER" = "u-boot" ]; then echo "image: copying files to part1..." mcopy $TARGET_IMG/$IMAGE_NAME.kernel "::/$KERNEL_NAME" mcopy $TARGET_IMG/$IMAGE_NAME.system ::/SYSTEM + mcopy $RELEASE_DIR/target/KERNEL.md5 "::/$KERNEL_NAME.md5" + mcopy $RELEASE_DIR/target/SYSTEM.md5 ::/SYSTEM.md5 if [ -n "$UBOOT_SYSTEM" -a -f "$RELEASE_DIR/3rdparty/bootloader/u-boot-$UBOOT_SYSTEM.img" ]; then mcopy "$RELEASE_DIR/3rdparty/bootloader/u-boot-$UBOOT_SYSTEM.img" ::/u-boot.img