SATA support for u-boot updates

I was wondering if there was a way to update an Apalis iMX6 SOMs over a SATA connection.

I have built the source code for u-boot by following

and am currently updating u-boot/kernel/fdt/rootfs using usb and u-boot commands:

run setupdate
run update

Is there an equivalent operation I can create and run that is similar to

setsdupdate= ...
setusbupdate=usb start && setenv interface usb; setenv drive 0; load ${interface} ${drive}:1 ${loadaddr} flash_blk.img && source ${loadaddr}
setethupdate= ...

but for a sata drive? I imagine updating from an internal sata drive could solve issues relating to user preemptively removing sd card, usb drive, and/or ethernet connection being dropped

My question being do you know what steps I need to take to setup updating from sata drive?



While I never used SATA for this I expect it to work nicely.

You need to initialize the SATA subsystem, after that you can load files from SATA the same way as you would from an MMC card. e.g. use ‘sata’ instead of ‘mmc’ in the part of the load command.

Apalis iMX6 # load
load - load binary file from a filesystem

load <interface> [<dev[:part]> [<addr> [<filename> [bytes [pos]]]]]
    - Load binary file 'filename' from partition 'part' on device
       type 'interface' instance 'dev' to address 'addr' in memory.
      'bytes' gives the size to load in bytes.
      If 'bytes' is 0 or omitted, the file is read until the end.
      'pos' gives the file byte position to start reading from.
      If 'pos' is 0 or omitted, the file is read from the start.

Apalis iMX6 # sata init
AHCI 0001.0300 32 slots 1 ports 3 Gbps 0x1 impl SATA mode
flags: ncq stag pm led clo only pmp pio slum part
SATA Device Info:
S/N: 50026B723C0BA821
Product model number: KINGSTON SMS200S330G
Firmware version: 507KC4
Capacity: 58626288 sectors

Apalis iMX6 # load sata 0:1 $loadaddr uImage
reading uImage
5071680 bytes read in 50 ms (96.7 MiB/s)



I have the same issue for my Apalis iMX6 module. SATA update works, but you need to make a few modification on some files.
First of all some words about my setup. I have a SSD with a big primary partition for data and a small extended partition for the update files. So my interface to the update partiton is “sata 0:5”. If you only have one partiton it will be “sata 0:1”.
Now lets start at the point you have build a new image, unpack it and get a project folder like “Apalis_iMX6_LinuxImageV2.6.1”.

We need a “flash_sata.img” file, so create a file called “flash_sata.scr” in the apalis-imx6_bin folder.

test -n ${interface} || setenv interface sata 0:5

setenv set_blkcnt 'setexpr blkcnt ${filesize} + 0x1ff && setexpr blkcnt ${blkcnt} / 0x200'
#workaround U-Boot counting in hex and split did in decimal
setenv incr_decimal 'setexpr filenum ${filenum} + 1; setexpr filenrlow ${filenum} % 0x10; test ${filenrlow} -eq "a" && setexpr filenum ${filenum} + 0x6; true'
setenv set_nextnum 'run incr_decimal; setexpr blkstart ${blkstart} + ${blkcnt}'

setenv check_1 'setenv conf_blk_offset 0x1fff; mmc read ${loadaddr} ${conf_blk_offset} 1'
setenv check_2 'setenv conf_blk_offset 0xfff; mmc read ${loadaddr} ${conf_blk_offset} 1'
setenv check_3 'setenv conf_blk_offset 0x7ff; mmc read ${loadaddr} ${conf_blk_offset} 1'
setenv check_configblock 'setexpr toradex_oui_addr ${loadaddr} + 8; mw.l ${kernel_addr_r} 0x002d1400; mmc dev 0 1; run check_1 || run check_2 || run check_3; cmp.b ${kernel_addr_r} ${toradex_oui_addr} 3'

setenv migrate_configblock 'run check_configblock; mmc dev 0 0 && mmc read ${loadaddr} 0x500 1 && cmp.b ${kernel_addr_r} ${toradex_oui_addr} 3 && mmc dev 0 1 && mmc write ${loadaddr} ${conf_blk_offset} 1'

setenv migrate_uboot_old 'load ${interface} ${loadaddr} ${board_name}/u-boot.imx${module_type} && run set_blkcnt && mmc dev 0 0 && mmc write ${loadaddr} 2 ${blkcnt}'
setenv migrate_uboot 'load ${interface} ${loadaddr} ${board_name}/u-boot.imx${module_type} && run set_blkcnt && mmc dev 0 1 && mmc write ${loadaddr} 2 ${blkcnt} && mmc bootbus 0 2 1 2 && mmc partconf 0 1 1 0'
[link text][1]
setenv cp_file_chunk 'load ${interface} ${loadaddr} ${board_name}/root.ext3-${filenum}; run set_blkcnt; mmc dev 0 0 && mmc write ${loadaddr} ${blkstart} ${blkcnt}'

