#!/bin/sh ################################## functions ################################## #mkfs_jffs2() mkfs_jffs2() { ! [ -x /usr/sbin/mkfs.jffs2 ] \ && ! [ -x /sbin/mkfs.jffs2 ] \ && echo "Not Found /usr/sbin/mkfs.jffs2 or /sbin/mkfs.jffs2" \ && return 1 # format to jffs2 local erase_block=$(/bin/cat /proc/mtd \ | /bin/grep "$(basename $1)" \ | /usr/bin/awk '{print $3}') /bin/mkdir -p /tmp/jffs2.dir/tmp mkfs.jffs2 -p -e 0x${erase_block} -d /tmp/jffs2.dir \ -o /tmp/jffs2.img >/dev/null || return 1 /bin/dd if=/tmp/jffs2.img of=$1 || return 1 /bin/rm -rf /tmp/jffs2.img /tmp/jffs2.dir return 0 } mount_etc() { local etc_update=0 # if enable ota, do update [ -f /etc/init.d/rc.ota-upgrade ] \ && source /etc/init.d/ota-upgrade # fix fs local root_dev="$(readlink /dev/by-name/rootfs)" /bin/echo ${root_dev} | /bin/grep -q "mtdblock" \ || /usr/sbin/fsck.ext4 -y /dev/by-name/rootfs_data &>/dev/null # if mount failed, format. case "${root_dev}" in /dev/mtdblock*) /bin/mount -t jffs2 /dev/by-name/rootfs_data /etc \ && [ -e /etc/etc_complete -a ! -e /etc/etc_need_update ] \ && return # /etc/etc_complete and /etc/etc_need_update both exist, that means we just need to update [ -e /etc/etc_complete -a -e /etc/etc_need_update ] && /bin/echo "do etc update" && etc_update=1 /bin/umount /etc [ x$etc_update = x"1" ] || { # not update, format first /bin/echo "Mount Failed: formating /dev/by-name/rootfs_data to jffs2 ..." mkfs_jffs2 "/dev/by-name/rootfs_data" || return 1 } mount -t jffs2 /dev/by-name/rootfs_data /mnt ;; *) /bin/mount -t ext4 /dev/by-name/rootfs_data /etc \ && [ -e /etc/etc_complete -a ! -e /etc/etc_need_update ] \ && return # /etc/etc_complete and /etc/etc_need_update both exist, that means we just need to update [ -e /etc/etc_complete -a -e /etc/etc_need_update ] && /bin/echo "do etc update" && etc_update=1 /bin/umount /etc [ x$etc_update = x"1" ] || { # not update, format first /bin/echo "Mount Failed: formating /dev/by-name/rootfs_data to ext4 ..." mkfs.ext4 -m 0 /dev/by-name/rootfs_data >/dev/null || return 1 } /bin/mount -t ext4 /dev/by-name/rootfs_data /mnt ;; esac mkdir -p /tmp/etc /bin/cp -af /etc/* /tmp/etc/ # keep the wifi config [ -e /mnt/wifi/wpa_supplicant.conf ] && { /bin/echo "keep the wifi config" /bin/cp /mnt/wifi/wpa_supplicant.conf /tmp/etc/wifi/ } /bin/cp -af /tmp/etc/* /mnt/ rm -rf /tmp/etc sync [ ! -e /mnt/etc_complete ] && touch /mnt/etc_complete [ -e /mnt/etc_need_update ] && /bin/echo "etc update done" && rm -f /mnt/etc_need_update sync /bin/mount -o move /mnt /etc } mount_usr(){ [ -L /dev/by-name/extend ] || return /bin/mkdir -p /tmp/usr /bin/mount /dev/by-name/extend /tmp/usr >/dev/null || { rm -rf /tmp/usr return } ! [ -d /tmp/usr/bin ] \ && umount /tmp/usr \ && rm -rf /tmp/usr \ && return /bin/mount -o move /tmp/usr /usr \ && rm -rf /tmp/usr } mount_sec_storage(){ [ -e /dev/by-name/sec_storage ] || return local root_dev="$(readlink /dev/by-name/rootfs)" # fix sec_storage if [ -h /dev/by-name/sec_storage ]; then echo ${root_dev} | grep -q "mtdblock" \ || /usr/sbin/fsck.ext4 -y /dev/by-name/sec_storage &>/dev/null fi # mount sec_storage if [ -h /dev/by-name/sec_storage -a -d /data/tee ]; then case "${root_dev}" in /dev/mtdblock*) /bin/busybox mount -t jffs2 /dev/by-name/sec_storage /data/tee 2>/dev/null if [ "$?" -ne "0" ]; then mkfs_jffs2 "/dev/by-name/sec_storage" /bin/busybox mount -t jffs2 /dev/by-name/sec_storage /data/tee 2>/dev/null fi ;; *) /bin/busybox mount -t ext4 /dev/by-name/sec_storage /data/tee 2>/dev/null if [ "$?" -ne "0" ]; then mkfs.ext4 /dev/by-name/sec_storage >/dev/null /bin/busybox mount -t ext4 /dev/by-name/sec_storage /data/tee 2>/dev/null fi ;; esac fi } mount_single_app(){ /usr/sbin/fsck.ext4 -y /dev/by-name/app &>/dev/null /bin/mount /dev/by-name/app /mnt/app } mount_dual_app(){ mkdir -p /var/lock local appAB=$(fw_printenv -n appAB) local first_app=app local second_app=app_sub local applimit=$(fw_printenv -n applimit) [ x"$applimit" != x"" -a "$applimit" -ne 0 ] && { local appcount=$(fw_printenv -n appcount) let appcount+=1 [ "$appcount" -gt "$applimit" ] && { echo "Warning: applimit ($applimit) exceeded. Switch app partition." if [ x"$appAB" = x"A" ]; then appAB=B elif [ x"$appAB" = x"B" ]; then appAB=A else echo "check appAB error: appAB=$appAB" appAB=A fi fw_setenv appAB $appAB echo "Switch appAB to $appAB" appcount=1 } fw_setenv appcount $appcount } echo "appAB=$appAB" if [ x"$appAB" = x"A" ]; then first_app=app second_app=app_sub elif [ x"$appAB" = x"B" ]; then first_app=app_sub second_app=app else echo "check appAB error: appAB=$appAB" fi /usr/sbin/fsck.ext4 -y /dev/by-name/$first_app &> /dev/null /bin/mount -t ext4 /dev/by-name/$first_app /mnt/app \ && echo "mount $first_app success" \ && return echo "mount $first_app fail, now try mount $second_app" #mount first_app fail, try second_app /usr/sbin/fsck.ext4 -y /dev/by-name/$second_app &> /dev/null /bin/mount -t ext4 /dev/by-name/$second_app /mnt/app \ && echo "mount $second_app success" \ && return echo "mount app fail" } mount_app() { [ -L /dev/by-name/app ] || return if [ -L /dev/by-name/app_sub ]; then mount_dual_app else mount_single_app fi } set_parts_by_name() { # create by-name local parts part /bin/mkdir -p /dev/by-name parts=$partitions for part in $(/bin/echo ${parts} | /bin/sed 's/:/ /g') do [ ! -e /dev/${part#*@} ] && mdev -s #for initramfs /bin/ln -fs "/dev/${part#*@}" "/dev/by-name/${part%@*}" done } etc_part=/dev/nande #hardcode rootfs_data partition as nande mount_etc_hardcode() { # fix fs /usr/sbin/fsck.ext4 -y $etc_part &>/dev/null /bin/mount -t ext4 $etc_part /etc \ && [ -e /etc/etc_complete ] \ && return /bin/echo "mount Failed or etc_complete not exist" /bin/echo "now format $etc_part to ext4 ..." /bin/umount /etc mkfs.ext4 -m 0 $etc_part >/dev/null || return 1 /bin/mount -t ext4 $etc_part /mnt /bin/cp -af /etc/* /mnt/ sync /bin/mount -o move /mnt /etc #prepare by-name in /etc for next boot set_parts_by_name cp -fpr /dev/by-name /etc sync #now rootfs_data is ready, next boot can mount it as etc touch /etc/etc_complete sync # this sync not necessary, but sync after modify something is good } set_parts_by_name_hardcode() { #UDISK is the last partition, when UDISK is there, the /etc/by-name is ready [ -e /etc/by-name/UDISK ] && { #set_part_by_name may cost more than 100ms, now just copy it from /etc cp -fpr /etc/by-name /dev/ return } #should not go here. now just show warning and do set_parts_by_name echo "warning: no /etc/by-name/UDISK, please check it" set_parts_by_name } #---------------------------------------------------------------- /bin/mount -t proc /proc /proc /bin/mount -t tmpfs tmpfs /tmp /bin/mount -t sysfs sys /sys #common but slow set_parts_by_name mount_sec_storage mount_usr mount_etc mount_app #hardcode but fast #mount_etc_hardcode #set_parts_by_name_hardcode #mount_usr exec /sbin/init