This patch makes use of a new sunxi SPL header format, where fields for passing data to U-Boot are reserved. This allows the "fel" utility to provide specific pieces of information by setting these fields (which will be evaluated by U-Boot then). For now, we may specify a memory region by address and size.
Currently the typical use case is to provide the memory location of the boot script file (boot.scr). A suitably modified U-Boot can adjust the boot process accordingly and will auto-execute the script. Signed-off-by: Bernhard Nortmann <bernhard.nortm...@web.de> --- fel.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/fel.c b/fel.c index e3566fb..cd10dd3 100644 --- a/fel.c +++ b/fel.c @@ -926,6 +926,48 @@ void aw_fel_process_spl_and_uboot(libusb_device_handle *usb, aw_fel_write_uboot_image(usb, buf + SPL_LEN_LIMIT, size - SPL_LEN_LIMIT); } +/* + * Test the SPL header for our "sunxi" variant. We want to make sure that + * we can safely use specific header fields to pass information to U-Boot. + * In case of a missing signature (e.g. Allwinner boot0) or header version + * mismatch, this function will return "false". If all seems fine, + * the result is "true". + */ +#define SPL_SIGNATURE "SPL" /* marks "sunxi" header */ +#define SPL_EXPECTED_VERSION 1 +int have_sunxi_spl(libusb_device_handle *usb, soc_sram_info *sram_info) +{ + const uint8_t expected[] = SPL_SIGNATURE; + uint8_t spl_signature[4]; + + aw_fel_read(usb, sram_info->spl_addr + 0x14, + &spl_signature, sizeof(spl_signature)); + return (memcmp(spl_signature, expected, 3) == 0 + && spl_signature[3] == SPL_EXPECTED_VERSION); +} + +/* + * Pass information to U-Boot via specialized fields in the SPL header + * (see "boot_file_head" in ${U-BOOT}/tools/mksunxiboot.c), providing + * information about some data address and size. + * Typically this will be the DRAM location of a boot script (boot.scr). + */ +void pass_fel_information(libusb_device_handle *usb, soc_sram_info *sram_info, + uint32_t data_addr, size_t data_size) +{ + /* write something _only_ if we have a suitable SPL header */ + if (have_sunxi_spl(usb, sram_info)) { + struct { + uint32_t fel_data_address; + uint32_t fel_data_size; + } transfer = {data_addr, data_size}; + pr_info("Passing boot info via sunxi SPL: data addr 0x%08X, size 0x%X\n", + transfer.fel_data_address, transfer.fel_data_size); + aw_fel_write(usb, &transfer, + sram_info->spl_addr + 0x18, sizeof(transfer)); + } +} + static int aw_fel_get_endpoint(libusb_device_handle *usb) { struct libusb_device *dev = libusb_get_device(usb); @@ -1067,13 +1109,24 @@ int main(int argc, char **argv) double t1, t2; size_t size; void *buf = load_file(argv[3], &size); + uint32_t offset = strtoul(argv[2], NULL, 0); t1 = gettime(); - aw_fel_write(handle, buf, strtoul(argv[2], NULL, 0), size); + aw_fel_write(handle, buf, offset, size); t2 = gettime(); if (t2 > t1) pr_info("Written %.1f KB in %.1f sec (speed: %.1f KB/s)\n", (double)size / 1000., t2 - t1, (double)size / (t2 - t1) / 1000.); + + /* + * If we have transferred a script, try to inform U-Boot about it. + * An IH_TYPE_SCRIPT has a well-defined header (including length), + * so we pass only the address and keep the size value at zero. + * (Reserving size > 0 for different data / future extensions.) + */ + if (get_image_type(buf, size) == IH_TYPE_SCRIPT) + pass_fel_information(handle, sram_info, offset, 0); + free(buf); skip=3; } else if (strcmp(argv[1], "read") == 0 && argc > 4) { -- 2.4.6 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.