aboutsummaryrefslogtreecommitdiff
path: root/tools/kwboot.c
diff options
context:
space:
mode:
authorPali Rohár <pali@kernel.org>2021-09-24 23:06:48 +0200
committerStefan Roese <sr@denx.de>2021-10-01 11:07:13 +0200
commit2ef87f75d16bcdc2a29e7339b8f2c2508985fe12 (patch)
tree01fcfbd97cc28372efe214104b9f39cf18a20465 /tools/kwboot.c
parentd5ba8dbd75c1b3f45c341341a1259114d894c45f (diff)
downloadu-boot-2ef87f75d16bcdc2a29e7339b8f2c2508985fe12.zip
u-boot-2ef87f75d16bcdc2a29e7339b8f2c2508985fe12.tar.gz
u-boot-2ef87f75d16bcdc2a29e7339b8f2c2508985fe12.tar.bz2
tools: kwboot: Split sending image into header and data stages
This change is required to implement other features in kwboot. Split sending header and data parts of the image into two stages. Signed-off-by: Pali Rohár <pali@kernel.org> [ refactored ] Signed-off-by: Marek Behún <marek.behun@nic.cz> Reviewed-by: Stefan Roese <sr@denx.de>
Diffstat (limited to 'tools/kwboot.c')
-rw-r--r--tools/kwboot.c84
1 files changed, 55 insertions, 29 deletions
diff --git a/tools/kwboot.c b/tools/kwboot.c
index 0e533e3..7f231c0 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -57,11 +57,13 @@ static unsigned char kwboot_msg_debug[] = {
#define NAK 21 /* target block negative ack */
#define CAN 24 /* target/sender transfer cancellation */
+#define KWBOOT_XM_BLKSZ 128 /* xmodem block size */
+
struct kwboot_block {
uint8_t soh;
uint8_t pnum;
uint8_t _pnum;
- uint8_t data[128];
+ uint8_t data[KWBOOT_XM_BLKSZ];
uint8_t csum;
} __packed;
@@ -356,16 +358,15 @@ static size_t
kwboot_xm_makeblock(struct kwboot_block *block, const void *data,
size_t size, int pnum)
{
- const size_t blksz = sizeof(block->data);
size_t i, n;
block->soh = SOH;
block->pnum = pnum;
block->_pnum = ~block->pnum;
- n = size < blksz ? size : blksz;
+ n = size < KWBOOT_XM_BLKSZ ? size : KWBOOT_XM_BLKSZ;
memcpy(&block->data[0], data, n);
- memset(&block->data[n], 0, blksz - n);
+ memset(&block->data[n], 0, KWBOOT_XM_BLKSZ - n);
block->csum = 0;
for (i = 0; i < n; i++)
@@ -425,48 +426,73 @@ kwboot_xm_sendblock(int fd, struct kwboot_block *block)
}
static int
-kwboot_xmodem(int tty, const void *_data, size_t size)
+kwboot_xmodem_one(int tty, int *pnum, int header, const uint8_t *data,
+ size_t size)
{
- const uint8_t *data = _data;
- int rc, pnum, N, err;
-
- pnum = 1;
- N = 0;
+ size_t sent, left;
+ int rc;
- kwboot_printv("Sending boot image...\n");
+ kwboot_printv("Sending boot image %s (%zu bytes)...\n",
+ header ? "header" : "data", size);
- sleep(2); /* flush isn't effective without it */
- tcflush(tty, TCIOFLUSH);
+ left = size;
+ sent = 0;
- do {
+ while (sent < size) {
struct kwboot_block block;
- int n;
+ size_t blksz;
- n = kwboot_xm_makeblock(&block,
- data + N, size - N,
- pnum++);
- if (!n)
- break;
+ blksz = kwboot_xm_makeblock(&block, data, left, (*pnum)++);
+ data += blksz;
rc = kwboot_xm_sendblock(tty, &block);
if (rc)
goto out;
- N += n;
- kwboot_progress(N * 100 / size, '.');
- } while (1);
+ sent += blksz;
+ left -= blksz;
+
+ kwboot_progress(sent * 100 / size, '.');
+ }
- rc = kwboot_tty_send_char(tty, EOT);
+ kwboot_printv("Done\n");
+ return 0;
out:
kwboot_printv("\n");
return rc;
+}
-can:
- err = errno;
- kwboot_tty_send_char(tty, CAN);
- errno = err;
- goto out;
+static int
+kwboot_xmodem(int tty, const void *_img, size_t size)
+{
+ const uint8_t *img = _img;
+ int rc, pnum;
+ size_t hdrsz;
+
+ if (image_version(img) == 0)
+ hdrsz = KWBHEADER_V0_SIZE((struct main_hdr_v0 *)img);
+ else
+ hdrsz = KWBHEADER_V1_SIZE((struct main_hdr_v1 *)img);
+
+ kwboot_printv("Waiting 2s and flushing tty\n");
+ sleep(2); /* flush isn't effective without it */
+ tcflush(tty, TCIOFLUSH);
+
+ pnum = 1;
+
+ rc = kwboot_xmodem_one(tty, &pnum, 1, img, hdrsz);
+ if (rc)
+ return rc;
+
+ img += hdrsz;
+ size -= hdrsz;
+
+ rc = kwboot_xmodem_one(tty, &pnum, 0, img, size);
+ if (rc)
+ return rc;
+
+ return kwboot_tty_send_char(tty, EOT);
}
static int