#!/bin/sh MOUNT_ETC=0 MOUNT_OVERLAY=1 ################################## 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 } mkfs_ubifs() { mkfs.ubifs -x lzo -y "$1" } mount_etc() { local etc_update=0 # if enable ota, do update [ -f /etc/init.d/rc.ota-upgrade ] \ && source /etc/init.d/ota-upgrade local root_dev="$(readlink /dev/by-name/rootfs)" # 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 ;; /dev/ubi*) /bin/mount -t ubifs /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 ubifs ..." mkfs_ubifs "/dev/by-name/rootfs_data" || return 1 } /bin/mount -t ubifs /dev/by-name/rootfs_data /mnt ;; *) /usr/sbin/fsck.ext4 -y /dev/by-name/rootfs_data &>/dev/null /bin/mount -t ext4 -o sync,data=journal /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 -o sync,data=journal /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(){ local extend_name=$(fw_printenv -n extend_partition) if [ $extend_name == extendB ]; then extend_name="extend_backup" else extend_name="extend" fi local extend_partition="/dev/by-name/${extend_name}" [ -L ${extend_partition} ] || if [ ${extend_partition} == "/dev/by-name/extend" ]; then [ -L /dev/by-name/extend_backup ] || return else [ -L /dev/by-name/extend ] || return fi /bin/mkdir -p /tmp/usr /bin/mount ${extend_partition} /tmp/usr >/dev/null || { if [ ${extend_partition} == "/dev/by-name/extend" ]; then echo "****** 111 mount /dev/by-name/extend_backup /usr *******" /bin/mount /dev/by-name/extend_backup /tmp/usr > /dev/null return else echo "********** 222 mount /dev/by-name/extend /usr ********" /bin/mount /dev/by-name/extend /tmp/usr > /dev/null fi } echo "*******333 mount ${extend_partition} /usr ******" ! [ -d /tmp/usr/bin ] \ && umount /tmp/usr \ && rm -rf /tmp/usr \ && return /bin/mount -o move /tmp/usr /usr \ && rm -rf /tmp/usr } rc_mount_filesystem() { local fs_src="$1" local fs_mntpt="$2" # mount filesystem if [ -e "$fs_src" -a -d "$fs_mntpt" ]; then [ -L "$fs_src" ] && fs_src=$(readlink "$fs_src") case "$fs_src" in /dev/mtdblock*) mount -t jffs2 "$fs_src" "$fs_mntpt" 2>/dev/null if [ "$?" -ne "0" ]; then mkfs_jffs2 "$fs_src" mount -t jffs2 "$fs_src" "$fs_mntpt" 2>/dev/null fi ;; /dev/ubi*) mount -t ubifs "$fs_src" "$fs_mntpt" 2>/dev/null if [ "$?" -ne "0" ]; then mkfs_ubifs "$fs_src" mount -t ubifs "$fs_src" "$fs_mntpt" 2>/dev/null fi ;; *) /usr/sbin/fsck.ext4 -y "$fs_src" &>/dev/null mount -t ext4 "$fs_src" "$fs_mntpt" 2>/dev/null if [ "$?" -ne "0" ]; then # linux < 3.18 not support metadata_csum, e2fsprogs version:1.46.4 grep "Linux version 3.*" /proc/version >> /dev/null if [ $? -eq 0 ]; then echo "linux < 3.18, mkfs.ext4 do not use metadata and journal checksum features." mkfs.ext4 -m 0 -O ^metadata_csum "$fs_src" >/dev/null else mkfs.ext4 -m 0 "$fs_src" >/dev/null fi mount -t ext4 "$fs_src" "$fs_mntpt" 2>/dev/null fi ;; esac # restore /mnt file contexts if [ -f /sbin/restorecon ]; then /sbin/restorecon -R /mnt fi fi } rc_mount() { rc_mount_filesystem "/dev/by-name/UDISK" "/mnt/UDISK" # rc_mount_filesystem "/dev/by-name/user-res" "/mnt/user" # enable hotplug [ -x /sbin/mdev ] && { [ -f /proc/sys/kernel/hotplug ] && echo /sbin/mdev > /proc/sys/kernel/hotplug /sbin/mdev -s } } mount_sec_storage(){ [ -e /dev/by-name/sec_storage ] || return local root_dev="$(readlink /dev/by-name/rootfs)" # 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 ;; /dev/ubi*) /bin/busybox mount -t ubifs /dev/by-name/sec_storage /data/tee 2>/dev/null if [ "$?" -ne "0" ]; then mkfs_ubifs "/dev/by-name/sec_storage" /bin/busybox mount -t ubifs /dev/by-name/sec_storage /data/tee 2>/dev/null fi ;; *) /usr/sbin/fsck.ext4 -y /dev/by-name/sec_storage &>/dev/null /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(){ 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 } mount_overlay() { local root_dev="$(readlink /dev/by-name/rootfs)" local mount_partition_dir case "$1" in UDISK) mount_partition_dir="/mnt/UDISK" ;; rootfs_data) mount_partition_dir="/overlay" ;; *) echo "error: please choose rootfs_data or UDISK" return 1 esac case "${root_dev}" in /dev/mtdblock*) /bin/mount -t jffs2 /dev/by-name/$1 ${mount_partition_dir} || { /bin/echo "Mount Failed: formating /dev/by-name/$1 to jffs2 ..." mkfs_jffs2 "/dev/by-name/$1" || return 1 mount -t jffs2 /dev/by-name/$1 ${mount_partition_dir} } ;; /dev/ubi*) /bin/mount -t ubifs /dev/by-name/$1 ${mount_partition_dir} || { /bin/echo "Mount Failed: formating /dev/by-name/$1 to ubifs ..." mkfs_ubifs "/dev/by-name/$1" || return 1 /bin/mount -t ubifs /dev/by-name/$1 ${mount_partition_dir} } ;; *) /usr/sbin/fsck.ext4 -y /dev/by-name/$1 &>/dev/null /bin/mount -t ext4 -o sync,data=journal /dev/by-name/$1 ${mount_partition_dir} || { /bin/echo "Mount Failed: formating /dev/by-name/$1 to ext4 ..." mkfs.ext4 -m 0 /dev/by-name/$1 >/dev/null || return 1 /bin/mount -t ext4 -o sync,data=journal /dev/by-name/$1 ${mount_partition_dir} } ;; esac fgrep -sq overlay /proc/filesystems || { /bin/echo "skip mount overlayfs as kernel not support" return } # only for recovery,copy boot_partition(boot) wifi information to boot_partition(recovery) local system=$(fw_printenv -n boot_partition) if [ x"$system" = x"recovery" ]; then [ -e /overlay/upper/etc/wifi/wpa_supplicant ] && { cp -fpr /overlay/upper/etc/wifi/* /etc/wifi/ } fi #When /dev/root is readonly, such as squashfs or ext4 ro, we try to mount overlayfs.Otherwise, don't mount overlayfs fgrep -sq '/dev/root / squashfs ro' /proc/mounts || fgrep -sq '/dev/root / ext4 ro' /proc/mounts || { /bin/echo "skip mount overlayfs as now rootfs not squashfs or readonly ext4" return } # First, try to mount without a workdir, for overlayfs v22 and before. # If it fails, it means that we are probably using a v23 and # later versions that require a workdir # mount -n -t overlay overlayfs:/overlay -o rw,noatime,lowerdir=/,upperdir=/overlay /mnt || { # mkdir -p /overlay/upper /overlay/workdir # mount -n -t overlay overlayfs:/overlay -o rw,noatime,lowerdir=/,upperdir=/overlay/upper,workdir=/overlay/workdir /mnt # } local overlay_need_workdir=1 # overlayfs in linux-3.4 and linux-3.10 is v22 and before, should mount without a workdir fgrep -sq 'Linux version 3' /proc/version && overlay_need_workdir=0 local mount_overlay_dir="/overlay" [ x"${mount_partition_dir}" = x"/mnt/UDISK" ] && { mkdir -p /mnt/UDISK/overlay mount_overlay_dir="/mnt/UDISK/overlay" } if [ x"$overlay_need_workdir" = x"0" ]; then mount -n -t overlayfs overlayfs:${mount_overlay_dir} -o rw,noatime,lowerdir=/,upperdir=${mount_overlay_dir} /mnt else mkdir -p ${mount_overlay_dir}/upper ${mount_overlay_dir}/workdir mount -n -t overlay overlayfs:${mount_overlay_dir} -o rw,noatime,lowerdir=/,upperdir=${mount_overlay_dir}/upper,workdir=${mount_overlay_dir}/workdir /mnt fi mount -n /proc -o noatime,move /mnt/proc pivot_root /mnt /mnt/rom mount -n /rom/dev -o noatime,move /dev mount -n /rom/tmp -o noatime,move /tmp mount -n /rom/sys -o noatime,move /sys mount -n /rom$mount_partition_dir -o noatime,move $mount_partition_dir fgrep -sq '/rom/usr' /proc/mounts && { mount -n /rom/usr -o noatime,move /usr if [ x"$overlay_need_workdir" = x"0" ]; then mkdir -p $mount_overlay_dir/usr mount -n -t overlayfs overlayfs:${mount_overlay_dir} -o rw,noatime,lowerdir=/usr,upperdir=${mount_overlay_dir}/usr /usr else mkdir -p ${mount_overlay_dir}/upper/usr ${mount_overlay_dir}/workdir/usr mount -n -t overlay overlayfs:${mount_overlay_dir} -o rw,noatime,lowerdir=/usr,upperdir=${mount_overlay_dir}/upper/usr,workdir=${mount_overlay_dir}/workdir/usr /usr fi } [ x"$1" = x"UDISK" ] && rm -rf /overlay } 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#*@} ] && [ -x /sbin/mdev ] && 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 -o sync,data=journal $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 } check_update_system_state() { swu_mode=`fw_printenv | grep swu_mode | awk -F '=' '{print $2}'` echo "swu_mode:$swu_mode" if [ $swu_mode == ]; then echo "Not thing todo" else # update_flash_flag && boot_partition_flag # bit3~7: reserve # bit2 : extend(/usr) 1:extend 0:extend_back # bit1 : rootfs 1:rootfs 0:rootfs_backup # bit0 : kernel 1:kernel 0:kernel_back dd if=/dev/mtdblock0 of=/tmp/boot0_flag skip=61439 ibs=1 bs=1 count=1 1>/dev/null 2>&1 boot_flash_flag=0x`xxd /tmp/boot0_flag | awk -F ' ' '{print $2}'` boot_partition_flag=0x`fw_printenv | grep update_partition_flag | awk 'BEGIN{FS="="} {print $2}'` echo "boot_flash_flag:$boot_flash_flag, boot_partition_flag:$boot_partition_flag" if [ $boot_flash_flag == $boot_partition_flag ]; then boot_flash_flag_tmp=$((boot_flash_flag&0x7)) echo "boot_flash_flag_tmp:$boot_flash_flag_tmp" # The system has been updated, but env has not been updated case $boot_flash_flag_tmp in 0) fw_setenv boot_partition bootB fw_setenv root_partition rootfsB fw_setenv extend_parttion extendB fw_setenv swu_mode ;; 1) fw_setenv boot_partition bootA fw_setenv root_partition rootfsB fw_setenv extend_parttion extendB fw_setenv swu_mode ;; 2) fw_setenv boot_partition bootB fw_setenv root_partition rootfsA fw_setenv extend_parttion extendB fw_setenv swu_mode ;; 3) fw_setenv boot_partition bootB fw_setenv root_partition rootfsB fw_setenv extend_parttion extendA fw_setenv swu_mode ;; 4) fw_setenv boot_partition bootA fw_setenv root_partition rootfsA fw_setenv extend_parttion extendB fw_setenv swu_mode ;; 5) fw_setenv boot_partition bootA fw_setenv root_partition rootfsB fw_setenv extend_parttion extendA fw_setenv swu_mode ;; 6) fw_setenv boot_partition bootB fw_setenv root_partition rootfsA fw_setenv extend_parttion extendA fw_setenv swu_mode ;; 7) fw_setenv boot_partition bootA fw_setenv root_partition rootfsA fw_setenv extend_parttion extendA fw_setenv swu_mode ;; *) echo "not match boot_flash_flag_tmp" ;; esac else echo "update system fail, not clean swu_mode" fi fi } #---------------------------------------------------------------- /bin/mount -t proc /proc /proc /bin/mount -t tmpfs tmpfs /tmp /bin/mount -t sysfs sys /sys # /bin/mount -t devtmpfs none /dev #demo_video_in -n 40 -s0 1920x1088 -f0 0 -pf 12 -trd 1 -pf2 0 fgrep -sq pstore /proc/filesystems && { /bin/mount -t pstore pstore /sys/fs/pstore } #fw_setenv, fw_printenv need /var/lock mkdir -p /var/lock #common but slow set_parts_by_name mount_sec_storage # OTA's configuration is not turned on by default exit returns, # which does not affect the startup speed check_update_system_state mount_usr [ x"$MOUNT_ETC" = x"1" ] && mount_etc [ x"$MOUNT_OVERLAY" = x"1" ] && mount_overlay UDISK #choose rootfs_data or UDISK mount_app MODULES_DIR="/lib/modules/`uname -r`" insmod $MODULES_DIR/xr806.ko /etc/init.d/S50wifidaemon start & # insmod $MODULES_DIR/disp.ko # loaded by kernel insmod $MODULES_DIR/sunxi_gpadc.ko /etc/init.d/S00mpp start # snd should be loaded before app /APP/SL100BACKPANEL & insmod $MODULES_DIR/evdev.ko insmod $MODULES_DIR/cst9220.ko #hardcode but fast #mount_etc_hardcode #set_parts_by_name_hardcode #mount_usr exec /sbin/init