Commit ed0c2c0a9ead7d1b5739fc83cf99ac85a16cb979

Authored by Albert ARIBAUD \(3ADEV\)
Committed by Stefano Babic
1 parent 303a24435f

tools: mkimage: add support for Vybrid image format

This format can be flashed directly at address 0 of
the NAND FLASH, as it contains all necessary headers.

Signed-off-by: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>

Showing 8 changed files with 187 additions and 8 deletions Side-by-side Diff

... ... @@ -845,6 +845,12 @@
845 845 %.imx: %.bin
846 846 $(Q)$(MAKE) $(build)=arch/arm/imx-common $@
847 847  
  848 +%.vyb: %.imx
  849 + $(Q)$(MAKE) $(build)=arch/arm/cpu/armv7/vf610 $@
  850 +
  851 +quiet_cmd_copy = COPY $@
  852 + cmd_copy = cp $< $@
  853 +
848 854 u-boot.dtb: dts/dt.dtb
849 855 $(call cmd,copy)
850 856  
... ... @@ -144,5 +144,8 @@
144 144 ALL-y += u-boot.imx
145 145 endif
146 146 endif
  147 +ifneq ($(CONFIG_VF610),)
  148 +ALL-y += u-boot.vyb
  149 +endif
147 150 endif
arch/arm/cpu/armv7/vf610/Makefile
... ... @@ -6,4 +6,9 @@
6 6  
7 7 obj-y += generic.o
8 8 obj-y += timer.o
  9 +
  10 +MKIMAGEFLAGS_u-boot.vyb = -T vybridimage
  11 +
  12 +u-boot.vyb: u-boot.imx
  13 + $(call if_changed,mkimage)
... ... @@ -161,6 +161,7 @@
161 161 { IH_TYPE_RKIMAGE, "rkimage", "Rockchip Boot Image" },
162 162 { IH_TYPE_RKSD, "rksd", "Rockchip SD Boot Image" },
163 163 { IH_TYPE_RKSPI, "rkspi", "Rockchip SPI Boot Image" },
  164 + { IH_TYPE_VYBRIDIMAGE, "vybridimage", "Vybrid Boot Image", },
164 165 { IH_TYPE_ZYNQIMAGE, "zynqimage", "Xilinx Zynq Boot Image" },
165 166 { IH_TYPE_ZYNQMPIMAGE, "zynqmpimage", "Xilinx ZynqMP Boot Image" },
166 167 { IH_TYPE_FPGA, "fpga", "FPGA Image" },
include/configs/pcm052.h
... ... @@ -119,9 +119,8 @@
119 119 #define CONFIG_EXTRA_ENV_SETTINGS \
120 120 "fdt_high=0xffffffff\0" \
121 121 "initrd_high=0xffffffff\0" \
122   - "blimg_file=u-boot.imx\0" \
123   - "blsec_addr=0x81000000\0" \
124   - "blimg_addr=0x81000400\0" \
  122 + "blimg_file=u-boot.vyb\0" \
  123 + "blimg_addr=0x81000000\0" \
125 124 "kernel_file=zImage\0" \
126 125 "kernel_addr=0x82000000\0" \
127 126 "fdt_file=zImage.dtb\0" \
128 127  
... ... @@ -163,12 +162,11 @@
163 162 "nand read ${kernel_addr} kernel; " \
164 163 "nand read ${ram_addr} root; " \
165 164 "bootz ${kernel_addr} ${ram_addr} ${fdt_addr}\0" \
166   - "update_bootloader_from_tftp=mtdparts default; " \
167   - "nand read ${blsec_addr} bootloader; " \
168   - "mw.b ${blimg_addr} 0xff 0x5FC00; " \
169   - "if tftp ${blimg_addr} ${tftpdir}${blimg_file}; then " \
  165 + "update_bootloader_from_tftp=if tftp ${blimg_addr} "\
  166 + "${tftpdir}${blimg_file}; then " \
  167 + "mtdparts default; " \
