k3-bootswitch: Initial version for boot selection script
authorNikhil Devshatwar <nikhil.nd@ti.com>
Tue, 7 Apr 2020 07:14:18 +0000 (12:44 +0530)
committerNikhil Devshatwar <nikhil.nd@ti.com>
Tue, 7 Apr 2020 11:49:45 +0000 (17:19 +0530)
Add a bootswitch tool for J721e EVM which can
* Use DFU boot mode to select the boot mode of the EVM from
 command line.
* Mount the SD card and eMMC devices from board to the Linux PC

Commit the working binaries for mounting the storage devices
Also add minified SPL to do bootmode writes.

Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
k3-bootswitch/README.rst [new file with mode: 0644]
k3-bootswitch/bin/sysfw.itb [new file with mode: 0644]
k3-bootswitch/bin/tiboot3.bin [new file with mode: 0644]
k3-bootswitch/bin/tispl.bin [new file with mode: 0644]
k3-bootswitch/bin/u-boot.img [new file with mode: 0644]
k3-bootswitch/boot_select/spl.mmc [new file with mode: 0755]
k3-bootswitch/boot_select/spl.noboot [new file with mode: 0644]
k3-bootswitch/boot_select/spl.ospi [new file with mode: 0644]
k3-bootswitch/boot_select/spl.uart [new file with mode: 0644]
k3-bootswitch/dfu-boot.sh [new file with mode: 0755]

