mirror of
https://github.com/Fishwaldo/bl_mcu_sdk.git
synced 2025-07-05 20:38:45 +00:00
[feat][boot2] add bl616 boot2 iap demo
This commit is contained in:
parent
1b35880999
commit
8d6352419a
34 changed files with 7421 additions and 0 deletions
277
examples/boot2_isp/blsp_boot_decompress.c
Normal file
277
examples/boot2_isp/blsp_boot_decompress.c
Normal file
|
@ -0,0 +1,277 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file blsp_boot_decompress.c
|
||||
* @version V1.2
|
||||
* @date
|
||||
* @brief This file is the peripheral case c file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2018 Bouffalo Lab</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of Bouffalo Lab nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "xz.h"
|
||||
#include "blsp_bootinfo.h"
|
||||
#include "blsp_common.h"
|
||||
#include "blsp_media_boot.h"
|
||||
#include "softcrc.h"
|
||||
#include "partition.h"
|
||||
#include "bflb_flash.h"
|
||||
|
||||
#define BFLB_BOOT2_XZ_WRITE_BUF_SIZE 4 * 1024
|
||||
#define BFLB_BOOT2_XZ_READ_BUF_SIZE 4 * 1024
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief Decompress XZ Firmware
|
||||
*
|
||||
* @param srcAddress: Source address on flash
|
||||
* @param destAddress: Destination address on flash
|
||||
* @param destMaxSize: Destination flash region size for erase
|
||||
* @param pDestSize: Pointer for output destination firmware size
|
||||
*
|
||||
* @return Decompress result status
|
||||
*
|
||||
*******************************************************************************/
|
||||
static int32_t blsp_boot2_fw_decompress(uint32_t src_address, uint32_t dest_address, uint32_t dest_max_size, uint32_t *p_dest_size)
|
||||
{
|
||||
struct xz_buf b;
|
||||
struct xz_dec *s;
|
||||
enum xz_ret ret;
|
||||
|
||||
*p_dest_size = 0;
|
||||
|
||||
if (dest_max_size > 0) {
|
||||
bflb_flash_erase(dest_address, dest_max_size);
|
||||
}
|
||||
|
||||
xz_crc32_init();
|
||||
simple_malloc_init(g_malloc_buf, sizeof(g_malloc_buf));
|
||||
|
||||
/*
|
||||
* Support up to 32k dictionary. The actually needed memory
|
||||
* is allocated once the headers have been parsed.
|
||||
*/
|
||||
s = xz_dec_init(XZ_PREALLOC, 1 << 15);
|
||||
|
||||
if (s == NULL) {
|
||||
//LOG_E("Memory allocation failed\n");
|
||||
return BFLB_BOOT2_MEM_ERROR;
|
||||
}
|
||||
|
||||
b.in = vmalloc(BFLB_BOOT2_XZ_READ_BUF_SIZE);
|
||||
b.in_pos = 0;
|
||||
b.in_size = 0;
|
||||
b.out = vmalloc(BFLB_BOOT2_XZ_WRITE_BUF_SIZE);
|
||||
b.out_pos = 0;
|
||||
b.out_size = BFLB_BOOT2_XZ_WRITE_BUF_SIZE;
|
||||
|
||||
while (1) {
|
||||
if (b.in_pos == b.in_size) {
|
||||
LOG_F("XZ Feeding\r\n");
|
||||
|
||||
if (BFLB_BOOT2_SUCCESS != blsp_mediaboot_read(src_address, (uint8_t *)b.in, BFLB_BOOT2_XZ_READ_BUF_SIZE)) {
|
||||
//LOG_E("Read XZFW fail\r\n");
|
||||
return BFLB_BOOT2_FLASH_READ_ERROR;
|
||||
}
|
||||
|
||||
b.in_size = BFLB_BOOT2_XZ_READ_BUF_SIZE;
|
||||
b.in_pos = 0;
|
||||
src_address += BFLB_BOOT2_XZ_READ_BUF_SIZE;
|
||||
}
|
||||
|
||||
ret = xz_dec_run(s, &b);
|
||||
|
||||
if (b.out_pos == BFLB_BOOT2_XZ_WRITE_BUF_SIZE) {
|
||||
//if (fwrite(out, 1, b.out_pos, stdout) != b.out_pos) {
|
||||
// msg = "Write error\n";
|
||||
// goto error;
|
||||
//}'
|
||||
LOG_F("XZ outputing\r\n");
|
||||
|
||||
if (dest_max_size > 0) {
|
||||
bflb_flash_write(dest_address, b.out, BFLB_BOOT2_XZ_WRITE_BUF_SIZE);
|
||||
}
|
||||
|
||||
dest_address += BFLB_BOOT2_XZ_WRITE_BUF_SIZE;
|
||||
*p_dest_size += BFLB_BOOT2_XZ_WRITE_BUF_SIZE;
|
||||
b.out_pos = 0;
|
||||
}
|
||||
|
||||
if (ret == XZ_OK) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//if (fwrite(out, 1, b.out_pos, stdout) != b.out_pos
|
||||
// || fclose(stdout)) {
|
||||
// msg = "Write error\n";
|
||||
// goto error;
|
||||
//}
|
||||
if (b.out_pos > 0) {
|
||||
if (dest_max_size > 0) {
|
||||
bflb_flash_write(dest_address, b.out, b.out_pos);
|
||||
}
|
||||
|
||||
dest_address += b.out_pos;
|
||||
*p_dest_size += b.out_pos;
|
||||
}
|
||||
|
||||
switch (ret) {
|
||||
case XZ_STREAM_END:
|
||||
xz_dec_end(s);
|
||||
return 0;
|
||||
|
||||
case XZ_MEM_ERROR:
|
||||
//LOG_E("Memory allocation failed\n");
|
||||
goto error;
|
||||
|
||||
case XZ_MEMLIMIT_ERROR:
|
||||
//LOG_E("Memory usage limit reached\n");
|
||||
goto error;
|
||||
|
||||
case XZ_FORMAT_ERROR:
|
||||
LOG_E("Not a .xz file\n");
|
||||
goto error;
|
||||
|
||||
case XZ_OPTIONS_ERROR:
|
||||
//LOG_E("Unsupported options in the .xz headers\n");
|
||||
goto error;
|
||||
|
||||
case XZ_DATA_ERROR:
|
||||
case XZ_BUF_ERROR:
|
||||
LOG_E("File is corrupt\n");
|
||||
goto error;
|
||||
|
||||
default:
|
||||
LOG_E("XZ Bug!\n");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
error:
|
||||
xz_dec_end(s);
|
||||
return BFLB_BOOT2_FAIL;
|
||||
}
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief Update decompressed firmware to flash according to XZ firmware
|
||||
*
|
||||
* @param activeID: Active partition table ID
|
||||
* @param ptStuff: Pointer of partition table stuff
|
||||
* @param ptEntry: Pointer of active entry
|
||||
*
|
||||
* @return XZ firmware update result status
|
||||
*
|
||||
*******************************************************************************/
|
||||
int32_t blsp_boot2_update_fw(pt_table_id_type active_id, pt_table_stuff_config *pt_stuff, pt_table_entry_config *pt_entry)
|
||||
{
|
||||
uint8_t active_index = pt_entry->active_index;
|
||||
uint32_t new_fw_len;
|
||||
int32_t ret;
|
||||
|
||||
LOG_F("try to decomp,xz s addr %08x,d addr %08x\r\n",
|
||||
pt_entry->start_address[active_index],
|
||||
pt_entry->start_address[!(active_index & 0x01)]);
|
||||
|
||||
/* Try to check Image integrity: try to decompress */
|
||||
if (BFLB_BOOT2_SUCCESS != blsp_boot2_fw_decompress(pt_entry->start_address[active_index],
|
||||
pt_entry->start_address[!(active_index & 0x01)],
|
||||
0, &new_fw_len)) {
|
||||
#ifdef BLSP_BOOT2_ROLLBACK
|
||||
/* Decompress fail, try to rollback to old one */
|
||||
pt_entry->active_index = !(active_index & 0x01);
|
||||
pt_entry->age++;
|
||||
ret = pt_table_update_entry((pt_table_id_type)(!active_id), pt_stuff, pt_entry);
|
||||
|
||||
if (ret != PT_ERROR_SUCCESS) {
|
||||
//LOG_E("Rollback Update Partition table entry fail\r\n");
|
||||
return BFLB_BOOT2_FAIL;
|
||||
}
|
||||
#endif
|
||||
return BFLB_BOOT2_SUCCESS;
|
||||
}
|
||||
|
||||
LOG_F("get new fw len %d\r\n", new_fw_len);
|
||||
|
||||
if (new_fw_len > pt_entry->max_len[!(active_index & 0x01)]) {
|
||||
LOG_F("decomped img too large!\r\n");
|
||||
#ifdef BLSP_BOOT2_ROLLBACK
|
||||
/* Decompress fail, try to rollback to old one */
|
||||
pt_entry->active_index = !(active_index & 0x01);
|
||||
pt_entry->age++;
|
||||
ret = pt_table_update_entry((pt_table_id_type)(!active_id), pt_stuff, pt_entry);
|
||||
|
||||
if (ret != PT_ERROR_SUCCESS) {
|
||||
//LOG_E("Rollback Update Partition table entry fail\r\n");
|
||||
return BFLB_BOOT2_FAIL;
|
||||
}
|
||||
#endif
|
||||
return BFLB_BOOT2_SUCCESS;
|
||||
}
|
||||
|
||||
/* Do decompress */
|
||||
if (BFLB_BOOT2_SUCCESS == blsp_boot2_fw_decompress(pt_entry->start_address[active_index],
|
||||
pt_entry->start_address[!(active_index & 0x01)],
|
||||
pt_entry->max_len[!(active_index & 0x01)], &new_fw_len)) {
|
||||
pt_entry->active_index = !(active_index & 0x01);
|
||||
pt_entry->len = new_fw_len;
|
||||
pt_entry->age++;
|
||||
ret = pt_table_update_entry((pt_table_id_type)(!active_id), pt_stuff, pt_entry);
|
||||
|
||||
if (ret != PT_ERROR_SUCCESS) {
|
||||
//LOG_E("Update Partition table entry fail\r\n");
|
||||
return BFLB_BOOT2_FAIL;
|
||||
}
|
||||
} else {
|
||||
LOG_E("XZ Decomp fail\r\n");
|
||||
return BFLB_BOOT2_FAIL;
|
||||
}
|
||||
|
||||
LOG_F("get new fw len %d\r\n", new_fw_len);
|
||||
return BFLB_BOOT2_SUCCESS;
|
||||
}
|
||||
|
||||
/****************************************************************************/ /**
|
||||
* @brief Check if buffer is XZ header
|
||||
*
|
||||
* @param buffer: Buffer of firmware
|
||||
*
|
||||
* @return 1 for XZ firmware and 0 for not
|
||||
*
|
||||
*******************************************************************************/
|
||||
int blsp_boot2_verify_xz_header(uint8_t *buffer)
|
||||
{
|
||||
const uint8_t xz_header[6] = { 0xFD, '7', 'z', 'X', 'Z', 0x00 };
|
||||
|
||||
//const uint8_t xz_header[6] = { 0x42, 0x46, 0x4e, 0x50, 0x01, 0x00 };
|
||||
if (buffer) {
|
||||
if (!memcmp(buffer, xz_header, 6)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue