]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
tools: kwboot: Split sending image into header and data stages
authorPali Rohár <pali@kernel.org>
Fri, 24 Sep 2021 21:06:48 +0000 (23:06 +0200)
committerStefan Roese <sr@denx.de>
Fri, 1 Oct 2021 09:07:13 +0000 (11:07 +0200)
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>
tools/kwbimage.h
tools/kwboot.c

index 10e3254a58f53eb16db36c07056df3380f863c99..73da950d86e5a414f649b54da3d83ea610031c25 100644 (file)
@@ -195,6 +195,10 @@ struct register_set_hdr_v1 {
 #define OPT_HDR_V1_BINARY_TYPE   0x2
 #define OPT_HDR_V1_REGISTER_TYPE 0x3
 
+#define KWBHEADER_V0_SIZE(hdr) \
+       (((hdr)->ext & 0x1) ? sizeof(struct kwb_header) : \
+                             sizeof(struct main_hdr_v0))
+
 #define KWBHEADER_V1_SIZE(hdr) \
        (((hdr)->headersz_msb << 16) | le16_to_cpu((hdr)->headersz_lsb))
 
@@ -225,9 +229,9 @@ void init_kwb_image_type (void);
  * header, byte 8 was reserved, and always set to 0. In the v1 header,
  * byte 8 has been changed to a proper field, set to 1.
  */
-static inline unsigned int image_version(void *header)
+static inline unsigned int image_version(const void *header)
 {
-       unsigned char *ptr = header;
+       const unsigned char *ptr = header;
        return ptr[8];
 }
 
index 0e533e369838a5db8c17b7ee54f4d48ada426235..7f231c0823c4038d653a0f7d5f22b3d8d86336f8 100644 (file)
@@ -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