#! /bin/bash
#
# Creates a NAND image with X-loader, U-boot and a given QNX IFS.
# The X-loader file should be named MLO and the U-boot image u-boot.bin. Both
# should exist in the current directory.
#
# Original author:
# Copyright (C) 2008 yajin (yajin@vm-kernel.org)

# We assume that rootfs image has oob info
# while xloader u-boot and kernel image does not have oob info.

if [ 2 -ne "$#" ]; then
    echo "Usage: $0 <nand-image> <IFS>"
    exit 1
fi

# Nand flash partitions
# 0x00000000-0x00080000 : "X-Loader"
# 0x00080000-0x00260000 : "U-Boot"
# 0x00260000-0x00280000 : "U-Boot Env"
# 0x00280000-0x00680000 : "Kernel"  
# 0x00680000-0x10000000 : "File System"

flash_page_size=2048
flash_oob_size=64
flash_image_pages=131072

xloader_page_offset=0
uboot_page_offset=256
uboot_env_page_offset=1216
kernel_page_offset=1280
rootfs_page_offset=3328


flash_image_name=$1
xloader_image_name=MLO
uboot_image_name=u-boot.bin
kernel_image_name=$2

echo "Writing NAND image to $1"

put_no_oob()
{
    image_name=$1
    image_page_offset=$2
    image_max=$3
    image_len=`du -shb $image_name |awk '{print $1}'`
    image_pages=$[$image_len/2048]

    # echo "put_no_oob: len $image_len max $image_max"

    if [ 0 -ne $[$image_len%$flash_page_size] ]; then
        image_pages=$[$image_pages+1]
    fi

    if [ "$image_len" -gt "$image_max" ]; then
        echo "Image size ($image_len) > image maximum! ($image_max)  IMAGE TRUNCATED!"
    fi

    i=0
    while [ $i -lt $image_pages  ]; do
        out_offset=$[$image_page_offset+$i]
        in_offset=$i
        dd if=$image_name of=$flash_image_name conv=notrunc count=1 \
            obs=$[$flash_page_size+$flash_oob_size] ibs=$flash_page_size \
            seek=$out_offset skip=$in_offset >& /dev/null
        i=$[$i + 1]
    done
}

#beagle board's NAND flash is 2G bit(256M bytes)
if [ ! -e "$1" ]; then
    if [ ! -r "MLO" ]; then
        echo "Missing X-loader file (MLO)"
        exit 1
    fi
    if [ ! -r "u-boot.bin" ]; then
        echo "Missing U-boot file (u-boot.bin)"
        exit 1
    fi

    echo "Generating initial NAND image"
    echo -en \\0377\\0377\\0377\\0377\\0377\\0377\\0377\\0377 > .8b
    cat .8b .8b > .16b
    cat .16b .16b >.32b
    cat .32b .32b >.64b  #OOB is 64 bytes
    cat .64b .64b .64b .64b .64b .64b .64b .64b > .512b
    cat .512b .512b .512b .512b .64b>.page  # A page is 2K bytes of data + 64bytes OOB
    cat .page .page .page .page .page .page .page .page >.8page
    cat .8page .8page .8page .8page .8page .8page .8page .8page >.block  # a block = 64 pages
    cat .block .block .block .block .block .block .block .block >.8block
    cat .8block .8block .8block .8block .8block .8block .8block .8block >.64block
    cat .64block .64block .64block .64block .64block .64block .64block .64block >.512block
    cat .512block .512block .512block .512block >$flash_image_name
    rm -rf .8b .16b .32b .64b .512b .page .8page .64sec .block .8block .64block .512block

    echo "Writing X loader"
    put_no_oob $xloader_image_name $xloader_page_offset $[$[$uboot_page_offset-$xloader_page_offset]*$flash_page_size]

    echo "Writing U-boot"
    put_no_oob $uboot_image_name $uboot_page_offset $[$[$kernel_page_offset-$uboot_page_offset]*$flash_page_size]
fi


echo "Writing IFS"
put_no_oob $2 $kernel_page_offset $[$[$rootfs_page_offset-$kernel_page_offset]*$flash_page_size]
echo "Done!"
