#!/bin/bash VERSION="0.2.1" source $(dirname $0)/target.tb show_help() { echo -ne "Usage: mkpatch-nand.sh -p [-o ] [-bh] " echo -e "\033[32m\033[0m" echo -e "Options:" echo -e "\t-h: show this help message and exit" echo -e "\t-o : out directory [default current dir]" echo -e "\t-p : the platform to make" echo -e "\t-v: just show driver version and exit" echo -e "" echo "Eg. ./mkpatch-nand.sh -p r16 ~/worksapce/tina : make nand patch for r16" } get_kernel_version() { local list="$(find ${ROOT}/target/allwinner -maxdepth 1 -name "$1-*" -type d)" local one ver version platform for one in ${list} do grep -q 'common$' <<< "${one}" && continue [ -f "${one}/Makefile" ] || continue unset ver ver="$(awk -F":=" '/KERNEL_PATCHVER/{print $2}' ${one}/Makefile)" if [ -z "${version}" ]; then platform="${one}" version="${ver}" else [ "${version}" = "${ver}" ] && continue echo -en "\033[31mkernel version diff: " echo -en "$(basename ${one}) (${ver}) Vs. " echo -e "$(basename ${platform}) (${version})\033[0m" [ "$(echo "${ver} > ${version}" | bc)" -eq 1 ] && version="${ver}" fi done kernel="linux-${version}" } get_uboot_version() { local kernel=$1 case "${kernel}" in linux-3.4) uboot="u-boot-2011.09" ;; *) uboot="u-boot-2014.07" ;; esac } get_chip() { local fconfig fconfig="${ROOT}/target/allwinner/$1-*/config-$(awk -F'-' '{print $2}' <<< $2)" chip="$(awk -F'[_=]' '/CONFIG_ARCH_SUN.*P.*=y/{print tolower($3)}' ${fconfig} | head -n 1)" } check_platform() { up_platform="$(sed 's/.*/\u&/g' <<< "${platform}")" info="$(sed 's/ /\n/g' <<< "${table[@]}" | awk "/${up_platform}/{print}")" [ -z "${info}" ] && return 1 platform="$(sed 's/.*/\l&/g' <<< ${platform})" target="$(awk -F: '{print $1}' <<< ${info})" get_kernel_version ${target} get_uboot_version ${kernel} get_chip ${target} ${kernel} # kernel case ${kernel} in "linux-3.4"|"linux-3.10") kbase="drivers/block/nand" kdriver="lichee/${kernel}/${kbase}/${chip}" ;; *) kbase="modules/nand" kdriver="lichee/${kernel}/${kbase}/${chip}" ;; esac kversion=$(grep '#define *NAND_DRV_VERSION_.*' ${ROOT}/${kdriver}/nfd/nand_osal_for_linux.c \ | awk '{print $3}' \ | sed 's/0x0*//;N;s/\n//;s/0x/./') # uboot case ${uboot} in *2011*) udriver="lichee/brandy/${uboot}/nand_sunxi/${chip%p*}" ;; *) udriver="lichee/brandy/${uboot}/nand_sunxi/${chip}" ;; esac ubase="${ROOT}/${udriver}/osal" if [ -f "${ubase}/nand_osal_uboot.c" ]; then uversion=$(grep '#define *NAND_DRV_VERSION_.*' ${ubase}/nand_osal_uboot.c 2>/dev/null \ | awk '{print $3}' \ | sed 's/0x0*//;N;s/\n//;s/0x/./') else #有时候为了多方案共用osal,并不会单独维护一份osal,而是在common中共用 nand_uboot_use_common=$(grep -oE 'common[^/]*' ${ubase}/Makefile | head -n 1) ubase="${ROOT}/${udriver}/../${nand_uboot_use_common}/osal" uversion=$(grep '#define *NAND_DRV_VERSION_.*' ${ubase}/nand_osal_uboot.c 2>/dev/null \ | awk '{print $3}' \ | sed 's/0x0*//;N;s/\n//;s/0x/./') fi echo "====================================================================" echo "platform: ${platform}" echo "kernel: ${kernel}" echo "uboot: ${uboot}" echo "chip: ${chip}" echo "target: ${target}" echo "kernel driver: ${kdriver}" echo "kernel driver version: ${kversion}" echo "uboot driver: ${udriver}" echo "uboot driver version: ${uversion}" echo "====================================================================" [ -z "${platform}" -o -z "${kernel}" -o -z "${uboot}" -o -z "${chip}" -o -z "${target}" \ -o -z "${kversion}" -o -z "${uversion}" ] && return 1 || return 0 } mk_README() { cat > ${tmpdir}/README.txt << EOF 注意: ============================================================= 此补丁只适用于更新全志 TinaSDK 或 AndroidSDK 的 nand 驱动 ============================================================= 补丁信息: ============================================================= nand驱动: ${kversion} 适用方案: ${platform} (${kernel} + ${uboot}) 补丁提取日期: $(date +%Y-%m-%d\ %H:%M:%S) ============================================================= 文件内容: ============================================================= patch.tar.gz : nand 补丁 bin.tar.gz : Tina nand bin 补丁 README.txt : 说明文档 md5sum.txt : 补丁包的md5码 install.sh : 快速更新脚本 ============================================================= 更新步骤: ============================================================= 1. 安装补丁 ./install.sh Android SDK: 打补丁及重新编译uboot Tina SDK: 打补丁及替换uboot/boot0的bin Eg. install.sh ~/workspace/tina : 打补丁+替换uboot/boot0的bin Eg. install.sh ~/workspace/android : 打补丁+编译uboot Note. Android SDK根目录 指全志AndroidSDK中,包含lichee与Android源码 的目录。目录结构如下: android/ (SDK根目录) ├── android └── lichee 2. 对TinaSDK,如果有定制uboot,需要手动编译uboot ./install -u Android SDK: 步骤1,默认编译uboot,不用执行步骤2 Tina SDK: 重新编译uboot Eg. install.sh -u ~/workspace/tina : 重新编译Tina的uboot 3. 重新编译&打包 若编译失败,表示补丁更新失败,请提供编译log以进一步分析 ============================================================= EOF } mk_md5sum() { ! [ -f "${tmpdir}/patch.tar.gz" ] \ && echo -e "\033[31mNot Found ${tmpdir}/patch.tar.gz\033[0m" \ && return 1 cd ${tmpdir} >/dev/null md5sum bin.tar.gz >> ${tmpdir}/md5sum.txt md5sum patch.tar.gz > ${tmpdir}/md5sum.txt } mk_install() { touch ${tmpdir}/install.sh chmod +x ${tmpdir}/install.sh cat > ${tmpdir}/install.sh << EOF #!/bin/bash show_help() { echo -e "Usage: install.sh [-ahpu] \\033[32m\\033[0m" echo -e "Options:" echo -e "\\t-a: patch and build uboot [default]" echo -e "\\t-h: show this help message and exit" echo -e "\\t-p: just patch" echo -e "\\t-u: just build uboot" echo -e "" echo "Eg. ./install.sh ~/worksapce/tina : just patch" echo "Eg. ./install.sh -u ~/worksapce/android: just build uboot" } check_top() { OBJ_ROOT="\$1" [ -f "\${OBJ_ROOT}/android/build/envsetup.sh" -a -d "\${OBJ_ROOT}/lichee" ] \\ && SDK=android && return 0 [ -f "\${OBJ_ROOT}/build/envsetup.sh" -a -d "\${OBJ_ROOT}/../lichee" ] \\ && SDK=android && OBJ_ROOT="\${OBJ_ROOT}/.." && return 0 [ -f "\${OBJ_ROOT}/build/envsetup.sh" -a -d "\${OBJ_ROOT}/target/allwinner" ] \\ && SDK=tina && return 0 echo -e "\\033[31mInvalid Root of TinaSDK or AndroidSDK\\033[0m\n" return 1 } check_md5() { ! which md5sum &>/dev/null \\ && echo -e "\\033[31mPlease Install md5sum\\033[0m" \\ && return 1 ! which tar &>/dev/null \\ && echo -e "\\033[31mPlease Install tar\\033[0m" \\ && return 1 [ ! -f \${cur}/patch.tar.gz ] \\ && echo -e "\\033[31mNot Found Tina Patch In Current Path\\033[0m" \\ && return 1 [ ! -f \${cur}/md5sum.txt ] \\ && echo -e "\\033[31mNot Found md5sum.txt In Current Path\\033[0m" \\ && return 1 ! md5sum -c md5sum.txt &>/dev/null \\ && echo -e "\\033[31mCheck md5sum Failed\\033[0m" \\ && return 1 return 0 } check() { [ \$# -ne 1 -o ! -d "\$1" ] && show_help && exit 1 ! check_top "\$1" && show_help && exit 1 ! check_md5 && echo -e "\\n\\033[31mBad Patch\\033[0m" && exit 1 return 0 } uboot() { echo -e "\\033[33mCheck Env\\033[0m" export TARGET_PLATFORM="${target}" chip="${chip}" uboot="${uboot}" echo -e "\\033[32mCheck Env ... OK\\033[0m" # build uboot echo -e "\\n\\033[33mBuild Uboot\\033[0m" cd \${OBJ_ROOT}/lichee/brandy/\${uboot} make distclean make \${chip}_config make -j4 # check build [ "\$?" -ne 0 ] \\ && echo -e "\\n\\033[31mBuild Uboot Failed\\033[0m" \\ && exit 1 echo -e "\\033[32mBuild Uboot ... OK\\033[0m" return 0 } patch() { ! tar -mzxf \${cur}/patch.tar.gz -C \${OBJ_ROOT} \\ && echo -e "\\033[31mPatch Failed\\033[0m" \\ && exit 1 if [ "\${SDK}" = "tina" -a -f "\${cur}/bin.tar.gz" ]; then ! tar -zmxf \${cur}/bin.tar.gz -C \${OBJ_ROOT} target \\ && echo -e "\\033[31mPatch Failed\\033[0m" \\ && exit 1 echo -e "\\033[32mPatch Bin for Tina SDK ... OK\\033[0m" fi echo -e "\\033[32mPatch ... OK\\033[0m" return 0 } clean() { # clean uboot rm -rf \${OBJ_ROOT}/${udriver}/lib-nand # clean kernel rm -rf \${OBJ_ROOT}/${kdriver}/lib make -C \${OBJ_ROOT}/lichee/${kernel}/${kbase} clean &>/dev/null $(if [ "${kernel}" = "linux-3.4" -o "${kernel}" = "linux-3.10" ]; then echo " rm -rf \${OBJ_ROOT}/lichee/${kernel}/modules/nand/${chip}/lib" echo " make -C \${OBJ_ROOT}/lichee/${kernel}/modules/nand clean &>/dev/null" fi) } # update update() { cur=\$(dirname \$0) opts=\$(getopt -o 'ahpu' -- \$@) || return 1 eval set -- "\${opts}" while true do case "\$1" in -a) actor="clean patch uboot" shift ;; -h) show_help exit 0 ;; -p) actor="clean patch" shift ;; -u) actor="clean uboot" shift ;; --) shift break esac done check \$@ if [ -z "\${actor}" ]; then actor="clean patch" [ "\${SDK}" = "android" ] && actor="\${actor} uboot" fi eval "\$(sed 's/ /\\n/g' <<< \${actor})" echo -e "\\033[32m--- END ---\\033[0m" } update \$@ EOF } mk_patch() { [ ! -d "${ROOT}/${kdriver}" -o ! -d "${ROOT}/${udriver}" ] \ && echo -e "\033[31mMiss Driver Codes\033[0m" && return 1 # clean all echo -ne "\033[32mCleaning kernel ... \033[0m" make -C ${ROOT}/lichee/${kernel} M=${kbase} clean &>/dev/null echo -e "\033[32mOK\033[0m" echo -ne "\033[32mCleaning uboot ... \033[0m" make -C ${ROOT}/lichee/brandy/${uboot} M=nand_sunxi clean &>/dev/null echo -e "\033[32mOK\033[0m" echo # kernel mkdir -p ${tmpdir}/${kdriver%/*} cp -r ${ROOT}/${kdriver} ${tmpdir}/${kdriver} if grep "block" <<< ${kdriver} &>/dev/null; then # fix for android mkdir -p ${tmpdir}/lichee/${kernel}/modules/nand cp -r ${ROOT}/${kdriver} ${tmpdir}/lichee/${kernel}/modules/nand sed -i '1s/\(obj-\).*\( += nand.o\)/\1m\2/' \ ${tmpdir}/lichee/${kernel}/modules/nand/${chip}/Makefile fi #有可能是软连接,因此拷贝的可能只是软链接 if [ -L "${ROOT}/${kdriver}" ]; then kdriver="${kdriver%/*}/$(readlink ${ROOT}/${kdriver})" cp -r ${ROOT}/${kdriver} ${tmpdir}/${kdriver} if grep "block" <<< ${kdriver} &>/dev/null; then # fix for android mkdir -p ${tmpdir}/lichee/${kernel}/modules/nand cp -r ${ROOT}/${kdriver} ${tmpdir}/lichee/${kernel}/modules/nand sed -i '1s/\(obj-\).*\( += nand.o\)/\1m\2/' \ ${tmpdir}/lichee/${kernel}/modules/nand/${chip}/Makefile fi fi # uboot mkdir -p ${tmpdir}/${udriver%/*} cp -r ${ROOT}/${udriver} ${tmpdir}/${udriver} [ -n "${nand_uboot_use_common}" ] \ && cp -r ${ROOT}/${udriver}/../${nand_uboot_use_common} ${tmpdir}/${udriver}/.. # bin mkdir -p ${tmpdir}/target/allwinner/${target}-common/bin cp -r ${ROOT}/target/allwinner/${target}-common/bin/{boot0_nand_sun*.bin,u-boot-sun*.bin} \ ${tmpdir}/target/allwinner/${target}-common/bin # clean src rm -rf ${tmpdir}/${udriver}/lib-nand rm -rf ${tmpdir}/${kdriver}/lib if [ "${kernel}" = "linux-3.4" -o "${kernel}" = "linux-3.10" ]; then rm -rf ${tmpdir}/lichee/${kernel}/modules/nand/${chip}/lib fi find ${tmpdir} -name "tags" -exec rm -f {} \; find ${tmpdir} -name ".*" -exec rm -rf {} \; &>/dev/null # pack cd ${tmpdir} echo -e "\033[33mPatch List\033[0m" tar -zcvf bin.tar.gz target tar -zcvf patch.tar.gz lichee } do_patch() { base="${up_platform}_Update_Nand_To_${kversion}_$(date +%Y-%m-%d)" tmpdir="${outdir}/${base}" outfile="${base}.tar.gz" rm -rf ${tmpdir} rm -f ${outdir}/${outfile} mkdir -p ${tmpdir} mk_README && mk_install && mk_patch && mk_md5sum [ "$?" -ne 0 ] && exit 1 echo "" rm -rf lichee target cd ${tmpdir}/.. tar -zcvf ${outdir}/${outfile} ${base} > /dev/null ! [ -f "${outdir}/${outfile}" ] \ && echo -e "\033[32mMake Patch Failed\033[0m" \ && exit 1 echo -e "\033[32mMake Patch Finish\033[0m" echo -e "Patch at:\n\033[33m ${outdir}/${outfile}\033[0m" } check_top() { ROOT="$(sed 's#/$##' <<< $1)" [ ! -f "${ROOT}/build/envsetup.sh" ] \ && echo -e "\033[31mInvalid Root of Tina SDK\033[0m\n" \ && return 1 return 0 } check() { [ -z "${platform}" ] \ && echo -e "\033[31mPlease Tell Me The Platform by -p \033[0m" \ && return 1 [ $# -ne 1 -o ! -d "$1" ] \ && echo -e "\033[31mMiss Root Of SDK\033[0m" \ && show_help && return 1 ! check_top "$1" && return 1 ! check_platform \ && echo -e "\033[31mInvalid Platform: ${platform}\033[0m" \ && return 1 echo "" return 0 } show_version() { echo "VERSION for this script: ${VERSION}" } mkpatch() { opts=$(getopt -o 'ho:p:v' -- $@) || return 1 eval set -- "${opts}" while true do case "$1" in -h) show_help exit 0 ;; -p) shift platform="$1" shift ;; -o) shift outdir="$(cd $1 && pwd)" shift ;; -v) shift do_and_exit="show_version" ;; --) shift break esac done [ -z "${outdir}" -o "${outdir}" = '.' ] && outdir="${PWD}" check $@ || exit 1 [ -n "${do_and_exit}" ] && { $(sed 's/ /\n/g' <<< ${do_and_exit}) exit 0 } do_patch echo -e "\033[32m--- END ---\033[0m" } mkpatch $@