From 46afd808b7d138a6fd83573688777c51739fef13 Mon Sep 17 00:00:00 2001 From: JianHang Wu Date: Mon, 9 Dec 2024 16:26:29 +0800 Subject: [PATCH] Scripts:do some optimizations. -add overlap checking, error reporting, info print functionality in gen_firmware_xml.c. -remove some redundant files(gen_spi_flash.c and gen_sg2044r_spi_flash.c,etc). If you need to add new board-level firmware, please follow the example to add the corresponding information at the head of gen_firmware_xml.c file. Additionally, add or modify the relevant functions in envsetup.sh (including specifying the release-note path and macros, etc). Signed-off-by: JianHang Wu --- scripts/envsetup.sh | 22 +- scripts/gen_sg2044r_spi_flash.c | 191 ------------ scripts/gen_spi_flash.c | 228 -------------- scripts/make_pack_tool.sh | 13 - scripts/make_xml.c | 158 ---------- scripts/pack/pack.c | 181 ----------- .../{pack => pack_firmware_bin}/.gitignore | 0 scripts/{pack => pack_firmware_bin}/README.md | 0 .../ezxml/GNUmakefile | 0 .../ezxml/Makefile | 0 .../ezxml/changelog.txt | 0 .../{pack => pack_firmware_bin}/ezxml/ezxml.c | 0 .../{pack => pack_firmware_bin}/ezxml/ezxml.h | 0 .../ezxml/ezxml.html | 0 .../ezxml/ezxml.txt | 0 .../ezxml/license.txt | 0 scripts/pack_firmware_bin/gen_firmware_xml.c | 295 ++++++++++++++++++ scripts/pack_firmware_bin/pack_firmware_bin.c | 216 +++++++++++++ 18 files changed, 529 insertions(+), 775 deletions(-) delete mode 100644 scripts/gen_sg2044r_spi_flash.c delete mode 100644 scripts/gen_spi_flash.c delete mode 100644 scripts/make_pack_tool.sh delete mode 100644 scripts/make_xml.c delete mode 100644 scripts/pack/pack.c rename scripts/{pack => pack_firmware_bin}/.gitignore (100%) rename scripts/{pack => pack_firmware_bin}/README.md (100%) rename scripts/{pack => pack_firmware_bin}/ezxml/GNUmakefile (100%) rename scripts/{pack => pack_firmware_bin}/ezxml/Makefile (100%) rename scripts/{pack => pack_firmware_bin}/ezxml/changelog.txt (100%) rename scripts/{pack => pack_firmware_bin}/ezxml/ezxml.c (100%) rename scripts/{pack => pack_firmware_bin}/ezxml/ezxml.h (100%) rename scripts/{pack => pack_firmware_bin}/ezxml/ezxml.html (100%) rename scripts/{pack => pack_firmware_bin}/ezxml/ezxml.txt (100%) rename scripts/{pack => pack_firmware_bin}/ezxml/license.txt (100%) create mode 100644 scripts/pack_firmware_bin/gen_firmware_xml.c create mode 100644 scripts/pack_firmware_bin/pack_firmware_bin.c diff --git a/scripts/envsetup.sh b/scripts/envsetup.sh index 96701c92..e3fb9cbe 100755 --- a/scripts/envsetup.sh +++ b/scripts/envsetup.sh @@ -1487,11 +1487,21 @@ function build_rv_firmware_bin() { RELEASED_NOTE_PATH=$RV_TOP_DIR/bootloader-riscv/release-note build_rv_firmware - source $RV_SCRIPTS_DIR/make_pack_tool.sh $CHIP - if [ ! -e "$RELEASED_NOTE_MD" ] || [ ! -s "$RELEASED_NOTE_MD" ];then + gcc $RV_SCRIPTS_DIR/pack_firmware_bin/gen_firmware_xml.c -D${CHIP^^} -o $RV_FIRMWARE_INSTALL_DIR/make_xml + gcc $RV_SCRIPTS_DIR/pack_firmware_bin/pack_firmware_bin.c -o $RV_FIRMWARE_INSTALL_DIR/pack + + if [ "$CHIP" = "mango" ];then + RELEASED_NOTE_MD="$RELEASED_NOTE_PATH/sg2042_release_note.md" + cp $RV_FIRMWARE/fip.bin $RV_FIRMWARE_INSTALL_DIR/ + elif [ "$CHIP" = "sg2044" ];then + RELEASED_NOTE_MD="$RELEASED_NOTE_PATH/sg2044_release_note.md" + fi + + if [ ! -e "$RELEASEDOTE_MD" ] || [ ! -s "$RELEASED_NOTE_MD" ];then version="1.0.0" - else + else + cp $RELEASED_NOTE_MD $RV_FIRMWARE_INSTALL_DIR/ version=$(awk 'END {split($1, a, "_"); print a[1]}' $RELEASED_NOTE_MD) fi @@ -1499,6 +1509,10 @@ function build_rv_firmware_bin() rm -f firmware*.bin *.xml ./make_xml *.dtb + if [ $? -ne 0 ];then + popd + return + fi mkdir -p $RV_SCRIPTS_DIR/build/ && cp ./*.xml $RV_SCRIPTS_DIR/build/ ./pack *.xml rm -f make_xml pack @@ -1508,7 +1522,7 @@ function build_rv_firmware_bin() cp firmware-$version.bin image-bmc $RV_SCRIPTS_DIR/gen-tar-for-bmc.sh image-bmc -o obmc-bios.tar.gz -m ast2600-sophgo -v $version -s fi - rm -f image-bmc *.xml + rm -f image-bmc *.xml *.md popd } diff --git a/scripts/gen_sg2044r_spi_flash.c b/scripts/gen_sg2044r_spi_flash.c deleted file mode 100644 index 4fbcc10d..00000000 --- a/scripts/gen_sg2044r_spi_flash.c +++ /dev/null @@ -1,191 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SPI_FLASH_MAX_SIZE 0x4000000 -#define DISK_PART_TABLE_ADDR 0x80000 -#define BUFFER_SIZE 1024 -#define UP_4K_ALIGN 0x1000 -#define NUM_PAR_PER_PART 4 - -enum { - DPT_MAGIC = 0x55aa55aa, -}; - -/* disk partition table */ -struct part_info { - /* disk partition table magic number */ - uint32_t magic; - char name[32]; - uint32_t offset; - uint32_t size; - char reserve[4]; - /* load memory address*/ - uint64_t lma; -}; - -static int spi_flash_pack(int fd_spi, struct part_info *info, const char *name) -{ - int fd, i; - unsigned char buf[BUFFER_SIZE]; - int read_len; - int pack_size = 0; - - fd = open(name, O_RDONLY, 0); - if (fd < 0) { - printf("open %s failed\n", name); - return fd; - } - - lseek(fd_spi, info->offset, SEEK_SET); - while ((read_len = read(fd, buf, BUFFER_SIZE)) > 0) { - write(fd_spi, buf, read_len); - pack_size += read_len; - } - - close(fd); - - return pack_size; -} - -int paser_and_setup_part_info(struct part_info *info, - const char *part_name, - const char *file_name, - uint64_t lma, int offset) -{ - struct stat file_stat; - int len, size; - int ret; - const char xmr_name[] = "sg2044r_xmrig"; - - memset(info, 0, sizeof(struct part_info)); - - len = strlen(part_name); - size = sizeof(info->name); - ret = stat(file_name, &file_stat); - if (ret || !file_stat.st_size) { - printf("can't get file %s size %ld\n", file_name, - file_stat.st_size); - return -1; - } - - info->magic = DPT_MAGIC; - memcpy(info->name, part_name, len > size ? size : len); - - if (!memcmp(xmr_name, part_name, len)) { - info->offset = (offset + (UP_4K_ALIGN - 1)) & ~(UP_4K_ALIGN - 1); - } else { - info->offset = offset; - } - - info->size = file_stat.st_size; - info->lma = lma; - - printf("%s offset:0x%x size:0x%x lma:0x%lx\n", - info->name, info->offset, - info->size, info->lma); - - if (info->offset + info->size > SPI_FLASH_MAX_SIZE) { - printf("%s too big\n", info->name); - return -1; - } - - return 0; -} - -int main(int argc, char **argv) -{ - int part_num, offset, size, ret, i; - int fd_spi; - struct stat fd_statbuf; - unsigned char raw_byte; - char *part_name, *file_name; - struct part_info *info; - uint64_t lma, flash_offset; - unsigned char zero_byte = 0; - - fd_spi = open("./spi_flash_xmr.bin", O_CREAT | O_RDWR, 0644); - if (fd_spi < 0) { - ret = errno; - printf("open spi_flash failed %d\n", ret); - return ret; - } - - part_num = (argc - 1) / NUM_PAR_PER_PART; - offset = DISK_PART_TABLE_ADDR + sizeof(struct part_info) * part_num; - offset = (offset + UP_4K_ALIGN - 1) & ~(UP_4K_ALIGN - 1); - info = malloc(sizeof(struct part_info) * part_num); - if (info == NULL) { - printf("failed to malloc\n"); - goto failed_pack; - } - - for (i = 0; i < part_num; i++) { - part_name = argv[i * NUM_PAR_PER_PART + 1]; - file_name = argv[i * NUM_PAR_PER_PART + 2]; - ret = sscanf(argv[i * NUM_PAR_PER_PART + 3], "0x%lx", - &flash_offset); - if (ret < 0) { - printf("sscanf flash_offset error\n"); - goto failed_pack; - } - - /* dtb files are placed after partition table by default */ - if (i != 0 && (strstr(part_name, "dtb") != NULL || - strstr(file_name, "dtb") != NULL) ) { - flash_offset = offset; - } else { - if (flash_offset & (UP_4K_ALIGN - 1)) { - printf("Flash offset needs aligned to 4KB.\n"); - flash_offset = (flash_offset + UP_4K_ALIGN - 1) - & ~(UP_4K_ALIGN - 1); - } - - if (offset > flash_offset) { - printf("Flash offset overlaps with the previous file.\ - flash_offset=0x%lx\toffset=0x%x\n", - flash_offset, offset); - goto failed_pack; - } - - offset = flash_offset; - } - - ret = sscanf(argv[i * NUM_PAR_PER_PART + 4], "0x%lx", &lma); - if (ret < 0) { - printf("sscanf lma error\n"); - goto failed_pack; - } - - ret = paser_and_setup_part_info(&info[i], part_name, file_name, - lma, flash_offset); - if (ret) { - printf("failed to setup part info\n"); - goto failed_pack; - } - - size = spi_flash_pack(fd_spi, &info[i], file_name); - if (size <= 0) { - printf("failed to pack spi flash\n"); - goto failed_pack; - } - offset += size; - } - - /* write partition table */ - lseek(fd_spi, DISK_PART_TABLE_ADDR, SEEK_SET); - write(fd_spi, info, sizeof(struct part_info) * part_num); - -failed_pack: - close(fd_spi); - free(info); - - return ret; -} diff --git a/scripts/gen_spi_flash.c b/scripts/gen_spi_flash.c deleted file mode 100644 index 1d0ef51b..00000000 --- a/scripts/gen_spi_flash.c +++ /dev/null @@ -1,228 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SPIF_OFFSET_A_FIP 0x00030000 // 192KB -#define SPIF_OFFSET_B_FIP 0x00230000 // 2MB + 192KB - -#define SPI_FLASH_MAX_SIZE 0x4000000 -#define DISK_PART_TABLE_ADDR 0x600000 -#define BUFFER_SIZE 1024 -#define UP_4K_ALIGN 0x1000 -#define NUM_PAR_PER_PART 4 - -enum { - DPT_MAGIC = 0x55aa55aa, -}; - -/* disk partition table */ -struct part_info { - /* disk partition table magic number */ - uint32_t magic; - char name[32]; - uint32_t offset; - uint32_t size; - char reserve[4]; - /* load memory address*/ - uint64_t lma; -}; - -static int spi_flash_pack(int fd_spi, struct part_info *info, const char *name) -{ - int fd, i; - unsigned char buf[BUFFER_SIZE]; - int read_len; - int pack_size = 0; - - fd = open(name, O_RDONLY, 0); - if (fd < 0) { - printf("open %s failed\n", name); - return fd; - } - - lseek(fd_spi, info->offset, SEEK_SET); - while ((read_len = read(fd, buf, BUFFER_SIZE)) > 0) { - write(fd_spi, buf, read_len); - pack_size += read_len; - } - - close(fd); - - return pack_size; -} - -int paser_and_setup_part_info(struct part_info *info, - const char *part_name, - const char *file_name, - uint64_t lma, int offset) -{ - struct stat file_stat; - int len, size; - int ret; - const char xmr_name[] = "mango_xmrig"; - const char xmr_bak_name[] = "xmr_app_bak"; - - memset(info, 0, sizeof(struct part_info)); - - len = strlen(part_name); - size = sizeof(info->name); - ret = stat(file_name, &file_stat); - if (ret || !file_stat.st_size) { - printf("can't get file %s size %ld\n", file_name, - file_stat.st_size); - return -1; - } - - info->magic = DPT_MAGIC; - memcpy(info->name, part_name, len > size ? size : len); - - if (!memcmp(xmr_name, part_name, len)) { - info->offset = (offset + (UP_4K_ALIGN - 1)) & ~(UP_4K_ALIGN - 1); - } else if (!memcmp(xmr_bak_name, part_name, len)) { - info->offset = (offset + (UP_4K_ALIGN - 1)) & ~(UP_4K_ALIGN - 1); - } else { - info->offset = offset; - } - - info->size = file_stat.st_size; - info->lma = lma; - - printf("%s offset:0x%x size:0x%x lma:0x%lx\n", - info->name, info->offset, - info->size, info->lma); - - if (info->offset + info->size > SPI_FLASH_MAX_SIZE) { - printf("%s too big\n", info->name); - return -1; - } - - return 0; -} - -int main(int argc, char **argv) -{ - int part_num, offset, size, ret, i; - int fd_spi, fd_fip; - struct stat fd_statbuf; - unsigned char raw_byte; - char *part_name, *file_name; - struct part_info *info; - uint64_t lma, flash_offset; - unsigned char zero_byte = 0; - - fd_spi = open("./spi_flash.bin", O_CREAT | O_RDWR, 0644); - if (fd_spi < 0) { - ret = errno; - printf("open spi_flash failed %d\n", ret); - return ret; - } - - fd_fip = open("./fip.bin", O_RDONLY, 0); - if (fd_fip < 0) { - ret = errno; - printf("open fip failed %d\n", ret); - goto failed_pack; - } - - // pack fip.bin A - for ( offset = 0; offset < SPIF_OFFSET_A_FIP; offset++) - write(fd_spi, &zero_byte, 1); - stat("./fip.bin", &fd_statbuf); - printf("offset=0x%x, fip.bin 0x%lx\n", offset, fd_statbuf.st_size); - for (i = 0; i < fd_statbuf.st_size; i++) { - read(fd_fip, &raw_byte, 1); - write(fd_spi, &raw_byte, 1); - offset++; - } - - lseek(fd_fip, 0, SEEK_SET); - - // pack fip.bin B - for ( ; offset < SPIF_OFFSET_B_FIP; offset++) - write(fd_spi, &zero_byte, 1); - printf("offset=0x%x, fip.bin 0x%lx\n", offset, fd_statbuf.st_size); - for (i = 0; i < fd_statbuf.st_size; i++) { - read(fd_fip, &raw_byte, 1); - write(fd_spi, &raw_byte, 1); - offset++; - } - - part_num = (argc - 1) / NUM_PAR_PER_PART; - offset = DISK_PART_TABLE_ADDR + sizeof(struct part_info) * part_num; - offset = (offset + UP_4K_ALIGN - 1) & ~(UP_4K_ALIGN - 1); - info = malloc(sizeof(struct part_info) * part_num); - if (info == NULL) { - printf("failed to malloc\n"); - goto failed_pack; - } - - for (i = 0; i < part_num; i++) { - part_name = argv[i * NUM_PAR_PER_PART + 1]; - file_name = argv[i * NUM_PAR_PER_PART + 2]; - ret = sscanf(argv[i * NUM_PAR_PER_PART + 3], "0x%lx", - &flash_offset); - if (ret < 0) { - printf("sscanf flash_offset error\n"); - goto failed_pack; - } - - /* dtb files are placed after partition table by default */ - if (i != 0 && (strstr(part_name, "dtb") != NULL || - strstr(file_name, "dtb") != NULL) ) { - flash_offset = offset; - } else { - if (flash_offset & (UP_4K_ALIGN - 1)) { - printf("Flash offset needs aligned to 4KB.\n"); - flash_offset = (flash_offset + UP_4K_ALIGN - 1) - & ~(UP_4K_ALIGN - 1); - } - - if (offset > flash_offset) { - printf("Flash offset overlaps with the previous file.\ - flash_offset=0x%lx\toffset=0x%x\n", - flash_offset, offset); - goto failed_pack; - } - - offset = flash_offset; - } - - ret = sscanf(argv[i * NUM_PAR_PER_PART + 4], "0x%lx", &lma); - if (ret < 0) { - printf("sscanf lma error\n"); - goto failed_pack; - } - - ret = paser_and_setup_part_info(&info[i], part_name, file_name, - lma, flash_offset); - if (ret) { - printf("failed to setup part info\n"); - goto failed_pack; - } - - size = spi_flash_pack(fd_spi, &info[i], file_name); - if (size <= 0) { - printf("failed to pack spi flash\n"); - goto failed_pack; - } - offset += size; - } - - /* write partition table */ - lseek(fd_spi, DISK_PART_TABLE_ADDR, SEEK_SET); - write(fd_spi, info, sizeof(struct part_info) * part_num); - -failed_pack: - close(fd_spi); - close(fd_fip); - free(info); - - return ret; -} diff --git a/scripts/make_pack_tool.sh b/scripts/make_pack_tool.sh deleted file mode 100644 index e0324f92..00000000 --- a/scripts/make_pack_tool.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -if [ "$1" = "mango" ];then - gcc $RV_SCRIPTS_DIR/make_xml.c -DSG2042 -o $RV_FIRMWARE_INSTALL_DIR/make_xml - gcc $RV_SCRIPTS_DIR/pack/pack.c -DSG2042 -o $RV_FIRMWARE_INSTALL_DIR/pack - RELEASED_NOTE_MD="$RELEASED_NOTE_PATH/sg2042_release_note.md" - cp $RV_FIRMWARE/fip.bin $RV_FIRMWARE_INSTALL_DIR/ -elif [ "$1" = "sg2044" ];then - gcc $RV_SCRIPTS_DIR/make_xml.c -DSG2044 -o $RV_FIRMWARE_INSTALL_DIR/make_xml - gcc $RV_SCRIPTS_DIR/pack/pack.c -DSG2044 -o $RV_FIRMWARE_INSTALL_DIR/pack - RELEASED_NOTE_MD="$RELEASED_NOTE_PATH/sg2044_release_note.md" - cp $RV_FIRMWARE/fsbl.bin $RV_FIRMWARE_INSTALL_DIR/ -fi \ No newline at end of file diff --git a/scripts/make_xml.c b/scripts/make_xml.c deleted file mode 100644 index 08c357f0..00000000 --- a/scripts/make_xml.c +++ /dev/null @@ -1,158 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "pack/ezxml/ezxml.h" -#include "pack/ezxml/ezxml.c" - -#define BUFFERSIZE 16 - -#define SG2042_DTB_OFFSET 0x601000 -#define SG2042_DTB_LOADER "0x20000000" -#define SG2044_DTB_OFFSET 0x500000 -#define SG2044_DTB_LOADER "0x88000000" - -void format_xml(const char *input,char *output){ - const char *ptr = input; - char *out_ptr = output; - int indent=0,marked=0; - while(*ptr){ - if(*ptr=='>'){ - if(*(ptr+1)=='<'){ - if(*(ptr+2)=='/'){ - *out_ptr++=*ptr++; - indent-=1; - marked=1; - } - else{ - if(marked){ - *out_ptr++=*ptr++; - marked=0; - } - else{ - indent+=1; - *out_ptr++=*ptr++; - } - } - *out_ptr++='\n'; - memset(out_ptr,'\t',indent); - out_ptr+=indent; - } - else{ - marked=1; - *out_ptr++=*ptr++; - } - }else{ - *out_ptr++=*ptr++; - } - } - *out_ptr = '\0'; -} - -int ezxml_set_element(ezxml_t parent,char *child,char *name,char *offset,char *loader,char* size){ - ezxml_t component=ezxml_add_child(parent,child,0); - if (component==NULL){ - ezxml_free(parent); - return -1; - } - if(name){ - ezxml_set_txt(ezxml_add_child(component, "name", 0), name); - ezxml_set_txt(ezxml_add_child(component, "file", 0), name); - } - if(offset){ - ezxml_set_txt(ezxml_add_child(component,"offset" , 0), offset); - } - if(loader){ - ezxml_set_txt(ezxml_add_child(component,"loader" , 0), loader); - } - if(size){ - ezxml_set_txt(ezxml_add_child(component,"size" , 0), size); - } - return 0; -} - -void ezxml_set_component(ezxml_t parent,char *comp_name,char *comp_offset,char *comp_loader){ - ezxml_set_element(parent,"component",comp_name,comp_offset,comp_loader,NULL); -} - -int main(int argc, char* argv[]) { - - struct stat file_stat; - int ret,i; - char* file_name,*out_put; - char *ld_dtb; - char sflash_offset[argc-1][BUFFERSIZE]; - uint64_t of_dtb; - ezxml_t xml = ezxml_new("firmware"); - if (xml==NULL){ - printf("generate xml file failed!"); - return -1; - } - // generate xml file - #ifdef SG2042 - of_dtb=SG2042_DTB_OFFSET; - ld_dtb=SG2042_DTB_LOADER; - ezxml_set_txt(ezxml_add_child(xml, "name", 0), "SG2042"); - ezxml_set_txt(ezxml_add_child(xml, "size", 0), "0x4000000"); - // add efie - ezxml_set_element(xml,"efie",NULL,"0x600000",NULL,"4096"); - //add fip.bin - ezxml_set_element(xml,"fip","fip.bin","0x00030000",NULL,NULL); - //add zsbl.bin - ezxml_set_component(xml,"zsbl.bin","0x2a00000","0x40000000"); - //add fw_dynamic.bin - ezxml_set_component(xml,"fw_dynamic.bin","0x660000","0x00000000"); - //add riscv64_Image - ezxml_set_component(xml,"riscv64_Image","0x6b0000","0x02000000"); - //add initrd.img - ezxml_set_component(xml,"initrd.img","0x2b00000","0x30000000"); - out_put="sg2042-layout.xml"; - #elif defined(SG2044) - of_dtb=SG2044_DTB_OFFSET; - ld_dtb=SG2044_DTB_LOADER; - ezxml_set_txt(ezxml_add_child(xml, "name", 0), "SG2044"); - ezxml_set_txt(ezxml_add_child(xml, "size", 0), "0x4000000"); - // add efie - ezxml_set_element(xml,"efie",NULL,"0x80000",NULL,"4096"); - //add zsbl.bin - ezxml_set_component(xml,"zsbl.bin","0x2f0000","0x40000000"); - //add fsbl.bin - ezxml_set_component(xml,"fsbl.bin","0x81000","0x7010080000"); - //add fw_dynamic.bin - ezxml_set_component(xml,"fw_dynamic.bin","0x15d000","0x80000000"); - //add SG2044.fd - ezxml_set_component(xml,"SG2044.fd","0x600000","0x80200000"); - out_put="sg2044-layout.xml"; - #endif - - // add device-tree - for (i=0;i\n"); - const char *raw_xml = ezxml_toxml(xml); - char formatted_xml[8192]; - format_xml(raw_xml, formatted_xml); - fprintf(fp, "%s", formatted_xml); - fclose(fp); - } - ezxml_free(xml); - return 0; -} diff --git a/scripts/pack/pack.c b/scripts/pack/pack.c deleted file mode 100644 index 43d2db36..00000000 --- a/scripts/pack/pack.c +++ /dev/null @@ -1,181 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ezxml/ezxml.h" -#include "ezxml/ezxml.c" - - - -enum { - DPT_MAGIC = 0x55aa55aa, -}; -#define UP_4K_ALIGN 0x1000 -#define BUFFER_SIZE 1024 -#define OUTPUT "firmware.bin" - -struct part_info { - /* disk partition table magic number */ - uint32_t magic; - char name[32]; - uint32_t offset; - uint32_t size; - char reserve[4]; - /* load memory address*/ - uint64_t lma; -}; - -int paser_and_setup_part_info(struct part_info *info, - const char *part_name, - const char *file_name, - uint64_t lma, int offset) -{ - struct stat file_stat; - int len, size; - int ret; - const char xmr_name[] = "mango_xmrig"; - const char xmr_bak_name[] = "xmr_app_bak"; - - memset(info, 0, sizeof(struct part_info)); - - len = strlen(part_name); - size = sizeof(info->name); - ret = stat(file_name, &file_stat); - if (ret || !file_stat.st_size) { - printf("can't get file %s size %ld\n", file_name, - file_stat.st_size); - return -1; - } - - info->magic = DPT_MAGIC; - memcpy(info->name, part_name, len > size ? size : len); - - if (!memcmp(xmr_name, part_name, len)) { - info->offset = (offset + (UP_4K_ALIGN - 1)) & ~(UP_4K_ALIGN - 1); - } else if (!memcmp(xmr_bak_name, part_name, len)) { - info->offset = (offset + (UP_4K_ALIGN - 1)) & ~(UP_4K_ALIGN - 1); - } else { - info->offset = offset; - } - - info->size = file_stat.st_size; - info->lma = lma; - - printf("%s offset:0x%x size:0x%x lma:0x%lx\n", - info->name, info->offset, - info->size, info->lma); - - // if (info->offset + info->size > SPI_FLASH_MAX_SIZE) { - // printf("%s too big\n", info->name); - // return -1; - // } - - return 0; -} -static int spi_flash_pack(int fd_spi, struct part_info *info, const char *name) -{ - int fd, i; - unsigned char buf[BUFFER_SIZE]; - int read_len; - int pack_size = 0; - - fd = open(name, O_RDONLY, 0); - if (fd < 0) { - printf("open %s failed\n", name); - return fd; - } - - lseek(fd_spi, info->offset, SEEK_SET); - while ((read_len = read(fd, buf, BUFFER_SIZE)) > 0) { - write(fd_spi, buf, read_len); - pack_size += read_len; - } - - close(fd); - - return pack_size; -} - -int pack_v3(int argc, char *argv[]){ - - char * __attribute__((unused)) firmware_name = "unknown_firmware"; - uint32_t firmware_size; - ezxml_t p,comp; - char *file=argv[1]; - printf("%s\n",argv[1]); - unsigned int comp_count; - int fd,ret,size,fd_fip; - // struct part_info *com_part; - - ezxml_t firmware=ezxml_parse_file(file); - if (strcmp(firmware->name, "firmware")) { - printf("not a valid layout file\n"); - return -1; - } - p=ezxml_child(firmware,"name"); - firmware_name=p->txt; - p=ezxml_child(firmware,"size"); - firmware_size=(uint32_t)strtoul(p->txt,NULL,16); - - ezxml_t efie; - uint32_t efie_offset,efie_size; - efie=ezxml_child(firmware,"efie"); - p=ezxml_child(efie,"offset"); - efie_offset=strtol(p->txt,NULL,16); - p=ezxml_child(efie,"size"); - efie_size=strtol(p->txt,NULL,0); - printf("efie offset:%X,size:%X\n",efie_offset,efie_size); - - fd = open(OUTPUT, O_CREAT | O_RDWR | O_TRUNC, 0644); - ezxml_t f; - uint32_t f_offset; - #ifdef SG2042 - fd_fip=open("./fip.bin", O_RDONLY, 0); - printf("open fip.bin success!\n"); - f=ezxml_child(firmware,"fip"); - p=ezxml_child(f,"offset"); - f_offset=(uint32_t)strtoul(p->txt,NULL,16); - int read_len; - unsigned char buf[BUFFER_SIZE]; - lseek(fd, f_offset, SEEK_SET); - while ((read_len = read(fd_fip, buf, BUFFER_SIZE)) > 0) { - write(fd, buf, read_len); - } - - #endif - - for (comp=ezxml_child(firmware,"component"),comp_count=0;comp;comp=comp->next,comp_count++){ - char *com_name=NULL, *com_file=NULL; - unsigned int com_type; - uint32_t com_offset; - uint64_t com_addr; - - p=ezxml_child(comp,"name"); - com_name=p->txt; - p=ezxml_child(comp,"file"); - com_file=p->txt; - p=ezxml_child(comp,"offset"); - com_offset=strtol(p->txt,NULL,16); - p=ezxml_child(comp,"loader"); - com_addr=strtol(p->txt,NULL,16); - struct part_info info; - ret=paser_and_setup_part_info(&info,com_name,com_file,com_addr,com_offset); - size = spi_flash_pack(fd, &info, com_file); - - lseek(fd, efie_offset+comp_count*sizeof(struct part_info), SEEK_SET); - write(fd, &info, sizeof(struct part_info)); - } - - return 0; -} - -int main(int argc, char *argv[]){ - pack_v3(argc,argv); - return 0; -} diff --git a/scripts/pack/.gitignore b/scripts/pack_firmware_bin/.gitignore similarity index 100% rename from scripts/pack/.gitignore rename to scripts/pack_firmware_bin/.gitignore diff --git a/scripts/pack/README.md b/scripts/pack_firmware_bin/README.md similarity index 100% rename from scripts/pack/README.md rename to scripts/pack_firmware_bin/README.md diff --git a/scripts/pack/ezxml/GNUmakefile b/scripts/pack_firmware_bin/ezxml/GNUmakefile similarity index 100% rename from scripts/pack/ezxml/GNUmakefile rename to scripts/pack_firmware_bin/ezxml/GNUmakefile diff --git a/scripts/pack/ezxml/Makefile b/scripts/pack_firmware_bin/ezxml/Makefile similarity index 100% rename from scripts/pack/ezxml/Makefile rename to scripts/pack_firmware_bin/ezxml/Makefile diff --git a/scripts/pack/ezxml/changelog.txt b/scripts/pack_firmware_bin/ezxml/changelog.txt similarity index 100% rename from scripts/pack/ezxml/changelog.txt rename to scripts/pack_firmware_bin/ezxml/changelog.txt diff --git a/scripts/pack/ezxml/ezxml.c b/scripts/pack_firmware_bin/ezxml/ezxml.c similarity index 100% rename from scripts/pack/ezxml/ezxml.c rename to scripts/pack_firmware_bin/ezxml/ezxml.c diff --git a/scripts/pack/ezxml/ezxml.h b/scripts/pack_firmware_bin/ezxml/ezxml.h similarity index 100% rename from scripts/pack/ezxml/ezxml.h rename to scripts/pack_firmware_bin/ezxml/ezxml.h diff --git a/scripts/pack/ezxml/ezxml.html b/scripts/pack_firmware_bin/ezxml/ezxml.html similarity index 100% rename from scripts/pack/ezxml/ezxml.html rename to scripts/pack_firmware_bin/ezxml/ezxml.html diff --git a/scripts/pack/ezxml/ezxml.txt b/scripts/pack_firmware_bin/ezxml/ezxml.txt similarity index 100% rename from scripts/pack/ezxml/ezxml.txt rename to scripts/pack_firmware_bin/ezxml/ezxml.txt diff --git a/scripts/pack/ezxml/license.txt b/scripts/pack_firmware_bin/ezxml/license.txt similarity index 100% rename from scripts/pack/ezxml/license.txt rename to scripts/pack_firmware_bin/ezxml/license.txt diff --git a/scripts/pack_firmware_bin/gen_firmware_xml.c b/scripts/pack_firmware_bin/gen_firmware_xml.c new file mode 100644 index 00000000..95f86d28 --- /dev/null +++ b/scripts/pack_firmware_bin/gen_firmware_xml.c @@ -0,0 +1,295 @@ +#include +#include +#include +#include +#include +#include +#include "ezxml/ezxml.h" +#include "ezxml/ezxml.c" +#include + +#define NAMESIZE 32 +#define LOADERSIZE 20 +#define INVALID "invalid" +#define FLASHSIZE 0x4000000 + +#ifdef SG2044R + #define PARTION{"efie","0x80000",\ + "fsbl.bin", "0x81000" ,"0x7010080000" ,\ + "fw_dynamic.bin", "0x15d000", "0x82200000", \ + "ap_Image" ,"0x2f0000" ,"0x82400000", \ + "ap_rootfs.cpio", "0x2a00000" ,"0xa0000000", \ + "sg2044r_xmrig" ,"0x34b4000" ,"0x0"} + #define PARTNUM 6 + #define DTB_OFFSET 0x25b1000 + #define DTB_LOADER "0x90000000" + #define OUTPUT "sg2044r-layout.xml" + #define NAME "SG2044R" + #define RELEASENOTE "sg2044r_release_note.md" +#endif + +#ifdef MANGO + #define PARTION {"fip.bin","0x00030000",\ + "efie","0x600000","0x1000",\ + "zsbl.bin","0x2a00000","0x40000000",\ + "fw_dynamic.bin","0x660000","0x00000000",\ + "riscv64_Image","0x6b0000","0x02000000",\ + "initrd.img","0x2b00000","0x30000000",\ + "SG2042.fd","0x2000000","0x2000000"} + #define PARTNUM 7 + #define DTB_OFFSET 0x601000 + #define DTB_LOADER "0x20000000" + #define OUTPUT "sg2042-layout.xml" + #define NAME "SG2042" + #define RELEASENOTE "sg2042_release_note.md" +#endif + +#ifdef SG2044 + #define PARTION {"efie","0x80000","4096",\ + "zsbl.bin","0x2f0000","0x40000000",\ + "fsbl.bin","0x81000","0x7010080000",\ + "fw_dynamic.bin","0x15d000","0x80000000",\ + "SG2044.fd","0x600000","0x80200000"} + #define PARTNUM 5 + #define DTB_OFFSET 0x500000 + #define DTB_LOADER "0x88000000" + #define OUTPUT "sg2044-layout.xml" + #define NAME "SG2044" + #define RELEASENOTE "sg2044_release_note.md" +#endif + +typedef struct p_info{ + char p_name[NAMESIZE]; + uint32_t p_off; + char p_ldr[LOADERSIZE]; + char p_size[LOADERSIZE]; +}p_info; + +void get_dtb_info(struct p_info *info, char *dtb_name, uint32_t dtb_off, char* dtb_ldr){ + strcpy(info->p_name,dtb_name); + info->p_off=dtb_off; + strcpy(info->p_ldr,dtb_ldr); +} + +int get_part_info(struct p_info *info, int p_num, char *part[]){ + int i,j,ret; + struct stat file_stat; + char p_stat[LOADERSIZE]; + for(i=0,j=0;ip_name,part[j++]); + (info+i)->p_off=strtoul(part[j++],NULL,16); + strcpy((info+i)->p_ldr,INVALID); + ret=stat((info+i)->p_name,&file_stat); + if (ret || !file_stat.st_size) { + printf("failed to get the file %s size !\n",(info+i)->p_name); + return -1; + } + sprintf(p_stat,"0x%lX",file_stat.st_size); + strcpy((info+i)->p_size,p_stat); + i++; + } + if(part[j]=="efie"){ + strcpy((info+i)->p_name,part[j++]); + (info+i)->p_off=strtoul(part[j++],NULL,16); + strcpy((info+i)->p_ldr,INVALID); + strcpy((info+i)->p_size,part[j++]); + i++; + } + strcpy((info+i)->p_name,part[j++]); + (info+i)->p_off=strtoul(part[j++],NULL,16); + strcpy((info+i)->p_ldr,part[j++]); + stat((info+i)->p_name,&file_stat); + sprintf(p_stat,"0x%lX",file_stat.st_size); + strcpy((info+i)->p_size,p_stat); + } + return 0; +} + +void parse_info(ezxml_t parent, struct p_info *info, char*sp_off){ + char *txt; + if( !strcmp(info->p_name,"efie") ){ + txt="efie"; + }else{ + txt="component"; + } + ezxml_t child=ezxml_add_child(parent,txt,0); + ezxml_set_txt(ezxml_add_child(child,"name",0), info->p_name); + sprintf(sp_off,"0x%X",info->p_off); + ezxml_set_txt(ezxml_add_child(child,"offset",0), sp_off); + if(strcmp(info->p_ldr,INVALID)){ + ezxml_set_txt(ezxml_add_child(child,"loader",0), info->p_ldr); + } + if(strcmp(info->p_size,INVALID)){ + ezxml_set_txt(ezxml_add_child(child,"size",0), info->p_size); + } +} + +void format_xml(const char *input, char *output){ + const char *ptr = input; + char *out_ptr = output; + int indent=0,marked=0; + while(*ptr){ + if(*ptr=='>'){ + if(*(ptr+1)=='<'){ + if(*(ptr+2)=='/'){ + *out_ptr++=*ptr++; + indent-=1; + marked=1; + } + else{ + if(marked){ + *out_ptr++=*ptr++; + marked=0; + } + else{ + indent+=1; + *out_ptr++=*ptr++; + } + } + *out_ptr++='\n'; + memset(out_ptr,'\t',indent); + out_ptr+=indent; + } + else{ + marked=1; + *out_ptr++=*ptr++; + } + }else{ + *out_ptr++=*ptr++; + } + } + *out_ptr = '\0'; +} + +int gen_xml(FILE *fp,ezxml_t parent, struct p_info *info, int p_num){ + int i,j,tar=0; + uint32_t min_off,cur_off=0; + char origin[p_num*LOADERSIZE]; + char* sp_off=origin; + uint32_t all_off[p_num]; + uint64_t all_size[p_num]; + for(i=0;icur_off && info[j].p_offall_off[i+1]){ + printf("failed for overlap: check the layer of the %dth file and the %dth file !\n",i,i+1); + return -1; + } + } + if(all_off[p_num-1]+all_size[p_num-1]>FLASHSIZE){ + printf("failed for overlap: the layer of the %dth file over the flash !\n",p_num-1); + return -1; + } + return 0; +} + +int get_version(char *file_name, char* version){ + FILE *file=fopen(file_name,"r"); + char buffer[64]; + if(file == NULL || fgetc(file) == EOF){ + strcpy(version,"1.0.0"); + printf("generate the default version: 1.0.0\n"); + return 0; + } + else{ + fseek(file,0,SEEK_END); + long size=ftell(file); + long pos; + for (pos = size - 1; pos >= 0; pos--) { + fseek(file, pos, SEEK_SET); + if (pos == 0 || fgetc(file) == '\n') { + break; + } + } + if (fgets(buffer, sizeof(buffer), file) != NULL) { + char *first_word = strtok(buffer, " "); + strcpy(version,strtok(first_word,"_")); + printf("generate the firmware version: %s\n",version); + } + } + return 0; +} + +int main(int argc, char* argv[]) { + int ret,i; + char *part[]=PARTION; + int p_num=PARTNUM; + int dtb_num=argc-1; + struct p_info info[dtb_num+p_num]; + uint32_t dtb_off=DTB_OFFSET; + char* dtb_ldr=DTB_LOADER; + struct stat dtb_stat; + char *output=OUTPUT; + char flash_size[LOADERSIZE]; + char version[LOADERSIZE]; + + time_t t = time(NULL); + struct tm *tm_info = localtime(&t); + char date[LOADERSIZE]; + strftime(date, sizeof(date), "%Y%m%d", tm_info); + + for (i=0;i +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ezxml/ezxml.h" +#include "ezxml/ezxml.c" + +enum { + DPT_MAGIC = 0x55aa55aa, +}; + +#define UP_4K_ALIGN 0x1000 +#define BUFFER_SIZE 1024 +#define OUTPUT "firmware.bin" +#define LOADERSIZE 20 +#define VERSIONOFFSET 0x0000000 +#define DATEOFFSET 0x0000100 + +struct part_info { + /* disk partition table magic number */ + uint32_t magic; + char name[32]; + uint32_t offset; + uint32_t size; + char reserve[4]; + /* load memory address*/ + uint64_t lma; +}; + +static int spi_flash_pack(int fd_spi, uint32_t offset, const char *name) +{ + int fd; + unsigned char buf[BUFFER_SIZE]; + int read_len; + int pack_size = 0; + + fd = open(name, O_RDONLY, 0); + if (fd < 0) { + printf("open %s failed\n", name); + return fd; + } + + lseek(fd_spi, offset, SEEK_SET); + while ((read_len = read(fd, buf, BUFFER_SIZE)) > 0) { + write(fd_spi, buf, read_len); + pack_size += read_len; + } + printf("write %s to flash start at 0x%x and end at 0x%X\n",name, offset, offset+pack_size); + close(fd); + + return pack_size; +} + +int spi_flash_version(int fd_spi, char* version){ + uint32_t ver_size; + lseek(fd_spi, VERSIONOFFSET, SEEK_SET); + if((ver_size=write(fd_spi, version, strlen(version)+1))<=0){ + printf("failed to write version\n"); + return -1; + } + printf("write version:%s to flash start at 0x%x and end at 0x%x\n", version, VERSIONOFFSET, VERSIONOFFSET+ver_size); + return 0; +} + +int spi_flash_date(int fd_spi, char* date){ + uint32_t date_size; + lseek(fd_spi, DATEOFFSET, SEEK_SET); + if((date_size=write(fd_spi, date, strlen(date)+1))<=0){ + printf("failed to write date\n"); + return -1; + } + printf("write date:%s to flash start at 0x%x and end at 0x%x\n", date, DATEOFFSET, DATEOFFSET+date_size); + return 0; +} + +int get_efie_info(ezxml_t parent, uint32_t* p_off, uint32_t* p_size){ + ezxml_t p=ezxml_child(parent,"efie"); + if(!p){ + printf("failed to find efie element\n"); + return -1; + } + p = ezxml_child(ezxml_child(parent,"efie"),"offset"); + *p_off = strtol(p->txt,NULL,16); + p = ezxml_child(ezxml_child(parent,"efie"),"size"); + *p_size = strtol(p->txt,NULL,0); + return 0; + // printf("get the efie partion offset: 0x%x size: %d\n",*p_off,*p_size); +} + +int get_component_info(ezxml_t parent, struct part_info *info, int *flag){ + char* p_name; + uint32_t magic, p_offset, p_size; + int len, size, ret; + uint64_t p_lma; + ezxml_t p; + memset(info, 0, sizeof(struct part_info)); + + info->magic = DPT_MAGIC; + + //add offset info + p=ezxml_child(parent,"offset"); + p_offset=strtoul(p->txt,NULL,16); + info->offset=p_offset; + + //add name info + p=ezxml_child(parent,"name"); + p_name=p->txt; + len = strlen(p_name); + size = sizeof(info->name); + memcpy(info->name, p_name, len > size ? size : len); + if( !strcmp(p_name, "fip.bin")){ + // printf("skip %s info\n",p_name); + *flag = 1; + return 0; + } + + //add size info + struct stat file_stat; + p=ezxml_child(parent,"size"); + p_size=strtoul(p->txt,NULL,0); + ret = stat(p_name, &file_stat); + if (ret || file_stat.st_size != p_size) { + printf("failed to get file %s size or size: %ld not equal size from xml:%d\n", p_name, + file_stat.st_size,p_size); + return -1; + } + info->size = file_stat.st_size; + + //add loader info + p=ezxml_child(parent,"loader"); + p_lma=strtoul(p->txt,NULL,16); + info->lma=p_lma; + + return 0; +} + +int main(int argc, char *argv[]){ + + char * __attribute__((unused)) firmware_name = "firmware"; + char *firmware_version,*firmware_date; + ezxml_t p,comp; + char *file=argv[1]; + unsigned int comp_count=0; + int fd,ret,fd_fip,flag; + + ezxml_t firmware=ezxml_parse_file(file); + if (strcmp(firmware->name, "firmware")) { + printf("failed: %s is not a valid layout file\n",file); + return -1; + } + p=ezxml_child(firmware,"name"); + firmware_name=p->txt; + + p=ezxml_child(firmware,"version"); + firmware_version=p->txt; + if(strlen(firmware_version)+1>LOADERSIZE){ + printf("failed: version number is too long, check the name length limit\n"); + return -1; + } + + p=ezxml_child(firmware,"date"); + firmware_date=p->txt; + if(strlen(firmware_date)+1>LOADERSIZE){ + printf("failed: date size is too big, check the name length limit\n"); + return -1; + } + + fd = open(OUTPUT, O_CREAT | O_RDWR | O_TRUNC, 0644); + if( fd == -1){ + printf("failed to open %s\n",OUTPUT); + return -1; + } + + if(ret=spi_flash_version(fd, firmware_version)){ + printf("failed to get version\n"); + goto failed_pack; + } + + if(ret=spi_flash_date(fd, firmware_date)){ + printf("failed to get date\n"); + goto failed_pack; + } + + uint32_t efie_offset,efie_size; + if(ret=get_efie_info(firmware, &efie_offset, &efie_size)){ + printf("failed to get efie info\n"); + goto failed_pack; + } + + for (comp=ezxml_child(firmware,"component"); comp; comp=comp->next){ + struct part_info info; + flag=0; + if(ret=get_component_info(comp,&info,&flag)){ + goto failed_pack; + } + if( !flag ){ + lseek(fd, efie_offset+comp_count*sizeof(struct part_info), SEEK_SET); + write(fd, &info, sizeof(struct part_info)); + // printf("wtite %s info to the %dth partion table at 0x%lx\n",info.name,comp_count, + // efie_offset+comp_count*sizeof(struct part_info)); + comp_count++; + } + spi_flash_pack(fd, info.offset, info.name); + } + +failed_pack: + close(fd); + return ret; +} +