setenv update_uboot 'load ${interface} ${loadaddr} ${board_name}/u-boot.imx${module_type} && run set_blkcnt && mmc dev 0 1 && mmc write ${loadaddr} 2 ${blkcnt} && updt_fuse && mmc bootbus 0 2 0 1 && mmc partconf 0 1 1 0 && mmc rst-function 0 1'
setenv update_uboot_it 'setenv module_type -it; run update_uboot'

setenv update_kernel 'load ${interface} ${loadaddr} ${board_name}/uImage && fatwrite mmc 0:1 ${loadaddr} uImage ${filesize}'

setenv update_fdt 'load ${interface} ${loadaddr} ${board_name}/${fdt_file} && fatwrite mmc 0:1 ${loadaddr} ${fdt_file} ${filesize}'

setenv update_configblock 'run check_configblock; load ${interface} ${loadaddr} ${board_name}/configblock.bin && mmc dev 0 1 && mmc write ${loadaddr} ${conf_blk_offset} 1'

setenv update_1 'load ${interface} ${loadaddr} ${board_name}/mbr.bin && mmc dev 0 0 && mmc write ${loadaddr} 0x0 0x1'
setenv update_2 'load ${interface} ${loadaddr} ${board_name}/boot.vfat && run set_blkcnt && mmc dev 0 0 && mmc write ${loadaddr} 0x2000 ${blkcnt}'
#do it in chunks like tftpboot
setenv update_3 'setenv filesize 4000000; setenv filenum 10; setenv blkstart a000; while test ${filesize} -eq "4000000"; do run cp_file_chunk; run set_nextnum; done; true'

setenv echo_migrate echo "successfully updated U-Boot, power-cycle and enter \"run setupdate\; run migrate\" to complete update"
setenv echo_migrate-it echo "successfully updated U-Boot, power-cycle and enter \"run setupdate\; run migrate_it\" to complete update"
setenv migrate 'run migrate_configblock; run update_latest; reset'
setenv migrate_it 'setenv module_type -it; run migrate'
setenv update_v2.4b1 'run check_configblock || run migrate_configblock; run migrate_uboot_old && run echo_migrate${module_type}'
setenv update_v2.5b3 'run check_configblock || run migrate_configblock; run migrate_uboot && run echo_migrate${module_type}'

setenv update_latest 'run update_uboot; run update_1; run update_2; run update_kernel; run update_fdt; run update_3'
setenv update_new 'updt_fuse -n && run update_latest && reset; run update_v2.5b3'
setenv update 'mmc bootbus 0 2 0 1 && run update_new && exit; run update_v2.4b1'
setenv update_it 'setenv module_type -it; run update'

echo 'enter "run update" or "run update_it" to update the entire module'

The second new file you need is called “fwd_sata.img” so create a file called “fwd_sata.scr” in the same folder.

#the script renames this. fwd_sata.scr -> ../flash_sata.img
load ${interface} ${loadaddr} ${board_name}/flash_sata.img && source ${loadaddr}

If you now run the “” in this folder the .img files are created.

Modify the script:

#copy to $OUT_DIR
	${BINARIES}/${IMAGEFILE} ${BINARIES}/flash*.img ${BINARIES}/versions.txt "$OUT_DIR"
[ "${U_BOOT_BINARY}x" != "${U_BOOT_BINARY_IT}x" ] && sudo cp ${BINARIES}/${U_BOOT_BINARY_IT} "$OUT_DIR"
sudo cp ${BINARIES}/fwd_blk.img "$OUT_DIR/../flash_blk.img"
sudo cp ${BINARIES}/fwd_eth.img "$OUT_DIR/../flash_eth.img"
sudo cp ${BINARIES}/fwd_mmc.img "$OUT_DIR/../flash_mmc.img"
#add the next linee
sudo cp ${BINARIES}/fwd_sata.img "$OUT_DIR/../flash_sata.img"
#cleanup intermediate files

Now run “./ -co /to_destination_folder” and you will get a new set of files including the two new files for sata update and copy them to the partition you will use for the update. I have problems reading the root.ext3, so I do it like tftpboot and read it in chunks. That why you need the “c” option for running the script.

Finally you have to setup an additional environment variable and edit “setupdate” after entering the bootloader mode.

setsataupdate=sata init; sata device 0; setenv interface sata 0:5; load ${interface} ${loadaddr} flash_sata.img && source ${loadaddr}
setupdate=run setsataupdate || run setsdupdate || run setusbupdate || run setethupdate

Type “run setsataupdate; run setup”.

I hope, I haven’t forgot something…

Best Regards