[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