diff --git a/k3-bootswitch/README.rst b/k3-bootswitch/README.rst
new file mode 100644 (file)
index 0000000..1ae35cb
--- /dev/null
@@ -0,0 +1,90 @@
+K3-bootswitch tool
+==================
+
+This tool allows to boot the J7-EVM in any boot mode from command line.
+This is useful for controlling the board remotely for individual developers
+as well as test farm.
+
+Hardware setup
+--------------
+
+* Type-C cable should be connected from the board to the Linux PC
+* UART cable should be connected from the main_uart to Linux PC
+* Default switch settings should be for DFU boot mode
+* SW8 = 1000 0000    SW9 = 0010 0000    SW3 = 0101 00 1010
+* Power supply to the board should be connected via phidget USB relay
+
+Usage
+-----
+
+* Install dfu-util package on the Linux PC with
+    ``sudo apt-get install dfu-util``
+* To boot the board in MMC bootmode, run following
+    ``sudo ./dfu-util.sh --bootmode mmc``
+
+  Currently supported bootmodes are: **mmc, emmc, ospi, uart, noboot**
+
+* To mount the emmc from the board to the Linux PC, run following
+    ``sudo ./dfu-util.sh --mount 0``
+* To mount the SD card from the board to the Linux PC, run following
+    ``sudo ./dfu-util.sh --mount 1``
+
+
+Advantages
+----------
+
+* Allows to remotely control the board by eliminating need to physically
+  change the switch settings
+* Can be used for regular development flow, where it removes the need
+  to physically plug out the SD card for updating images.
+* Makes it very easy to partition, format and update contents of the
+  eMMC device.
+* Can be used for factory flashing of the OSPI/eMMC images using
+  automated scripts
+
+How it works
+------------
+The DFU bootmode allows to pass any custom bootloader to the board. By keeping
+the switch settings in DFU mode, board always waits for the Linux PC to send
+a bootloader. In J721E SoC, the BOOTMODE and MCU_BOOTMODE registers reflect the
+values of the boot switches at the cold boot. This register can be modified and
+the values written are retained through the warm reset. These two features
+allows to set the bootmode from the command line PC tool.
+
+In the **boot_select** directory of this tool, there are many files which act
+as the custom bootloader every time the board boots with DFU-boot mode.
+The custom bootloader does only two important things; First it overwrites the
+BOOTMODE and MCU_BOOTMODE registers to change to the desired boot mode and then
+it issues a soft reset to the SoC causing it to boot the second time with new
+bootmode.
+
+All of this happens very fast when run from a script that it does not add
+considerable amount of time for developer bootflow.
+
+The mount of SD card or eMMC is achieved using the u-boot's
+UMS (USB Mass Storage) feature. In this case, the tool sends a real R5 u-boot as
+bootloader, System firmware ITB, A72 u-boot images and then runs the ums command.
+Note that all the binaries are being sent from the Linux PC, so there is
+absolutely no dependency on the contents of SD card.
+
+
+Customization
+-------------
+
+Default setup assumes most common setup for J7EVM. In case you are using
+differnent mechanism, update the **dfu-boot.sh** script with following:
+
+* Update the **uart_dev** variable to reflect the correct tty device
+  for main uart. (The one where all u-boot/SBL/kernel logs appear)
+* Update the function **toggle_power** to use your custom method to toggle_power
+  remote power switch instead of the default phidget commands
+
+
+
+Limitatinos
+-----------
+
+* Do not use this mechanism to measure any boot time numbers
+* The bootloader images are specific to TI J7 EVM. Different images are required
+  to be able to mount the SD/eMMC from custom boards
+
diff --git a/k3-bootswitch/bin/sysfw.itb b/k3-bootswitch/bin/sysfw.itb
new file mode 100644 (file)
index 0000000..f97bd61
Binary files /dev/null and b/k3-bootswitch/bin/sysfw.itb differ
diff --git a/k3-bootswitch/bin/tiboot3.bin b/k3-bootswitch/bin/tiboot3.bin
new file mode 100644 (file)
index 0000000..8b8b133
Binary files /dev/null and b/k3-bootswitch/bin/tiboot3.bin differ
diff --git a/k3-bootswitch/bin/tispl.bin b/k3-bootswitch/bin/tispl.bin
new file mode 100644 (file)
index 0000000..fae3543
Binary files /dev/null and b/k3-bootswitch/bin/tispl.bin differ
diff --git a/k3-bootswitch/bin/u-boot.img b/k3-bootswitch/bin/u-boot.img
new file mode 100644 (file)
index 0000000..011462a
Binary files /dev/null and b/k3-bootswitch/bin/u-boot.img differ
diff --git a/k3-bootswitch/boot_select/spl.mmc b/k3-bootswitch/boot_select/spl.mmc
new file mode 100755 (executable)
index 0000000..552f417
Binary files /dev/null and b/k3-bootswitch/boot_select/spl.mmc differ
diff --git a/k3-bootswitch/boot_select/spl.noboot b/k3-bootswitch/boot_select/spl.noboot
new file mode 100644 (file)
index 0000000..8e1a67d
Binary files /dev/null and b/k3-bootswitch/boot_select/spl.noboot differ
diff --git a/k3-bootswitch/boot_select/spl.ospi b/k3-bootswitch/boot_select/spl.ospi
new file mode 100644 (file)
index 0000000..02ef1ef
Binary files /dev/null and b/k3-bootswitch/boot_select/spl.ospi differ
diff --git a/k3-bootswitch/boot_select/spl.uart b/k3-bootswitch/boot_select/spl.uart
new file mode 100644 (file)
index 0000000..6da0886
Binary files /dev/null and b/k3-bootswitch/boot_select/spl.uart differ
diff --git a/k3-bootswitch/dfu-boot.sh b/k3-bootswitch/dfu-boot.sh
new file mode 100755 (executable)
index 0000000..b82ed31
--- /dev/null
@@ -0,0 +1,124 @@
+#!/bin/bash
+# Utility script to select the bootmode from command line
+# Author: Nikhil Devshatwar
+
+SCRIPT=$(readlink -f $0)
+SCRIPTPATH=`dirname $SCRIPT`
+prefix=$SCRIPTPATH/bin
+boot_select=$SCRIPTPATH/boot_select
+user=`logname`
+
+UMS_part1=/dev/disk/by-id/usb-Linux_UMS_disk*part1
+UMS_part2=/dev/disk/by-id/usb-Linux_UMS_disk*part2
+
+# Customize this as required
+uart_dev=/dev/ttyUSB0
+dev=1
+
+usage()
+{
+       echo "Usage:"
+       echo "  dfu-boot.sh - Utility script to select bootmode and mount MMC to PC"
+       echo "  sudo ./dfu-boot.sh --mount DEV"
+       echo "      DEV: 1 for MMC, 0 for eMMC"
+       echo "  sudo ./dfu-boot.sh --bootmode MODE"
+       echo "      MODE: " `ls $boot_select/ | awk -F"." 'BEGIN{ORS=" "} { print $2 }'`
+}
+
+# Bootloader takes time to initialize
+# wait till then
+wait_till_ready() {
+msg=$1
+       for i in `seq 30`; do
+               dfu-util -l | grep "Found DFU" >/dev/null 2>&1
+               if [ $? -eq "0" ]; then
+                       >&2 echo "    >>>> dfu ready $msg after $i tries"
+                       return
+               fi
+               sleep 0.2
+       done
+       >&2 echo "    >>>> ERROR: Timeout waiting for dfu"
+       >&2 echo "    >>>>        Make sure to connect Type-C cable to EVM and host machine"
+       >&2 echo "    >>>>        Bootswitch settings fot DFU boot:"
+       >&2 echo "    SW8 = 1000 0000    SW9 = 0010 0000    SW3 = 0101 00 1010"
+       exit 1
+}
+
+# Use dfu to send all bootloaders till you get to the
+# A72 u-boot prompt
+boot_till_uboot() {
+       wait_till_ready "for tiboot3.bin"
+       2>&1 dfu-util -R -a bootloader -D $prefix/tiboot3.bin
+       wait_till_ready "for sysfw.itb"
+       2>&1 dfu-util -R -a sysfw.itb -D $prefix/sysfw.itb
+       wait_till_ready "for tispl.bin"
+       2>&1 dfu-util -R -a tispl.bin -D $prefix/tispl.bin
+       wait_till_ready "for u-boot.img"
+       2>&1 dfu-util -R -a u-boot.img -D $prefix/u-boot.img
+}
+
+# Detect and mount the partitions
+try_mount() {
+       for i in `seq 1 100`; do
+               echo "ums 0 mmc $1" > $uart_dev
+               sleep 0.1
+               if [ -b $UMS_part1 ] && [ -b $UMS_part2 ]; then
+                       mkdir -p /media/$user/UMS-boot
+                       mkdir -p /media/$user/UMS-rootfs
+                       mount $UMS_part1 /media/$user/UMS-boot
+                       mount $UMS_part2 /media/$user/UMS-rootfs
+                       echo "    >>>> Mounted partions at /media/$user/UMS-boot and /media/$user/UMS-rootfs"
+                       return
+               fi
+       done
+       >&2 echo "    >>>> ERROR: Could not find partitions $UMS_part1"
+       exit 1
+}
+
+toggle_power()
+{
+       echo "    >>>> Toggling phidget..."
+       (phidget-switch 0 0 && sleep 0.5 && phidget-switch 0 1 && sleep 0.1) >/dev/null 2>&1
+       if [ $? -ne 0 ]; then
+               echo -n "ERROR: phidget not found, Reboot manually and press enter.. "
+               read DUMMY
+       fi
+}
+
+# Main script starts from here
+if [ `whoami` != "root" ]; then
+       echo "This script should be called with sudo!!"
+       usage
+       exit 1
+fi
+
+if [ "$1" = "--mount" ]; then
+       if [ ! -z "$2" ]; then
+               dev=$2
+       fi
+       toggle_power
+       boot_till_uboot >/dev/null
+       try_mount $dev
+elif [ "$1" = "--bootmode" ]; then
+       if [ ! -z "$2" ]; then
+               bootmode=$2
+       fi
+       if [ ! -f $boot_select/spl.$bootmode ]; then
+               echo "Invalid bootmode $bootmode"
+               usage
+               exit 2
+       fi
+
+       toggle_power
+       wait_till_ready
+       echo "    >>>> Selecting bootmode: $bootmode"
+       dfu-util -R -a bootloader -D $boot_select/spl.$bootmode >/dev/null 2>&1
+       if [ $? -eq 0 ]; then
+               echo "    >>>> SUCCESS"
+       else
+               echo "    >>>> FAILED"
+       fi
+else
+       echo " Invalid usage"
+       usage
+fi