1. mkimage

#!/bin/sh

get_value_by_key()
{
    local str="$1"
    local key=$2
    local value=""

    if [ "${str/$key=}" != "$str" ]; then
        value=${str##*$key=}
        value=${value%% *}
        value=${value%%,*}
    fi
    echo $value
}

generate_ubi_cfg()
{
#ubi config
cat > $ubifs_cfg << UBI_CFG
[ubifs0]
mode=ubi
image=$ubifs_img1
vol_id=0
vol_size=$leb_size
vol_type=dynamic
vol_name=meta
vol_alignment=1

[ubifs1]
mode=ubi
image=$ubifs_img2
vol_id=1
vol_size=$fssize
vol_type=dynamic
vol_name=data
vol_alignment=1
vol_flags=autoresize
UBI_CFG
}

make_ubifs_image()
{
    local str="$1"
    local ubi_img=$2

    local mk_ubifs=$buildroot_dir/output/host/usr/sbin/mkfs.ubifs
    local mk_ubinize=$buildroot_dir/output/host/usr/sbin/ubinize

    #generate mkfs.ubifs if necessary
    if [ ! -f $mk_ubifs ]; then
        echo "Generating mkfs tool..."
        local cwd=`pwd`
        cd $buildroot_dir
        make host-mtd
        cd $cwd
        echo "done"
    fi

    [ ! -f $mk_ubifs ] && echo "Make fs tool failed" && return 1

    local fsroot=`get_value_by_key "$str" fsroot`
    local fssize=`get_value_by_key "$str" fssize`

    local ubifs_img1=/tmp/tmp_img_file1
    local ubifs_img2=/tmp/tmp_img_file2
    local ubifs_cfg=/tmp/tmp_img_cfg

    #make meta
    dd if=/dev/zero of=$ubifs_img1 bs=$leb_size count=1
    dd if=$volume_config_file of=$ubifs_img1 conv=notrunc || return 1
    #make data
    $mk_ubifs -r $fsroot -m $min_io_size -e $leb_size -c $max_leb_cnt -o $ubifs_img2 || return 1

    #generate config file
    generate_ubi_cfg

    #output the image
    $mk_ubinize -o $ubi_img -m $min_io_size -p 128KiB $ubifs_cfg || return 1

    return 0
}

add2image()
{
    local str="$1"
    local outfile=$2
    local offset=${str%%:*}
    local file=`get_value_by_key "$str" file`
    local size=`get_value_by_key "$str" size`
    local content=`get_value_by_key "$str" content`
    local fstype=`get_value_by_key "$str" fstype`

    [ -z "$offset" ] && return 1
    #from hex to dec
    offset=$(($offset))

    if [ -n "$content" ]; then
        printf "$content\0" > /tmp/tmp_file
        dd if=/tmp/tmp_file of=$outfile bs=1 conv=notrunc seek=$offset || return 1
    fi

    if [ -n "$file" ]; then
        if [ -n "$size" ]; then
            dd if=$file of=$outfile bs=1 conv=notrunc seek=$offset count=$size || return 1
        else
            dd if=$file of=$outfile bs=128K conv=notrunc seek=$((offset/128/1024)) || return 1
        fi  
    fi 

    if [ "$fstype" = "ubifs" ]; then
        local img_out=ubi.img
        rm -f $img_out
        make_ubifs_image "$str" $img_out || return 1
        dd if=$img_out of=$outfile bs=128k conv=notrunc seek=$((offset/128/1024)) || return 1
    fi

    return 0
}

#load config
. *_image.cfg

#generate the whole empty image
dd if=/dev/zero bs=$flash_size count=1 | tr '\000' '\377' > $outfile

echo "$flash_map" | while read line
do
    if [ -n "$line" ]; then
        add2image "$line" $outfile || exit 1
    fi
done

if [ "$?" = "0" ]; then
    #print map
    echo "====SUCCESS===="
    echo "$flash_map"
else
    echo "====FAILURE===="
    echo see *_image.cfg
fi

2. shell devmem脚本

#!/bin/sh

while true;
do
        devmem 0x100003003005C 32 0x1000000
        devmem 0x100003013005C 32 0x1000000
        devmem 0x100003043005C 32 0x1000000
        devmem 0x100003053005C 32 0x1000000
        devmem 0x100003083005C 32 0x1000000
        devmem 0x100003093005C 32 0x1000000
        devmem 0x1000030c3005C 32 0x1000000
        devmem 0x1000030d3005C 32 0x1000000

        devmem 0x100005003005C 32 0x1000000
        devmem 0x100005013005C 32 0x1000000
        devmem 0x100005043005C 32 0x1000000
        devmem 0x100005053005C 32 0x1000000
        devmem 0x100005083005C 32 0x1000000
        devmem 0x100005093005C 32 0x1000000
        devmem 0x1000050c3005C 32 0x1000000
        devmem 0x1000050d3005C 32 0x1000000
done

3. shell判断是否包含字串

注意:[[ "$line2" != "$line1"* ]]

  • 双方括号不能少
  • 通配符*不能在引号内
  • 含通配符的字符串不能是左操作符
    common_path_2line() { #(line1, line2)
      local line1=$1
      local line2=$2
      while [[ "$line2" != "$line1"* ]];do
          line1=`dirname $line1`
      done
      echo $line1
    }
    

4. awk处理表格, 以mkimage为例

fpxt-b_image.conf:

#----------------------------------------------------------------------------------
# start : type : source : descption
#----------------------------------------------------------------------------------
0x00000000 : file : u-boot.bin : bps uboot
0x00120000 : empty : : bps flags sector, leave empty
0x00140000 : string : committed : pkg A status, put committed
0x00160000 : string : uncommitted : pkg B status, put uncommitted
0x00180000 : file : u-boot.itb : uboot package A fit image
0x002C0000 : empty : : uboot package B fit image, leave empty
0x00400000 : file : vmlinux.itb : linux fit image(vmlinux and rootfs)
0x01FE0000 : empty : : uboot env variables, leave empty

处理上面文件的脚本:

create_blank_image() #(size)
{
    dd if=/dev/zero bs=$1 count=1 | tr '\000' '\377' > $image_file
}

fill_data_from_file() #(start,file)
{
    local start=$1
    local file=$2

    [ ! -f $file ] && echo "#### **ERROR** No such file: $file" && exit 1
    dd if=$file of=$image_file bs=128K conv=notrunc seek=$((start/128/1024))
}

fill_data_from_string() #(start,string)
{
    local start=$1
    local string=$2
    local tmpfile=`mktemp`

    printf "$string\0" > $tmpfile
    fill_data_from_file $start $tmpfile
    rm -rf $tmpfile
}


awk_wrapper() #(start,type,source)
{
    local start=$1
    local type=$2
    local source=$3

    case "$type" in
        file)
            fill_data_from_file $start $source_dir/$source
            ;;
        string)
            fill_data_from_string $start $source
            ;;
        empty)
            ;;
        *)
            ;;
    esac
}

# export for awk sub-shell used
export -f awk_wrapper fill_data_from_file fill_data_from_string
export source_dir image_file

echo "#### fill image data"
cat "$image_conf" | sed '/^#/d'| sed '/^$/d' | awk -F: '{
    print "####" $4;
    ret=system("awk_wrapper "$1" "$2" "$3" ");
    if(ret!=0) {
        exit ret
    }
}'

5. 记录日志

SYSLOG_NAME=`basename $0`                                       

log()                                                           
{                                                              
    if [ -n "$SYSLOG_NAME" ]                                   
    then                                                       
        LOGGER_ARGS="-t $SYSLOG_NAME"                          
    fi                                                        

    if [ -n "$SYSLOG_PRIORITY" ]                              
    then                                                      
        LOGGER_ARGS="$LOGGER_ARGS -p $SYSLOG_PRIORITY"        
    fi                                                        

    logger -s $LOGGER_ARGS "$@"                               
}                                                             

debug()                                                       
{                                                             
    if config_flag_enabled verbose; then                      
        SYSLOG_PRIORITY=user.debug log "$@"                   
    fi                                                        
}                                                             

info()                                                                     
{                                                                          
    if config_flag_enabled verbose; then                                   
        SYSLOG_PRIORITY=user.info log "$@"                                 
    fi                                                                     
}                                                                          

warning()                                                                  
{                                                                          
    SYSLOG_PRIORITY=user.warn log "$@"                                     
}                                                                          

error()                                                                    
{                                                                          
    SYSLOG_PRIORITY=user.error log "$@"                                    
}

6. 等待一个文件

