#!/bin/sh 
#+--------------------------------------------------------------------------------------------
#|Description: This shell script  used to mount /apps, /info partition to jffs2 and 
#|             mount /data partition to ubifs
#|     Author:  GuoWenxue <guowenxue@gmail.com> QQ: 281143292 
#|  ChangeLog:
#|           1, Initialize 1.0.0 on 2012.04.18
#|           2, Modify to 2.0.0 on 2012.08.28 by guowenxue, add seprate parition mount support
#+--------------------------------------------------------------------------------------------

usage()
{
   printf "Usage: $0 [OPTIONS] [-o OPTS] PARTITION\n"

   printf "\nMount a system partition\n"
   printf "\n\t-a Mount all default filesystems when system start up\n"
   printf "\t-t [jffs2/ubifs] Filesystem type(s), only support jffs2 and ubifs here.\n"
   printf "\t-o OPT    mount options, multiple options use , to separate.\n"

   printf "\t\t[a]sync         Writes are [a]synchronous\n"
   printf "\t\tremount         Remount a mounted filesystem, changing flags\n"
   printf "\t\tro/rw\n"

   printf "\tPARTITION should be [apps/data/backup]\n"
   
   printf "\nEXAMPLE:\n"
   printf "$0 -t ubifs -o rw,sync backup\n"
   printf "$0 -t jffs2 -o ro,sync info\n"

   exit
}

is_mounted( )
{
   /bin/mountpoint $1  > /dev/null 2>&1  
   return $?
}

ubifs_mount( )
{ 
   mtd_num=$1
   mtd_name=$2
   mnt_opts=$3
   
   if [ ! -e /dev/ubi$mtd_num ] ; then
      ubiattach -m $mtd_num -d $mtd_num /dev/ubi_ctrl
      echo "ubiattach -m $mtd_num -d $mtd_num /dev/ubi_ctrl"
      sleep 1
   fi
   
   let size_hex=0x`cat /proc/mtd | grep mtd$mtd_num | awk '{print $2}'`
   partition_size_in_bytes=`echo $size_hex`

   #It's 2048 blocks on K9F2G08
   blocks_per_device=2048
   block_size_in_bytes=131072
   logical_erase_block_size=129024
   wear_level_reserved_blocks=`expr $blocks_per_device / 100 \* 2`

   partition_physical_blocks=`expr $partition_size_in_bytes / $block_size_in_bytes`
   patition_logical_blocks=`expr $partition_physical_blocks - $wear_level_reserved_blocks`
   vol_size=`expr $patition_logical_blocks \* $logical_erase_block_size`
        
   if [ ! -e /dev/ubi$mtd_num"_0" ] ; then 
      ubimkvol /dev/ubi$mtd_num -n 0 -N $mtd_name -s $vol_size 
   fi
   
   if [ ! -z $mnt_opts ] ; then
      mnt_opts="-o $mnt_opts"
   fi
      
   echo "mount -t ubifs $mnt_opts ubi$mtd_num:$mtd_name /$mtd_name"
   mount -t ubifs $mnt_opts ubi$mtd_num:$mtd_name /$mtd_name
}

jffs2_mount( )
{
   mtd_num=$1
   mtd_name=$2
   mnt_opts=$3
   
   if [ ! -z $mnt_opts ] ; then
      mnt_opts="-o $mnt_opts"
   fi
   
   echo "/bin/mount -t jffs2 $mnt_opts /dev/mtdblock$mtd_num /$mtd_name"
   /bin/mount -t jffs2 $mnt_opts /dev/mtdblock$mtd_num /$mtd_name
}

mnt_partition( )
{
   mtd_name=$1
   fs_type=$2
   mnt_opts=$3
   mnt_point=/$mtd_name
   
   if [ ! -d $mnt_point ] ; then
      echo "$mtd_name is not a valid partition."
      exit;
   fi
   
   mtd_num=`cat /proc/mtd | grep -m 1 $mtd_name | awk -F ":" '{print $1}' | grep -Eo '[0-9]+'`
   if [ -z $mtd_num ] ; then
      echo "$mtd_name is not a valid partition."
      exit;
   fi
   
   if ! is_mounted $mnt_point ; then
      if [ "$fs_type" == "ubifs" ] ; then
         ubifs_mount $mtd_num $mtd_name $mnt_opts
      elif [ "$fs_type" == "jffs2" ] ; then
         jffs2_mount $mtd_num $mtd_name $mnt_opts
      fi
   fi
}

if [ $# -le 0 ] ; then
  usage
fi

while getopts "aho:t:" opt
do
   case $opt in
       a)
          mnt_default=yes
          break;
          ;;

       o)
          mnt_opts=$OPTARG
          shift 2
          ;;

       t)
          fs_type=$OPTARG
          shift 2
          ;;

       h)
          usage
          ;;

       ?)
          usage
          ;;

   esac
done

mtd_name=$1

if [ "$mnt_default" = "yes" ] ; then
   jffs2_opts="sync,noatime,ro"
   ubifs_opts="sync,noatime,rw"
   
   mnt_partition apps ubifs $ubifs_opts
   mnt_partition data ubifs $ubifs_opts
   mnt_partition backup jffs2 $ubifs_opts
   
elif [ -n "$mtd_name" -a -n "$fs_type" ] ; then
   mnt_partition $mtd_name $fs_type $mnt_opts
else
   usage
fi

exit;


