[PATCH u-boot-marvell v3 11/39] tools: kwboot: Split sending image into header and data stages
Stefan Roese
sr at denx.de
Fri Oct 1 08:17:03 CEST 2021
On 24.09.21 23:06, Marek Behún wrote:
> From: Pali Rohár <pali at kernel.org>
>
> 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 at kernel.org>
> [ refactored ]
> Signed-off-by: Marek Behún <marek.behun at nic.cz>
Reviewed-by: Stefan Roese <sr at denx.de>
Thanks,
Stefan
> ---
> tools/kwbimage.h | 8 +++--
> tools/kwboot.c | 84 +++++++++++++++++++++++++++++++-----------------
> 2 files changed, 61 insertions(+), 31 deletions(-)
>
> diff --git a/tools/kwbimage.h b/tools/kwbimage.h
> index e063e3e41e..074bdfbe46 100644
> --- a/tools/kwbimage.h
> +++ b/tools/kwbimage.h
> @@ -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];
> }
>
> diff --git a/tools/kwboot.c b/tools/kwboot.c
> index 0e533e3698..7f231c0823 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
>
Viele Grüße,
Stefan
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-51 Fax: (+49)-8142-66989-80 Email: sr at denx.de
More information about the U-Boot
mailing list