wait_for_file()                                                
{                                                              
    local retval=0                                             
    local file=$1                                              
    local cnt=0                                                
    local cntmax                                               
    if [ -z "$2" ]; then                                       
        cntmax=20                                              
    else                                                       
        cntmax=$2                                              
    fi                                                         
    echo -n Waiting for $file...                               
    while [ ! -e $file -a $cnt -le $cntmax ]; do               
        usleep 100000 #100 ms                                  
        let 'cnt++'                                            
    done                                                       
    if [ -e $file ]; then                                      
        echo " ok (waited $cnt * 100 ms)"                                   
    else                                                                    
        echo " timeout ($cntmax * 100 ms)! System behavior is unspecified..."
        retval=1                                                            
    fi                                                                      
    return $retval                                                          
}

7. 发送SIGHUP到pid并等待进程终止

wait_app_done_pid()
{
    local pid=$1
    # if reading the cmdline in the application's proc directory
    # fails, the application most has most likely already stopped
    local app
    if ! app=$(cat /proc/$pid/task/$pid/stat 2>/dev/null); then
        return 0
    fi

    app=${app#*\(}
    app=${app%%\)*}

    local cnt=0
    local cntmax
    if [ -z "$2" ]; then
        cntmax=60
    else
        cntmax=$2
    fi

    echo -n "Waiting up to $cntmax seconds for $app (PID $pid) to go down..."
    while kill -s 0 "$pid" 2>/dev/null && [ $cnt -le $cntmax ]; do
        sleep 1
        let 'cnt++'
    done
    if [ $cnt -le $cntmax ]; then
          echo "ok, $app (PID $pid) finished in $cnt seconds."
          return 0
    else
          echo "darn, $app (PID $pid) did not finish within $cntmax seconds.. oh well.."
          return 1
    fi
}

8. pid到进程名

pid_to_procname()
{
    local pid=$1
    local app=$(cat /proc/$pid/task/$pid/stat 2>/dev/null)
    app=${app#*(}
    app=${app%%)*}
    echo $app
}

9. mac地址转换到字符串

mac_hex_to_string()
{
    local hex=$1
    echo $hex | sed -e 's/../&:/g' -e 's/:$//'
}

10. 大小写转换

tolower()
{
    local str=$1
    echo $str | tr '[:upper:]' '[:lower:]'
}

toupper()
{
    local str=$1
    echo $str | tr '[:lower:]' '[:upper:]'
}

11. 去掉前后空格

trim()
{
    local str=$1
    echo $str | sed -e 's/^ *//g' -e 's/ *$//g'
}

12. 加0x前缀, 负数时加-0x

hex_prefix()
{
    # add 0x as prefix if not yet present (but take into account negative numbers)
    echo $1 | sed -e 's/0x//I' -e 's/^\(-\?\)/\10x/'
}

13. 两个16进制数相加

addhex()
{
    # sum two hex numbers
    # input can but doesn't have to contain 0x prefix, output will be without 0x
    local res
    let "res = $(hex_prefix $1) + $(hex_prefix $2)"
    printf '%x\n' $res
}

14. 查看进程是否还在

isalive()
{
    # Simply return the return code of pidof (0=alive, 1=dead)
    pidof "$@" > /dev/null
}

15. 网络接口是否存在

interface_exists()
{
    local iface=$1
    [ -e /sys/class/net/$iface ]
}

16. 解析命令参数

支持key=value格式转换key为变量, 注意until和shift的用法

# Alternative getopt that accepts input of the form
# "key1=value1 key2=value2" and exposes key1 and key2
# as shell variables.
# Usage: getopt_simple <cmdline>
getopt_simple()
{
    until [ -z "$1" ]
    do
        parameter=${1%%=*} # Extract name.
        value=${1##*=} # Extract value.
        # Verify if parameter starts with a valid alpha-character, or ignore
        case $parameter in
            [A-z]*) eval $parameter=\"$value\" ;;
        esac
        shift # Drop $1 and shift $2 to $1
    done
}

# Expose only the selected key/value pair. This is safer than getopt_simple
# because it avoids overwriting variables of the calling script unexpectedly.
# Usage: getopt_simple_onevar <key> <cmdline>
getopt_simple_onevar()
{
    local key=$1
    shift

    until [ -z "$1" ]
    do
        parameter=${1%%=*} # Extract name.
        value=${1##*=} # Extract value.
        if [ "$parameter" = "$key" ]; then
            eval $parameter=\"$value\"
        fi
        shift # Drop $1 and shift $2 to $1
    done
}

results matching ""

    No results matching ""