kwboot: Marvell Dove UART booting

Pali Rohár pali at kernel.org
Mon Feb 14 00:42:51 CET 2022


On Sunday 13 February 2022 15:24:46 Tony Dinh wrote:
> Hi Pali,
> 
> Looks different, but the BootROM did not start the image. Please see
> the log below.
> 
> On Sun, Feb 13, 2022 at 2:48 PM Pali Rohár <pali at kernel.org> wrote:
> >
> > On Sunday 13 February 2022 14:45:07 Tony Dinh wrote:
> > > Hi Pali,
> > >
> > > Some compile errors, please see below.
> > >
> > > On Sun, Feb 13, 2022 at 8:16 AM Pali Rohár <pali at kernel.org> wrote:
> > > >
> > > > On Wednesday 22 December 2021 20:08:56 Tony Dinh wrote:
> > > > > *** Run kwboot
> > > > >
> > > > > # kwboot -t -p -B 115200 /dev/ttyUSB0 -D /localdisk/mtd0.t5335z
> > > > > Patching image boot signature to UART
> > > > > Aligning image header to Xmodem block size
> > > > > Waiting 2s and flushing tty
> > > > > Sending boot image header (512 bytes)...
> > > > >  25 % [....                                                                  ]
> > > > > Done
> > > > > Sending boot image data (607664 bytes)...
> > > > >   0 % [......................................................................]
> > > > >   1 % [......................................................................]
> > > > >   2 % [......................................................................]
> > > > > <snip>
> > > > >  95 % [......................................................................]
> > > > >  97 % [......................................................................]
> > > > >  98 % [..........................................................            ]
> > > > > Done
> > > > > Finishing transfer
> > > > > [Type Ctrl-\ + c to quit]
> > > > >
> > > > > *** Hung here! BootROM did not execute the image payload.
> > > > > ***
> > > > > *** The file mtd0.t5335z is a dd dump from the SPI flash mtd0 with
> > > > > *** this command:
> > > > > ***     # dd if=/dev/mtd0 of=mtd0.t5335z bs=768k conv=sync
> > > > >
> > > > > <End log>
> > > > >
> > > > >
> > > > > - Pali's observation:
> > > > >
> > > > > It looks like Dove uses kwbimage v0 format with extensions, at
> > > > > least according to Function Spec. See 'Binary Code Extension' and
> > > > > 'Header Extension'. Currently kwboot and kwbimage supports v0 image only
> > > > > with one extension.
> > > >
> > > > I quickly looked at it. Could you try following patch?
> > > >
> > > > diff --git a/tools/kwbimage.h b/tools/kwbimage.h
> > > > index 74e5d87a4fef..15e83ececc76 100644
> > > > --- a/tools/kwbimage.h
> > > > +++ b/tools/kwbimage.h
> > > > @@ -61,14 +64,46 @@ struct ext_hdr_v0_reg {
> > > >         uint32_t rdata;
> > > >  } __packed;
> > > >
> > > > -#define EXT_HDR_V0_REG_COUNT ((0x1dc - 0x20) / sizeof(struct ext_hdr_v0_reg))
> > > > -
> > > > +/* Structure of the extension header, version 0 (Kirkwood, Dove) */
> > > >  struct ext_hdr_v0 {
> > > > -       uint32_t              offset;
> > > > -       uint8_t               reserved[0x20 - sizeof(uint32_t)];
> > > > -       struct ext_hdr_v0_reg rcfg[EXT_HDR_V0_REG_COUNT];
> > > > -       uint8_t               reserved2[7];
> > > > -       uint8_t               checksum;
> > > > +       /*
> > > > +        * Beware that extension header offsets specified in 88AP510 Functional
> > > > +        * Specifications are relative to the start of the main header, not to
> > > > +        * the start of the extension header itself.
> > > > +        */
> > > > +       uint32_t offset;                /* 0x0-0x3     */
> > > > +       uint8_t  rsvd1[8];              /* 0x4-0xB     */
> > > > +       uint32_t ddrinitdelay;          /* 0xC-0xF     */
> > > > +       uint32_t match_addr;            /* 0x10-0x13   */
> > > > +       uint32_t match_mask;            /* 0x14-0x17   */
> > > > +       uint32_t match_value;           /* 0x18-0x1B   */
> > > > +       uint8_t  ddrwritetype;          /* 0x1C        */
> > > > +       uint8_t  ddrresetmpp;           /* 0x1D        */
> > > > +       uint8_t  ddrclkenmpp;           /* 0x1E        */
> > > > +       uint8_t  ddrmppdelay;           /* 0x1F        */
> > > > +       struct ext_hdr_v0_reg rcfg[55]; /* 0x20-0x1D7  */
> > > > +       uint8_t  rsvd2[7];              /* 0x1D8-0x1DE */
> > > > +       uint8_t  checksum;              /* 0x1DF       */
> > > > +} __packed;
> > > > +
> > > > +/* Structure of the binary code header, version 0 (Dove) */
> > > > +struct binext_hdr_v0 {
> > > > +       uint32_t match_addr;            /* 0x00-0x03  */
> > > > +       uint32_t match_mask;            /* 0x04-0x07  */
> > > > +       uint32_t match_value;           /* 0x08-0x0B  */
> > > > +       uint32_t offset;                /* 0x0C-0x0F  */
> > > > +       uint32_t destaddr;              /* 0x10-0x13  */
> > > > +       uint32_t size;                  /* 0x14-0x17  */
> > > > +       uint32_t execaddr;              /* 0x18-0x1B  */
> > > > +       uint32_t param1;                /* 0x1C-0x1F  */
> > > > +       uint32_t param2;                /* 0x20-0x23  */
> > > > +       uint32_t param3;                /* 0x24-0x27  */
> > > > +       uint32_t param4;                /* 0x28-0x2B  */
> > > > +       uint8_t  params;                /* 0x2C       */
> > > > +       uint8_t  rsvd1;                 /* 0x2D       */
> > > > +       uint8_t  rsvd2;                 /* 0x2E       */
> > > > +       uint8_t  checksum;              /* 0x2F       */
> > > > +       uint8_t  code[2000];            /* 0x30-0x7FF */
> > > >  } __packed;
> > > >
> > > >  /* Structure of the main header, version 1 (Armada 370/XP/375/38x/39x) */
> > > > @@ -213,8 +248,20 @@ static inline size_t kwbheader_size(const void *header)
> > > >         if (kwbimage_version(header) == 0) {
> > > >                 const struct main_hdr_v0 *hdr = header;
> > > >
> > > > +               /*
> > > > +                * First extension header starts immediately after the main
> > > > +                * header without any padding. Between extension headers is
> > > > +                * 0x20 byte padding. There is no padding after the last
> > > > +                * extension header. First binary code header starts immediately
> > > > +                * after the last extension header (or immediately after the
> > > > +                * main header if there is no extension header) without any
> > > > +                * padding. There is no padding between binary code headers and
> > > > +                * neither after the last binary code header.
> > > > +                */
> > > >                 return sizeof(*hdr) +
> > > > -                      hdr->ext ? sizeof(struct ext_hdr_v0) : 0;
> > > > +                      hdr->ext * sizeof(struct ext_hdr_v0) +
> > > > +                      ((hdr->ext > 1) ? (hdr->ext * 0x20) : 0) +
> > > > +                      hdr->binext * sizeof(struct binext_hdr_v0);
> > > >         } else {
> > > >                 const struct main_hdr_v1 *hdr = header;
> > > >
> > > >
> > > >
> > > > It fixes kwbheader_size() function to returns correct size of the image
> > > > header (with all v0 extensions), so it could help kwboot to convert
> > > > image with non-UART sign to UART version and send it over UART.
> > >
> > > Applied the patch, and make tools gave this error:
> > >
> > > tools/kwbimage.h:255:13: error: ‘const struct main_hdr_v0’ has no
> > > member named ‘binext’
> > >  255 |          hdr->binext * sizeof(struct binext_hdr_v0);
> > >
> > > Thanks,
> > > Tony
> >
> > Ah, I have not sent whole patch...
> >
> > In tools/kwbimage.h for struct main_hdr_v0 { ... } replace
> >
> >   uint16_t rsvd2;
> >
> > by
> >
> >   uint8_t  rsvd2;
> >   uint8_t  binext;
> >
> >
> 
> Fixed that, and then I ran it the same way before. In the serial
> console, tell BootROM to set the boot device to UART, and then exit,
> run kwboot.
> 
> <BEGIN log>
> 
> Bootstrap 2.33>x 0x0E
> 
> Terminating...
> Thanks for using picocom
> 
> ./kwboot-2022/kwboot.dove -t -p -B 115200 /dev/ttyUSB0 -D ./t5335z/mtd0.t5335z
> kwboot version 2022.04-rc1-00360-g162c22bfbc-dirty
> Patching image boot signature to UART
> Sending boot image header (3072 bytes)...
>   4 % [........................                                              ]
> Done
> Sending boot image data (605104 bytes)...
>   0 % [......................................................................]
> <snip>
>  97 % [......................................................................]
>  99 % [......................................                                ]
> Done
> Finishing transfer
> [Type Ctrl-\ + c to quit]
> <END log>
> 
> It hung here. And I have to recycle power to boot again.
> 
> Observation: in the previous run with unpatched kwboot, the header
> size was 512 bytes, and the image was 607664 bytes. So this time
> kwboot sends the extension header, too. Not sure if 3072 bytes is
> correct.

If I parsed that image (file mtd0.t5335z) correctly it has:
* main header  (0x20)
* ext header   (0x1E0)
* 0x20 padding (0x20)
* ext header   (0x1E0)
* bin header   (0x800)
* image data   (0x93bb0)

So it is: 3072 bytes for headers + 605104 bytes for image data, which
now matches.

Plus in main header is stored that image data starts at offset 0xc00
which is 3072 bytes.

Now kwboot showed just that is patching UART signature and no more
alignment, so it should send headers and data without adding any
additional padding or alignment.

If it still does not work, I do not have an idea...

It would be required to take U-Boot source code for that board and build
UART image from sources. Maybe UART version needs to be compiled
differently, like it was in past also for Armada builds.

> Thanks,
> Tony


More information about the U-Boot mailing list