aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/pci_mvebu.c11
-rw-r--r--tools/kwbimage.c250
-rw-r--r--tools/kwbimage.h25
-rw-r--r--tools/kwboot.c28
4 files changed, 200 insertions, 114 deletions
diff --git a/drivers/pci/pci_mvebu.c b/drivers/pci/pci_mvebu.c
index c575e94..14cd82d 100644
--- a/drivers/pci/pci_mvebu.c
+++ b/drivers/pci/pci_mvebu.c
@@ -97,7 +97,6 @@ struct mvebu_pcie {
* and 64K of I/O space when registered.
*/
static void __iomem *mvebu_pcie_membase = (void __iomem *)MBUS_PCI_MEM_BASE;
-#define PCIE_MEM_SIZE (128 << 20)
static void __iomem *mvebu_pcie_iobase = (void __iomem *)MBUS_PCI_IO_BASE;
static inline bool mvebu_pcie_link_up(struct mvebu_pcie *pcie)
@@ -433,14 +432,14 @@ static int mvebu_pcie_probe(struct udevice *dev)
mvebu_pcie_set_local_dev_nr(pcie, 1);
pcie->mem.start = (u32)mvebu_pcie_membase;
- pcie->mem.end = pcie->mem.start + PCIE_MEM_SIZE - 1;
- mvebu_pcie_membase += PCIE_MEM_SIZE;
+ pcie->mem.end = pcie->mem.start + MBUS_PCI_MEM_SIZE - 1;
+ mvebu_pcie_membase += MBUS_PCI_MEM_SIZE;
if (mvebu_mbus_add_window_by_id(pcie->mem_target, pcie->mem_attr,
(phys_addr_t)pcie->mem.start,
- PCIE_MEM_SIZE)) {
+ MBUS_PCI_MEM_SIZE)) {
printf("PCIe unable to add mbus window for mem at %08x+%08x\n",
- (u32)pcie->mem.start, PCIE_MEM_SIZE);
+ (u32)pcie->mem.start, MBUS_PCI_MEM_SIZE);
}
pcie->io.start = (u32)mvebu_pcie_iobase;
@@ -459,7 +458,7 @@ static int mvebu_pcie_probe(struct udevice *dev)
/* PCI memory space */
pci_set_region(hose->regions + 0, pcie->mem.start,
- pcie->mem.start, PCIE_MEM_SIZE, PCI_REGION_MEM);
+ pcie->mem.start, MBUS_PCI_MEM_SIZE, PCI_REGION_MEM);
pci_set_region(hose->regions + 1,
0, 0,
gd->ram_size,
diff --git a/tools/kwbimage.c b/tools/kwbimage.c
index 67c0c62..875f636 100644
--- a/tools/kwbimage.c
+++ b/tools/kwbimage.c
@@ -101,6 +101,8 @@ enum image_cfg_type {
IMAGE_CFG_DATA,
IMAGE_CFG_DATA_DELAY,
IMAGE_CFG_BAUDRATE,
+ IMAGE_CFG_UART_PORT,
+ IMAGE_CFG_UART_MPP,
IMAGE_CFG_DEBUG,
IMAGE_CFG_KAK,
IMAGE_CFG_CSK,
@@ -129,6 +131,8 @@ static const char * const id_strs[] = {
[IMAGE_CFG_DATA] = "DATA",
[IMAGE_CFG_DATA_DELAY] = "DATA_DELAY",
[IMAGE_CFG_BAUDRATE] = "BAUDRATE",
+ [IMAGE_CFG_UART_PORT] = "UART_PORT",
+ [IMAGE_CFG_UART_MPP] = "UART_MPP",
[IMAGE_CFG_DEBUG] = "DEBUG",
[IMAGE_CFG_KAK] = "KAK",
[IMAGE_CFG_CSK] = "CSK",
@@ -161,6 +165,8 @@ struct image_cfg_element {
struct ext_hdr_v0_reg regdata;
unsigned int regdata_delay;
unsigned int baudrate;
+ unsigned int uart_port;
+ unsigned int uart_mpp;
unsigned int debug;
const char *key_name;
int csk_idx;
@@ -260,6 +266,18 @@ static bool image_get_spezialized_img(void)
return e->sec_specialized_img;
}
+static int image_get_bootfrom(void)
+{
+ struct image_cfg_element *e;
+
+ e = image_find_option(IMAGE_CFG_BOOT_FROM);
+ if (!e)
+ /* fallback to SPI if no BOOT_FROM is not provided */
+ return IBR_HDR_SPI_ID;
+
+ return e->bootfrom;
+}
+
/*
* Compute a 8-bit checksum of a memory area. This algorithm follows
* the requirements of the Marvell SoC BootROM specifications.
@@ -840,6 +858,41 @@ done:
return ret;
}
+static size_t image_headersz_align(size_t headersz, uint8_t blockid)
+{
+ /*
+ * Header needs to be 4-byte aligned, which is already ensured by code
+ * above. Moreover UART images must have header aligned to 128 bytes
+ * (xmodem block size), NAND images to 256 bytes (ECC calculation),
+ * and SATA and SDIO images to 512 bytes (storage block size).
+ * Note that SPI images do not have to have header size aligned
+ * to 256 bytes because it is possible to read from SPI storage from
+ * any offset (read offset does not have to be aligned to block size).
+ */
+ if (blockid == IBR_HDR_UART_ID)
+ return ALIGN(headersz, 128);
+ else if (blockid == IBR_HDR_NAND_ID)
+ return ALIGN(headersz, 256);
+ else if (blockid == IBR_HDR_SATA_ID || blockid == IBR_HDR_SDIO_ID)
+ return ALIGN(headersz, 512);
+ else
+ return headersz;
+}
+
+static size_t image_headersz_v0(int *hasext)
+{
+ size_t headersz;
+
+ headersz = sizeof(struct main_hdr_v0);
+ if (image_count_options(IMAGE_CFG_DATA) > 0) {
+ headersz += sizeof(struct ext_hdr_v0);
+ if (hasext)
+ *hasext = 1;
+ }
+
+ return image_headersz_align(headersz, image_get_bootfrom());
+}
+
static void *image_create_v0(size_t *imagesz, struct image_tool_params *params,
int payloadsz)
{
@@ -853,12 +906,7 @@ static void *image_create_v0(size_t *imagesz, struct image_tool_params *params,
* Calculate the size of the header and the size of the
* payload
*/
- headersz = sizeof(struct main_hdr_v0);
-
- if (image_count_options(IMAGE_CFG_DATA) > 0) {
- has_ext = 1;
- headersz += sizeof(struct ext_hdr_v0);
- }
+ headersz = image_headersz_v0(&has_ext);
image = malloc(headersz);
if (!image) {
@@ -872,15 +920,14 @@ static void *image_create_v0(size_t *imagesz, struct image_tool_params *params,
/* Fill in the main header */
main_hdr->blocksize =
- cpu_to_le32(payloadsz - headersz);
+ cpu_to_le32(payloadsz);
main_hdr->srcaddr = cpu_to_le32(headersz);
main_hdr->ext = has_ext;
+ main_hdr->version = 0;
main_hdr->destaddr = cpu_to_le32(params->addr);
main_hdr->execaddr = cpu_to_le32(params->ep);
+ main_hdr->blockid = image_get_bootfrom();
- e = image_find_option(IMAGE_CFG_BOOT_FROM);
- if (e)
- main_hdr->blockid = e->bootfrom;
e = image_find_option(IMAGE_CFG_NAND_ECC_MODE);
if (e)
main_hdr->nandeccmode = e->nandeccmode;
@@ -890,6 +937,28 @@ static void *image_create_v0(size_t *imagesz, struct image_tool_params *params,
main_hdr->checksum = image_checksum8(image,
sizeof(struct main_hdr_v0));
+ /*
+ * For SATA srcaddr is specified in number of sectors starting from
+ * sector 0. The main header is stored at sector number 1.
+ * This expects the sector size to be 512 bytes.
+ * Header size is already aligned.
+ */
+ if (main_hdr->blockid == IBR_HDR_SATA_ID)
+ main_hdr->srcaddr = cpu_to_le32(headersz / 512 + 1);
+
+ /*
+ * For SDIO srcaddr is specified in number of sectors starting from
+ * sector 0. The main header is stored at sector number 0.
+ * This expects sector size to be 512 bytes.
+ * Header size is already aligned.
+ */
+ if (main_hdr->blockid == IBR_HDR_SDIO_ID)
+ main_hdr->srcaddr = cpu_to_le32(headersz / 512);
+
+ /* For PCIe srcaddr is not used and must be set to 0xFFFFFFFF. */
+ if (main_hdr->blockid == IBR_HDR_PEX_ID)
+ main_hdr->srcaddr = cpu_to_le32(0xFFFFFFFF);
+
/* Generate the ext header */
if (has_ext) {
struct ext_hdr_v0 *ext_hdr;
@@ -977,11 +1046,7 @@ static size_t image_headersz_v1(int *hasext)
*hasext = 1;
}
- /*
- * The payload should be aligned on some reasonable
- * boundary
- */
- return ALIGN(headersz, 4096);
+ return image_headersz_align(headersz, image_get_bootfrom());
}
int add_binary_header_v1(uint8_t **cur, uint8_t **next_ext,
@@ -1186,6 +1251,7 @@ static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
{
struct image_cfg_element *e;
struct main_hdr_v1 *main_hdr;
+ struct opt_hdr_v1 *ohdr;
struct register_set_hdr_v1 *register_set_hdr;
struct secure_hdr_v1 *secure_hdr = NULL;
size_t headersz;
@@ -1217,7 +1283,7 @@ static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
/* Fill the main header */
main_hdr->blocksize =
- cpu_to_le32(payloadsz - headersz);
+ cpu_to_le32(payloadsz);
main_hdr->headersz_lsb = cpu_to_le16(headersz & 0xFFFF);
main_hdr->headersz_msb = (headersz & 0xFFFF0000) >> 16;
main_hdr->destaddr = cpu_to_le32(params->addr);
@@ -1225,9 +1291,8 @@ static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
main_hdr->srcaddr = cpu_to_le32(headersz);
main_hdr->ext = hasext;
main_hdr->version = 1;
- e = image_find_option(IMAGE_CFG_BOOT_FROM);
- if (e)
- main_hdr->blockid = e->bootfrom;
+ main_hdr->blockid = image_get_bootfrom();
+
e = image_find_option(IMAGE_CFG_NAND_BLKSZ);
if (e)
main_hdr->nandblocksize = e->nandblksz / (64 * 1024);
@@ -1239,7 +1304,13 @@ static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
main_hdr->nandbadblklocation = e->nandbadblklocation;
e = image_find_option(IMAGE_CFG_BAUDRATE);
if (e)
- main_hdr->options = baudrate_to_option(e->baudrate);
+ main_hdr->options |= baudrate_to_option(e->baudrate);
+ e = image_find_option(IMAGE_CFG_UART_PORT);
+ if (e)
+ main_hdr->options |= (e->uart_port & 3) << 3;
+ e = image_find_option(IMAGE_CFG_UART_MPP);
+ if (e)
+ main_hdr->options |= (e->uart_mpp & 7) << 5;
e = image_find_option(IMAGE_CFG_DEBUG);
if (e)
main_hdr->flags = e->debug ? 0x1 : 0;
@@ -1323,7 +1394,7 @@ static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
return NULL;
}
- if (secure_hdr && add_secure_header_v1(params, ptr, payloadsz,
+ if (secure_hdr && add_secure_header_v1(params, ptr, payloadsz + headersz,
headersz, image, secure_hdr))
return NULL;
@@ -1331,6 +1402,14 @@ static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
main_hdr->checksum = image_checksum8(main_hdr, headersz);
*imagesz = headersz;
+
+ /* Fill the real header size without padding into the main header */
+ headersz = sizeof(*main_hdr);
+ for_each_opt_hdr_v1 (ohdr, main_hdr)
+ headersz += opt_hdr_v1_size(ohdr);
+ main_hdr->headersz_lsb = cpu_to_le16(headersz & 0xFFFF);
+ main_hdr->headersz_msb = (headersz & 0xFFFF0000) >> 16;
+
return image;
}
@@ -1441,6 +1520,12 @@ static int image_create_config_parse_oneline(char *line,
case IMAGE_CFG_BAUDRATE:
el->baudrate = strtoul(value1, NULL, 10);
break;
+ case IMAGE_CFG_UART_PORT:
+ el->uart_port = strtoul(value1, NULL, 16);
+ break;
+ case IMAGE_CFG_UART_MPP:
+ el->uart_mpp = strtoul(value1, NULL, 16);
+ break;
case IMAGE_CFG_DEBUG:
el->debug = strtoul(value1, NULL, 10);
break;
@@ -1540,17 +1625,6 @@ static int image_get_version(void)
return e->version;
}
-static int image_get_bootfrom(void)
-{
- struct image_cfg_element *e;
-
- e = image_find_option(IMAGE_CFG_BOOT_FROM);
- if (!e)
- return -1;
-
- return e->bootfrom;
-}
-
static void kwbimage_set_header(void *ptr, struct stat *sbuf, int ifd,
struct image_tool_params *params)
{
@@ -1558,9 +1632,22 @@ static void kwbimage_set_header(void *ptr, struct stat *sbuf, int ifd,
void *image = NULL;
int version;
size_t headersz = 0;
+ size_t datasz;
uint32_t checksum;
+ struct stat s;
int ret;
+ /*
+ * Do not use sbuf->st_size as it contains size with padding.
+ * We need original image data size, so stat original file.
+ */
+ if (stat(params->datafile, &s)) {
+ fprintf(stderr, "Could not stat data file %s: %s\n",
+ params->datafile, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ datasz = ALIGN(s.st_size, 4);
+
fcfg = fopen(params->imagename, "r");
if (!fcfg) {
fprintf(stderr, "Could not open input file %s\n",
@@ -1595,11 +1682,11 @@ static void kwbimage_set_header(void *ptr, struct stat *sbuf, int ifd,
*/
case -1:
case 0:
- image = image_create_v0(&headersz, params, sbuf->st_size);
+ image = image_create_v0(&headersz, params, datasz + 4);
break;
case 1:
- image = image_create_v1(&headersz, params, ptr, sbuf->st_size);
+ image = image_create_v1(&headersz, params, ptr, datasz + 4);
break;
default:
@@ -1616,11 +1703,10 @@ static void kwbimage_set_header(void *ptr, struct stat *sbuf, int ifd,
free(image_cfg);
- /* Build and add image checksum header */
+ /* Build and add image data checksum */
checksum = cpu_to_le32(image_checksum32((uint8_t *)ptr + headersz,
- sbuf->st_size - headersz - sizeof(uint32_t)));
- memcpy((uint8_t *)ptr + sbuf->st_size - sizeof(uint32_t), &checksum,
- sizeof(uint32_t));
+ datasz));
+ memcpy((uint8_t *)ptr + headersz + datasz, &checksum, sizeof(uint32_t));
/* Finally copy the header into the image area */
memcpy(ptr, image, headersz);
@@ -1663,6 +1749,9 @@ static int kwbimage_verify_header(unsigned char *ptr, int image_size,
struct image_tool_params *params)
{
size_t header_size = kwbheader_size(ptr);
+ uint8_t blockid;
+ uint32_t offset;
+ uint32_t size;
uint8_t csum;
if (header_size > image_size)
@@ -1682,61 +1771,64 @@ static int kwbimage_verify_header(unsigned char *ptr, int image_size,
if (csum != ext_hdr->checksum)
return -FDT_ERR_BADSTRUCTURE;
}
+
+ blockid = mhdr->blockid;
+ offset = le32_to_cpu(mhdr->srcaddr);
+ size = le32_to_cpu(mhdr->blocksize);
} else if (kwbimage_version(ptr) == 1) {
struct main_hdr_v1 *mhdr = (struct main_hdr_v1 *)ptr;
const uint8_t *mhdr_end;
struct opt_hdr_v1 *ohdr;
- uint32_t offset;
- uint32_t size;
mhdr_end = (uint8_t *)mhdr + header_size;
for_each_opt_hdr_v1 (ohdr, ptr)
if (!opt_hdr_v1_valid_size(ohdr, mhdr_end))
return -FDT_ERR_BADSTRUCTURE;
+ blockid = mhdr->blockid;
offset = le32_to_cpu(mhdr->srcaddr);
+ size = le32_to_cpu(mhdr->blocksize);
+ } else {
+ return -FDT_ERR_BADSTRUCTURE;
+ }
- /*
- * For SATA srcaddr is specified in number of sectors.
- * The main header is must be stored at sector number 1.
- * This expects that sector size is 512 bytes and recalculates
- * data offset to bytes relative to the main header.
- */
- if (mhdr->blockid == IBR_HDR_SATA_ID) {
- if (offset < 1)
- return -FDT_ERR_BADSTRUCTURE;
- offset -= 1;
- offset *= 512;
- }
+ /*
+ * For SATA srcaddr is specified in number of sectors.
+ * The main header is must be stored at sector number 1.
+ * This expects that sector size is 512 bytes and recalculates
+ * data offset to bytes relative to the main header.
+ */
+ if (blockid == IBR_HDR_SATA_ID) {
+ if (offset < 1)
+ return -FDT_ERR_BADSTRUCTURE;
+ offset -= 1;
+ offset *= 512;
+ }
- /*
- * For SDIO srcaddr is specified in number of sectors.
- * This expects that sector size is 512 bytes and recalculates
- * data offset to bytes.
- */
- if (mhdr->blockid == IBR_HDR_SDIO_ID)
- offset *= 512;
+ /*
+ * For SDIO srcaddr is specified in number of sectors.
+ * This expects that sector size is 512 bytes and recalculates
+ * data offset to bytes.
+ */
+ if (blockid == IBR_HDR_SDIO_ID)
+ offset *= 512;
- /*
- * For PCIe srcaddr is always set to 0xFFFFFFFF.
- * This expects that data starts after all headers.
- */
- if (mhdr->blockid == IBR_HDR_PEX_ID && offset == 0xFFFFFFFF)
- offset = header_size;
+ /*
+ * For PCIe srcaddr is always set to 0xFFFFFFFF.
+ * This expects that data starts after all headers.
+ */
+ if (blockid == IBR_HDR_PEX_ID && offset == 0xFFFFFFFF)
+ offset = header_size;
- if (offset > image_size || offset % 4 != 0)
- return -FDT_ERR_BADSTRUCTURE;
+ if (offset > image_size || offset % 4 != 0)
+ return -FDT_ERR_BADSTRUCTURE;
- size = le32_to_cpu(mhdr->blocksize);
- if (size < 4 || offset + size > image_size || size % 4 != 0)
- return -FDT_ERR_BADSTRUCTURE;
+ if (size < 4 || offset + size > image_size || size % 4 != 0)
+ return -FDT_ERR_BADSTRUCTURE;
- if (image_checksum32(ptr + offset, size - 4) !=
- *(uint32_t *)(ptr + offset + size - 4))
- return -FDT_ERR_BADSTRUCTURE;
- } else {
+ if (image_checksum32(ptr + offset, size - 4) !=
+ *(uint32_t *)(ptr + offset + size - 4))
return -FDT_ERR_BADSTRUCTURE;
- }
return 0;
}
@@ -1793,8 +1885,7 @@ static int kwbimage_generate(struct image_tool_params *params,
*/
case -1:
case 0:
- alloc_len = sizeof(struct main_hdr_v0) +
- sizeof(struct ext_hdr_v0);
+ alloc_len = image_headersz_v0(NULL);
break;
case 1:
@@ -1824,6 +1915,7 @@ static int kwbimage_generate(struct image_tool_params *params,
* The resulting image needs to be 4-byte aligned. At least
* the Marvell hdrparser tool complains if its unaligned.
* After the image data is stored 4-byte checksum.
+ * Final UART image must be aligned to 128 bytes.
* Final SPI and NAND images must be aligned to 256 bytes.
* Final SATA and SDIO images must be aligned to 512 bytes.
*/
@@ -1831,6 +1923,8 @@ static int kwbimage_generate(struct image_tool_params *params,
return 4 + (256 - (alloc_len + s.st_size + 4) % 256) % 256;
else if (bootfrom == IBR_HDR_SATA_ID || bootfrom == IBR_HDR_SDIO_ID)
return 4 + (512 - (alloc_len + s.st_size + 4) % 512) % 512;
+ else if (bootfrom == IBR_HDR_UART_ID)
+ return 4 + (128 - (alloc_len + s.st_size + 4) % 128) % 128;
else
return 4 + (4 - s.st_size % 4) % 4;
}
@@ -1893,7 +1987,7 @@ static int kwbimage_check_params(struct image_tool_params *params)
char *msg = "Configuration file for kwbimage creation omitted";
fprintf(stderr, "Error:%s - %s\n", params->cmdname, msg);
- return CFG_INVALID;
+ return 1;
}
return (params->dflag && (params->fflag || params->lflag)) ||
diff --git a/tools/kwbimage.h b/tools/kwbimage.h
index f1ba95c..8d37357 100644
--- a/tools/kwbimage.h
+++ b/tools/kwbimage.h
@@ -42,7 +42,8 @@ struct main_hdr_v0 {
uint8_t nandeccmode; /* 0x1 */
uint16_t nandpagesize; /* 0x2-0x3 */
uint32_t blocksize; /* 0x4-0x7 */
- uint32_t rsvd1; /* 0x8-0xB */
+ uint8_t version; /* 0x8 */
+ uint8_t rsvd1[3]; /* 0x9-0xB */
uint32_t srcaddr; /* 0xC-0xF */
uint32_t destaddr; /* 0x10-0x13 */
uint32_t execaddr; /* 0x14-0x17 */
@@ -190,28 +191,6 @@ struct register_set_hdr_v1 {
#define OPT_HDR_V1_BINARY_TYPE 0x2
#define OPT_HDR_V1_REGISTER_TYPE 0x3
-enum kwbimage_cmd {
- CMD_INVALID,
- CMD_BOOT_FROM,
- CMD_NAND_ECC_MODE,
- CMD_NAND_PAGE_SIZE,
- CMD_SATA_PIO_MODE,
- CMD_DDR_INIT_DELAY,
- CMD_DATA
-};
-
-enum kwbimage_cmd_types {
- CFG_INVALID = -1,
- CFG_COMMAND,
- CFG_DATA0,
- CFG_DATA1
-};
-
-/*
- * functions
- */
-void init_kwb_image_type (void);
-
/*
* Byte 8 of the image header contains the version number. In the v0
* header, byte 8 was reserved, and always set to 0. In the v1 header,
diff --git a/tools/kwboot.c b/tools/kwboot.c
index bacca15..d22e6ea 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -1073,6 +1073,14 @@ kwboot_xmodem(int tty, const void *_img, size_t size, int baudrate)
hdrsz = kwbheader_size(img);
+ /*
+ * If header size is not aligned to xmodem block size (which applies
+ * for all images in kwbimage v0 format) then we have to ensure that
+ * the last xmodem block of header contains beginning of the data
+ * followed by the header. So align header size to xmodem block size.
+ */
+ hdrsz += (KWBOOT_XM_BLKSZ - hdrsz % KWBOOT_XM_BLKSZ) % KWBOOT_XM_BLKSZ;
+
kwboot_printv("Waiting 2s and flushing tty\n");
sleep(2); /* flush isn't effective without it */
tcflush(tty, TCIOFLUSH);
@@ -1083,12 +1091,17 @@ kwboot_xmodem(int tty, const void *_img, size_t size, int baudrate)
if (rc)
return rc;
- img += hdrsz;
- size -= hdrsz;
-
- rc = kwboot_xmodem_one(tty, &pnum, 0, img, size, 0);
- if (rc)
- return rc;
+ /*
+ * If we have already sent image data as a part of the last
+ * xmodem header block then we have nothing more to send.
+ */
+ if (hdrsz < size) {
+ img += hdrsz;
+ size -= hdrsz;
+ rc = kwboot_xmodem_one(tty, &pnum, 0, img, size, 0);
+ if (rc)
+ return rc;
+ }
rc = kwboot_xm_finish(tty);
if (rc)
@@ -1627,7 +1640,6 @@ err:
static void
kwboot_usage(FILE *stream, char *progname)
{
- fprintf(stream, "kwboot version %s\n", PLAIN_VERSION);
fprintf(stream,
"Usage: %s [OPTIONS] [-b <image> | -D <image> ] [-B <baud> ] <TTY>\n",
progname);
@@ -1672,6 +1684,8 @@ main(int argc, char **argv)
after_img_rsv = KWBOOT_XM_BLKSZ;
baudrate = 115200;
+ printf("kwboot version %s\n", PLAIN_VERSION);
+
kwboot_verbose = isatty(STDOUT_FILENO);
do {