◎테스트 장비: ipTIME A1004 (Entry Point Address: 0x8000C150)
◎신 이미지: openwrt-18.06.5-ramips-mt7620-mt7620a_mt7530-squashfs-sysupgrade.bin
◎준비물: HxD Hexa Editor, CRC32 체크섬 (https://emn178.github.io/online-tools/crc32_checksum.html)
※uImage Header
/*
* Legacy format image header,
* all data in network byte order (aka natural aka bigendian).
*/
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 */
} image_header_t;
※ipTIME 공유기의 Original uImage Header 부분
※OpenWRT의 Original uImage Header 부분

1. 공식 펌웨어를 다운로드 하여 Hexa 에디터로 모델명을 확인한다. 아래 그림은 헤더의 Image Name 및 모델명 부분이다.

2. 신 이미지의 Image name 부분을 공유기 모델명으로 변경해 준다. 또한 필요할 경우 Entry Point 값도 변경해 준다.
3. 아래 그림과 같이 신 이미지의 uImage Header CRC Checksum 부분을 0으로 처리하고 uImage Header만 별도의 바이너리 파일로 만들어 저장한 후 CRC32 체크섬 값을 알아낸다.

4. 알아낸 체크섬을 신 이미지의 uImage Header CRC Checksum 부분에 기록하고 저장한다.

5. ipTIME 공유기에 USB-TTL 시리얼을 연결한 후 아래와 같은 방법으로 플래싱 한다.
============================================
Ralink UBoot Version: 4.1.2.0
--------------------------------------------
ASIC 7620_MP (Port5<->GigaSW)
DRAM component: 512 Mbits DDR, width 16
DRAM bus: 16 bit
Total memory: 64 MBytes
Flash component: SPI Flash
Date:Mar 11 2014 Time:14:18:46
============================================
icache: sets:512, ways:4, linesz:32 ,total:65536
dcache: sets:256, ways:4, linesz:32 ,total:32768
##### The CPU freq = 580 MHZ ####
estimate memory size =64 Mbytes
#Reset_MT7530
Disable WAN port....
cur reg0 = 00001040
new reg0 = 00001840
Please choose the operation: (t:tftp server/b(boot now)/f(flash test)) ← 여기서 연속하여 t를 누른다.
ETH_STATE_ACTIVE!!
TFTP server start
IP address: 192.168.0.1
Load address: 0x80100000
Reading: ..... ← 플래싱 대기 상태
윈도우 명령행 프롬프트에서 tftp를 써서 이미지를 플래싱 한다.
tftp -i 192.168.0.1 put openwrt-18.06.5-ramips-mt7620-mt7620a_mt7530-squashfs-sysupgrade.bin
###########... ← 플래싱
done
Bytes transferred = 7078067 (6c00b3 hex)
Check Firmware:80100000 =>[ Check Alias ... [a1004],[a1004] ] ->[ RUN : OK ]
Run Firmware Found!!
raspi_erase_write: offs:30000, count:6c00b3
Abort: image size larger than 3997696!
신 이미지가 3997696바이트 보다 커서 플래싱 실패. 크기를 줄여도 sysupgrade가 아닌 ramdisk 이미지를 사용하여 플래싱해야 할듯 하다.
하지만 이러한 방법으로 ipTIME의 u-boot 내부 체크 프로세스를 우회하여 플래싱은 가능하다.
아래는 이 과정을 일괄처리 할 수 있는 스크립트 이다.
#!/bin/bash
######################################################################
#
# OpenWRT 이미지를 ipTIME 공유기가 인식하도록 uImage 헤더를 수정한다.
#
######################################################################
IMAGE_NAME="a1004"
CMD_CRC32="crc32"
TMP_FILE="/tmp/__tmp_file__"
IMAGE_NAME_LEN=${#IMAGE_NAME}
######################################################################
#
# 사용방법 출력
#
######################################################################
function usage() {
echo ""
echo "$0 (bin file)"
echo ""
}
######################################################################
#
# uImage 헤더를 패치한다.
#
######################################################################
function patch_uimage_header() {
if [ ! -f ${1} ]
then
echo "File not found !"
exit 1
fi
# Header CRC checksum과 Image Name 초기화
dd if=/dev/zero of=${1} bs=1 seek=4 count=4 conv=notrunc
dd if=/dev/zero of=${1} bs=1 seek=32 count=32 conv=notrunc
# Image Name 기록
echo -n "${IMAGE_NAME}" | dd of=${1} bs=1 seek=32 conv=notrunc
dd if=${1} of=${TMP_FILE} bs=1 seek=0 count=64 conv=notrunc
# CRC32 checksum 연산
CRC32_CHECKSUM=$(${CMD_CRC32} ${TMP_FILE})
echo "*** CRC32 Checksum: ${CRC32_CHECKSUM}"
# CRC32 checksum 기록
echo "${CRC32_CHECKSUM}" | xxd -r -p > ${TMP_FILE}
dd if=${TMP_FILE} of=${1} bs=1 seek=4 count=4 conv=notrunc
rm -f ${TMP_FILE}
xxd -g 1 -c 16 -l 64 ${1}
}
######################################################################
#
# arguments가 1과 다르면 잘못된 옵션 지정이므로 끝낸다.
#
######################################################################
if [ $# -ne 1 ]
then
usage
exit 1
fi
echo "*** Filename: ${1}"
patch_uimage_header ${1}