From c4efb530cfad0bc0a970c2f5189216d47b889571 Mon Sep 17 00:00:00 2001 From: Piotr Dymacz Date: Sat, 17 Jun 2017 21:30:09 +0200 Subject: [PATCH] host_util: add helper script for U-Boot flashing over serial This script helps with flashing U-Boot image over serial line (kermit protocol, 'loadb' command) which can be useful on devices with only serial interface available. Script requires C-Kermit and includes some basic checks (start it without any argument to see short usage help). Tested on C-Kermit 9.0.302 Example run: $ host_util/u-boot-serial-flash bin/mr3020.bin - - - - - [INFO]: File to send: 'bin/mr3020.bin' [INFO]: Serial device: '/dev/ttyUSB0' [INFO]: Baudrate: '115200' [INFO]: CLI prompt: 'u-boot> ' [INFO]: Wait string: 'Hit any key to stop booting' [INFO]: File size: '125952' [INFO]: Backup size: '131072' (rounded up to 64K block) [INFO]: Erase size: '0x020000' (hex) >>>>>> Do you want to continue (type 'y' to continue)? y [INFO]: Power on device now... [INFO]: Backuping data in RAM... [INFO]: Sending command: 'cp.b 0x9f000000 0x80800000 0x020000' [INFO]: Sending command: 'loadb 0x80800000' [INFO]: Sending selected file to RAM at 0x80800000 (this may take a while)... >>>>>> File sent successfully, do you want to write it to FLASH (type 'y' to continue)? y [INFO]: Erasing FLASH, copying data from RAM to FLASH... [INFO]: Sending command: 'erase 0x9f000000 +0x020000 && cp.b 0x80800000 0x9f000000 0x020000' [ OK ]: Done! >>>>>> Reset board now or switch to U-Boot CLI (type 'y' for reset)? y [INFO]: Resetting the board... [INFO]: Sending command: 'reset' [ OK ]: U-Boot flashed successfully! >>>>>> Exit now or switch to U-Boot CLI (type 'y' to exit)? y --- host_util/u-boot-serial-flash | 277 ++++++++++++++++++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100755 host_util/u-boot-serial-flash diff --git a/host_util/u-boot-serial-flash b/host_util/u-boot-serial-flash new file mode 100755 index 0000000..1f7db8b --- /dev/null +++ b/host_util/u-boot-serial-flash @@ -0,0 +1,277 @@ +#!/usr/bin/kermit + + +# Disable input echo +# (change this to 'on' for debug) +set input echo off + +assign prog "\fbasename(\%0)" +assign dev "/dev/ttyUSB0" +assign brate "115200" +assign flaaddr "0x9f000000" +assign ramaddr "0x80800000" +assign waitstr "Hit any key to stop booting" +assign stopstr " \10" +assign prompt "u-boot> " +assign skipopt "(use '-' to skip and use default)" + +assign filesz 0 +assign bckpsz 0 +assign eraseszhex 0x0 + +# ============= +# Custom macros +# ============= +def usage { + echo "Usage:" + echo " \m(prog) [dev] [brate] [waitstr] [stopstr] [prompt]" + echo + echo "Arguments:" + echo " file image file to send (required)" + echo " dev serial device (optional, default: '\m(dev)')" + echo " brate baudrate (optional, default: '\m(brate)')" + echo " waitstr string to wait for before sending 'stopstr' (optional, default: '\m(waitstr)')" + echo " stopstr auto boot interrupt string (optional, default: '')" + echo " for special characters, use \\x, where x is ASCII code (e.g. for use \\27)" + echo " prompt command line prompt string in U-Boot (optional, default: '\m(prompt)')" + echo + echo "Skip optional argument with '-', example:" + echo " \m(prog) u-boot.bin - - - 'tpl' 'ar7240>'" + echo +} + +def echo_err { + if defined \%1 echo "[ERRO]: \%1!" + exit 1 +} + +def echo_info { + if defined \%1 echo "[INFO]: \%1" +} + +def echo_ok { + if defined \%1 echo "[ OK ]: \%1" +} + +def askuser { + echo + ask \%m ">>>>>> \%1 (type 'y' to continue)? " + if not defined \%m exit 0 + else if not equal \%m "y" exit 0 + echo +} + +def argsummary { + echo_info "File to send: '\m(file)'" + echo_info "Serial device: '\m(dev)'" + echo_info "Baudrate: '\m(brate)'" + echo_info "CLI prompt: '\m(prompt)'" + echo_info "Wait string: '\m(waitstr)'" + + echo + + echo_info "File size: '\m(filesz)'" + echo_info "Backup size: '\m(bckpsz)' (rounded up to 64K block)" + echo_info "Erase size: '\m(eraseszhex)' (hex)" + + askuser "Do you want to continue" +} + +def waitpromt { + assign tout 3 + if defined \%1 assign tout \%1 + + input \m(tout) "\m(prompt)" + if fail echo_err "Timeout occurred waiting for prompt string" +} + +def interrupt { + input 15 "\m(waitstr)" + if fail echo_err "Timeout occurred waiting for wait string" + + out "\m(stopstr)" + waitpromt +} + +def cmdtest { + lineout "?" + + input 2 "\fpattern(\%1*-*\10)" + if fail echo_err "Command '\%1' is not available" + + waitpromt +} + +def checkretval { + lineout "echo $?" + + input 3 "\fpattern(0*\10)" + if fail echo_err "\%1" + + waitpromt +} + +def sendcmd { + echo_info "Sending command: '\%1'" + lineout "\%1" +} + +# ===================== +# Execution begins here +# ===================== + +# We need 7 args +if < \v(argc) 7 { + usage + exit 1 +} + +# File to send +if not defined \%1 { + usage + echo_err "U-Boot image file not specified" +} +assign file \%1 + +if not exist \m(file) { + usage + echo_err "Specified file: '\m(file)' does not exist" +} + +assign filesz \fsize(\m(file)) +if fail { + usage + echo_err "Incorrect file specified: '\m(file)'" +} + +assign i \Feval(\m(filesz) / 65536) +assign bckpsz \Feval(\m(i) * 65536) + +if > \m(filesz) \m(bckpsz) { + assign i \Feval((\m(filesz) / 65536) + 1) + assign bckpsz \Feval(\m(i) * 65536) +} + +assign eraseszhex "0x\fn2hex(\m(bckpsz))" +if fail echo_err "Could not convert erase size to hex" + +# Serial device +if not defined \%2 { + usage + echo_err "Serial device not specified \m(skipopt)" +} else if not equal \%2 "-" assign dev \%2 + +set line \m(dev) +if fail { + usage + echo_err "Incorrect serial device specified: '\m(dev)'" +} + +# Baudrate +if not defined \%3 { + usage + echo_err "Baudrate not specified \m(skipopt)" +} else if not equal \%3 "-" assign brate \%3 + +set speed \m(brate) +if fail { + usage + echo_err "Incorrect baudrate specified: '\m(brate)'" +} + +# Wait for string +if not defined \%4 { + usage + echo_err "Wait string not specified \m(skipopt)" +} else if not equal \%4 "-" assign waitstr \%4 + +# Stop string +if not defined \%5 { + usage + echo_err "Stop string not specified \m(skipopt)" +} else if not equal \%5 "-" assign stopstr \%5 + +# CLI prompt +if not defined \%6 { + usage + echo_err "U-Boot CLI prompt not specified \m(skipopt)" +} else if not equal \%6 "-" assign prompt \%6 + +argsummary + +# Default configuration +robust +set serial 8n1 +set file type bin +set carrier-watch off +set prefixing all +set flow-control none +set handshake none +set modem none + +set window 10 +set send packet-length 1000 + +echo_info "Power on device now..." + +interrupt + +# Check if we have 'echo' and 'loadb' commands +cmdtest "echo" +cmdtest "loadb" + +# Backup existing image in RAM (round up to 64K block) +echo_info "Backuping data in RAM..." +sendcmd "cp.b \m(flaaddr) \m(ramaddr) \m(eraseszhex)" + +waitpromt 5 +checkretval "Could not backup data in RAM" + +# Start loadb +sendcmd "loadb \m(ramaddr)" +input 3 "\fpattern(Ready for binary*download*\10)" +if fail echo_err "Timeout occurred waiting for binary download ready" + +# Send file to RAM +echo_info "Sending selected file to RAM at \m(ramaddr) (this may take a while)..." +send /quiet "\m(file)" + +if = \v(status) 1 echo_err "File send failed" + +waitpromt +checkretval "File send failed" + +askuser "File sent successfully, do you want to write it to FLASH" + +# Erase flash and copy data from RAM to flash +echo_info "Erasing FLASH, copying data from RAM to FLASH..." +sendcmd "erase \m(flaaddr) +\m(eraseszhex) && cp.b \m(ramaddr) \m(flaaddr) \m(eraseszhex)" + +waitpromt 15 +checkretval "Erase/copy commands failed, do not reset the board" +echo_ok "Done!" + +echo +ask \%m ">>>>>> Reset board now or switch to U-Boot CLI (type 'y' for reset)? " +if not defined \%m { + connect + quit +} else if not equal \%m "y" { + connect + quit +} else { + echo + # Reset board and check if it's alive + echo_info "Resetting the board..." + sendcmd "reset" +} + +interrupt +echo_ok "U-Boot flashed successfully!" + +echo +ask \%m ">>>>>> Exit now or switch to U-Boot CLI (type 'y' to exit)? " +if not defined \%m connect +else if not equal \%m "y" connect +else quit + +quit -- 2.25.1