170 168 "nand erase.part bootloader; " \
171   - "nand write ${blsec_addr} bootloader ${filesize}; fi_addr} bootloader ${filesize}; fi\0" \" \
  169 + "nand write ${blimg_addr} bootloader ${filesize}; fi_addr} bootloader ${filesize}; fi\0" \" \
172 170 "update_kernel_from_sd=if fatload mmc 0:2 ${kernel_addr} " \
173 171 "${kernel_file}; " \
174 172 "then mtdparts default; " \
... ... @@ -278,6 +278,7 @@
278 278 IH_TYPE_ZYNQIMAGE, /* Xilinx Zynq Boot Image */
279 279 IH_TYPE_ZYNQMPIMAGE, /* Xilinx ZynqMP Boot Image */
280 280 IH_TYPE_FPGA, /* FPGA Image */
  281 + IH_TYPE_VYBRIDIMAGE, /* VYBRID .vyb Image */
281 282  
282 283 IH_TYPE_COUNT, /* Number of image types */
283 284 };
... ... @@ -89,6 +89,7 @@
89 89 os_support.o \
90 90 pblimage.o \
91 91 pbl_crc32.o \
  92 + vybridimage.o \
92 93 $(ROCKCHIP_OBS) \
93 94 socfpgaimage.o \
94 95 lib/sha1.o \
  1 +/*
  2 + * Image manipulator for Vybrid SoCs
  3 + *
  4 + * Derived from vybridimage.c
  5 + *
  6 + * (C) Copyright 2016 DENX Software Engineering GmbH
  7 + * Written-by: Albert ARIBAUD <albert.aribaud@3adev.fr>
  8 + *
  9 + * SPDX-License-Identifier: GPL-2.0+
  10 + */
  11 +
  12 +#include "imagetool.h"
  13 +#include <compiler.h>
  14 +#include <image.h>
  15 +
  16 +/*
  17 + * NAND page 0 boot header
  18 + */
  19 +
  20 +struct nand_page_0_boot_header {
  21 + union {
  22 + uint32_t fcb[128];
  23 + uint8_t fcb_bytes[512];
  24 + }; /* 0x00000000 - 0x000001ff */
  25 + uint8_t sw_ecc[512]; /* 0x00000200 - 0x000003ff */
  26 + uint32_t padding[65280]; /* 0x00000400 - 0x0003ffff */
  27 + uint8_t ivt_prefix[1024]; /* 0x00040000 - 0x000403ff */
  28 +};
  29 +
  30 +/* signature byte for a readable block */
  31 +
  32 +static struct nand_page_0_boot_header vybridimage_header;
  33 +
  34 +static int vybridimage_check_image_types(uint8_t type)
  35 +{
  36 + if (type == IH_TYPE_VYBRIDIMAGE)
  37 + return EXIT_SUCCESS;
  38 + return EXIT_FAILURE;
  39 +}
  40 +
  41 +static uint8_t vybridimage_sw_ecc(uint8_t byte)
  42 +{
  43 + uint8_t bit0 = (byte & (1 << 0)) ? 1 : 0;
  44 + uint8_t bit1 = (byte & (1 << 1)) ? 1 : 0;
  45 + uint8_t bit2 = (byte & (1 << 2)) ? 1 : 0;
  46 + uint8_t bit3 = (byte & (1 << 3)) ? 1 : 0;
  47 + uint8_t bit4 = (byte & (1 << 4)) ? 1 : 0;
  48 + uint8_t bit5 = (byte & (1 << 5)) ? 1 : 0;
  49 + uint8_t bit6 = (byte & (1 << 6)) ? 1 : 0;
  50 + uint8_t bit7 = (byte & (1 << 7)) ? 1 : 0;
  51 + uint8_t res = 0;
  52 +
  53 + res |= ((bit6 ^ bit5 ^ bit3 ^ bit2) << 0);
  54 + res |= ((bit7 ^ bit5 ^ bit4 ^ bit2 ^ bit1) << 1);
  55 + res |= ((bit7 ^ bit6 ^ bit5 ^ bit1 ^ bit0) << 2);
  56 + res |= ((bit7 ^ bit4 ^ bit3 ^ bit0) << 3);
  57 + res |= ((bit6 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0) << 4);
  58 +
  59 + return res;
  60 +}
  61 +
  62 +static int vybridimage_verify_header(unsigned char *ptr, int image_size,
  63 + struct image_tool_params *params)
  64 +{
  65 + struct nand_page_0_boot_header *hdr =
  66 + (struct nand_page_0_boot_header *)ptr;
  67 + int idx;
  68 +
  69 + if (hdr->fcb[1] != 0x46434220)
  70 + return -1;
  71 + if (hdr->fcb[2] != 1)
  72 + return -1;
  73 + if (hdr->fcb[7] != 64)
  74 + return -1;
  75 + if (hdr->fcb[14] != 6)
  76 + return -1;
  77 + if (hdr->fcb[30] != 0x0001ff00)
  78 + return -1;
  79 + if (hdr->fcb[43] != 1)
  80 + return -1;
  81 + if (hdr->fcb[54] != 0)
  82 + return -1;
  83 + if (hdr->fcb[55] != 8)
  84 + return -1;
  85 +
  86 + /* check software ECC */
  87 + for (idx = 0; idx < sizeof(hdr->fcb_bytes); idx++) {
  88 + uint8_t sw_ecc = vybridimage_sw_ecc(hdr->fcb_bytes[idx]);
  89 + if (sw_ecc != hdr->sw_ecc[idx])
  90 + return -1;
  91 + }
  92 +
  93 + return 0;
  94 +}
  95 +
  96 +static void vybridimage_set_header(void *ptr, struct stat *sbuf, int ifd,
  97 + struct image_tool_params *params)
  98 +{
  99 + struct nand_page_0_boot_header *hdr =
  100 + (struct nand_page_0_boot_header *)ptr;
  101 + int idx;
  102 +
  103 + /* fill header with 0x00 for first 56 entries then 0xff */
  104 + memset(&hdr->fcb[0], 0x0, 56*sizeof(uint32_t));
  105 + memset(&hdr->fcb[56], 0xff, 72*sizeof(uint32_t));
  106 + /* fill SW ecc and padding with 0xff */
  107 + memset(&hdr->sw_ecc[0], 0xff, sizeof(hdr->sw_ecc));
  108 + memset(&hdr->padding[0], 0xff, sizeof(hdr->padding));
  109 + /* fill IVT prefix with 0x00 */
  110 + memset(&hdr->ivt_prefix[0], 0x00, sizeof(hdr->ivt_prefix));
  111 +
  112 + /* populate fcb */
  113 + hdr->fcb[1] = 0x46434220; /* signature */
  114 + hdr->fcb[2] = 0x00000001; /* version */
  115 + hdr->fcb[5] = 2048; /* page size */
  116 + hdr->fcb[6] = (2048+64); /* page + OOB size */
  117 + hdr->fcb[7] = 64; /* pages per block */
  118 + hdr->fcb[14] = 6; /* ECC mode 6 */
  119 + hdr->fcb[26] = 128; /* fw address (0x40000) in 2K pages */
  120 + hdr->fcb[27] = 128; /* fw address (0x40000) in 2K pages */
  121 + hdr->fcb[30] = 0x0001ff00; /* DBBT search area start address */
  122 + hdr->fcb[33] = 2048; /* BB marker physical offset */
  123 + hdr->fcb[43] = 1; /* DISBBM */
  124 + hdr->fcb[54] = 0; /* DISBB_Search */
  125 + hdr->fcb[55] = 8; /* Bad block search limit */
  126 +
  127 + /* compute software ECC */
  128 + for (idx = 0; idx < sizeof(hdr->fcb_bytes); idx++)
  129 + hdr->sw_ecc[idx] = vybridimage_sw_ecc(hdr->fcb_bytes[idx]);
  130 +}
  131 +
  132 +static void vybridimage_print_hdr_field(struct nand_page_0_boot_header *hdr,
  133 + int idx)
  134 +{
  135 + printf("header.fcb[%d] = %08x\n", idx, hdr->fcb[idx]);
  136 +}
  137 +
  138 +static void vybridimage_print_header(const void *ptr)
  139 +{
  140 + struct nand_page_0_boot_header *hdr =
  141 + (struct nand_page_0_boot_header *)ptr;
  142 + int idx;
  143 +
  144 + for (idx = 0; idx < 56; idx++)
  145 + vybridimage_print_hdr_field(hdr, idx);
  146 +}
  147 +
  148 +/*
  149 + * vybridimage parameters
  150 + */
  151 +U_BOOT_IMAGE_TYPE(
  152 + vybridimage,
  153 + "Vybrid Boot Image",
  154 + sizeof(vybridimage_header),
  155 + (void *)&vybridimage_header,
  156 + NULL,
  157 + vybridimage_verify_header,
  158 + vybridimage_print_header,
  159 + vybridimage_set_header,
  160 + NULL,
  161 + vybridimage_check_image_types,
  162 + NULL,
  163 + NULL
  164 +);