source: SVN/jtag/linux/x86/mkimage_jtag @ 72

Last change on this file since 72 was 72, checked in by Tim Harvey, 2 years ago

mkimage_jtag: add emmc support

The mkimage_jtag script now supports creating images intended for eMMC
supported on Ventana and Newport product families.

See http://trac.gateworks.com/wiki/jtag_instructions#images

Signed-off-by: Tim Harvey <tharvey@…>

  • Property svn:executable set to *
File size: 8.9 KB
Line 
1#!/bin/bash
2#
3# mkimage_jtag v1.1.0
4# Copyright 2014-2018 Gateworks Corporation <support@gateworks.com>
5#
6# create a binary image suitable for jtag_usbv4
7#
8# usage: mkimage_jtag [OPTIONS]
9#
10# Options:
11#   --nand - (default) create image suitable for NAND flash (rootfs is a ubi)
12#   --emmc - create image suitable for block device (rootfs is a disk image)
13#
14# NAND Examples:
15#   # create jtagable bin containing just bootloader (will not overwrite all)
16#   mkimage_jtag -nand <SPL> <u-boot.img> > uboot.bin
17#   # create jtagable bin containing bootloader+ubi (will overwrite all)
18#   mkimage_jtag -nand <SPL> <u-boot.img> <ubi> > image.bin
19#   # create jtagable bin containing ubi (will not overwrite bootloader/env)
20#   mkimage_jtag -nand <ubi> > image.bin
21#
22# EMMC Examples:
23#   # create jtagable bin for emmc erasing entire part and programming boot fw
24#   mkimage_jtag --emmc -e --partconf=user firmware.img@user > image.bin
25#   # create jtagable bin for emmc programming boot fw (will not overwrite all)
26#   mkimage_jtag --emmc -s --partconf=user firmware.img@user > image.bin
27#
28# This puts a simple header around the binary parts that make up a bootable
29# image, sending the output to stdout.
30#
31# The header consists of the following structure (little-endian):
32#
33# u16 magic: GW
34# u16 config:
35#   bit[0:1] - erase_config
36#      0=entire flash (use only on first header)
37#      1=none (perform no erase)
38#      2=part (erase only this part - offset must align with flash block)
39#      3=to end (erase from this part to end of device)
40#   bit[2:4]   - partition number (for eMMC: 1-boot0 2=boot1 7=user)
41#   bit[5]     - gzip compressed data (1=gzip-compressed 0=uncompressed)
42#   bit[6:12]  - reserved
43#   bit[13:15] - type (0=NAND 1=eMMC)
44# u32 offset: byte offset in flash (logical) to program this data
45#      (this must align with a flash block boundary if erasing part or to end
46#       and otherwise must align with a flashs page boundary)
47# u32 dsize: byte size of this data segment
48# u32 psize: part size of this data segment
49#
50# The psize value is only used in the special case where dsize=0 which
51# specifies a bootstream.  This must be the first part in a series of parts
52# and is programmed in a specific fashion on NAND FLASH in accordance with
53# the requirements of the i.MX6 BOOT ROM.  In this case the data must
54# be an i.MX6 bootlet containing an IVT and DCD, such as u-boot.imx.
55#
56
57# erase_config: config[0:1]
58ERASE_ALL=0
59ERASE_NON=1
60ERASE_PRT=2
61ERASE_END=3
62
63# partition_no: config[2:3]
64PART_BOOT0=$((1<<2))
65PART_BOOT1=$((2<<2))
66PART_USER=$((0<<2))
67PART_RPMB=$((3<<2))
68
69# data type: config[13:15]
70TYPE_NAND=$((0<<13))
71TYPE_EMMC=$((1<<13))
72
73error() {
74        echo "$@" 1>&2
75        exit
76}
77
78debug() {
79        echo "$@" 1>&2
80}
81
82usage() {
83echo "
84usage: $0 [OPTIONS]
85
86  NAND:
87    $0 [<SPL> <u-boot.img>]|[<SPL> <u-boot.img> <ubi>]|[<ubi>]
88
89  EMMC:
90    $0 --emmc [--partconf=<boot0|boot1|user>] <blobopt> [<blobopt>...]
91"
92        exit 1
93}
94
95gettype() {
96        case $(($1 & 0xe000)) in
97                $TYPE_NAND) echo "NAND";;
98                $TYPE_EMMC) echo "eMMC";;
99        esac
100}
101
102getpart() {
103        case $(($1 & 0x1c)) in
104                $PART_BOOT0) echo "Boot0";;
105                $PART_BOOT1) echo "Boot1";;
106                $PART_USER) echo "User";;
107                $PART_RPMB) echo "RPMB";;
108        esac
109}
110
111getmode() {
112        case $(($1 & 0x3)) in
113                $ERASE_ALL) echo "all";;
114                $ERASE_NON) echo "segment";;
115                $ERASE_PRT) echo "partition";;
116                $ERASE_END) echo "to-end";;
117        esac
118}
119
120getsize() {(
121        local mult=1
122        local val=$1
123        local suffix regex
124
125        shopt -s nocasematch
126        for suffix in '' K M G; do
127                regex="^([0-9]+)(${suffix}i?B?)?\$"
128                [[ $val =~ $regex ]] && {
129                        /usr/bin/printf "0x%x" $((${BASH_REMATCH[1]} * mult))
130                        return 0
131                }
132                regex="^0x([0-9A-Fa-f]+)(${suffix}i?B?)?\$"
133                [[ $1 =~ $regex ]] && {
134                        echo $((0x${BASH_REMATCH[1]} * mult))
135                        return 0
136                }
137
138                ((mult *= 1024))
139        done
140        echo "invalid size: $1" >&2
141        return 1
142)}
143
144# output binary u32
145# $1 int
146u32() {
147        b0=$(( $(($1>>24)) & 0xff))
148        b1=$(( $(($1>>16)) & 0xff))
149        b2=$(( $(($1>>8)) & 0xff))
150        b3=$(( $(($1>>0)) & 0xff))
151
152        /usr/bin/printf "\\x$(/usr/bin/printf "%x" $b3)"
153        /usr/bin/printf "\\x$(/usr/bin/printf "%x" $b2)"
154        /usr/bin/printf "\\x$(/usr/bin/printf "%x" $b1)"
155        /usr/bin/printf "\\x$(/usr/bin/printf "%x" $b0)"
156}
157
158# output binary u16
159# $1 int
160u16() {
161        b0=$(( $(($1>>8)) & 0xff))
162        b1=$(( $(($1>>0)) & 0xff))
163
164        /usr/bin/printf "\\x$(/usr/bin/printf "%x" $b1)"
165        /usr/bin/printf "\\x$(/usr/bin/printf "%x" $b0)"
166}
167
168# emit a blob of 1byte length to force erasing a partition
169erasepart() {
170        debug "erasepart $1"
171
172        /usr/bin/printf "GW" # magic
173        u16 $((config|type))
174        u32 0 # offset
175        u32 4 # blob size
176        u32 0 # partition size
177
178        u32 0 # blob data
179}
180
181# emit a configuration header for setting eMMC PART_CONFIG
182# (if file size and offset are both 0, then PART_CONFIG gets set to part_num)
183# $1 config
184emmc_partconf()
185{
186        local config=$1
187        local attr=
188
189        debug "  emit Partiton Config=$(getpart $config)"
190        /usr/bin/printf "GW" # magic
191        u16 $(($config|$type))
192        u32 0
193        u32 0
194        u32 0
195}
196
197# emit a part
198# $1 file
199# $2 config
200# $3 offset (bytes for NAND, blocks for eMMC)
201# $4 size (only needed if offset==0 for bootloader part size)
202emit()
203{
204        local file=$1
205        local config=$2
206        local offset=$3
207        local part_size=${4:-0}
208        local fsize
209        local part=""
210
211        [ $type = $TYPE_EMMC ] && part="part=$(getpart $config)"
212        if [ $(($part_size)) -eq 0 ]; then
213                debug "$(/usr/bin/printf "  emit %s@0x%08x erase:%s %s\n" \
214                        $file $offset $(getmode $config) $part)"
215        else
216                debug "$(/usr/bin/printf "  emit %s@0x%08x-0x%08x erase:%s %s\n" \
217                        $file $offset $((offset+part_size)) $(getmode $config) $part)"
218        fi
219
220        [ "$file" -a -r "$file" ] || error "invalid file '$file'"
221        fsize=$(ls -lL $file | awk '{print $5}')
222
223        /usr/bin/printf "GW" # magic
224        u16 $((config|type))
225        u32 $offset
226        u32 $fsize
227        u32 $part_size
228        cat $file
229}
230
231type=$TYPE_NAND
232[ "$1" == "--emmc" ] && { type=$TYPE_EMMC; shift; }
233[ "$1" == "--nand" ] && { type=$TYPE_NAND; shift; }
234
235# Scripted usage: space separated list of:
236#  file@[part:]offset[-end]
237#  if -end not specified will erase up to size of file (rounded to end of block)
238#  if end not specified will erase to end of device
239#  -e starts off by erasing the entire part
240#
241# Examples:
242#  - update falcon mode kernel at 18MB:
243#  mkimage_jtag -s uImage@18M
244#  - update SPL and uboot with full erase:
245#  mkimage_jtag -e SPL@0 u-boot.img@14M
246#  - erase env
247#  dd if=/dev/zero of=env bs=1M count=1 && ./mkimage_jtag -s env@16M
248[ "$1" = "-s" -o "$1" = "-e" ] && {
249        count=0
250
251        # initial erase type
252        mode=$ERASE_NON
253        [ "$1" = "-e" ] && mode=$ERASE_ALL
254        shift
255
256        # EMMC: optional partconf
257        [ $type = $TYPE_EMMC ] && {
258                case "$1" in
259                        --partconf=boot0) emmc_partconf $PART_BOOT0; shift;;
260                        --partconf=boot1) emmc_partconf $PART_BOOT1; shift;;
261                        --partconf=user) emmc_partconf $PART_USER; shift;;
262                        --partconf=*)
263                                error "invalid partition: $1"
264                                usage
265                                ;;
266                esac
267        }
268
269        # parse blobs
270        while [ "$1" ]; do
271                count=$((count+1))
272                str=$1
273                shift
274
275                # check for hw partition and erase mode syntax
276                if [[ $str =~ ^(.*)@(.*):(.*):(.+)$ ]]; then
277                        #debug "$count:<blob>@<partition>:<erase_mode>:<offset>"
278                        mode=0
279                        # parse partition
280                        case "${BASH_REMATCH[2]}" in
281                        "user") mode=$((mode|$PART_USER));;
282                        "boot0") mode=$((mode|$PART_BOOT0));;
283                        "boot1") mode=$((mode|$PART_BOOT1));;
284                        "rpmb") mode=$((mode|$PART_RPMB));;
285                        esac
286                        # parse erase_mode
287                        #debug "partition=${BASH_REMATCH[2]} mode=$mode"
288                        case "${BASH_REMATCH[3]}" in
289                        "erase_none") mode=$((mode|$ERASE_NON));;
290                        "erase_all") mode=$((mode|$ERASE_ALL));;
291                        "erase_part") mode=$((mode|$ERASE_PRT));;
292                        "erase_end") mode=$((mode|$ERASE_END));;
293                        *) mode=$((mode|$ERASE_NON));;
294                        esac
295                        #debug "erase_mode=${BASH_REMATCH[3]} mode=$mode"
296                        str=${BASH_REMATCH[1]}@${BASH_REMATCH[4]}
297                fi
298
299                # file@start-end
300                if [[ $str =~ ^(.*)@(.*)-(.+)$ ]]; then
301                        debug "$count:<blob>@<start>-<end>"
302                        file=${BASH_REMATCH[1]}
303                        start=$(getsize ${BASH_REMATCH[2]})
304                        end=$(getsize ${BASH_REMATCH[3]})
305                        size=$(/usr/bin/printf "0x%x" $((end-start)))
306                        emit $file $mode $start $size
307                # file@start-
308                elif [[ $str =~ ^(.*)@(.*)-$ ]]; then
309                        debug "$count:<blob>@<start>-"
310                        file=${BASH_REMATCH[1]}
311                        start=$(getsize ${BASH_REMATCH[2]})
312                        emit $file $mode $start
313                # file@start
314                elif [[ $str =~ ^(.*)@(.*)$ ]]; then
315                        debug "$count:<blob>@<start>"
316                        file=${BASH_REMATCH[1]}
317                        start=$(getsize ${BASH_REMATCH[2]})
318                        emit $file $mode $start
319                else
320                        error "invalid parameter: $str"
321                fi
322
323                mode=$ERASE_NON
324        done
325        exit
326}
327
328[ $type = $TYPE_NAND ] || usage
329
330# Legacy support for NAND flash
331case $# in
332        # ubi (w/o touching bootloader+env)
333        1)
334        debug "rootfs (erase to end):"
335        emit $1 $ERASE_END 0x1100000    # rootfs@17MB- (erase to end)
336        ;;
337
338        # bootloader (SPL + u-boot.img) w/o eraseing env/ubi
339        2)
340        debug "SPL + u-boot.img (bootloader only):"
341        emit $1 $ERASE_PRT 0 0xE00000   # SPL@0-14MB
342        emit $2 $ERASE_PRT 0x0E00000 0x0200000  # u-boot@14MB-16MB
343        ;;
344
345        # erase entire part and program SPL + u-boot.img + ubi
346        3)
347        debug "SPL + u-boot.img + ubi (full erase):"
348        emit $1 $ERASE_ALL 0 0xE00000   # SPL@0-14MB
349        emit $2 $ERASE_NON 0x0E00000    # u-boot@14MB
350        emit $3 $ERASE_NON 0x1100000    # rootfs@17MB
351        ;;
352
353        # usage
354        *)
355        usage
356        ;;
357esac
Note: See TracBrowser for help on using the repository browser.