1#! /bin/bash 2# 3# CompuLab CM-FX6 module boot loader update utility 4# 5# Copyright (C) 2013-2015 CompuLab, Ltd. 6# Author: Igor Grinberg <grinberg@compulab.co.il> 7# 8# This program is free software; you can redistribute it and/or modify 9# it under the terms of the GNU General Public License as published by 10# the Free Software Foundation; either version 2 of the License, or 11# (at your option) any later version. 12# 13# This program is distributed in the hope that it will be useful, 14# but WITHOUT ANY WARRANTY; without even the implied warranty of 15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16# GNU General Public License for more details. 17 18UPDATER_VERSION="2.3" 19UPDATER_VERSION_DATE="Oct 18 2015" 20UPDATER_BANNER="CompuLab CM-FX6 (Utilite) boot loader update utility ${UPDATER_VERSION} (${UPDATER_VERSION_DATE})" 21 22NORMAL="\033[0m" 23WARN="\033[33;1m" 24BAD="\033[31;1m" 25BOLD="\033[1m" 26GOOD="\033[32;1m" 27 28function good_msg() { 29 local msg_string=$1 30 msg_string="${msg_string:-...}" 31 echo -e "${GOOD}>>${NORMAL}${BOLD} ${msg_string} ${NORMAL}" 32} 33 34function bad_msg() { 35 local msg_string=$1 36 msg_string="${msg_string:-...}" 37 echo -e "${BAD}!!${NORMAL}${BOLD} ${msg_string} ${NORMAL}" 38} 39 40function warn_msg() { 41 local msg_string=$1 42 msg_string="${msg_string:-...}" 43 echo -e "${WARN}**${NORMAL}${BOLD} ${msg_string} ${NORMAL}" 44} 45 46function DD() { 47 dd $* &> /dev/null & pid=$! 48 49 while [ -e /proc/$pid ] ; do 50 echo -n "." 51 sleep 1 52 done 53 54 echo "" 55 wait $pid 56 return $? 57} 58 59function confirm() { 60 good_msg "$1" 61 62 select yn in "Yes" "No"; do 63 case $yn in 64 "Yes") 65 return 0; 66 ;; 67 "No") 68 return 1; 69 ;; 70 *) 71 case ${REPLY,,} in 72 "y"|"yes") 73 return 0; 74 ;; 75 "n"|"no"|"abort") 76 return 1; 77 ;; 78 esac 79 esac 80 done 81 82 return 1; 83} 84 85EEPROM_DEV="/sys/bus/i2c/devices/2-0050/eeprom" 86MTD_DEV="mtd0" 87MTD_DEV_FILE="/dev/${MTD_DEV}" 88CPU_NAME="" 89DRAM_NAME="" 90BOOTLOADER_FILE="cm-fx6-firmware" 91 92function find_bootloader_file() { 93 read -p "Please input firmware file path (or press ENTER to use \"cm-fx6-firmware\"): " filepath 94 if [[ -n $filepath ]]; then 95 BOOTLOADER_FILE=`eval "echo $filepath"` 96 fi 97 98 good_msg "Looking for boot loader image file: $BOOTLOADER_FILE" 99 if [ ! -s $BOOTLOADER_FILE ]; then 100 bad_msg "Can't find boot loader image file for the board" 101 return 1; 102 fi 103 104 good_msg "...Found" 105 return 0; 106} 107 108function check_spi_flash() { 109 good_msg "Looking for SPI flash: $MTD_DEV" 110 111 grep -qE "$MTD_DEV: [0-f]+ [0-f]+ \"uboot\"" /proc/mtd 112 if [ $? -ne 0 ]; then 113 bad_msg "Can't find $MTD_DEV device, is the SPI flash support enabled in kernel?" 114 return 1; 115 fi 116 117 if [ ! -c $MTD_DEV_FILE ]; then 118 bad_msg "Can't find $MTD_DEV device special file: $MTD_DEV_FILE" 119 return 1; 120 fi 121 122 good_msg "...Found" 123 return 0; 124} 125 126function get_uboot_version() { 127 local file="$1" 128 grep -oaE "U-Boot [0-9]+\.[0-9]+.* \(... +[0-9]+ [0-9]+ - [0-9]+:[0-9]+:[0-9]+.*\)" "$file" 129} 130 131function check_bootloader_versions() { 132 local flash_version=`echo \`get_uboot_version $MTD_DEV_FILE\`` 133 local file_version=`echo \`get_uboot_version $BOOTLOADER_FILE\`` 134 local file_size=`du -hL $BOOTLOADER_FILE | cut -f1` 135 136 good_msg "Current U-Boot version in SPI flash:\t$flash_version" 137 good_msg "New U-Boot version in file:\t\t$file_version ($file_size)" 138 139 confirm "Proceed with the update?" && return 0; 140 141 return 1; 142} 143 144function check_utility() { 145 local util_name="$1" 146 local utility=`which "$util_name"` 147 148 if [[ -z "$utility" || ! -x $utility ]]; then 149 bad_msg "Can't find $util_name utility! Please install $util_name before proceding!" 150 return 1; 151 fi 152 153 return 0; 154} 155 156function check_utilities() { 157 good_msg "Checking for utilities..." 158 159 check_utility "diff" || return 1; 160 check_utility "grep" || return 1; 161 check_utility "sed" || return 1; 162 check_utility "hexdump" || return 1; 163 check_utility "dd" || return 1; 164 check_utility "flash_erase" || return 1; 165 166 good_msg "...Done" 167 return 0; 168} 169 170function erase_spi_flash() { 171 good_msg "Erasing SPI flash..." 172 173 flash_erase $MTD_DEV_FILE 0 0 174 if [ $? -ne 0 ]; then 175 bad_msg "Failed erasing SPI flash!" 176 bad_msg "If you reboot, your system might not boot anymore!" 177 bad_msg "Please, try re-installing mtd-utils package and retry!" 178 return 1; 179 fi 180 181 good_msg "...Done" 182 return 0; 183} 184 185function write_bootloader() { 186 good_msg "Writing boot loader to the SPI flash..." 187 188 DD if=$BOOTLOADER_FILE of=$MTD_DEV_FILE 189 if [ $? -ne 0 ]; then 190 bad_msg "Failed writing boot loader to the SPI flash!" 191 bad_msg "If you reboot, your system might not boot anymore!" 192 bad_msg "Please, try re-installing mtd-utils package and retry!" 193 return 1; 194 fi 195 196 good_msg "...Done" 197 return 0; 198} 199 200function check_bootloader() { 201 good_msg "Checking boot loader in the SPI flash..." 202 203 local test_file="${BOOTLOADER_FILE}.test" 204 local size=$((`du -L $BOOTLOADER_FILE | cut -f1`*1024)) 205 206 DD if=$MTD_DEV_FILE of=$test_file bs=$size count=1 207 208 diff $BOOTLOADER_FILE $test_file > /dev/null 209 if [ $? -ne 0 ]; then 210 bad_msg "Boot loader check failed! Please retry the update procedure!" 211 return 1; 212 fi 213 214 rm -f $test_file 215 216 good_msg "...Done" 217 return 0; 218} 219 220function check_board() { 221 good_msg "Checking that board is CM-FX6 (Utilite)..." 222 local module=`hexdump -C $EEPROM_DEV | grep 00000080 | sed 's/.*|\(CM-FX6\).*/\1/g'` 223 if [ "$module" == "CM-FX6" ]; then 224 good_msg "...Done" 225 return 0; 226 fi; 227 228 bad_msg "This board is not a CM-FX6 (Utilite)!" 229 return 1; 230} 231 232function error_exit() { 233 bad_msg "Boot loader update failed!" 234 exit $1; 235} 236 237function env_set() { 238 local var=$1 239 local value=$2 240 241 fw_setenv $var "$value" 242 243 local match=`fw_printenv $var | grep -e "^$var=$value\$" | wc -l` 244 [ $match -eq 1 ] && return 0; 245 246 return 1; 247} 248 249function reset_environment() { 250 warn_msg "Resetting U-Boot environment will override any changes made to the environment!" 251 confirm "Reset U-Boot environment (recommended)?" 252 if [ $? -eq 1 ]; then 253 good_msg "U-boot environment will not be reset." 254 return 0; 255 fi 256 257 check_utility "fw_setenv" && check_utility "fw_printenv" 258 if [[ $? -ne 0 ]]; then 259 bad_msg "Cannot reset environment." 260 return 1; 261 fi 262 263 local bootcmd_new="env default -a && saveenv; reset" 264 env_set bootcmd "$bootcmd_new" && env_set bootdelay 0 265 if [[ $? -eq 0 ]]; then 266 good_msg "U-boot environment will be reset on restart." 267 return 0; 268 fi 269 270 bad_msg "U-Boot environment reset failed!" 271 return 1; 272} 273 274#main() 275echo -e "\n${UPDATER_BANNER}\n" 276 277check_utilities || error_exit 4; 278check_board || error_exit 3; 279find_bootloader_file || error_exit 1; 280check_spi_flash || error_exit 2; 281check_bootloader_versions || exit 0; 282 283warn_msg "Do not power off or reset your computer!!!" 284 285erase_spi_flash || error_exit 5; 286write_bootloader || error_exit 6; 287check_bootloader || error_exit 7; 288 289good_msg "Boot loader update succeeded!\n" 290 291reset_environment || exit 0; 292 293good_msg "Done!\n" 294