aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilosz Wasilewski <milosz.wasilewski@linaro.org>2019-01-09 12:47:04 +0000
committerMilosz Wasilewski <milosz.wasilewski@linaro.org>2019-01-09 12:47:04 +0000
commit6426fde4a468f9b6c779e054575261465eaa3d16 (patch)
tree8010342a2145e36963bd5509101e3e6fa2565286
initial commit
Signed-off-by: Milosz Wasilewski <milosz.wasilewski@linaro.org>
-rw-r--r--README12
-rwxr-xr-xserial-boot.pl441
-rwxr-xr-xserial-download94
-rwxr-xr-xu-boot-recovery.sh184
-rw-r--r--u-boot-recovery.yaml26
-rw-r--r--u-boot-spl.binbin0 -> 79754 bytes
-rwxr-xr-xu-boot_fastboot.expect27
7 files changed, 784 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..6b524c1
--- /dev/null
+++ b/README
@@ -0,0 +1,12 @@
+Scripts for sending u-boot to TI boards over serial connection.
+
+Settings for GPEVM X15 board (AM57xx):
+ - J3: 1-2 closed
+ - J4: 1-2 closed
+ - J6: 1-2 closed
+
+In addition to the above settings, in order to prevent board
+powering down, J5 has to be closed before powering board up.
+
+Serial cable has to be connected. When updating u-boot in eMMC
+micro USB cable also has to be connected.
diff --git a/serial-boot.pl b/serial-boot.pl
new file mode 100755
index 0000000..97d34ce
--- /dev/null
+++ b/serial-boot.pl
@@ -0,0 +1,441 @@
+#!/usr/bin/perl
+#####################################################################
+# serial-boot.pl
+#
+# OMAP Flashing Alternative perl script
+# Serial module usage copied from http://ttime.no/dev.shtml
+#
+# Copyright (C) 2007 Texas Instruments, Inc.
+#
+# This package is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+# WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+#
+# INSTALLATION NOTES:
+# -------------------
+# WIN32:
+# This package depends on Win32::SerialPort if using windows
+# Download from http://www.bribes.org/perl/ppm/
+# PPD file and tgz to c:\perl, open a cmd and cd c:\perl
+# run ppm install Win32-SerialPort.ppd
+#
+# Linux/Other OS:
+# This package depends on Device::SerialPort if using any other OS.
+# Download this using cpan -> cpan install Device::SerialPort
+#
+# The perl script by itself requires only r/w permission to serial port
+#
+# History
+# -------
+# 0.01 2007-11-08 Nishanth Menon Created initial version
+# 0.02 2013-08-07 Minal Shah Reading 69-bytes ASIC Id instead of 58-bytes
+# Updated printing the ASIC Id in hex
+# Changed name of this script file from
+# omap_flash.pl to serial-boot.pl
+#####################################################################
+use strict;
+use File::stat;
+use Getopt::Std;
+use IO::Handle;
+use Time::HiRes qw(usleep);
+
+################# MAIN ##############################################
+# get options
+my %options = ();
+getopt( "tpsd", \%options );
+
+my $portId = "$options{p}";
+my $second_file = "$options{s}";
+
+my $max_timeout = "$options{t}";
+my $debug = "$options{d}";
+
+#portId should be number only..
+#if ( ( ( $portId == '' ) && ( "$portId" != "0" ) )
+# || ( "$portId" =~ /[^0-9]/ ) )
+#{
+# print "'$portId' port is invalid\n";
+# help_message();
+# exit(1);
+#}
+
+#debug should be 0 or 1
+if ( ( "$debug" != '' ) && ( "$debug" != "0" ) && ( "$debug" != "1" ) ) {
+ print "'$debug' debug is invalid\n";
+ help_message();
+ exit(1);
+}
+if ( "$debug" == '' ) {
+ $debug = 0;
+}
+if ( ( "$max_timeout" =~ /[^0-9]/ ) ) {
+ print "'$portId' Timeout Period is invalid\n";
+ help_message();
+ exit(1);
+}
+if ( !$max_timeout ) {
+ $max_timeout = 30;
+}
+
+if ( ( !$second_file ) || ( !file_size($second_file) ) ) {
+ print "MLO file '$second_file' is invalid\n";
+ help_message();
+ exit(1);
+}
+
+#my $port = ( $^O eq 'MSWin32' ? "COM$portId" : "/dev/ttyS$portId" );
+my $port = $portId;
+
+STDOUT->autoflush(1);
+my $chunk_count = 0;
+
+# open the port
+my $handler = openPort($port, 'even') || die "could not open port $port:$!\n";
+
+####################################################################
+
+############ DOWNLOAD 2ND FILE ALONE CONNECT WITH CSST ############
+
+##### FORMAT MY FILE SIZE
+my $file_size = file_size($second_file);
+my $file_bytes = pack( "L", $file_size );
+my $prefix_bytes = pack( "L", 0xF0030002 );
+my $string_bytes = "$prefix_bytes" . "$file_bytes";
+if (1) {
+#$debug) {
+ print "BYTES=$file_size file_bytes="
+ . unpack( "H*", $file_bytes )
+ . " prefix_bytes="
+ . unpack( "H*", $prefix_bytes )
+ . " string bytes="
+ . unpack( "H*", $string_bytes ) . "\n";
+}
+
+print "----Please reset the Board NOW (timeout=$max_timeout sec)----\n";
+
+# Read the 69 bytes of ASIC ID
+read_asicID( $handler, 69 )
+ || die "Timedout while waiting for read asic id ($max_timeout sec).";
+
+print "Board Detected\n";
+
+#Send File Size
+writePort( $handler, $string_bytes ) || die "Unable To send File Size";
+
+# Send the file
+send_file( $handler, $second_file ) || die "Could Not Send $second_file File";
+
+print "\n$second_file file download completed\n";
+
+#$debug = 1;
+#read_text( $handler, 200 );
+
+closePort($handler);
+
+my $handler = openPort($port, 'none') || die "could not open port $port:$!\n";
+read_text( $handler, 300 ) || die "\nUART boot message not found\n";
+print "\nUART Ymodem download has started on target\n";
+closePort($handler);
+
+exit(0);
+
+###################################################################
+######## HELPERS ###########
+###################################################################
+
+###################################################################
+sub help_message() {
+###################################################################
+ print "serial-boot.pl: Flashing Utility\n"
+ . "Syntax:\n"
+ . "serial-boot.pl -p <device> -s <second_file> [-d <dbg_lvl>] [-t <timeout>]\n"
+ . " port - Port ID as a device (i.e. /dev/ttyS0 || COM1)\n"
+ . " second_file - MLO File or the inital software\n"
+ . " dbg_lvl - Debug Level 0-silent, 1-verbose (optional)\n"
+ . " timeout - timeout period in seconds (optional)\n";
+}
+
+############## OMAP/FILE FUNCTIONS ###############################
+
+##################################################################
+sub read_asicID() {
+##################################################################
+ my ( $handler, $asic_id_length ) = @_;
+ my $char_count = 0;
+ my $timer = 0;
+
+ my $string_in_hex;
+
+ do {
+ my ( $count_in, $string_in ) = $handler->read(1);
+ $string_in_hex = unpack( "H*", $string_in );
+ if ( $count_in > 0 ) {
+ $char_count++;
+ if ($debug) {
+ print "$string_in_hex\t";
+ }
+
+ # reset the timer
+ $timer = 0;
+ }
+ else {
+ $timer++;
+
+ #r/w const timeout is in terms of 10 ms
+ return 0 if ( $timer > ( $max_timeout * 100 ) );
+ }
+ } while ( $char_count < $asic_id_length );
+ print "\n";
+ return 1;
+}
+
+##################################################################
+sub read_text() {
+##################################################################
+ my ( $handler, $asic_id_length ) = @_;
+ my $char_count = 0;
+ my $timer = 0;
+ my $pattern = 'Trying to boot from UART';
+ my $pattern_idx = 0;
+
+ my $string_in_hex;
+
+ do {
+ my ( $count_in, $string_in ) = $handler->read(1);
+ $string_in_hex = unpack( "H*", $string_in );
+ if ( $count_in > 0 ) {
+ $char_count++;
+ #print "$string_in_hex ($string_in)\t";
+ print "$string_in";
+
+ if ( $string_in eq substr($pattern, $pattern_idx, 1) ) {
+ $pattern_idx++;
+ print "*";
+ if ( $pattern_idx >= length($pattern) ) {
+ return 1;
+ }
+ }
+ else {
+ $pattern_idx = 0;
+ }
+
+ # reset the timer
+ $timer = 0;
+ }
+ else {
+ $timer++;
+
+ #r/w const timeout is in terms of 10 ms
+ return 0 if ( $timer > ( $max_timeout * 100 ) );
+ }
+ } while ( $char_count < $asic_id_length );
+ print "\n";
+ return 0;
+}
+
+##################################################################
+sub file_size() {
+##################################################################
+ my ($file) = @_;
+ my $FILE = stat("$file");
+ if ( !$FILE ) {
+ return 0;
+ }
+ my $filesize = $FILE->size;
+
+ return "$filesize";
+}
+
+##################################################################
+sub send_file() {
+##################################################################
+ my ( $handler, $file ) = @_;
+ my $buffer;
+ my $len;
+ my $total_len = 0;
+ my $chunk_size = 2048;
+ open FILE, "<$file" or die "can't open $file $!";
+ binmode(FILE);
+ do {
+ $len = read( FILE, $buffer, $chunk_size );
+ if ($len) {
+ my $ret = writePort( $handler, $buffer );
+ if ( !$ret ) {
+ print "write port failed: $chunk_size $total_len $ret\n";
+ return 0;
+ }
+ }
+ $total_len += $chunk_size;
+ } while ( $len != 0 );
+ close(FILE);
+ return 1;
+}
+
+############# SERIAL PORT FUNCTIONS ##############################
+
+##################################################################
+sub openPort {
+##################################################################
+ my ($port, $parity) = @_;
+
+ my $quiet;
+ my $ob = undef;
+ if ( $^O eq 'MSWin32' ) {
+ require Win32::SerialPort;
+ Win32::SerialPort->import();
+ $ob = Win32::SerialPort->new( "\\\\.\\$port", $quiet );
+ }
+ else {
+ eval ' require Device::SerialPort; ';
+ if ( !$@ ) {
+ require Device::SerialPort;
+ Device::SerialPort->import();
+ $ob = Device::SerialPort->new( "$port", $quiet );
+ }
+ else {
+ print "Unable to find required Perl module Device::SerialPort\n";
+ }
+ }
+ my $ok = 0;
+
+ if ($ob) {
+ # OMAP PARAMETERS
+ my $omap_baud = 115200;
+ my $omap_partiy = $parity;
+ my $omap_data_bits = 8;
+ my $omap_stop_bits = 1;
+ my $omap_handshake = 'none';
+
+ #$ob->debug(0);
+ my @baud_opt = $ob->baudrate;
+ my @parity_opt = $ob->parity;
+ my @data_opt = $ob->databits;
+ my @stop_opt = $ob->stopbits;
+ my @hshake_opt = $ob->handshake;
+
+ foreach $a (@baud_opt) {
+ if ( $a == $omap_baud ) {
+ $ok++;
+ last;
+ }
+ }
+ foreach $a (@parity_opt) {
+ if ( $a eq $omap_partiy ) {
+ $ok++;
+ last;
+ }
+ }
+ foreach $a (@data_opt) {
+ if ( $a == $omap_data_bits ) {
+ $ok++;
+ last;
+ }
+ }
+ foreach $a (@stop_opt) {
+ if ( $a == $omap_stop_bits ) {
+ $ok++;
+ last;
+ }
+ }
+ foreach $a (@hshake_opt) {
+ if ( $a eq $omap_handshake ) {
+ $ok++;
+ last;
+ }
+ }
+ $ok++ if ( $ob->is_rs232 );
+
+ $ob->baudrate($omap_baud);
+ $ob->parity($omap_partiy);
+ $ob->databits($omap_data_bits);
+ $ob->stopbits($omap_stop_bits);
+ $ob->handshake($omap_handshake);
+ $ob->buffers( 1024 * 10, 1024 * 30 );
+ $ob->read_interval(0) if ( $^O eq 'MSWin32' );
+ $ob->read_char_time(0);
+ $ob->read_const_time(10);
+ $ob->write_char_time(0) if ( $^O eq 'MSWin32' );
+ $ob->write_const_time(0) if ( $^O eq 'MSWin32' );
+ $ob->write_drain if ( $^O ne 'MSWin32' ); # drain if not win
+ $ok++ if ( $ob->write_settings );
+
+ $ob->close if ( $ok < 6 );
+ }
+ undef $ob if ( $ok < 6 );
+ return $ob;
+}
+
+##################################################################
+sub closePort {
+##################################################################
+ my ($ob) = @_;
+ if ($ob) {
+ $ob->close;
+ undef $ob;
+ }
+}
+
+##################################################################
+sub readPort {
+##################################################################
+ my ($ob) = @_;
+ return -1 unless ($ob);
+ my ( $count_in, $string_in ) = $ob->read(1);
+ return ( $count_in > 0 ? ord($string_in) : -1 );
+}
+##################################################################
+sub flush_read {
+##################################################################
+ my ($port) = @_;
+ my $count_in;
+ my $string_in;
+ do {
+ ( $count_in, $string_in ) = $port->read(1);
+ } while ( $count_in != 0 );
+}
+##################################################################
+sub writePort {
+##################################################################
+ my ( $ob, $wbuf ) = @_;
+ if ( !$ob ) {
+ print "invalid ob\n";
+ return 0;
+ }
+ my $n = $ob->write("$wbuf");
+ my $timer_count = 4000; # 4000 ms delay
+ my $done = 0;
+ my $count_out;
+
+ $chunk_count++;
+
+ print "."; #Show some life
+ # Wait to ensure that the data did flow out
+ # This is required for Linux esp since it does a background operation
+ do {
+ ( $done, $count_out ) = $ob->write_done(0);
+ if ($debug) {
+ print "?";
+ }
+ $timer_count--;
+ if (!$done ) {
+ usleep(10000);
+ }
+ if ( !$timer_count ) {
+ print "\nTimedout waiting for draining";
+ return 0;
+ }
+ } while ( !$done );
+ if ($debug) {
+ my ( $done, $count_out ) = $ob->write_done(0);
+ print( "\n-->$chunk_count $n " . length($wbuf) . " $done $count_out\n" );
+ print "write failed\n" unless ($n);
+ warn "write incomplete\n" if ( $n != length($wbuf) );
+ }
+ return ( $n == length($wbuf) );
+}
+
+########### END OF FILE ########################################
diff --git a/serial-download b/serial-download
new file mode 100755
index 0000000..c771b92
--- /dev/null
+++ b/serial-download
@@ -0,0 +1,94 @@
+#!/bin/bash
+
+MY_DIR=$(dirname $0)
+
+abort() {
+ echo "$@"
+ exit 2
+}
+
+if [ -z "$1" ]; then
+ echo "usage: $0 TTY [dir]"
+ echo "where:"
+ echo " TTY is serial device connected to the board (i.e. /dev/ttyUSB0"
+ echo " dir is the directory where the u-boot files come from"
+ echo " will look for dir/u-boot.img "
+ echo " and either dir/u-boot-spl.bin or dir/spl/u-boot-spl.bin"
+ echo " if dir is not specified the current directory is used"
+ echo "Additionally ROM_UART_BOOT env variable is used to decide which"
+ echo "method to use for sending u-boot-spl to the board. Available options:"
+ echo " asic_id_raw - suitable for AM57xx (default)"
+ echo " xmodem - suitable for AM335x"
+ exit 1
+fi
+
+DUT_TTY=$1
+
+if [ -z "$ROM_UART_BOOT" ]; then
+ ROM_UART_BOOT=asic_id_raw
+fi
+
+if [ -n "$2" ]; then
+ U_BOOT_DIR=$2
+else
+ U_BOOT_DIR=.
+fi
+
+FILE2=$U_BOOT_DIR/u-boot.img
+
+if [ ! -f $FILE2 ]; then
+ echo "Can't find $FILE2"
+ exit 1
+fi
+
+FILE1=$U_BOOT_DIR/u-boot-spl.bin
+
+if [ ! -f $FILE1 ]; then
+ FILE1=$U_BOOT_DIR/spl/u-boot-spl.bin
+ if [ ! -f $FILE1 ]; then
+ echo "Can't find $FILE1"
+ exit 1
+ fi
+fi
+
+# SPL download for AM335x
+spl_download_xmodem() {
+ stty -F $DUT_TTY 115200 cs8 -parenb -cstopb
+ sx $FILE1 <$DUT_TTY >$DUT_TTY || abort "SPL download failed"
+}
+
+# SPL download for AM57x
+spl_download_asic_id_raw() {
+ stty -F $DUT_TTY 115200 cs8 -parenb -cstopb
+ $MY_DIR/serial-boot.pl -p $DUT_TTY -d0 -t40 -s $FILE1 || abort "SPL download failed"
+}
+
+# download u-boot image to SPL
+uboot_download() {
+ sx -kb --ymodem $FILE2 <$DUT_TTY >$DUT_TTY || abort "U-boot download failed"
+}
+
+# stop U-boot autoboot using expect
+stop_auto_boot() {
+ { cat <<- EOF
+ send_user "waiting for U-boot autoboot prompt\n"
+ spawn -noecho -open [open $DUT_TTY w+]
+ expect "Hit any key"
+ send " \r"
+ send_user "\nstopped auto boot\n"
+ sleep 1
+ send "\r"
+ sleep 0.1
+ expect "=>"
+EOF
+ } | expect -
+}
+
+if [ x"$ROM_UART_BOOT" == x"asic_id_raw" ]; then
+ spl_download_asic_id_raw
+else
+ spl_download_xmodem
+fi
+
+uboot_download
+stop_auto_boot
diff --git a/u-boot-recovery.sh b/u-boot-recovery.sh
new file mode 100755
index 0000000..2555897
--- /dev/null
+++ b/u-boot-recovery.sh
@@ -0,0 +1,184 @@
+#!/bin/sh
+
+set -u
+
+check_root() {
+ if [ "$(id -ru)" -eq 0 ]; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+error_fatal() {
+ # shellcheck disable=SC2039
+ local msg="$1"
+ [ -z "${msg}" ] && msg="Unknown error"
+ if which lava-test-raise;then
+ lava-test-raise "${msg}"
+ else
+ printf "FATAL ERROR: %s\n" "${msg}" >&2
+ fi
+ exit 1
+}
+
+error_msg() {
+ # shellcheck disable=SC2039
+ local msg="$1"
+ [ -z "${msg}" ] && msg="Unknown error"
+ printf "ERROR: %s\n" "${msg}" >&2
+ exit 1
+}
+
+info_msg() {
+ # shellcheck disable=SC2039
+ local msg="$1"
+ [ -z "${msg}" ] && msg="Unknown info"
+ printf "INFO: %s\n" "${msg}" >&1
+}
+
+report_pass() {
+ [ "$#" -ne 1 ] && error_msg "Usage: report_pass test_case"
+ # shellcheck disable=SC2039
+ local test_case="$1"
+ echo "${test_case} pass" | tee -a "${RESULT_FILE}"
+}
+
+dist_name() {
+ if [ -f /etc/os-release ]; then
+ # shellcheck disable=SC1091
+ dist=$(. /etc/os-release && echo "${ID}")
+ elif [ -x /usr/bin/lsb_release ]; then
+ dist="$(lsb_release -si)"
+ elif [ -f /etc/lsb-release ]; then
+ # shellcheck disable=SC1091
+ dist="$(. /etc/lsb-release && echo "${DISTRIB_ID}")"
+ elif [ -f /etc/debian_version ]; then
+ dist="debian"
+ elif [ -f /etc/fedora-release ]; then
+ dist="fedora"
+ elif [ -f /etc/centos-release ]; then
+ dist="centos"
+ else
+ dist="unknown"
+ warn_msg "Unsupported distro: cannot determine distribution name"
+ fi
+
+ # convert dist to lower case
+ dist=$(echo ${dist} | tr '[:upper:]' '[:lower:]')
+ case "${dist}" in
+ rpb*) dist="oe-rpb" ;;
+ esac
+}
+
+install_deps() {
+ # shellcheck disable=SC2039
+ local pkgs="$1"
+ [ -z "${pkgs}" ] && error_msg "Usage: install_deps pkgs"
+ # skip_install parmater is optional.
+ # shellcheck disable=SC2039
+ local skip_install="${2:-false}"
+
+ if [ "${skip_install}" = "True" ] || [ "${skip_install}" = "true" ]; then
+ info_msg "install_deps skipped"
+ else
+ ! check_root && \
+ error_msg "About to install packages, please run this script as root."
+ info_msg "Installing ${pkgs}"
+ dist_name
+ case "${dist}" in
+ debian|ubuntu)
+ last_apt_time=/tmp/apt-get-updated.last
+ apt_cache_time=21600 # 6 hours
+ # Only run apt-get update if it hasn't been run in $apt_cache_time seconds
+ if [ ! -e ${last_apt_time} ] || \
+ [ "$(stat --format=%Y ${last_apt_time})" -lt $(( $(date +%s) - apt_cache_time )) ]; then
+ DEBIAN_FRONTEND=noninteractive apt-get update -q -y && touch ${last_apt_time}
+ fi
+ # shellcheck disable=SC2086
+ DEBIAN_FRONTEND=noninteractive apt-get install -q -y ${pkgs}
+ ;;
+ centos)
+ # shellcheck disable=SC2086
+ yum -e 0 -y install ${pkgs}
+ ;;
+ fedora)
+ # shellcheck disable=SC2086
+ dnf -e 0 -y install ${pkgs}
+ ;;
+ *)
+ warn_msg "Unsupported distro: ${dist}! Package installation skipped."
+ ;;
+ esac
+ # shellcheck disable=SC2181
+ if [ $? -ne 0 ]; then
+ error_msg "Failed to install dependencies, exiting..."
+ fi
+ fi
+}
+
+create_out_dir() {
+ [ -z "$1" ] && error_msg "Usage: create_out_dir output_dir"
+ # shellcheck disable=SC2039
+ local OUTPUT=$1
+ [ -d "${OUTPUT}" ] &&
+ mv "${OUTPUT}" "${OUTPUT}_$(date -r "${OUTPUT}" +%Y%m%d%H%M%S)"
+ mkdir -p "${OUTPUT}"
+ [ -d "${OUTPUT}" ] || error_msg "Could not create output directory ${OUTPUT}"
+}
+
+OUTPUT="$(pwd)/output"
+RESULT_FILE="${OUTPUT}/result.txt"
+export RESULT_FILE
+IMAGE="aarch64/ubuntu"
+
+usage() {
+ echo "$0 [-d <directory with u-boot binaries>] [-u <u-boot.img>] [-m <MLO>]" 1>&2
+ exit 1
+}
+
+while getopts "u:m:d:h" o; do
+ case "$o" in
+ u) UBOOT_IMAGE="${OPTARG}" ;;
+ m) MLO_IMAGE="${OPTARG}" ;;
+ d) UBOOT_DIR="${OPTARG}" ;;
+ h|*) usage ;;
+ esac
+done
+
+! check_root && error_msg "You need to be root to run this script."
+create_out_dir "${OUTPUT}"
+
+install() {
+ dist_name
+ # shellcheck disable=SC2154
+ case "${dist}" in
+ debian|ubuntu)
+ install_deps lrzsz libdevice-serialport-perl expect fastboot
+ ;;
+ *)
+ warn_msg "No package installation support on ${dist}"
+ ;;
+ esac
+}
+
+if [ ! -d "${UBOOT_DIR}" ]; then
+ error_fatal "${UBOOT_DIR} doesn't exist"
+fi
+
+TTY=$(find /dev/ -xdev -name "ttyUSB*" -type c -print -quit)
+
+if [ "${UBOOT_DIR}" != "${PWD}" ]; then
+ cp "${UBOOT_DIR}/${UBOOT_IMAGE}" .
+fi
+./serial-download "${TTY}" || error_fatal "recovery failure"
+report_pass "download_uboot_to_memory"
+./u-boot_fastboot.expect "${TTY}"
+report_pass "start_fastboot"
+fastboot devices
+fastboot oem format || error_fatal "oem format failed"
+report_pass "format_emmc"
+fastboot flash xloader "${UBOOT_DIR}/${MLO_IMAGE}" || error_fatal "xloader flash failed"
+report_pass "flash_xloader"
+fastboot flash bootloader "${UBOOT_DIR}/${MLO_IMAGE}" || error_fatal "bootloader flash failed"
+report_pass "flash_bootloader"
diff --git a/u-boot-recovery.yaml b/u-boot-recovery.yaml
new file mode 100644
index 0000000..8ff1806
--- /dev/null
+++ b/u-boot-recovery.yaml
@@ -0,0 +1,26 @@
+metadata:
+ name: u-boot-recovery
+ format: "Lava-Test-Shell Test Definition 1.0"
+ description: "u-boot recovery for TI boards. u-boot is loaded
+ from serial device."
+ maintainer:
+ - milosz.wasilewski@linaro.org
+ os:
+ - debian
+ - ubuntu
+ scope:
+ - functional
+ environment:
+ - lava-test-shell
+ devices:
+ - x15-bl
+
+params:
+ # u-boot image
+ UBOOT_IMAGE: "/lava-lxc/u-boot.img"
+ UBOOT_MLO: "/lava-lxc/MLO"
+
+run:
+ steps:
+ - ./u-boot-recovery.sh -u "${UBOOT_IMAGE}" -m "${UBOOT_MLO}" -d "/lava-lxc/"
+ - ../../utils/send-to-lava.sh ./output/result.txt
diff --git a/u-boot-spl.bin b/u-boot-spl.bin
new file mode 100644
index 0000000..15c8873
--- /dev/null
+++ b/u-boot-spl.bin
Binary files differ
diff --git a/u-boot_fastboot.expect b/u-boot_fastboot.expect
new file mode 100755
index 0000000..141b7e4
--- /dev/null
+++ b/u-boot_fastboot.expect
@@ -0,0 +1,27 @@
+#!/usr/bin/expect
+set tty [lindex $argv 0]
+send_user "interact with u-boot, ctrl-C to exit\n"
+spawn -open [open $tty w+]
+send "\r"
+sleep 0.1
+expect "=>"
+sleep 0.1
+send "env default -f -a\r"
+sleep 0.1
+expect "=>"
+sleep 0.1
+send "setenv partitions \$partitions_android\r"
+sleep 0.1
+expect "=>"
+sleep 0.1
+send "env save\r"
+sleep 0.1
+expect "=>"
+sleep 0.1
+send "fastboot 1\r"
+expect {
+ timeout {
+ puts "Fastboot Running..."
+ exit
+ }
+}