diff --git a/mediatek_uimake.sh b/mediatek_uimake.sh index aaaf2eff817dd349c48214897f5ee475d72b8797..be8e5bf2b8178afe32d22c90a1b7ddc16f30e737 100755 --- a/mediatek_uimake.sh +++ b/mediatek_uimake.sh @@ -1,16 +1,16 @@ #!/bin/bash -mediatek=$1 -if [ ! $1 ]; then - echo "Pass the path to mediatek/Uboot as an argument" - exit -1 -fi +# mediatek=$1 +# if [ ! $1 ]; then +# echo "Pass the path to mediatek/Uboot as an argument" +# exit -1 +# fi DDR_CHIP=DEFAULT_DDR3_2048M CFG_ENV_IS=IN_NAND cp mt7621_stage_L2.bin uboot_a.bin -$mediatek/mt7621_ddr.sh uboot_a.bin uboot_a.bin $mediatek/mt7621_ddr_param.txt $DDR_CHIP $CFG_ENV_IS +./mt7621_ddr.sh uboot_a.bin uboot_a.bin mt7621_ddr_param.txt $DDR_CHIP $CFG_ENV_IS echo "0 10"|xxd -r|dd bs=1 count=1 seek=38 of=uboot_a.bin conv=notrunc echo "0 11"|xxd -r|dd bs=1 count=1 seek=39 of=uboot_a.bin conv=notrunc chmod 777 uboot_a.bin @@ -24,8 +24,7 @@ echo "$(((bytes + 4095)/4096))" dd if=u-boot.bin of=uboot_a.bin bs=1 count=$count seek=$(( ((bytes + 4095)/4096) * 4096 - 64 )) conv=notrunc -echo "$mkimage/tools/mkimage" -$mediatek/tools/mkimage -A mips -T standalone -C none \ +./tools/mkimage_mediatek -A mips -T standalone -C none \ -a 0xA0200000 -e 0xa0200000 \ -n "NAND Flash Image" \ -r DDR3 -s 16 -t 256 -u 32 \ diff --git a/mt7621_ddr.sh b/mt7621_ddr.sh new file mode 100755 index 0000000000000000000000000000000000000000..bbb3fe856adbd96c659ccc96eef0e61b41705ab6 --- /dev/null +++ b/mt7621_ddr.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +VAR=$4 +DDR3=$(echo ${VAR##*DDR3}) + +if [ "$DDR3" == "$4" ]; then +ddr_param_offset=200 +else +ddr_param_offset=96 +fi + +LINE_NUM=$(cat ./$3|sed -n "/$4/=") +LINE_NUM=$(echo $LINE_NUM + "1"|bc) + +if [ "$5" == "IN_NAND" ]; then +offset=$ddr_param_offset +sed -n "${LINE_NUM}p" ./$3|xxd -r -c 32|dd bs=1 count=32 seek=$offset of=$2 conv=notrunc +offset=$(echo $offset + "32"|bc) +LINE_NUM=$(echo $LINE_NUM + "1"|bc) +sed -n "${LINE_NUM}p" ./$3|xxd -r -c 32|dd bs=1 count=32 seek=$offset of=$2 conv=notrunc +offset=$(echo $offset + "32"|bc) +LINE_NUM=$(echo $LINE_NUM + "1"|bc) +sed -n "${LINE_NUM}p" ./$3|xxd -r -c 32|dd bs=1 count=32 seek=$offset of=$2 conv=notrunc +else +offset=$(echo "(($(stat -c %s uboot.bin)+$ddr_param_offset))" |bc) +sed -n "${LINE_NUM}p" ./$3|xxd -r -c 32|dd bs=1 count=32 seek=$offset of=$2 conv=notrunc +LINE_NUM=$(echo $LINE_NUM + "1"|bc) +offset=$(echo $offset + "32"|bc) +sed -n "${LINE_NUM}p" ./$3|xxd -r -c 32|dd bs=1 count=32 seek=$offset of=$2 conv=notrunc +LINE_NUM=$(echo $LINE_NUM + "1"|bc) +offset=$(echo $offset + "32"|bc) +sed -n "${LINE_NUM}p" ./$3|xxd -r -c 32|dd bs=1 count=32 seek=$offset of=$2 conv=notrunc +fi + diff --git a/mt7621_ddr_param.txt b/mt7621_ddr_param.txt new file mode 100755 index 0000000000000000000000000000000000000000..00db55dd4ee406cc62edf912db0257e20ff7c6ed --- /dev/null +++ b/mt7621_ddr_param.txt @@ -0,0 +1,32 @@ +[DEFAULT_DDR2_512M] +0xAA00AA00 0xAA00AA00 0x00000007 0x22174441 0x00000000 0xF0748661 0x40001273 0x9F0A0481 +0x0304692F 0x15602842 0x00008888 0x88888888 0x00000000 0x00000000 0x00000000 0x07100000 +0x00001B63 0x00002000 0x00004000 0x00006000 0x00000000 0x00000000 0x00000000 0x00000000 +[W9751G6KB_A02_DDR2_1066_512M] +0xAA00AA00 0xAA00AA00 0x00000007 0x33484584 0x00000000 0xF07486A1 0x50001273 0x9F010481 +0x0304693F 0x15602842 0x00008888 0x88888888 0x00000000 0x00000000 0x00000010 0x07100000 +0x00001F73 0x00002000 0x00004000 0x00006000 0x00000000 0x00000000 0x00000000 0x00000000 +[DEFAULT_DDR2_1024M] +0xAA00AA00 0xAA00AA00 0x00000007 0x22174441 0x01000000 0xF0748661 0x40001273 0x9F0F0481 +0x0304692F 0x15602842 0x00008888 0x88888888 0x00000000 0x00000000 0x00000000 0x07100000 +0x00001B63 0x00002000 0x00004000 0x00006000 0x00000000 0x00000000 0x00000000 0x00000000 +[W971GG6KB25_DDR2_800_1024M] +0xAA00AA00 0xAA00AA00 0x00000007 0x22174430 0x01000000 0xF0748661 0x40001273 0x9F0F0481 +0x0304692F 0x15602842 0x00008888 0x88888888 0x00000000 0x00000000 0x00000000 0x07100000 +0x00001B63 0x00002000 0x00004000 0x00006000 0x00000000 0x00000000 0x00000000 0x00000000 +[W971GG6KB18_DDR2_1066_1024M] +0xAA00AA00 0xAA00AA00 0x00000007 0x33484584 0x01000000 0xF07486A1 0x50001273 0x9F070481 +0x0304693F 0x15602842 0x00008888 0x88888888 0x00000000 0x00000000 0x00000010 0x07100000 +0x00001F73 0x00002000 0x00004000 0x00006000 0x00000000 0x00000000 0x00000000 0x00000000 +[DEFAULT_DDR3_1024M] +0xAA00AA00 0xAA00AA00 0x00000007 0x44694683 0x01000000 0xF07486A1 0xC287221D 0x9F060481 +0x03046948 0x15602842 0x00008888 0x88888888 0x00000000 0x00000000 0x00000210 0x07100000 +0x00001B61 0x00002040 0x00004010 0x00006000 0x0A000000 0x07070000 0x00000000 0x00000000 +[DEFAULT_DDR3_2048M] +0xAA00AA00 0xAA00AA00 0x00000007 0x44694673 0x01000000 0xF07486A1 0xC287221D 0x9F050481 +0x03046948 0x15602842 0x00008888 0x88888888 0x00000000 0x00000000 0x00000220 0x07100000 +0x00001B61 0x00002040 0x00004010 0x00006000 0x0A000000 0x07070000 0x00000000 0x00000000 +[DEFAULT_DDR3_4096M] +0xAA00AA00 0xAA00AA00 0x00000007 0x44694683 0x01000000 0xF07486A1 0xC287221D 0x9F0F0481 +0x03046948 0x15602842 0x00008888 0x88888888 0x00000000 0x00000000 0x00000240 0x07100000 +0x00001B61 0x00002040 0x00004010 0x00006000 0x0A000000 0x07070000 0x00000000 0x00000000 diff --git a/tools/Makefile b/tools/Makefile index da50e1bffca459b6a14bb4fe73371a8a79269e05..bb7a8c732641874cb5375b6bdca1003a77c47bf3 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -48,6 +48,9 @@ HOSTCFLAGS_img2srec.o := -pedantic hostprogs-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes HOSTCFLAGS_xway-swap-bytes.o := -pedantic +hostprogs-y += mkimage_mediatek +mkimage_mediatek-objs := mkimage_mediatek.o crc.o lib/crc32.o + hostprogs-y += mkenvimage mkenvimage-objs := mkenvimage.o os_support.o lib/crc32.o diff --git a/tools/crc.c b/tools/crc.c new file mode 100755 index 0000000000000000000000000000000000000000..1454121cb2e6b1f3678a5fdff9573da27dc316e4 --- /dev/null +++ b/tools/crc.c @@ -0,0 +1,150 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * James W. Williams of NASA Goddard Space Flight Center. + * + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#ifndef lint +#if 0 +static char sccsid[] = "@(#)crc.c 8.1 (Berkeley) 6/17/93"; +#endif +#endif /* not lint */ +#include <sys/cdefs.h> + +#include <sys/types.h> + +#include <stdint.h> +#include <unistd.h> + + +static const uint32_t crctab[] = { + 0x0, + 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, + 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, + 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, + 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, + 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f, + 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, + 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, + 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, + 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, + 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe, + 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, + 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, + 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, + 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, + 0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, + 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07, + 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, + 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, + 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, + 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, + 0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, + 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, + 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, + 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f, + 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, + 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, + 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, + 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, + 0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629, + 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, + 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, + 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, + 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, + 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8, + 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, + 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, + 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, + 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, + 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, + 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21, + 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, + 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087, + 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, + 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, + 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, + 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, + 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, + 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09, + 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, + 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, + 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 +}; + +/* + * Compute a POSIX 1003.2 checksum. This routine has been broken out so that + * other programs can use it. It takes a file descriptor to read from and + * locations to store the crc and the number of bytes read. It returns 0 on + * success and 1 on failure. Errno is set on failure. + */ +uint32_t crc_total = ~0; /* The crc over a number of files. */ + +int +crc(u_char* psrc, uint32_t *cval, int clen) +{ + uint32_t lcrc; + int nr; + off_t len; + u_char *pbuf; + int total_len = clen; +#define COMPUTE(var, ch) (var) = (var) << 8 ^ crctab[(var) >> 24 ^ (ch)] + + lcrc = len = 0; + crc_total = ~crc_total; + + pbuf = psrc; + while (total_len>0) + { + if (total_len >= 64) + nr = 64; + else + nr = total_len; + total_len-=nr; + for (len += nr; nr--; ++pbuf) { + COMPUTE(lcrc, *pbuf); + COMPUTE(crc_total, *pbuf); + } + } + + + /* Include the length of the file. */ + for (; len != 0; len >>= 8) { + COMPUTE(lcrc, len & 0xff); + COMPUTE(crc_total, len & 0xff); + } + + *cval = ~lcrc; + crc_total = ~crc_total; + return (0); +} diff --git a/tools/mediatek.h b/tools/mediatek.h new file mode 100644 index 0000000000000000000000000000000000000000..de9a85a4392ef0760081eaeac9ef1c8494f3649e --- /dev/null +++ b/tools/mediatek.h @@ -0,0 +1,65 @@ +/* + * Automatically generated by make menuconfig: don't edit + */ +#define AUTOCONF_INCLUDED +#define CONFIG_CROSS_COMPILER_PATH "/opt/mips-2012.03/bin/" +#define ASIC_BOARD 1 +#undef RT2880_ASIC_BOARD +#undef RT3350_ASIC_BOARD +#undef RT3052_ASIC_BOARD +#undef RT3352_ASIC_BOARD +#undef RT3883_ASIC_BOARD +#undef RT5350_ASIC_BOARD +#undef RT6855A_ASIC_BOARD +#undef MT7620_ASIC_BOARD +#define MT7621_ASIC_BOARD 1 +#undef MT7628_ASIC_BOARD +#define MT7621_MP 1 +#define MT7621_USE_GE1 1 +#undef MT7621_USE_GE2 +#undef GE_MII_FORCE_100 +#undef GE_RVMII_FORCE_100 +#undef GE_MII_AN +#define GE_RGMII_FORCE_1000 1 +#undef GE_RGMII_AN +#define MAC_TO_MT7530_MODE 1 +#define GPIOx_RESET_MODE 1 +#define ON_BOARD_NAND_FLASH_COMPONENT 1 +#undef ON_BOARD_SPI_FLASH_COMPONENT +#define ON_BOARD_NAND_BOOTSTRAP 1 +#define ON_BOARD_DDR3 1 +#define ON_BOARD_DDR_WIDTH_16 1 +#define ON_BOARD_16BIT_DRAM_BUS 1 +#undef ON_BOARD_512M_DRAM_COMPONENT +#undef ON_BOARD_1024M_DRAM_COMPONENT +#define ON_BOARD_2048M_DRAM_COMPONENT 1 +#undef ON_BOARD_4096M_DRAM_COMPONENT +#define MT7621_DDR_1200MHZ 1 +#undef MT7621_DDR_1066MHZ +#undef MT7621_DDR_800MHZ +#undef MT7621_DDR_400MHZ +#define MT7621_DDR_SPEED 0x11 +#define MT7621_CPU_880MHZ 1 +#undef MT7621_CPU_875MHZ +#undef MT7621_CPU_800MHZ +#undef MT7621_CPU_500MHZ +#undef MT7621_CPU_50MHZ +#define MT7621_CPU_FREQUENCY 0x370 +#define PDMA_NEW 1 +#define RX_SCATTER_GATTER_DMA 1 +#define UBOOT_RAM 1 +#undef DUAL_IMAGE_SUPPORT +#define RALINK_DUAL_CORE_FUN 1 +#define RALINK_DUAL_VPE_FUN 1 +#undef LAN_WAN_PARTITION +#define DDR_ACT_SETTING 1 +#undef DEFAULT_DDR3_1024M +#define DEFAULT_DDR3_2048M 1 +#undef DEFAULT_DDR3_4096M +#undef DEFAULT_DDR2_512M +#undef W9751G6KB_A02_DDR2_1066_512M +#undef DEFAULT_DDR2_1024M +#undef W971GG6KB25_DDR2_800_1024M +#undef W971GG6KB18_DDR2_1066_1024M +#define DDR_CHIP "DEFAULT_DDR3_2048M" +#define TEXT_BASE 0xA0200000 diff --git a/tools/mediatek_image.h b/tools/mediatek_image.h new file mode 100644 index 0000000000000000000000000000000000000000..c1eb60f6af086f8b852de87347bf2accdb086ce1 --- /dev/null +++ b/tools/mediatek_image.h @@ -0,0 +1,269 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __IMAGE_H__ +#define __IMAGE_H__ + +#include "mediatek.h" + +/* + * Operating System Codes + */ +#define IH_OS_INVALID 0 /* Invalid OS */ +#define IH_OS_OPENBSD 1 /* OpenBSD */ +#define IH_OS_NETBSD 2 /* NetBSD */ +#define IH_OS_FREEBSD 3 /* FreeBSD */ +#define IH_OS_4_4BSD 4 /* 4.4BSD */ +#define IH_OS_LINUX 5 /* Linux */ +#define IH_OS_SVR4 6 /* SVR4 */ +#define IH_OS_ESIX 7 /* Esix */ +#define IH_OS_SOLARIS 8 /* Solaris */ +#define IH_OS_IRIX 9 /* Irix */ +#define IH_OS_SCO 10 /* SCO */ +#define IH_OS_DELL 11 /* Dell */ +#define IH_OS_NCR 12 /* NCR */ +#define IH_OS_LYNXOS 13 /* LynxOS */ +#define IH_OS_VXWORKS 14 /* VxWorks */ +#define IH_OS_PSOS 15 /* pSOS */ +#define IH_OS_QNX 16 /* QNX */ +#define IH_OS_U_BOOT 17 /* Firmware */ +#define IH_OS_RTEMS 18 /* RTEMS */ +#define IH_OS_ARTOS 19 /* ARTOS */ +#define IH_OS_UNITY 20 /* Unity OS */ + +/* + * CPU Architecture Codes (supported by Linux) + */ +#define IH_CPU_INVALID 0 /* Invalid CPU */ +#define IH_CPU_ALPHA 1 /* Alpha */ +#define IH_CPU_ARM 2 /* ARM */ +#define IH_CPU_I386 3 /* Intel x86 */ +#define IH_CPU_IA64 4 /* IA64 */ +#define IH_CPU_MIPS 5 /* MIPS */ +#define IH_CPU_MIPS64 6 /* MIPS 64 Bit */ +#define IH_CPU_PPC 7 /* PowerPC */ +#define IH_CPU_S390 8 /* IBM S390 */ +#define IH_CPU_SH 9 /* SuperH */ +#define IH_CPU_SPARC 10 /* Sparc */ +#define IH_CPU_SPARC64 11 /* Sparc 64 Bit */ +#define IH_CPU_M68K 12 /* M68K */ +#define IH_CPU_NIOS 13 /* Nios-32 */ +#define IH_CPU_MICROBLAZE 14 /* MicroBlaze */ +#define IH_CPU_NIOS2 15 /* Nios-II */ + +/* + * Image Types + * + * "Standalone Programs" are directly runnable in the environment + * provided by U-Boot; it is expected that (if they behave + * well) you can continue to work in U-Boot after return from + * the Standalone Program. + * "OS Kernel Images" are usually images of some Embedded OS which + * will take over control completely. Usually these programs + * will install their own set of exception handlers, device + * drivers, set up the MMU, etc. - this means, that you cannot + * expect to re-enter U-Boot except by resetting the CPU. + * "RAMDisk Images" are more or less just data blocks, and their + * parameters (address, size) are passed to an OS kernel that is + * being started. + * "Multi-File Images" contain several images, typically an OS + * (Linux) kernel image and one or more data images like + * RAMDisks. This construct is useful for instance when you want + * to boot over the network using BOOTP etc., where the boot + * server provides just a single image file, but you want to get + * for instance an OS kernel and a RAMDisk image. + * + * "Multi-File Images" start with a list of image sizes, each + * image size (in bytes) specified by an "uint32_t" in network + * byte order. This list is terminated by an "(uint32_t)0". + * Immediately after the terminating 0 follow the images, one by + * one, all aligned on "uint32_t" boundaries (size rounded up to + * a multiple of 4 bytes - except for the last file). + * + * "Firmware Images" are binary images containing firmware (like + * U-Boot or FPGA images) which usually will be programmed to + * flash memory. + * + * "Script files" are command sequences that will be executed by + * U-Boot's command interpreter; this feature is especially + * useful when you configure U-Boot to use a real shell (hush) + * as command interpreter (=> Shell Scripts). + */ + +#define IH_TYPE_INVALID 0 /* Invalid Image */ +#define IH_TYPE_STANDALONE 1 /* Standalone Program */ +#define IH_TYPE_KERNEL 2 /* OS Kernel Image */ +#define IH_TYPE_RAMDISK 3 /* RAMDisk Image */ +#define IH_TYPE_MULTI 4 /* Multi-File Image */ +#define IH_TYPE_FIRMWARE 5 /* Firmware Image */ +#define IH_TYPE_SCRIPT 6 /* Script file */ +#define IH_TYPE_FILESYSTEM 7 /* Filesystem Image (any type) */ + +/* + * Compression Types + */ +#define IH_COMP_NONE 0 /* No Compression Used */ +#define IH_COMP_GZIP 1 /* gzip Compression Used */ +#define IH_COMP_BZIP2 2 /* bzip2 Compression Used */ +#define IH_COMP_LZMA 3 /* lzma Compression Used */ +#define IH_COMP_XZ 5 /* xz Compression Used */ + +#define IH_MAGIC 0x27051956 /* Image Magic Number */ + +#if defined (MT7621_ASIC_BOARD) || defined (MT7621_FPGA_BOARD) +#if defined (ON_BOARD_NAND_FLASH_COMPONENT) +#define IH_NMLEN (16-4) +#else +#define IH_NMLEN (16) +#endif +#elif defined (MT7620_ASIC_BOARD) || defined (MT7620_FPGA_BOARD) || defined (MT7628_ASIC_BOARD) || defined (MT7628_FPGA_BOARD) +#define IH_NMLEN (16-4*2) /* Image Name Length */ +#elif defined (RT6855A_ASIC_BOARD) || defined (RT6855A_FPGA_BOARD) +#define IH_NMLEN (16-4*4) +#else +#define IH_NMLEN 16 /* Image Name Length */ +#endif +/* + * all data in network byte order (aka natural aka bigendian) + */ + + +typedef struct dram_header { +#if defined(MT7620_ASIC_BOARD) || defined(MT7620_FPGA_BOARD) || defined(MT7628_ASIC_BOARD) || defined(MT7628_FPGA_BOARD) + uint16_t ddr_self_refresh; + uint16_t ddr_cfg11; + uint32_t ddr_cfg10; +#endif +#if defined (RT6855A_ASIC_BOARD) || defined (RT6855A_FPGA_BOARD) + uint32_t dram_pad_setting; + uint32_t ddr_cfg2; + uint32_t ddr_cfg3; + uint32_t ddr_cfg4; +#endif + uint8_t dram_parm; /* DRAM setting */ + union{ + uint8_t dram_magic; /* Magic number of DRAM setting (0x5a) */ + struct { + uint8_t cpu_pll_magic_l:4; + uint8_t dram_magic_h:4; + }u; + }; + uint16_t cpu_pll_cfg; +#if defined(RT3052_ASIC_BOARD) || defined(RT3052_FPGA_BOARD) ||\ + defined(RT3352_ASIC_BOARD) || defined(RT3352_FPGA_BOARD) ||\ + defined(RT5350_ASIC_BOARD) || defined(RT5350_FPGA_BOARD) ||\ + defined(RT3883_ASIC_BOARD) || defined(RT3883_FPGA_BOARD) + uint16_t magic_lh; /* low half word of magic number 0x5244 */ + uint16_t magic_hh; /* high half word of magic number 0x4D41 */ + union { + struct { + uint8_t syscfg1; + uint8_t ddr_cfg3; + uint16_t resv1; + uint32_t resv2; + }ddr; + + struct { + uint32_t sdram_cfg0; + uint32_t sdram_cfg1; + }sdr; + }; +#else + uint8_t magic; /* magic number 0x68 */ +#if defined (RT6855A_ASIC_BOARD) || defined (RT6855A_FPGA_BOARD) + uint8_t rsvd0[3]; +#else + uint8_t reservd; + uint16_t syscfg1_ddrcfg3_odt; +#endif + union { + struct { + uint32_t ddr_cfg0; + uint32_t ddr_cfg1; + }ddr; + struct { + uint32_t sdram_cfg0; + uint32_t sdram_cfg1; + }sdr; + }; +#endif +} dram_header_t __attribute__ ((packed)); + +typedef struct nand_badblock_info1_type { + uint32_t ecc_bits : 3; + uint32_t rsvd : 5; + uint32_t ecc_offset : 8; + uint32_t bad_block_offser : 8; + uint32_t checksum : 8; +} nand_badblock_info1_t __attribute__ ((packed)); + +typedef struct nand_info_1_type { + uint32_t pagesize : 2; + uint32_t rsvd0 : 2; + uint32_t addr_cycle : 2; + uint32_t rsvd1 : 2; + uint32_t spare_size : 2; + uint32_t rsvd2 : 2; + uint32_t total_size : 3; + uint32_t rsvd3 : 1; + uint32_t block_size : 2; + uint32_t rsvd4 : 2; + uint32_t magic_id : 12; +} nand_info_1_t __attribute__ ((packed)); + + +typedef struct nand_header { + uint32_t nand_ac_timing; + uint32_t ih_stage_offset; /* stage1 offset */ + uint32_t ih_bootloader_offset; /* bootloader offset */ + union + { + nand_info_1_t nand_info_1; + uint32_t nand_info_1_data; + }; + //nand_badblock_info1_t nand_badblock_info1; + uint32_t crc; +} nand_header_t __attribute__ ((packed)); + +typedef struct image_header { + uint32_t ih_magic; /* Image Header Magic Number */ + uint32_t ih_hcrc; /* Image Header CRC Checksum */ + uint32_t ih_time; /* Image Creation Timestamp */ + uint32_t ih_size; /* Image Data Size */ + uint32_t ih_load; /* Data Load Address */ + uint32_t ih_ep; /* Entry Point Address */ + uint32_t ih_dcrc; /* Image Data CRC Checksum */ + uint8_t ih_os; /* Operating System */ + uint8_t ih_arch; /* CPU architecture */ + uint8_t ih_type; /* Image Type */ + uint8_t ih_comp; /* Compression Type */ + uint8_t ih_name[IH_NMLEN]; /* Image Name */ +#if defined (MT7621_ASIC_BOARD) || defined (MT7621_FPGA_BOARD) + nand_header_t ih_nand; +#else + dram_header_t ih_dram; +#endif +} image_header_t __attribute__((packed)); + + +#endif /* __IMAGE_H__ */ diff --git a/tools/mkimage_mediatek.c b/tools/mkimage_mediatek.c new file mode 100644 index 0000000000000000000000000000000000000000..b61de02f551988e94fb8339e857518223d0e9f6b --- /dev/null +++ b/tools/mkimage_mediatek.c @@ -0,0 +1,1017 @@ +/* + * (C) Copyright 2000-2004 + * DENX Software Engineering + * Wolfgang Denk, wd@denx.de + * All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#ifndef __WIN32__ +#include <netinet/in.h> /* for host / network byte order conversions */ +#endif +#include <sys/mman.h> +#include <sys/stat.h> +#include <time.h> +#include <unistd.h> + +#if defined(__BEOS__) || defined(__NetBSD__) || defined(__APPLE__) +#include <inttypes.h> +#endif + +#ifdef __WIN32__ +typedef unsigned int __u32; + +#define SWAP_LONG(x) \ + ((__u32)( \ + (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \ + (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \ + (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \ + (((__u32)(x) & (__u32)0xff000000UL) >> 24) )) +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; + +#define ntohl(a) SWAP_LONG(a) +#define htonl(a) SWAP_LONG(a) +#endif /* __WIN32__ */ + +#ifndef O_BINARY /* should be define'd on __WIN32__ */ +#define O_BINARY 0 +#endif + +#include "mediatek_image.h" +#include "mediatek.h" + +extern int errno; + +#ifndef MAP_FAILED +#define MAP_FAILED (-1) +#endif + +char *cmdname; + +extern unsigned long crc32 (unsigned long crc, const char *buf, unsigned int len); + +typedef struct table_entry { + int val; /* as defined in image.h */ + char *sname; /* short (input) name */ + char *lname; /* long (output) name */ +} table_entry_t; + +table_entry_t arch_name[] = { + { IH_CPU_INVALID, NULL, "Invalid CPU", }, + { IH_CPU_ALPHA, "alpha", "Alpha", }, + { IH_CPU_ARM, "arm", "ARM", }, + { IH_CPU_I386, "x86", "Intel x86", }, + { IH_CPU_IA64, "ia64", "IA64", }, + { IH_CPU_M68K, "m68k", "MC68000", }, + { IH_CPU_MICROBLAZE, "microblaze", "MicroBlaze", }, + { IH_CPU_MIPS, "mips", "MIPS", }, + { IH_CPU_MIPS64, "mips64", "MIPS 64 Bit", }, + { IH_CPU_PPC, "ppc", "PowerPC", }, + { IH_CPU_S390, "s390", "IBM S390", }, + { IH_CPU_SH, "sh", "SuperH", }, + { IH_CPU_SPARC, "sparc", "SPARC", }, + { IH_CPU_SPARC64, "sparc64", "SPARC 64 Bit", }, + { -1, "", "", }, +}; + +table_entry_t os_name[] = { + { IH_OS_INVALID, NULL, "Invalid OS", }, + { IH_OS_4_4BSD, "4_4bsd", "4_4BSD", }, + { IH_OS_ARTOS, "artos", "ARTOS", }, + { IH_OS_DELL, "dell", "Dell", }, + { IH_OS_ESIX, "esix", "Esix", }, + { IH_OS_FREEBSD, "freebsd", "FreeBSD", }, + { IH_OS_IRIX, "irix", "Irix", }, + { IH_OS_LINUX, "linux", "Linux", }, + { IH_OS_LYNXOS, "lynxos", "LynxOS", }, + { IH_OS_NCR, "ncr", "NCR", }, + { IH_OS_NETBSD, "netbsd", "NetBSD", }, + { IH_OS_OPENBSD, "openbsd", "OpenBSD", }, + { IH_OS_PSOS, "psos", "pSOS", }, + { IH_OS_QNX, "qnx", "QNX", }, + { IH_OS_RTEMS, "rtems", "RTEMS", }, + { IH_OS_SCO, "sco", "SCO", }, + { IH_OS_SOLARIS, "solaris", "Solaris", }, + { IH_OS_SVR4, "svr4", "SVR4", }, + { IH_OS_U_BOOT, "u-boot", "U-Boot", }, + { IH_OS_VXWORKS, "vxworks", "VxWorks", }, + { -1, "", "", }, +}; + +table_entry_t type_name[] = { + { IH_TYPE_INVALID, NULL, "Invalid Image", }, + { IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image", }, + { IH_TYPE_FIRMWARE, "firmware", "Firmware", }, + { IH_TYPE_KERNEL, "kernel", "Kernel Image", }, + { IH_TYPE_MULTI, "multi", "Multi-File Image", }, + { IH_TYPE_RAMDISK, "ramdisk", "RAMDisk Image", }, + { IH_TYPE_SCRIPT, "script", "Script", }, + { IH_TYPE_STANDALONE, "standalone", "Standalone Program", }, + { -1, "", "", }, +}; + +table_entry_t comp_name[] = { + { IH_COMP_NONE, "none", "uncompressed", }, + { IH_COMP_BZIP2, "bzip2", "bzip2 compressed", }, + { IH_COMP_GZIP, "gzip", "gzip compressed", }, + { IH_COMP_LZMA, "lzma", "lzma compressed", }, + { IH_COMP_XZ, "xz", "xz compressed", }, + { -1, "", "", }, +}; + +static void copy_file (int, const char *, int); +static void usage (void); +static void print_header (image_header_t *); +static void print_type (image_header_t *); +static char *put_table_entry (table_entry_t *, char *, int); +static char *put_arch (int); +static char *put_type (int); +static char *put_os (int); +static char *put_comp (int); +static int get_table_entry (table_entry_t *, char *, char *); +static int get_arch(char *); +static int get_comp(char *); +static int get_os (char *); +static int get_type(char *); + + +char *datafile; +char *imagefile; + +int dflag = 0; +int eflag = 0; +int lflag = 0; +int vflag = 0; +int xflag = 0; +int opt_os = IH_OS_LINUX; +int opt_arch = IH_CPU_PPC; +int opt_type = IH_TYPE_KERNEL; +int opt_comp = IH_COMP_GZIP; + +image_header_t header; +image_header_t *hdr = &header; + +int +main (int argc, char **argv) +{ + int ifd; + uint32_t checksum; + uint32_t addr; + uint32_t ep; + struct stat sbuf; + unsigned char *ptr; + char *name = ""; + char *dram_name = ""; + uint32_t dram_type; + uint32_t dram_total_width; + uint32_t dram_size; + uint32_t dram_width; + uint32_t dram_cfg0; + uint32_t dram_cfg1; + uint16_t cpu_pll; + uint32_t stage1_start, bootloader_start; + cmdname = *argv; + + addr = ep = 0; + + while (--argc > 0 && **++argv == '-') { + while (*++*argv) { + switch (**argv) { + case 'l': + lflag = 1; + break; + case 'A': + if ((--argc <= 0) || + (opt_arch = get_arch(*++argv)) < 0) + usage (); + goto NXTARG; + case 'C': + if ((--argc <= 0) || + (opt_comp = get_comp(*++argv)) < 0) + usage (); + goto NXTARG; + case 'O': + if ((--argc <= 0) || + (opt_os = get_os(*++argv)) < 0) + usage (); + goto NXTARG; + case 'T': + if ((--argc <= 0) || + (opt_type = get_type(*++argv)) < 0) + usage (); + goto NXTARG; + + case 'a': + if (--argc <= 0) + usage (); + addr = strtoul (*++argv, (char **)&ptr, 16); + if (*ptr) { + fprintf (stderr, + "%s: invalid load address %s\n", + cmdname, *argv); + exit (EXIT_FAILURE); + } + goto NXTARG; + case 'd': + if (--argc <= 0) + usage (); + datafile = *++argv; + dflag = 1; + goto NXTARG; + case 'e': + if (--argc <= 0) + usage (); + ep = strtoul (*++argv, (char **)&ptr, 16); + if (*ptr) { + fprintf (stderr, + "%s: invalid entry point %s\n", + cmdname, *argv); + exit (EXIT_FAILURE); + } + eflag = 1; + goto NXTARG; + case 'r': + if (--argc <= 0) + usage (); + dram_name=*++argv; + if(strncasecmp(dram_name,"sdr",3)==0) { + dram_type=0; + }else if(strncasecmp(dram_name,"ddr",3)==0) { + dram_type=1; + }else { + if (*ptr) { + fprintf (stderr, + "%s: invalid dram type %s\n", + cmdname, *argv); + exit (EXIT_FAILURE); + } + } + goto NXTARG; + case 's': + if (--argc <= 0) + usage (); + dram_total_width = strtoul (*++argv, (char **)&ptr, 10); + switch(dram_total_width) { + case 16: + dram_total_width=0; + break; + case 32: + dram_total_width=1; + break; + default: + if (*ptr) { + fprintf (stderr, + "%s: invalid dram total width %s\n", + cmdname, *argv); + exit (EXIT_FAILURE); + } + } + goto NXTARG; + case 't': + if (--argc <= 0) + usage (); + dram_size = strtoul (*++argv, (char **)&ptr, 10); + switch(dram_size) { + case 2: + dram_size=0; + break; + case 8: + dram_size=1; + break; + case 16: + dram_size=2; + break; + case 32: + dram_size=3; + break; + case 64: + dram_size=4; + break; + case 128: + dram_size=5; + break; + case 256: + dram_size=6; + break; + default: + if (*ptr) { + fprintf (stderr, + "%s: invalid dram size%s\n", + cmdname, *argv); + exit (EXIT_FAILURE); + } + } + goto NXTARG; + case 'u': + if (--argc <= 0) + usage (); + dram_width = strtoul (*++argv, (char **)&ptr, 10); + switch(dram_width) { + case 16: + dram_width=0; + break; + case 32: + dram_width=1; + break; + default: + if (*ptr) { + fprintf (stderr, + "%s: invalid dram width %s\n", + cmdname, *argv); + exit (EXIT_FAILURE); + } + } + goto NXTARG; + case 'n': + if (--argc <= 0) + usage (); + name = *++argv; + goto NXTARG; + case 'v': + vflag++; + break; + case 'x': + xflag++; + break; + case 'y': + if (--argc <= 0) + usage (); +#if defined (MT7621_ASIC_BOARD) || defined (MT7621_FPGA_BOARD) + stage1_start = strtoul (*++argv, (char **)&ptr, 16); +#else + dram_cfg0 = strtoul (*++argv, (char **)&ptr, 16); + if (*ptr) { + fprintf (stderr, + "%s: invalid dram parameter 0 %s\n", + cmdname, *argv); + exit (EXIT_FAILURE); + } +#endif + goto NXTARG; + case 'z': + if (--argc <= 0) + usage (); +#if defined (MT7621_ASIC_BOARD) || defined (MT7621_FPGA_BOARD) + bootloader_start = strtoul (*++argv, (char **)&ptr, 16); +#else + dram_cfg1 = strtoul (*++argv, (char **)&ptr, 16); + if (*ptr) { + fprintf (stderr, + "%s: invalid dram parameter 1 %s\n", + cmdname, *argv); + exit (EXIT_FAILURE); + } +#endif + goto NXTARG; + case 'w': + if (--argc <= 0) + usage (); + cpu_pll = strtoul (*++argv, (char **)&ptr, 16); + goto NXTARG; + default: + usage (); + } + } +NXTARG: ; + } + + if ((argc != 1) || ((lflag ^ dflag) == 0)) + usage(); + + if (!eflag) { + ep = addr; + /* If XIP, entry point must be after the U-Boot header */ + if (xflag) + ep += sizeof(image_header_t); + } + + /* + * If XIP, ensure the entry point is equal to the load address plus + * the size of the U-Boot header. + */ + if (xflag) { + if (ep != addr + sizeof(image_header_t)) { + fprintf (stderr, "%s: For XIP, the entry point must be the load addr + %lu\n", + cmdname, + (unsigned long)sizeof(image_header_t)); + exit (EXIT_FAILURE); + } + } + + imagefile = *argv; + + if (lflag) { + ifd = open(imagefile, O_RDONLY|O_BINARY); + } else { + ifd = open(imagefile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0666); + } + + if (ifd < 0) { + fprintf (stderr, "%s: Can't open %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + + if (lflag) { + int len; + char *data; + /* + * list header information of existing image + */ + if (fstat(ifd, &sbuf) < 0) { + fprintf (stderr, "%s: Can't stat %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + + if ((unsigned)sbuf.st_size < sizeof(image_header_t)) { + fprintf (stderr, + "%s: Bad size: \"%s\" is no valid image\n", + cmdname, imagefile); + exit (EXIT_FAILURE); + } + + ptr = (unsigned char *)mmap(0, sbuf.st_size, + PROT_READ, MAP_SHARED, ifd, 0); + if ((caddr_t)ptr == (caddr_t)-1) { + fprintf (stderr, "%s: Can't read %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + + /* + * create copy of header so that we can blank out the + * checksum field for checking - this can't be done + * on the PROT_READ mapped data. + */ + memcpy (hdr, ptr, sizeof(image_header_t)); + + if (ntohl(hdr->ih_magic) != IH_MAGIC) { + fprintf (stderr, + "%s: Bad Magic Number: \"%s\" is no valid image\n", + cmdname, imagefile); + exit (EXIT_FAILURE); + } + + data = (char *)hdr; + len = sizeof(image_header_t); + + checksum = ntohl(hdr->ih_hcrc); + hdr->ih_hcrc = htonl(0); /* clear for re-calculation */ + + if (crc32 (0, data, len) != checksum) { + fprintf (stderr, + "*** Warning: \"%s\" has bad header checksum!\n", + imagefile); + } + + data = (char *)(ptr + sizeof(image_header_t)); + len = sbuf.st_size - sizeof(image_header_t) ; + + if (crc32 (0, data, len) != ntohl(hdr->ih_dcrc)) { + fprintf (stderr, + "*** Warning: \"%s\" has corrupted data!\n", + imagefile); + } + + /* for multi-file images we need the data part, too */ + print_header ((image_header_t *)ptr); + + (void) munmap((void *)ptr, sbuf.st_size); + (void) close (ifd); + + exit (EXIT_SUCCESS); + } + + /* + * Must be -w then: + * + * write dummy header, to be fixed later + */ + memset (hdr, 0, sizeof(image_header_t)); + + if (write(ifd, hdr, sizeof(image_header_t)) != sizeof(image_header_t)) { + fprintf (stderr, "%s: Write error on %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + + if (opt_type == IH_TYPE_MULTI || opt_type == IH_TYPE_SCRIPT) { + char *file = datafile; + unsigned long size; + + for (;;) { + char *sep = NULL; + + if (file) { + if ((sep = strchr(file, ':')) != NULL) { + *sep = '\0'; + } + + if (stat (file, &sbuf) < 0) { + fprintf (stderr, "%s: Can't stat %s: %s\n", + cmdname, file, strerror(errno)); + exit (EXIT_FAILURE); + } + size = htonl(sbuf.st_size); + } else { + size = 0; + } + + if (write(ifd, (char *)&size, sizeof(size)) != sizeof(size)) { + fprintf (stderr, "%s: Write error on %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + + if (!file) { + break; + } + + if (sep) { + *sep = ':'; + file = sep + 1; + } else { + file = NULL; + } + } + + file = datafile; + + for (;;) { + char *sep = strchr(file, ':'); + if (sep) { + *sep = '\0'; + copy_file (ifd, file, 1); + *sep++ = ':'; + file = sep; + } else { + copy_file (ifd, file, 0); + break; + } + } + } else { + copy_file (ifd, datafile, 0); + } + + /* We're a bit of paranoid */ +#if defined(_POSIX_SYNCHRONIZED_IO) && !defined(__sun__) && !defined(__FreeBSD__) + (void) fdatasync (ifd); +#else + (void) fsync (ifd); +#endif + + if (fstat(ifd, &sbuf) < 0) { + fprintf (stderr, "%s: Can't stat %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + + ptr = (unsigned char *)mmap(0, sbuf.st_size, + PROT_READ|PROT_WRITE, MAP_SHARED, ifd, 0); + if (ptr == (unsigned char *)MAP_FAILED) { + fprintf (stderr, "%s: Can't map %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + + hdr = (image_header_t *)ptr; + + checksum = crc32 (0, + (const char *)(ptr + sizeof(image_header_t)), + sbuf.st_size - sizeof(image_header_t) + ); + + /* Build new header */ + hdr->ih_magic = htonl(IH_MAGIC); + hdr->ih_time = htonl(sbuf.st_mtime); + hdr->ih_size = htonl(sbuf.st_size - sizeof(image_header_t)); + hdr->ih_load = htonl(addr); + hdr->ih_ep = htonl(ep); + hdr->ih_dcrc = htonl(checksum); + hdr->ih_os = opt_os; + hdr->ih_arch = opt_arch; + hdr->ih_type = opt_type; + hdr->ih_comp = opt_comp; + + strncpy((char *)hdr->ih_name, name, IH_NMLEN); + + +#if defined (MT7621_ASIC_BOARD) || defined(MT7621_FPGA_BOARD) +#if defined (ON_BOARD_NAND_FLASH_COMPONENT) + //memset(&(hdr->ih_nand), 0, sizeof(nand_header_t)); + printf("DDRCal Code Offset : 0x%08X\n",stage1_start); + printf("Uboot Offset : 0x%08X\n",bootloader_start); + hdr->ih_nand.ih_stage_offset = htonl(stage1_start); + hdr->ih_nand.ih_bootloader_offset = htonl(bootloader_start); +#if defined (ON_BOARD_NAND_HEADER) + hdr->ih_nand.nand_info_1.pagesize = NAND_PAGESIZE_INDEX; + hdr->ih_nand.nand_info_1.addr_cycle = NAND_ADDRLEN_INDEX; + hdr->ih_nand.nand_info_1.spare_size = NAND_SPARESIZE_INDEX; + hdr->ih_nand.nand_info_1.total_size = NAND_TOTALSIZE_INDEX; + hdr->ih_nand.nand_info_1.block_size = NAND_BLOCKSIZE_INDEX; + hdr->ih_nand.nand_info_1.magic_id = 0xDA0; + hdr->ih_nand.nand_info_1_data = htonl((unsigned int)(hdr->ih_nand.nand_info_1_data)); + hdr->ih_nand.nand_ac_timing = htonl(NAND_ACCTIME); +#endif +#endif +#else + //if dram_size=2M, that means dram parameters is invalid + if(dram_size==0) { + hdr->ih_dram.dram_magic=0; + } else { +#if defined (RT3352_ASIC_BOARD) || defined(RT3352_FPGA_BOARD) ||\ + defined (RT3883_ASIC_BOARD) || defined(RT3883_FPGA_BOARD) + hdr->ih_dram.dram_magic=0x5A; +#else + hdr->ih_dram.u.dram_magic_h=0x5; +#endif + } + + hdr->ih_dram.dram_parm = (dram_type<<5 | dram_total_width<<4 | dram_size<<1 | dram_width); + + if(dram_cfg0!=0xFF && dram_cfg1!=0xFF) { + +#if defined (RT3052_ASIC_BOARD) || defined(RT3052_FPGA_BOARD) ||\ + defined (RT3352_ASIC_BOARD) || defined(RT3352_FPGA_BOARD) ||\ + defined (RT5350_ASIC_BOARD) || defined(RT5350_FPGA_BOARD) ||\ + defined (RT3883_ASIC_BOARD) || defined(RT3883_FPGA_BOARD) + hdr->ih_dram.magic_lh=0x5244; + hdr->ih_dram.magic_hh=0x4D41; +#else + hdr->ih_dram.magic = 0x68; +#endif + } else { +#if defined(RT3052_ASIC_BOARD) || defined(RT3052_FPGA_BOARD) ||\ + defined(RT3352_ASIC_BOARD) || defined(RT3352_FPGA_BOARD) ||\ + defined(RT5350_ASIC_BOARD) || defined(RT5350_FPGA_BOARD) ||\ + defined(RT3883_ASIC_BOARD) || defined(RT3883_FPGA_BOARD) + hdr->ih_dram.magic_lh=0; + hdr->ih_dram.magic_hh=0; +#else + hdr->ih_dram.magic = 0x0; +#endif + dram_cfg0=0; + dram_cfg1=0; + } + +#if defined (CPU_PLL_PARAMETERS) +#if defined (RT6855A_ASIC_BOARD) || defined(RT6855A_FPGA_BOARD) +#endif +#if defined (MT7620_ASIC_BOARD) || defined(MT7620_FPGA_BOARD) || defined (MT7628_ASIC_BOARD) || defined(MT7628_FPGA_BOARD) +#if defined (CPLL_FROM_480MHZ) + cpu_pll = ntohs(1<<11); +#elif defined (CPLL_FROM_XTAL) + cpu_pll = ntohs(1<<12); +#else + cpu_pll = ntohs((CPLL_MULTI_RATIO_CFG<<8)|(CPLL_DIV_RATIO_CFG<<6)|(CPLL_SSC_CFG<<0)); +#endif +#endif + if(cpu_pll==0) { + hdr->ih_dram.u.cpu_pll_magic_l=0; + hdr->ih_dram.cpu_pll_cfg = 0; + }else{ + hdr->ih_dram.u.cpu_pll_magic_l=0xa; + hdr->ih_dram.cpu_pll_cfg = cpu_pll; + } +#endif + +#if defined (DRAM_PARAMETERS) +#if defined (RT3052_ASIC_BOARD) || defined(RT3052_FPGA_BOARD) ||\ + defined (RT3352_ASIC_BOARD) || defined(RT3352_FPGA_BOARD) ||\ + defined (RT5350_ASIC_BOARD) || defined(RT5350_FPGA_BOARD) ||\ + defined (RT3883_ASIC_BOARD) || defined(RT3883_FPGA_BOARD) + if(dram_type==0) {//SDR + hdr->ih_dram.sdr.sdram_cfg0 = dram_cfg0; + hdr->ih_dram.sdr.sdram_cfg1 = dram_cfg1; + }else { //DDR + hdr->ih_dram.ddr.syscfg1= (dram_cfg0 & 0x3F); + hdr->ih_dram.ddr.ddr_cfg3= (dram_cfg1 & 0x3); + } +#elif defined (RT6855A_ASIC_BOARD) || defined (RT6855A_FPGA_BOARD) ||\ + defined (MT7620_ASIC_BOARD) || defined (MT7620_FPGA_BOARD) ||\ + defined (MT7628_ASIC_BOARD) || defined (MT7628_FPGA_BOARD) + if(dram_type==0) {//SDR + hdr->ih_dram.sdr.sdram_cfg0 = ntohl(dram_cfg0); + hdr->ih_dram.sdr.sdram_cfg1 = ntohl(dram_cfg1); + }else { //DDR +#if defined (RT6855A_ASIC_BOARD) || defined (RT6855A_FPGA_BOARD) + hdr->ih_dram.ddr_cfg2 = ntohl(DDR_CFG2_SETTING); + hdr->ih_dram.ddr_cfg3 = ntohl(DDR_CFG3_SETTING); + hdr->ih_dram.ddr_cfg4 = ntohl(DDR_CFG4_SETTING); + hdr->ih_dram.dram_pad_setting = ntohl(DRAM_PAD_SETTING); +#endif + hdr->ih_dram.ddr.ddr_cfg0 = ntohl(dram_cfg0); + hdr->ih_dram.ddr.ddr_cfg1 = ntohl(dram_cfg1); +#if defined (MT7620_ASIC_BOARD) || defined (MT7620_FPGA_BOARD) || (MT7628_ASIC_BOARD) || defined (MT7628_FPGA_BOARD) + hdr->ih_dram.ddr_self_refresh = ntohs((((DDR_ODT_SRC&0x0F)<<8)|(DDR_ODT_OFF_DLY&0x0F)<<4)|\ + (DDR_ODT_ON_DLY&0x0F)); + hdr->ih_dram.syscfg1_ddrcfg3_odt = ntohs((SYSCFG1_ODT&0x0FFFC)|(DDRCFG3_ODT&0x03)); + hdr->ih_dram.ddr_cfg11 = ntohs(((DDR_CFG2_CAS&0x7)<<13)|(DDR_CFG11_FFD_EN<<12)|(DDR_CFG11_FCD_EN<<11)|\ + ((DDR_CFG11_FFD&0x0F)<<7)|(DDR_CFG11_FCD&0x7F)); + hdr->ih_dram.ddr_cfg10 = ntohl(((DDR_CFG3_DS&0x1)<<31)|DDR_CFG10_SETTING&(~((1<<31)|(1<<23)|(1<<15)|(1<<7)))); +#endif + } +#else +#error "DRAM config in imageheader is not supported" +#endif +#endif +#endif /* ! MT7621_ASIC_BOARD or MT7621_FPGA_BOARD */ + +#if (defined (MT7621_ASIC_BOARD) || defined (MT7621_FPGA_BOARD)) + //crc((const char *)hdr, &(hdr->ih_nand.crc), sizeof(image_header_t)); + crc((const char *)hdr, &checksum, sizeof(image_header_t)); + hdr->ih_nand.crc = htonl(checksum); +#endif + checksum = crc32(0,(const char *)hdr,sizeof(image_header_t)); + + hdr->ih_hcrc = htonl(checksum); + + print_header (hdr); + + (void) munmap((void *)ptr, sbuf.st_size); + + /* We're a bit of paranoid */ +#if defined(_POSIX_SYNCHRONIZED_IO) && !defined(__sun__) && !defined(__FreeBSD__) + (void) fdatasync (ifd); +#else + (void) fsync (ifd); +#endif + + if (close(ifd)) { + fprintf (stderr, "%s: Write error on %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + + exit (EXIT_SUCCESS); +} + +static void +copy_file (int ifd, const char *datafile, int pad) +{ + int dfd; + struct stat sbuf; + unsigned char *ptr; + int tail; + int zero = 0; + int offset = 0; + int size; + + if (vflag) { + fprintf (stderr, "Adding Image %s\n", datafile); + } + + if ((dfd = open(datafile, O_RDONLY|O_BINARY)) < 0) { + fprintf (stderr, "%s: Can't open %s: %s\n", + cmdname, datafile, strerror(errno)); + exit (EXIT_FAILURE); + } + + if (fstat(dfd, &sbuf) < 0) { + fprintf (stderr, "%s: Can't stat %s: %s\n", + cmdname, datafile, strerror(errno)); + exit (EXIT_FAILURE); + } + + ptr = (unsigned char *)mmap(0, sbuf.st_size, + PROT_READ, MAP_SHARED, dfd, 0); + if (ptr == (unsigned char *)MAP_FAILED) { + fprintf (stderr, "%s: Can't read %s: %s\n", + cmdname, datafile, strerror(errno)); + exit (EXIT_FAILURE); + } + + if (xflag) { + unsigned char *p = NULL; + /* + * XIP: do not append the image_header_t at the + * beginning of the file, but consume the space + * reserved for it. + */ + + if ((unsigned)sbuf.st_size < sizeof(image_header_t)) { + fprintf (stderr, + "%s: Bad size: \"%s\" is too small for XIP\n", + cmdname, datafile); + exit (EXIT_FAILURE); + } + + for (p=ptr; p < ptr+sizeof(image_header_t); p++) { + if ( *p != 0xff ) { + fprintf (stderr, + "%s: Bad file: \"%s\" has invalid buffer for XIP\n", + cmdname, datafile); + exit (EXIT_FAILURE); + } + } + + offset = sizeof(image_header_t); + } + + size = sbuf.st_size - offset; + if (write(ifd, ptr + offset, size) != size) { + fprintf (stderr, "%s: Write error on %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + + if (pad && ((tail = size % 4) != 0)) { + + if (write(ifd, (char *)&zero, 4-tail) != 4-tail) { + fprintf (stderr, "%s: Write error on %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } + } + + (void) munmap((void *)ptr, sbuf.st_size); + (void) close (dfd); +} + +void +usage () +{ + fprintf (stderr, "Usage: %s -l image\n" + " -l ==> list image header information\n" + " %s [-x] -A arch -O os -T type -C comp " + "-a addr -e ep -n name -d data_file[:data_file...] image\n", + cmdname, cmdname); + fprintf (stderr, " -A ==> set architecture to 'arch'\n" + " -O ==> set operating system to 'os'\n" + " -T ==> set image type to 'type'\n" + " -C ==> set compression type 'comp'\n" + " -a ==> set load address to 'addr' (hex)\n" + " -e ==> set entry point to 'ep' (hex)\n" + " -n ==> set image name to 'name'\n" + " -r ==> set dram type (sdr/ddr)\n" + " -s ==> set dram total width (16/32)\n" + " -t ==> set dram size (2/8/16/32/64/128/256MB)\n" + " -u ==> set dram width (16/32)\n" + " -d ==> use image data from 'datafile'\n" + " -x ==> set XIP (execute in place)\n" + " -y ==> set dram parameter 0\n" + " -z ==> set dram parameter 1\n" + ); + exit (EXIT_FAILURE); +} + +static void +print_header (image_header_t *hdr) +{ + time_t timestamp; + uint32_t size; + + timestamp = (time_t)ntohl(hdr->ih_time); + size = ntohl(hdr->ih_size); + + printf ("Image Name: %.*s\n", IH_NMLEN, hdr->ih_name); + printf ("Created: %s", ctime(×tamp)); + printf ("Image Type: "); print_type(hdr); + printf ("Data Size: %d Bytes = %.2f kB = %.2f MB\n", + size, (double)size / 1.024e3, (double)size / 1.048576e6 ); + printf ("Load Address: 0x%08X\n", ntohl(hdr->ih_load)); + printf ("Entry Point: 0x%08X\n", ntohl(hdr->ih_ep)); +#if defined (MT7621_ASIC_BOARD) || defined (MT7621_FPGA_BOARD) +#else + printf ("DRAM Parameter: %x (Parm0=%x Parm1=%x)\n", hdr->ih_dram.dram_parm, hdr->ih_dram.sdr.sdram_cfg0, hdr->ih_dram.sdr.sdram_cfg1); +#endif + if (hdr->ih_type == IH_TYPE_MULTI || hdr->ih_type == IH_TYPE_SCRIPT) { + int i, ptrs; + uint32_t pos; + unsigned long *len_ptr = (unsigned long *) ( + (unsigned long)hdr + sizeof(image_header_t) + ); + + /* determine number of images first (to calculate image offsets) */ + for (i=0; len_ptr[i]; ++i) /* null pointer terminates list */ + ; + ptrs = i; /* null pointer terminates list */ + + pos = sizeof(image_header_t) + ptrs * sizeof(long); + printf ("Contents:\n"); + for (i=0; len_ptr[i]; ++i) { + size = ntohl(len_ptr[i]); + + printf (" Image %d: %8d Bytes = %4d kB = %d MB\n", + i, size, size>>10, size>>20); + if (hdr->ih_type == IH_TYPE_SCRIPT && i > 0) { + /* + * the user may need to know offsets + * if planning to do something with + * multiple files + */ + printf (" Offset = %08X\n", pos); + } + /* copy_file() will pad the first files to even word align */ + size += 3; + size &= ~3; + pos += size; + } + } +} + + +static void +print_type (image_header_t *hdr) +{ + printf ("%s %s %s (%s)\n", + put_arch (hdr->ih_arch), + put_os (hdr->ih_os ), + put_type (hdr->ih_type), + put_comp (hdr->ih_comp) + ); +} + +static char *put_arch (int arch) +{ + return (put_table_entry(arch_name, "Unknown Architecture", arch)); +} + +static char *put_os (int os) +{ + return (put_table_entry(os_name, "Unknown OS", os)); +} + +static char *put_type (int type) +{ + return (put_table_entry(type_name, "Unknown Image", type)); +} + +static char *put_comp (int comp) +{ + return (put_table_entry(comp_name, "Unknown Compression", comp)); +} + +static char *put_table_entry (table_entry_t *table, char *msg, int type) +{ + for (; table->val>=0; ++table) { + if (table->val == type) + return (table->lname); + } + return (msg); +} + +static int get_arch(char *name) +{ + return (get_table_entry(arch_name, "CPU", name)); +} + + +static int get_comp(char *name) +{ + return (get_table_entry(comp_name, "Compression", name)); +} + + +static int get_os (char *name) +{ + return (get_table_entry(os_name, "OS", name)); +} + + +static int get_type(char *name) +{ + return (get_table_entry(type_name, "Image", name)); +} + +static int get_table_entry (table_entry_t *table, char *msg, char *name) +{ + table_entry_t *t; + int first = 1; + + for (t=table; t->val>=0; ++t) { + if (t->sname && strcasecmp(t->sname, name)==0) + return (t->val); + } + fprintf (stderr, "\nInvalid %s Type - valid names are", msg); + for (t=table; t->val>=0; ++t) { + if (t->sname == NULL) + continue; + fprintf (stderr, "%c %s", (first) ? ':' : ',', t->sname); + first = 0; + } + fprintf (stderr, "\n"); + return (-1); +}