mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-10-30 01:52:51 +00:00
1057 lines
29 KiB
Diff
1057 lines
29 KiB
Diff
From d673a23639860e21ef87c4c455018c4b6245868a Mon Sep 17 00:00:00 2001
|
|
From: John Crispin <john@phrozen.org>
|
|
Date: Wed, 3 Nov 2021 14:32:11 +0100
|
|
Subject: [PATCH] tools: add realtek image building code
|
|
|
|
Signed-off-by: John Crispin <john@phrozen.org>
|
|
---
|
|
tools/Makefile | 1 +
|
|
tools/rtk-tools/Makefile | 50 ++++
|
|
tools/rtk-tools/src/apmib.h | 77 +++++++
|
|
tools/rtk-tools/src/cvimg.c | 443 ++++++++++++++++++++++++++++++++++++
|
|
tools/rtk-tools/src/mgbin.c | 429 ++++++++++++++++++++++++++++++++++
|
|
5 files changed, 1000 insertions(+)
|
|
create mode 100644 tools/rtk-tools/Makefile
|
|
create mode 100644 tools/rtk-tools/src/apmib.h
|
|
create mode 100644 tools/rtk-tools/src/cvimg.c
|
|
create mode 100644 tools/rtk-tools/src/mgbin.c
|
|
|
|
diff --git a/tools/Makefile b/tools/Makefile
|
|
index ae3cc5dfd6..a2d49967e7 100644
|
|
--- a/tools/Makefile
|
|
+++ b/tools/Makefile
|
|
@@ -36,6 +36,7 @@ tools-$(CONFIG_TARGET_tegra) += cbootimage cbootimage-configs
|
|
tools-$(CONFIG_USES_MINOR) += kernel2minor
|
|
tools-$(CONFIG_USE_SPARSE) += sparse
|
|
tools-$(CONFIG_USE_LLVM_BUILD) += llvm-bpf
|
|
+tools-$(CONFIG_TARGET_rtkmipsel) += rtk-tools
|
|
|
|
# builddir dependencies
|
|
$(curdir)/autoconf/compile := $(curdir)/m4/compile
|
|
diff --git a/tools/rtk-tools/Makefile b/tools/rtk-tools/Makefile
|
|
new file mode 100644
|
|
index 0000000000..a7f79c04b6
|
|
--- /dev/null
|
|
+++ b/tools/rtk-tools/Makefile
|
|
@@ -0,0 +1,50 @@
|
|
+#
|
|
+# Copyright (C) 2006-2010 OpenWrt.org
|
|
+#
|
|
+# This is free software, licensed under the GNU General Public License v2.
|
|
+# See /LICENSE for more information.
|
|
+#
|
|
+
|
|
+include $(TOPDIR)/rules.mk
|
|
+
|
|
+PKG_NAME:=rtk-tools
|
|
+PKG_VERSION:=0.1
|
|
+
|
|
+HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/${PKG_NAME}-$(PKG_VERSION)
|
|
+HOST_CFLAGS += -DCOMPACT_FILENAME_BUFFER -DHOME_GATEWAY
|
|
+
|
|
+include $(INCLUDE_DIR)/host-build.mk
|
|
+
|
|
+define Host/Compile
|
|
+ $(HOSTCC) $(HOST_CFLAGS) -DCONFIG_RTL_8196C src/cvimg.c -o $(HOST_BUILD_DIR)/cvimg-rtl8196c
|
|
+ $(HOSTCC) $(HOST_CFLAGS) -DCONFIG_RTL_8196C src/mgbin.c -o $(HOST_BUILD_DIR)/mgbin-rtl8196c
|
|
+ $(HOSTCC) $(HOST_CFLAGS) -DCONFIG_RTL_8196E src/cvimg.c -o $(HOST_BUILD_DIR)/cvimg-rtl8196e
|
|
+ $(HOSTCC) $(HOST_CFLAGS) -DCONFIG_RTL_8196E src/mgbin.c -o $(HOST_BUILD_DIR)/mgbin-rtl8196e
|
|
+ $(HOSTCC) $(HOST_CFLAGS) -DCONFIG_RTL_819XD src/cvimg.c -o $(HOST_BUILD_DIR)/cvimg-rtl819xd
|
|
+ $(HOSTCC) $(HOST_CFLAGS) -DCONFIG_RTL_819XD src/mgbin.c -o $(HOST_BUILD_DIR)/mgbin-rtl819xd
|
|
+ $(HOSTCC) $(HOST_CFLAGS) -DCONFIG_RTL_819XD src/cvimg.c -o $(HOST_BUILD_DIR)/cvimg-rtl819xdt
|
|
+ $(HOSTCC) $(HOST_CFLAGS) -DCONFIG_RTL_819XD src/mgbin.c -o $(HOST_BUILD_DIR)/mgbin-rtl819xdt
|
|
+ $(HOSTCC) $(HOST_CFLAGS) -DCONFIG_RTL_819XD src/cvimg.c -o $(HOST_BUILD_DIR)/cvimg-rtl89xxd
|
|
+ $(HOSTCC) $(HOST_CFLAGS) -DCONFIG_RTL_819XD src/cvimg.c -o $(HOST_BUILD_DIR)/cvimg-rtl8198c
|
|
+ $(HOSTCC) $(HOST_CFLAGS) -DCONFIG_RTL_819XD src/cvimg.c -o $(HOST_BUILD_DIR)/cvimg-rtl8954e
|
|
+ $(HOSTCC) $(HOST_CFLAGS) -DCONFIG_RTL_819XD src/cvimg.c -o $(HOST_BUILD_DIR)/cvimg-rtl8197f
|
|
+ $(HOSTCC) $(HOST_CFLAGS) -DCONFIG_RTL_819XD src/mgbin.c -o $(HOST_BUILD_DIR)/mgbin-rtl89xxd
|
|
+ $(HOSTCC) $(HOST_CFLAGS) -DCONFIG_RTL_819XD src/mgbin.c -o $(HOST_BUILD_DIR)/mgbin-rtl8198c
|
|
+ $(HOSTCC) $(HOST_CFLAGS) -DCONFIG_RTL_819XD src/mgbin.c -o $(HOST_BUILD_DIR)/mgbin-rtl8954e
|
|
+ $(HOSTCC) $(HOST_CFLAGS) -DCONFIG_RTL_819XD src/mgbin.c -o $(HOST_BUILD_DIR)/mgbin-rtl8197f
|
|
+ $(HOSTCC) $(HOST_CFLAGS) -DCONFIG_RTL_8881A src/cvimg.c -o $(HOST_BUILD_DIR)/cvimg-rtl8881a
|
|
+ $(HOSTCC) $(HOST_CFLAGS) -DCONFIG_RTL_8881A src/mgbin.c -o $(HOST_BUILD_DIR)/mgbin-rtl8881a
|
|
+endef
|
|
+
|
|
+define Host/Install
|
|
+ $(INSTALL_DIR) $(STAGING_DIR_HOST)/bin
|
|
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/cvimg* $(STAGING_DIR_HOST)/bin/
|
|
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/mgbin* $(STAGING_DIR_HOST)/bin/
|
|
+endef
|
|
+
|
|
+define Host/Clean
|
|
+ rm -f $(STAGING_DIR_HOST)/bin/cvimg*
|
|
+ rm -f $(STAGING_DIR_HOST)/bin/mgbin*
|
|
+endef
|
|
+
|
|
+$(eval $(call HostBuild))
|
|
diff --git a/tools/rtk-tools/src/apmib.h b/tools/rtk-tools/src/apmib.h
|
|
new file mode 100644
|
|
index 0000000000..bf7257efa1
|
|
--- /dev/null
|
|
+++ b/tools/rtk-tools/src/apmib.h
|
|
@@ -0,0 +1,77 @@
|
|
+#ifndef __APMIB_H
|
|
+#define __APMIB_H
|
|
+
|
|
+#ifndef WIN32
|
|
+#define __PACK__ __attribute__ ((packed))
|
|
+#else
|
|
+#define __PACK__
|
|
+#endif
|
|
+
|
|
+#define BOOT_HEADER ((char *)"boot")
|
|
+
|
|
+#if defined(CONFIG_RTL_8196B)
|
|
+#define ROOT_HEADER ((char *)"r6br")
|
|
+#elif defined(CONFIG_RTL_8196C) || defined(CONFIG_RTL_8198) || defined(CONFIG_RTL_819XD) || defined(CONFIG_RTL_8196E) || defined(CONFIG_RTL_8881A)
|
|
+#define ROOT_HEADER ((char *)"r6cr")
|
|
+#else
|
|
+#define ROOT_HEADER ((char *)"root")
|
|
+#endif //#if defined(CONFIG_RTL_8196B)
|
|
+
|
|
+#if defined(CONFIG_RTL_8196B)
|
|
+#if (defined(HOME_GATEWAY) && defined(VPN_SUPPORT))
|
|
+#define WEB_HEADER ((char *)"w6bv")
|
|
+#elif (defined(HOME_GATEWAY))
|
|
+#define WEB_HEADER ((char *)"w6bg")
|
|
+#else
|
|
+#define WEB_HEADER ((char *)"w6ba")
|
|
+#endif
|
|
+#elif defined(CONFIG_RTL_8196C) || defined(CONFIG_RTL_8198) || defined(CONFIG_RTL_819XD) || defined(CONFIG_RTL_8196E) || defined(CONFIG_RTL_8881A)
|
|
+#if (defined(HOME_GATEWAY) && defined(VPN_SUPPORT))
|
|
+#define WEB_HEADER ((char *)"w6cv")
|
|
+#elif (defined(HOME_GATEWAY))
|
|
+#define WEB_HEADER ((char *)"w6cg")
|
|
+#else
|
|
+#define WEB_HEADER ((char *)"w6ca")
|
|
+#endif
|
|
+#else
|
|
+#if (defined(HOME_GATEWAY) && defined(VPN_SUPPORT))
|
|
+#define WEB_HEADER ((char *)"webv")
|
|
+#elif (defined(HOME_GATEWAY))
|
|
+#define WEB_HEADER ((char *)"webg")
|
|
+#else
|
|
+#define WEB_HEADER ((char *)"weba")
|
|
+#endif
|
|
+#endif //#if defined(CONFIG_RTL_8196B)
|
|
+
|
|
+#if defined(CONFIG_RTL_8196B)
|
|
+#define FW_HEADER_WITH_ROOT ((char *)"cr6b")
|
|
+#define FW_HEADER ((char *)"cs6b")
|
|
+#elif defined(CONFIG_RTL_8196C) || defined(CONFIG_RTL_8198) || defined(CONFIG_RTL_819XD) || defined(CONFIG_RTL_8196E) || defined(CONFIG_RTL_8881A)
|
|
+#define FW_HEADER_WITH_ROOT ((char *)"cr6c")
|
|
+#define FW_HEADER ((char *)"cs6c")
|
|
+#else
|
|
+#define FW_HEADER_WITH_ROOT ((char *)"csro")
|
|
+#define FW_HEADER ((char *)"csys")
|
|
+#endif //#if defined(CONFIG_RTL_8196B)
|
|
+
|
|
+#define ALL_HEADER ((char *)"allp")
|
|
+
|
|
+#define HW_SETTING_OFFSET 0x6000
|
|
+#define DEFAULT_SETTING_OFFSET 0x8000
|
|
+#define CURRENT_SETTING_OFFSET 0xc000
|
|
+
|
|
+#define DWORD_SWAP(v) ( (((v&0xff)<<24)&0xff000000) | ((((v>>8)&0xff)<<16)&0xff0000) | \
|
|
+ ((((v>>16)&0xff)<<8)&0xff00) | (((v>>24)&0xff)&0xff) )
|
|
+
|
|
+#define WORD_SWAP(v) ((unsigned short)(((v>>8)&0xff) | ((v<<8)&0xff00)))
|
|
+
|
|
+#define SIGNATURE_LEN 4
|
|
+
|
|
+typedef struct img_header {
|
|
+ unsigned char signature[SIGNATURE_LEN];
|
|
+ unsigned int startAddr;
|
|
+ unsigned int burnAddr;
|
|
+ unsigned int len;
|
|
+}__PACK__ IMG_HEADER_T, *IMG_HEADER_Tp;
|
|
+
|
|
+#endif
|
|
diff --git a/tools/rtk-tools/src/cvimg.c b/tools/rtk-tools/src/cvimg.c
|
|
new file mode 100644
|
|
index 0000000000..de681d803e
|
|
--- /dev/null
|
|
+++ b/tools/rtk-tools/src/cvimg.c
|
|
@@ -0,0 +1,443 @@
|
|
+/*
|
|
+ * Tool to convert ELF image to be the AP downloadable binary
|
|
+ *
|
|
+ * Authors: David Hsu <davidhsu@realtek.com.tw>
|
|
+ *
|
|
+ * $Id: cvimg.c,v 1.4 2009/06/12 07:10:44 michael Exp $
|
|
+ *
|
|
+ */
|
|
+
|
|
+#include <stdlib.h>
|
|
+#include <stdio.h>
|
|
+#include <sys/types.h>
|
|
+#include <sys/stat.h>
|
|
+#include <fcntl.h>
|
|
+#include <unistd.h>
|
|
+#include <stdlib.h>
|
|
+#include <string.h>
|
|
+#undef HOME_GATEWAY
|
|
+#define HOME_GATEWAY
|
|
+#define RTK_4K_CHKSUM_FIX
|
|
+
|
|
+#include "apmib.h"
|
|
+
|
|
+/* 32-bit ELF base types. */
|
|
+typedef unsigned int Elf32_Addr;
|
|
+typedef unsigned short Elf32_Half;
|
|
+typedef unsigned int Elf32_Off;
|
|
+typedef unsigned int Elf32_Word;
|
|
+
|
|
+#define EI_NIDENT 16
|
|
+
|
|
+typedef struct elf32_hdr{
|
|
+ unsigned char e_ident[EI_NIDENT];
|
|
+ Elf32_Half e_type;
|
|
+ Elf32_Half e_machine;
|
|
+ Elf32_Word e_version;
|
|
+ Elf32_Addr e_entry; /* Entry point */
|
|
+ Elf32_Off e_phoff;
|
|
+ Elf32_Off e_shoff;
|
|
+ Elf32_Word e_flags;
|
|
+ Elf32_Half e_ehsize;
|
|
+ Elf32_Half e_phentsize;
|
|
+ Elf32_Half e_phnum;
|
|
+ Elf32_Half e_shentsize;
|
|
+ Elf32_Half e_shnum;
|
|
+ Elf32_Half e_shstrndx;
|
|
+} Elf32_Ehdr;
|
|
+
|
|
+#define DEFAULT_START_ADDR 0x80500000
|
|
+#define DEFAULT_BASE_ADDR 0x80000000
|
|
+
|
|
+static unsigned short calculateChecksum(char *buf, int len);
|
|
+
|
|
+/////////////////////////////////////////////////////////
|
|
+static unsigned int calculate_long_checksum(unsigned int *buf, int len)
|
|
+{
|
|
+ int i, j;
|
|
+ unsigned int sum=0, tmp;
|
|
+
|
|
+ j = len/4;
|
|
+
|
|
+ for (i=0; i<j; buf++, i++) {
|
|
+ tmp = *buf;
|
|
+ sum += DWORD_SWAP(tmp);
|
|
+ }
|
|
+ return ~sum+1;
|
|
+}
|
|
+
|
|
+unsigned int extractStartAddr(char *filename)
|
|
+{
|
|
+ int fh;
|
|
+ Elf32_Ehdr hdr;
|
|
+ char *buf;
|
|
+
|
|
+ buf = (char *)&hdr;
|
|
+ fh = open(filename, O_RDONLY);
|
|
+ if ( fh == -1 ) {
|
|
+ printf("Open input file error2!\n");
|
|
+ exit(1);
|
|
+ }
|
|
+ lseek(fh, 0L, SEEK_SET);
|
|
+ if ( read(fh, buf, sizeof(Elf32_Ehdr)) != sizeof(Elf32_Ehdr)) {
|
|
+ printf("Read file error2!\n");
|
|
+ close(fh);
|
|
+ exit(1);
|
|
+ }
|
|
+ close(fh);
|
|
+
|
|
+ return(hdr.e_entry);
|
|
+}
|
|
+
|
|
+void printf_usage(void)
|
|
+{
|
|
+ printf("Version: 1.1\n");
|
|
+ printf("Usage: cvimg <option> input-filename output-filename start-addr burn-addr [signature]\n");
|
|
+ printf("<option>: root|linux|boot|all|vmlinux|vmlinuxhdr|signature\n");
|
|
+ printf("[signature]: user-specified signature (4 characters)\n");
|
|
+}
|
|
+
|
|
+#ifdef RTK_4K_CHKSUM_FIX
|
|
+#define JFFS2_ENDMARK_LEN 4
|
|
+static int rtk_fix_4k_chk(char *inputFile,char *outFile)
|
|
+{
|
|
+ struct stat status;
|
|
+ char *buf;
|
|
+ int fh, size;
|
|
+ IMG_HEADER_Tp pHeader;
|
|
+ unsigned short checksum=0;
|
|
+ int old_linx_len=0;
|
|
+
|
|
+ if ( stat(inputFile, &status) < 0 ) {
|
|
+ printf("Can't stat file! [%s]\n", inputFile );
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ //decide output size , current , stat+(checksum)
|
|
+ size= status.st_size ;
|
|
+
|
|
+ buf = malloc(size);
|
|
+ if (buf == NULL) {
|
|
+ printf("Malloc buffer failed!\n");
|
|
+ exit(1);
|
|
+ }
|
|
+ memset(buf, '\0', size);
|
|
+
|
|
+ pHeader = (IMG_HEADER_Tp)buf;
|
|
+
|
|
+ fh = open(inputFile, O_RDONLY);
|
|
+ if ( fh == -1 ) {
|
|
+ printf("Open input file error!\n");
|
|
+ free( pHeader );
|
|
+ exit(1);
|
|
+ }
|
|
+ lseek(fh, 0L, SEEK_SET);
|
|
+
|
|
+ if ( read(fh, buf, status.st_size) != status.st_size) {
|
|
+ printf("Read file error!\n");
|
|
+ close(fh);
|
|
+ free(pHeader);
|
|
+ exit(1);
|
|
+ }
|
|
+ close(fh);
|
|
+
|
|
+ //update len(not include jffs2 endmark)
|
|
+ old_linx_len = DWORD_SWAP(pHeader->len);
|
|
+ //printf("old_linx_len = %8x\n !!",old_linx_len);
|
|
+ pHeader->len = DWORD_SWAP((size-sizeof(IMG_HEADER_T)-JFFS2_ENDMARK_LEN));
|
|
+
|
|
+ //erase old chksum
|
|
+ //printf("old_cksum = %8x\n !!",*((unsigned short *)&buf[sizeof(IMG_HEADER_T)+old_linx_len-sizeof(checksum)]));
|
|
+ *((unsigned short *)&buf[sizeof(IMG_HEADER_T)+old_linx_len-sizeof(checksum)]) = 0;
|
|
+
|
|
+ //add new chksum
|
|
+ checksum = WORD_SWAP(calculateChecksum(buf+sizeof(IMG_HEADER_T), (size-sizeof(IMG_HEADER_T)-JFFS2_ENDMARK_LEN)));
|
|
+ //*((unsigned short *)&buf[status.st_size]) = checksum;
|
|
+ *((unsigned short *)&buf[sizeof(IMG_HEADER_T)+old_linx_len-sizeof(checksum)]) = checksum;
|
|
+
|
|
+ //write to new file
|
|
+ fh = open(outFile, O_RDWR|O_CREAT|O_TRUNC,S_IRWXU); //mark_88
|
|
+ if ( fh == -1 ) {
|
|
+ printf("Create output file error! [%s]\n", outFile);
|
|
+ free(pHeader);
|
|
+ exit(1);
|
|
+ }
|
|
+ write(fh, pHeader, size);
|
|
+ close(fh);
|
|
+ chmod(outFile, DEFFILEMODE);
|
|
+
|
|
+ printf("Generate 4k alignment image(with jffs2 end mark)successfully, length=%d, checksum=0x%x\n", (int)DWORD_SWAP(pHeader->len), checksum);
|
|
+
|
|
+ free(pHeader);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+#endif
|
|
+
|
|
+int main(int argc, char** argv)
|
|
+{
|
|
+#ifdef COMPACT_FILENAME_BUFFER
|
|
+ const char *inFile = NULL, *outFile = NULL;
|
|
+#else
|
|
+ char inFile[80]={0}, outFile[80]={0};
|
|
+#endif
|
|
+ int fh, size;
|
|
+ struct stat status;
|
|
+ char *buf;
|
|
+ IMG_HEADER_Tp pHeader;
|
|
+ unsigned int startAddr;
|
|
+ unsigned int burnAddr;
|
|
+ unsigned short checksum=0;
|
|
+ int is_vmlinux = 0;
|
|
+ int is_vmlinuxhdr = 0;
|
|
+ int is_signature = 0;
|
|
+ unsigned int lchecksum, padding_len=0;
|
|
+ unsigned int start_addr=0;
|
|
+
|
|
+ if (argc == 4 && !strcmp(argv[1], "size_chk")) {
|
|
+ unsigned int total_size;
|
|
+
|
|
+#ifdef COMPACT_FILENAME_BUFFER
|
|
+ inFile = argv[2];
|
|
+#else
|
|
+ sscanf(argv[2], "%s", inFile);
|
|
+#endif
|
|
+ sscanf(argv[3], "%x", &startAddr);
|
|
+ if ( stat(inFile, &status) < 0 ) {
|
|
+ printf("Can't stat file! [%s]\n", inFile );
|
|
+ exit(1);
|
|
+ }
|
|
+ printf("==============================================\n");
|
|
+ printf("Summary ==>\n");
|
|
+ printf("Image loading addr :0x%x\n", (int)startAddr);
|
|
+ printf("Image decompress end addr :0x%x\n", ((unsigned int)DEFAULT_BASE_ADDR)+(unsigned int)status.st_size);
|
|
+
|
|
+ total_size = startAddr - ((unsigned int)DEFAULT_BASE_ADDR);
|
|
+
|
|
+ if (status.st_size > (int)total_size)
|
|
+ {
|
|
+ printf("Error!!!! : Kernel image decompress will overwirte load image\n");
|
|
+ exit(1);
|
|
+ }
|
|
+ else
|
|
+ printf("Available size :0x%08x\n",
|
|
+ (unsigned int)(total_size - status.st_size));
|
|
+
|
|
+ exit(0);
|
|
+ }
|
|
+
|
|
+#ifdef CONFIG_RTL_FLASH_MAPPING_ENABLE
|
|
+ if (argc == 3 && !strcmp(argv[1], "flash_size_chk")) {
|
|
+ unsigned int total_size;
|
|
+
|
|
+#ifdef COMPACT_FILENAME_BUFFER
|
|
+ inFile = argv[2];
|
|
+#else
|
|
+ sscanf(argv[2], "%s", inFile);
|
|
+#endif
|
|
+ if ( stat(inFile, &status) < 0 ) {
|
|
+ printf("Can't stat file! [%s]\n", inFile );
|
|
+ exit(1);
|
|
+ }
|
|
+ printf("==============================================\n");
|
|
+ printf("Summary ==>\n");
|
|
+ printf("Image flash start addr :0x%x\n", (unsigned int)CODE_IMAGE_OFFSET);
|
|
+ printf("Image flash end addr :0x%x\n", (unsigned int)CODE_IMAGE_OFFSET+(unsigned int)status.st_size);
|
|
+
|
|
+#ifdef CONFIG_RTL_802_1X_CLIENT_SUPPORT
|
|
+ total_size = ROOT_IMAGE_OFFSET - CODE_IMAGE_OFFSET - CERT_SIZE; // To reserve CERT_SIZE for 802.1x wlan client mode to store 802.1x certs
|
|
+#else
|
|
+ total_size = ROOT_IMAGE_OFFSET - CODE_IMAGE_OFFSET;
|
|
+#endif
|
|
+
|
|
+ if (status.st_size > (int)total_size)
|
|
+ {
|
|
+ printf("Error!!!! : Kernel image too big will overwirte rootfs image, cur size(%d), available size(%d).\n",(int)status.st_size, total_size);
|
|
+ exit(1);
|
|
+ }
|
|
+ else
|
|
+ printf("Available size :0x%08x\n",
|
|
+ (unsigned int)(total_size - status.st_size));
|
|
+
|
|
+ exit(0);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+#ifdef RTK_4K_CHKSUM_FIX
|
|
+ if (argc == 4 && !strcmp(argv[1], "fix_chksum"))
|
|
+ {
|
|
+ rtk_fix_4k_chk(argv[2],argv[3]);
|
|
+ return 0;
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ if (argc == 4 && !strcmp(argv[1], "vmlinux"))
|
|
+ is_vmlinux = 1;
|
|
+
|
|
+ if (argc == 5 && !strcmp(argv[1], "vmlinuxhdr")) {
|
|
+ is_vmlinuxhdr = 1;
|
|
+ start_addr = extractStartAddr(argv[4]);
|
|
+ }
|
|
+
|
|
+ if (!strcmp(argv[1], "signature")) {
|
|
+ is_signature = 1;
|
|
+ if (argc != 7) {
|
|
+ printf_usage();
|
|
+ exit(1);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // parse input arguments
|
|
+ if ( argc != 6 && !is_vmlinux && !is_vmlinuxhdr && !is_signature) {
|
|
+ printf_usage();
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+
|
|
+
|
|
+#ifdef COMPACT_FILENAME_BUFFER
|
|
+ inFile = argv[2];
|
|
+ outFile = argv[3];
|
|
+#else
|
|
+ sscanf(argv[2], "%s", inFile);
|
|
+ sscanf(argv[3], "%s", outFile);
|
|
+#endif
|
|
+
|
|
+ if ((!is_vmlinux) && (!is_vmlinuxhdr)) {
|
|
+ sscanf(argv[4], "%x", &startAddr);
|
|
+ sscanf(argv[5], "%x", &burnAddr);
|
|
+ }
|
|
+ // check input file and allocate buffer
|
|
+ if ( stat(inFile, &status) < 0 ) {
|
|
+ printf("Can't stat file! [%s]\n", inFile );
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ if (is_vmlinuxhdr) {
|
|
+ size = status.st_size + sizeof(padding_len) + sizeof(lchecksum) + sizeof(start_addr);
|
|
+ padding_len = 4 - (size%4);
|
|
+ size += padding_len;
|
|
+ }
|
|
+ else if (!is_vmlinux) {
|
|
+ size = status.st_size + sizeof(IMG_HEADER_T) + sizeof(checksum);
|
|
+ if (size%2)
|
|
+ size++; // pad
|
|
+ }
|
|
+ else {
|
|
+ size = status.st_size + sizeof(padding_len) + sizeof(lchecksum);
|
|
+ padding_len = 4 - (size%4);
|
|
+ size += padding_len;
|
|
+ }
|
|
+
|
|
+ buf = malloc(size);
|
|
+ if (buf == NULL) {
|
|
+ printf("Malloc buffer failed!\n");
|
|
+ exit(1);
|
|
+ }
|
|
+ memset(buf, '\0', size);
|
|
+ pHeader = (IMG_HEADER_Tp)buf;
|
|
+
|
|
+ if (is_vmlinuxhdr)
|
|
+ buf += 8; // skip padding-length field and start-address field
|
|
+ else if (!is_vmlinux)
|
|
+ buf += sizeof(IMG_HEADER_T);
|
|
+ else
|
|
+ buf += 4; // skip padding-length field
|
|
+
|
|
+ // Read data and generate header
|
|
+ fh = open(inFile, O_RDONLY);
|
|
+ if ( fh == -1 ) {
|
|
+ printf("Open input file error!\n");
|
|
+ free( pHeader );
|
|
+ exit(1);
|
|
+ }
|
|
+ lseek(fh, 0L, SEEK_SET);
|
|
+ if ( read(fh, buf, status.st_size) != status.st_size) {
|
|
+ printf("Read file error!\n");
|
|
+ close(fh);
|
|
+ free(pHeader);
|
|
+ exit(1);
|
|
+ }
|
|
+ close(fh);
|
|
+
|
|
+ if (is_vmlinuxhdr) {
|
|
+ *((unsigned int *)pHeader) = DWORD_SWAP(padding_len);
|
|
+ *((unsigned int *)((char *)pHeader+4)) = start_addr;
|
|
+ lchecksum = DWORD_SWAP(calculate_long_checksum((unsigned int *)buf, size-12));
|
|
+ memcpy(&buf[size-12], &lchecksum, 4);
|
|
+ }
|
|
+ else if (!is_vmlinux) {
|
|
+ if( !strcmp("root", argv[1]))
|
|
+ memcpy(pHeader->signature, ROOT_HEADER, SIGNATURE_LEN);
|
|
+ else if ( !strcmp("boot", argv[1]))
|
|
+ memcpy(pHeader->signature, BOOT_HEADER, SIGNATURE_LEN);
|
|
+ else if ( !strcmp("linux", argv[1]))
|
|
+ memcpy(pHeader->signature, FW_HEADER, SIGNATURE_LEN);
|
|
+ else if ( !strcmp("linux-ro", argv[1]))
|
|
+ memcpy(pHeader->signature, FW_HEADER_WITH_ROOT, SIGNATURE_LEN);
|
|
+ else if ( !strcmp("signature", argv[1]))
|
|
+ memcpy(pHeader->signature, argv[6], SIGNATURE_LEN);
|
|
+ else{
|
|
+ printf("not supported signature\n");
|
|
+ exit(1);
|
|
+ }
|
|
+ pHeader->len = DWORD_SWAP((size-sizeof(IMG_HEADER_T)));
|
|
+ pHeader->startAddr = DWORD_SWAP(startAddr);
|
|
+ pHeader->burnAddr = DWORD_SWAP(burnAddr);
|
|
+
|
|
+ if( !strcmp("root", argv[1])) {
|
|
+ #define SIZE_OF_SQFS_SUPER_BLOCK 640
|
|
+ unsigned int fs_len;
|
|
+ fs_len = DWORD_SWAP((size-sizeof(IMG_HEADER_T) - sizeof(checksum)- SIZE_OF_SQFS_SUPER_BLOCK));
|
|
+ memcpy(buf + 8, &fs_len, 4);
|
|
+ }
|
|
+
|
|
+ checksum = WORD_SWAP(calculateChecksum(buf, status.st_size));
|
|
+ *((unsigned short *)&buf[size-sizeof(IMG_HEADER_T)-sizeof(checksum)]) = checksum;
|
|
+ }
|
|
+ else { // is_vmlinux=1
|
|
+ *((unsigned int *)pHeader) = DWORD_SWAP(padding_len);
|
|
+ lchecksum = DWORD_SWAP(calculate_long_checksum((unsigned int *)buf, size-8));
|
|
+ memcpy(&buf[size-8], &lchecksum, 4);
|
|
+ }
|
|
+
|
|
+ // Write image to output file
|
|
+ fh = open(outFile, O_RDWR|O_CREAT|O_TRUNC,S_IRWXU); //mark_88
|
|
+ if ( fh == -1 ) {
|
|
+ printf("Create output file error! [%s]\n", outFile);
|
|
+ free(pHeader);
|
|
+ exit(1);
|
|
+ }
|
|
+ write(fh, pHeader, size);
|
|
+ close(fh);
|
|
+ chmod(outFile, DEFFILEMODE);
|
|
+
|
|
+ if (is_vmlinuxhdr)
|
|
+ printf("Generate image successfully, length=%d, checksum=0x%x, padding=%d, start address=0x%08x\n", size-12-padding_len, lchecksum, padding_len, DWORD_SWAP(start_addr));
|
|
+ else if (!is_vmlinux)
|
|
+ printf("Generate image successfully, length=%d, checksum=0x%x\n", (int)DWORD_SWAP(pHeader->len), checksum);
|
|
+ else
|
|
+ printf("Generate image successfully, length=%d, checksum=0x%x, padding=%d\n", size-8-padding_len, lchecksum, padding_len);
|
|
+
|
|
+ free(pHeader);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static unsigned short calculateChecksum(char *buf, int len)
|
|
+{
|
|
+ int i, j;
|
|
+ unsigned short sum=0, tmp;
|
|
+
|
|
+ j = (len/2)*2;
|
|
+
|
|
+ for (i=0; i<j; i+=2) {
|
|
+ tmp = *((unsigned short *)(buf + i));
|
|
+ sum += WORD_SWAP(tmp);
|
|
+ }
|
|
+
|
|
+ if ( len % 2 ) {
|
|
+ tmp = buf[len-1];
|
|
+ sum += WORD_SWAP(tmp);
|
|
+ }
|
|
+ return ~sum+1;
|
|
+}
|
|
diff --git a/tools/rtk-tools/src/mgbin.c b/tools/rtk-tools/src/mgbin.c
|
|
new file mode 100644
|
|
index 0000000000..411c86aaae
|
|
--- /dev/null
|
|
+++ b/tools/rtk-tools/src/mgbin.c
|
|
@@ -0,0 +1,429 @@
|
|
+/*
|
|
+ * utility to merge all binary into one image
|
|
+ *
|
|
+ * Authors: David Hsu <davidhsu@realtek.com.tw>
|
|
+ *
|
|
+ * $Id: mgbin.c,v 1.7 2008/11/25 15:09:22 bradhuang Exp $
|
|
+ *
|
|
+ */
|
|
+#include <string.h>
|
|
+#include <stdio.h>
|
|
+#include <sys/types.h>
|
|
+#include <sys/stat.h>
|
|
+#include <fcntl.h>
|
|
+#include <stdlib.h>
|
|
+#include <sys/types.h>
|
|
+#ifdef WIN32
|
|
+ #include <io.h>
|
|
+#else
|
|
+ #include <unistd.h>
|
|
+#endif
|
|
+#define __mips__
|
|
+
|
|
+#include "apmib.h"
|
|
+
|
|
+//#define DEBUG_PRINT printf
|
|
+#define DEBUG_PRINT(...) do {} while(0)
|
|
+
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
+/* Input file type */
|
|
+typedef enum { BOOT_CODE=0, CONFIG, WEB_PAGES, SYS, ROOT, ALL, INVALID_FILE=-1 } TYPE_T;
|
|
+
|
|
+typedef struct _sector {
|
|
+ TYPE_T type;
|
|
+#ifdef COMPACT_FILENAME_BUFFER
|
|
+ const char *filename;
|
|
+#else
|
|
+ char filename[80];
|
|
+#endif
|
|
+ unsigned long offset;
|
|
+ unsigned long size;
|
|
+ int with_header;
|
|
+} SECTOR_T;
|
|
+
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
+static char *copyright="Copyright (c) Realtek Semiconductor Corp., 2007. All Rights Reserved.";
|
|
+static char *version="1.0";
|
|
+
|
|
+static SECTOR_T sector[ROOT+1];
|
|
+static int no_hw_config=0;
|
|
+
|
|
+#define BYTE_SWAP(word) (((word >> 8) &0xff) | ((((unsigned char)word)<<8)&0xff00) )
|
|
+
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
+static TYPE_T checkInputFile(char *filename, int *pWith_header)
|
|
+{
|
|
+ int fh;
|
|
+ char signature[6];
|
|
+
|
|
+#ifdef WIN32
|
|
+ fh = open(filename, O_RDONLY|O_BINARY);
|
|
+#else
|
|
+ fh = open(filename, O_RDONLY,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
|
|
+#endif
|
|
+ if ( fh == -1 )
|
|
+ return INVALID_FILE;
|
|
+
|
|
+ lseek(fh, 0, SEEK_SET);
|
|
+
|
|
+ if ( read(fh, signature, sizeof(signature)) != sizeof(signature)) {
|
|
+ close(fh);
|
|
+ return INVALID_FILE;
|
|
+ }
|
|
+ close(fh);
|
|
+
|
|
+ *pWith_header = 1;
|
|
+ if ( !memcmp(signature, BOOT_HEADER, 4))
|
|
+ return BOOT_CODE;
|
|
+ else if ( !memcmp(signature, WEB_HEADER, 3) )
|
|
+ return WEB_PAGES;
|
|
+
|
|
+ else if ( !memcmp(signature, FW_HEADER, 4) ||
|
|
+ !memcmp(signature, FW_HEADER_WITH_ROOT, 4))
|
|
+ return SYS;
|
|
+
|
|
+ else if ( !memcmp(signature, ROOT_HEADER, 4) )
|
|
+ return ROOT;
|
|
+
|
|
+ else if ( !memcmp(signature, "h", 1) || !memcmp(signature, "COMPHS", 6))
|
|
+ return CONFIG;
|
|
+ else if ( !memcmp(signature, "6G", 2) || !memcmp(signature, "6A", 2) || !memcmp(signature, "6g", 2) || !memcmp(signature, "6a", 2) || !memcmp(signature, "COMPDS", 6)) {
|
|
+ no_hw_config = 1;
|
|
+ return CONFIG;
|
|
+ }
|
|
+ else if ( !memcmp(signature, "\x0b\xf0\x00\x02", 4)) {
|
|
+ *pWith_header = 0;
|
|
+ return BOOT_CODE;
|
|
+ }
|
|
+ return INVALID_FILE;
|
|
+}
|
|
+
|
|
+////////////////////////////////////////////////////////////////////////////////
|
|
+static void showHelp(void)
|
|
+{
|
|
+ printf("\nRTL865x utility to merge binary.\n");
|
|
+ printf("%s Ver %s.\n\n", copyright, version);
|
|
+ printf("usage: mgbin [-s] [-c] [-a] -o outputfile bootcode config webpages linux root\n");
|
|
+ printf(" -s : do byte swap\n");
|
|
+ printf(" -c : cascade. May use this option to merge image for web upload\n");
|
|
+ printf(" -a : add all tag in header\n");
|
|
+
|
|
+}
|
|
+
|
|
+
|
|
+////////////////////////////////////////////////////////////////////////////////
|
|
+static void do_byteswap(unsigned char *buf, int len)
|
|
+{
|
|
+ unsigned short wVal, *ptr;
|
|
+ int i=0;
|
|
+
|
|
+ while (len > 0) {
|
|
+ len -= 2;
|
|
+ ptr = (unsigned short *)&buf[2*i];
|
|
+ wVal = *ptr;
|
|
+ *ptr = BYTE_SWAP( wVal );
|
|
+ i++;
|
|
+ }
|
|
+}
|
|
+
|
|
+static unsigned short calculateChecksum(char *buf, int len, unsigned short oldv)
|
|
+{
|
|
+ int i, j;
|
|
+ unsigned short sum=oldv, tmp;
|
|
+
|
|
+ j = (len/2)*2;
|
|
+
|
|
+ for (i=0; i<j; i+=2) {
|
|
+ tmp = *((unsigned short *)(buf + i));
|
|
+ sum += WORD_SWAP(tmp);
|
|
+ }
|
|
+
|
|
+ if ( len % 2 ) {
|
|
+ tmp = buf[len-1];
|
|
+ sum += WORD_SWAP(tmp);
|
|
+ }
|
|
+ return sum;
|
|
+}
|
|
+
|
|
+////////////////////////////////////////////////////////////////////////////////
|
|
+int main(int argc, char** argv)
|
|
+{
|
|
+ int argNum=1;
|
|
+#ifdef COMPACT_FILENAME_BUFFER
|
|
+ const char *outFile = NULL;
|
|
+#else
|
|
+ char outFile[80]={0};
|
|
+#endif
|
|
+ TYPE_T type;
|
|
+ int mask=0, fh_out, fh_in, len, i, total=0;
|
|
+ unsigned char *buf, *buf1;
|
|
+ struct stat sbuf;
|
|
+ int byteswap=0, cascade=0, last_idx=-1, is_all=0;
|
|
+ int offset=0, with_header;
|
|
+ IMG_HEADER_Tp pHeader;
|
|
+ unsigned long burnAddr=0;
|
|
+ IMG_HEADER_T allHeader;
|
|
+ unsigned short checksum=0;
|
|
+
|
|
+ memset(§or, 0, sizeof(sector));
|
|
+
|
|
+ while (argNum < argc) {
|
|
+ if ( !strcmp(argv[argNum], "-o") ) {
|
|
+ if (++argNum >= argc)
|
|
+ break;
|
|
+#ifdef COMPACT_FILENAME_BUFFER
|
|
+ outFile = argv[argNum];
|
|
+#else
|
|
+ sscanf(argv[argNum], "%s", outFile);
|
|
+#endif
|
|
+ }
|
|
+ else if ( !strcmp(argv[argNum], "-s") ) {
|
|
+ byteswap = 1;
|
|
+ }
|
|
+ else if ( !strcmp(argv[argNum], "-c") ) {
|
|
+ cascade = 1;
|
|
+ }
|
|
+ else if ( !strcmp(argv[argNum], "-a") ) {
|
|
+ is_all = 1;
|
|
+ memset(&allHeader, '\0', sizeof(IMG_HEADER_T));
|
|
+ memcpy(allHeader.signature, ALL_HEADER, SIGNATURE_LEN);
|
|
+ }
|
|
+#if 0
|
|
+ else if ( !strcmp(argv[argNum], "-a2") ) {
|
|
+ is_all = 1;
|
|
+ memset(&allHeader, '\0', sizeof(IMG_HEADER_T));
|
|
+ memcpy(allHeader.signature, ALL_HEADER2, SIGNATURE_LEN);
|
|
+ }
|
|
+#endif
|
|
+ else {
|
|
+ if (is_all) {
|
|
+ if ((argNum+1) < argc) {
|
|
+ printf("argument error, only input file could be specified!\n");
|
|
+ return -1;
|
|
+ }
|
|
+#ifdef COMPACT_FILENAME_BUFFER
|
|
+ sector[0].filename = argv[argNum];
|
|
+#else
|
|
+ strcpy(sector[0].filename,argv[argNum]);
|
|
+#endif
|
|
+ sector[0].type=ALL;
|
|
+ sector[0].with_header=0;
|
|
+ mask |= (1 << ALL);
|
|
+ }
|
|
+ else {
|
|
+ type=checkInputFile(argv[argNum], &with_header);
|
|
+ DEBUG_PRINT("filename=%s, type=%d\n", argv[argNum], type);
|
|
+ if (type == INVALID_FILE) {
|
|
+ printf("\nInvalid input file %s!!\n", argv[argNum]);
|
|
+ showHelp();
|
|
+ exit(1);
|
|
+ }
|
|
+#ifdef COMPACT_FILENAME_BUFFER
|
|
+ sector[type].filename = argv[argNum];
|
|
+#else
|
|
+ strcpy(sector[type].filename, argv[argNum]);
|
|
+#endif
|
|
+ sector[type].with_header = with_header;
|
|
+ sector[type].type = type;
|
|
+ mask |= (1 << type);
|
|
+ }
|
|
+ }
|
|
+ argNum++;
|
|
+ }
|
|
+
|
|
+#ifdef COMPACT_FILENAME_BUFFER
|
|
+ if( outFile == NULL )
|
|
+#else
|
|
+ if (!outFile[0])
|
|
+#endif
|
|
+ {
|
|
+ printf("No output file specified!\n");
|
|
+ showHelp();
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ if (mask == 0) {
|
|
+ printf("No valid input image found!\n");
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ // Create output file
|
|
+#ifdef WIN32
|
|
+ _chmod(outFile, S_IREAD|S_IWRITE);
|
|
+ fh_out = open(outFile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY);
|
|
+#else
|
|
+ chmod(outFile, S_IREAD|S_IWRITE);
|
|
+ fh_out = open(outFile, O_RDWR|O_CREAT|O_TRUNC,S_IRWXU);//mark_88
|
|
+#endif
|
|
+ if (fh_out == -1) {
|
|
+ printf("Create output file %s error!\n", outFile);
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ if (is_all) {
|
|
+ write(fh_out, &allHeader, sizeof(allHeader));
|
|
+ total += sizeof(allHeader);
|
|
+ printf("\nGenerate ");
|
|
+ }
|
|
+ else
|
|
+ printf("\nMerge ");
|
|
+
|
|
+ for (i=BOOT_CODE; i<=ROOT ; i++) {
|
|
+#ifdef COMPACT_FILENAME_BUFFER
|
|
+ if (sector[i].filename)
|
|
+#else
|
|
+ if (sector[i].filename[0])
|
|
+#endif
|
|
+ {
|
|
+ if ( stat(sector[i].filename, &sbuf) != 0 ) {
|
|
+ printf("Stat file %s error!\n", sector[i].filename);
|
|
+ exit(1);
|
|
+ }
|
|
+ buf = malloc(sbuf.st_size+1);
|
|
+ if (buf == NULL) {
|
|
+ printf("allocate buffer failed %d!\n", (int)sbuf.st_size);
|
|
+ exit(1);
|
|
+ }
|
|
+#ifdef WIN32
|
|
+ fh_in = open(sector[i].filename, O_RDONLY|O_BINARY);
|
|
+#else
|
|
+ fh_in = open(sector[i].filename, O_RDONLY,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
|
|
+#endif
|
|
+ if (fh_in < 0) {
|
|
+ printf("Open file %s error!\n", sector[i].filename);
|
|
+ close(fh_out);
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ switch(sector[i].type) {
|
|
+ case BOOT_CODE:
|
|
+ printf("BOOT-CODE ");
|
|
+ break;
|
|
+ case CONFIG:
|
|
+ printf("CONFIG-DATA(%s) ", (no_hw_config ? "no-hw" : "all"));
|
|
+ break;
|
|
+ case WEB_PAGES:
|
|
+ printf("WEB-PAGES ");
|
|
+ break;
|
|
+ case SYS:
|
|
+ printf("LINUX ");
|
|
+ break;
|
|
+ case ROOT:
|
|
+ printf("ROOT ");
|
|
+ break;
|
|
+ case ALL:
|
|
+ printf("ALL ");
|
|
+ break;
|
|
+ case INVALID_FILE:
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (read(fh_in, buf, sbuf.st_size) != sbuf.st_size) {
|
|
+ printf("Read file %s error!\n", sector[i].filename);
|
|
+ close(fh_in);
|
|
+ close(fh_out);
|
|
+ free(buf);
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ if (is_all)
|
|
+ checksum = calculateChecksum((char *)buf, sbuf.st_size, checksum);
|
|
+ else {
|
|
+ if (sector[i].with_header) {
|
|
+ if (sector[i].type == CONFIG) {
|
|
+ if (no_hw_config == 0)
|
|
+ burnAddr = HW_SETTING_OFFSET;
|
|
+ else
|
|
+ burnAddr = DEFAULT_SETTING_OFFSET;
|
|
+ }
|
|
+ else {
|
|
+ pHeader = (IMG_HEADER_Tp)buf;
|
|
+ burnAddr = DWORD_SWAP(pHeader->burnAddr);
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ burnAddr = 0;
|
|
+
|
|
+ if (byteswap) {
|
|
+ if (sbuf.st_size % 2) {
|
|
+ buf[sbuf.st_size] = '\0';
|
|
+ sbuf.st_size++;
|
|
+ }
|
|
+ do_byteswap(buf, sbuf.st_size);
|
|
+ }
|
|
+
|
|
+ // try to append 0 if necessary
|
|
+ if (!cascade && last_idx!=-1 && sector[i].with_header) {
|
|
+ if ((sector[last_idx].offset+sector[last_idx].size) < burnAddr) {
|
|
+ len = burnAddr - (sector[last_idx].offset+sector[last_idx].size);
|
|
+ buf1 = calloc(len, 1);
|
|
+ if (buf1 == NULL) {
|
|
+ printf("allocate buffer failed %d!\n", len);
|
|
+ exit(1);
|
|
+ }
|
|
+ write(fh_out, buf1, len); // pad 0
|
|
+
|
|
+ free(buf1);
|
|
+ total += len;
|
|
+// printf("pad size=%d, last_idx=%d, burnAddr=%d\n", len, last_idx, burnAddr);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // skip header if necessary
|
|
+ if (!cascade && sector[i].with_header &&
|
|
+ ((sector[i].type == ROOT) || (sector[i].type == BOOT_CODE))) {
|
|
+ offset = sizeof(IMG_HEADER_T);
|
|
+// sbuf.st_size -= sizeof(IMG_HEADER_T);
|
|
+ }
|
|
+ else
|
|
+ offset = 0;
|
|
+ }
|
|
+
|
|
+// printf("write offset=%d, size=%d\n", offset, sbuf.st_size);
|
|
+ if ( write(fh_out, buf + offset , sbuf.st_size-offset) != sbuf.st_size-offset) {
|
|
+ printf("Write output file %s error!\n", outFile);
|
|
+ close(fh_in);
|
|
+ close(fh_out);
|
|
+ free(buf);
|
|
+ exit(1);
|
|
+ }
|
|
+ close(fh_in);
|
|
+ if (burnAddr > 0)
|
|
+ sector[i].offset = burnAddr;
|
|
+ else
|
|
+ sector[i].offset = total;
|
|
+ sector[i].size = sbuf.st_size-offset;
|
|
+
|
|
+// printf("section[%d], offset=%d, size=%d\n", i, sector[i].offset, sector[i].size);
|
|
+
|
|
+ total += sbuf.st_size;
|
|
+ free(buf);
|
|
+ last_idx = i;
|
|
+ if (is_all)
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (is_all) {
|
|
+ allHeader.len = DWORD_SWAP((total+2));
|
|
+ checksum = calculateChecksum((char *)&allHeader, sizeof(allHeader), checksum);
|
|
+ checksum = WORD_SWAP((~checksum+1));
|
|
+ write(fh_out, &checksum, 2);
|
|
+ lseek(fh_out, 0, SEEK_SET);
|
|
+ allHeader.len = DWORD_SWAP((total+2));
|
|
+// allHeader.startAddr = DWORD_SWAP(image_num);
|
|
+ write(fh_out, &allHeader, sizeof(allHeader));
|
|
+ total += (2 + sizeof(allHeader));
|
|
+ }
|
|
+ close(fh_out);
|
|
+
|
|
+#ifdef WIN32
|
|
+ _chmod(outFile, S_IREAD);
|
|
+#else
|
|
+ chmod(outFile, DEFFILEMODE);
|
|
+#endif
|
|
+
|
|
+ printf("=> %s ok, size=%d.\n", outFile, total);
|
|
+ exit(0);
|
|
+}
|
|
+
|
|
--
|
|
2.25.1
|
|
|