Merge pull request #18 from NextThingCo/by/4.4multi

By/4.4multi
This commit is contained in:
Ben Young 2016-12-12 16:18:42 -08:00 committed by GitHub
commit 902ae95a8a
13 changed files with 769 additions and 2121 deletions

3
.gitignore vendored
View File

@ -1 +1,4 @@
.firmware
.dl
.new
env.sh

View File

@ -1,10 +0,0 @@
CC=$(CROSS_COMPILE)gcc
spl-image-builder: spl-image-builder.o
$(CC) -o $@ $<
all: spl-image-builder
clean:
rm -rf *.o
rm spl-image-builder

View File

@ -4,14 +4,11 @@ A collection of scripts for working with CHIP
## Requirements
1) [sunxi-tools](https://github.com/linux-sunxi/sunxi-tools.git)
2) **uboot-tools** from your package manager
2) **mtd-utils-mlc** from our repository (https://github.com/nextthingco/chip-mtd-utils) [for creating images]
## Included Tools
### chip-update-firmware
This tool is used to download the latest firmware release for CHIP and run **chip-fel-flash** with the newest firmware.
### chip-fel-flash
This tool is used to flash a local firmware image to a connected CHIP over FEL
### chip-fel-upload
This tool is used to upload uboot, a linux kernel and an initramfs and launch into it
This tool is used to download and flash the latest firmware release for CHIP. The tool also now only supports fastboot flashing.
### chip-create-nand-images
This tool is used to generate local firmware images for CHIP and CHIP Pro.

156
chip-create-nand-images.sh Executable file
View File

@ -0,0 +1,156 @@
#!/bin/bash -x
FEL=sunxi-fel
SCRIPTDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source $SCRIPTDIR/common.sh
UBOOTDIR="$1"
ROOTFSTAR="$2"
OUTPUTDIR="$3"
# build the UBI image
prepare_ubi() {
local tmpdir=`mktemp -d -t chip-ubi-XXXXXX`
local rootfs=$tmpdir/rootfs
local ubifs=$tmpdir/rootfs.ubifs
local ubicfg=$tmpdir/ubi.cfg
local outputdir="$1"
local rootfstar="$2"
local nandtype="$3"
local maxlebcount="$4"
local eraseblocksize="$5"
local pagesize="$6"
local subpagesize="$7"
local oobsize="$8"
local ebsize=`printf %x $eraseblocksize`
local psize=`printf %x $pagesize`
local osize=`printf %x $oobsize`
local ubi=$outputdir/chip-$ebsize-$psize-$osize.ubi
local sparseubi=$outputdir/chip-$ebsize-$psize-$osize.ubi.sparse
local mlcopts=""
if [ -z $subpagesize ]; then
subpagesize=$pagesize
fi
if [ "$nandtype" = "mlc" ]; then
lebsize=$((eraseblocksize/2-$pagesize*2))
mlcopts="-M dist3"
elif [ $subpagesize -lt $pagesize ]; then
lebsize=$((eraseblocksize-pagesize))
else
lebsize=$((eraseblocksize-pagesize*2))
fi
if [ "$osize" = "100" ]; then
#TOSH_512_SLC
volspec="vol_flags=autoresize"
elif [ "$osize" = "500" ]; then
#TOSH_4GB_MLC
volspec="vol_size=3584MiB"
elif [ "$osize" = "680" ]; then
#HYNI_8GB_MLC
volspec="vol_size=7168MiB"
else
echo "Unable to acquire appropriate volume size or flags, quitting!"
exit 1
fi
mkdir -p $rootfs
tar -xf $rootfstar -C $rootfs
mkfs.ubifs -d $rootfs -m $pagesize -e $lebsize -c $maxlebcount -o $ubifs
echo "[rootfs]
mode=ubi
vol_id=0
$volspec
vol_type=dynamic
vol_name=rootfs
vol_alignment=1
image=$ubifs" > $ubicfg
ubinize -o $ubi -p $eraseblocksize -m $pagesize -s $subpagesize $mlcopts $ubicfg
img2simg $ubi $sparseubi $eraseblocksize
rm -rf $tmpdir
}
# build the SPL image
prepare_spl() {
local tmpdir=`mktemp -d -t chip-spl-XXXXXX`
local outputdir=$1
local spl=$2
local eraseblocksize=$3
local pagesize=$4
local oobsize=$5
local repeat=$((eraseblocksize/pagesize/64))
local nandspl=$tmpdir/nand-spl.bin
local nandpaddedspl=$tmpdir/nand-padded-spl.bin
local ebsize=`printf %x $eraseblocksize`
local psize=`printf %x $pagesize`
local osize=`printf %x $oobsize`
local nandrepeatedspl=$outputdir/spl-$ebsize-$psize-$osize.bin
local padding=$tmpdir/padding
local splpadding=$tmpdir/nand-spl-padding
sunxi-nand-image-builder -c 64/1024 -p $pagesize -o $oobsize -u 1024 -e $eraseblocksize -b -s $spl $nandspl
local splsize=`filesize $nandspl`
local paddingsize=$((64-(splsize/(pagesize+oobsize))))
local i=0
while [ $i -lt $repeat ]; do
dd if=/dev/urandom of=$padding bs=1024 count=$paddingsize
sunxi-nand-image-builder -c 64/1024 -p $pagesize -o $oobsize -u 1024 -e $eraseblocksize -b -s $padding $splpadding
cat $nandspl $splpadding > $nandpaddedspl
if [ "$i" -eq "0" ]; then
cat $nandpaddedspl > $nandrepeatedspl
else
cat $nandpaddedspl >> $nandrepeatedspl
fi
i=$((i+1))
done
rm -rf $tmpdir
}
# build the bootloader image
prepare_uboot() {
local outputdir=$1
local uboot=$2
local eraseblocksize=$3
local ebsize=`printf %x $eraseblocksize`
local paddeduboot=$outputdir/uboot-$ebsize.bin
dd if=$uboot of=$paddeduboot bs=$eraseblocksize conv=sync
}
## copy the source images in the output dir ##
mkdir -p $OUTPUTDIR
cp $UBOOTDIR/spl/sunxi-spl.bin $OUTPUTDIR/
cp $UBOOTDIR/u-boot-dtb.bin $OUTPUTDIR/
cp $ROOTFSTAR $OUTPUTDIR/
## prepare ubi images ##
# Toshiba SLC image:
prepare_ubi $OUTPUTDIR $ROOTFSTAR "slc" 2048 262144 4096 1024 256
# Toshiba MLC image:
prepare_ubi $OUTPUTDIR $ROOTFSTAR "mlc" 4096 4194304 16384 16384 1280
# Hynix MLC image:
prepare_ubi $OUTPUTDIR $ROOTFSTAR "mlc" 4096 4194304 16384 16384 1664
## prepare spl images ##
# Toshiba SLC image:
prepare_spl $OUTPUTDIR $UBOOTDIR/spl/sunxi-spl.bin 262144 4096 256
# Toshiba MLC image:
prepare_spl $OUTPUTDIR $UBOOTDIR/spl/sunxi-spl.bin 4194304 16384 1280
# Hynix MLC image:
prepare_spl $OUTPUTDIR $UBOOTDIR/spl/sunxi-spl.bin 4194304 16384 1664
## prepare uboot images ##
# Toshiba SLC image:
prepare_uboot $OUTPUTDIR $UBOOTDIR/u-boot-dtb.bin 262144
# Toshiba/Hynix MLC image:
prepare_uboot $OUTPUTDIR $UBOOTDIR/u-boot-dtb.bin 4194304

View File

@ -1,132 +0,0 @@
#!/bin/bash
SCRIPTDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source $SCRIPTDIR/common.sh
FEL=fel
echo "BUILDROOT_OUTPUT_DIR = $BUILDROOT_OUTPUT_DIR"
NAND_ERASE_BB=false
if [ "$1" == "erase-bb" ]; then
NAND_ERASE_BB=true
fi
PATH=$PATH:$BUILDROOT_OUTPUT_DIR/host/usr/bin
TMPDIR=`mktemp -d -t chipflashXXXXXX`
PADDED_SPL="$TMPDIR/sunxi-padded-spl"
PADDED_SPL_SIZE=0
UBOOT_SCRIPT="$TMPDIR/uboot.scr"
UBOOT_SCRIPT_MEM_ADDR=0x43100000
UBOOT_SCRIPT_SRC="$TMPDIR/uboot.cmds"
SPL="$BUILDROOT_OUTPUT_DIR/images/sunxi-spl.bin"
SPL_MEM_ADDR=0x43000000
UBOOT="$BUILDROOT_OUTPUT_DIR/images/u-boot-dtb.bin"
PADDED_UBOOT="$TMPDIR/padded-uboot"
PADDED_UBOOT_SIZE=0xc0000
UBOOT_MEM_ADDR=0x4a000000
UBI="$BUILDROOT_OUTPUT_DIR/images/rootfs.ubi"
UBI_MEM_ADDR=0x4b000000
UBI_SIZE=`filesize $UBI | xargs printf "0x%08x"`
prepare_images() {
local in=$SPL
local out=$PADDED_SPL
if [ -e "$out" ]; then
rm "$out"
fi
# The BROM cannot read 16K pages: it only reads 8k of data at most.
# Split the SPL image in 8k chunks and pad each chunk with 8k of random
# data to limit the impact of repeated patterns on the MLC chip.
dd if=$in of=$out bs=8k count=1 skip=0 conv=sync
dd if=/dev/urandom of=$out bs=8k count=1 seek=1 conv=sync
dd if=$in of=$out bs=8k count=1 skip=1 seek=2 conv=sync
dd if=/dev/urandom of=$out bs=8k count=1 seek=3 conv=sync
dd if=$in of=$out bs=8k count=1 skip=2 seek=4 conv=sync
dd if=/dev/urandom of=$out bs=8k count=1 seek=5 conv=sync
PADDED_SPL_SIZE=`filesize $out | xargs printf "0x%08x"`
# Align the u-boot image on a page boundary
dd if=$UBOOT of=$PADDED_UBOOT bs=16k conv=sync
UBOOT_SIZE=`filesize $PADDED_UBOOT | xargs printf "0x%08x"`
dd if=/dev/urandom of=$PADDED_UBOOT seek=$((UBOOT_SIZE / 0x4000)) bs=16k count=$(((PADDED_UBOOT_SIZE - UBOOT_SIZE) / 0x4000))
}
prepare_uboot_script() {
if [ "$NAND_ERASE_BB" = true ] ; then
echo "nand scrub -y 0x0 0x200000000" > "${UBOOT_SCRIPT_SRC}"
else
echo "nand erase 0x0 0x200000000" > "${UBOOT_SCRIPT_SRC}"
fi
echo "sunxi_nand config spl" >> "${UBOOT_SCRIPT_SRC}"
echo "nand write $SPL_MEM_ADDR 0x0 $PADDED_SPL_SIZE" >> "${UBOOT_SCRIPT_SRC}"
echo "nand write $SPL_MEM_ADDR 0x100000 $PADDED_SPL_SIZE" >> "${UBOOT_SCRIPT_SRC}"
echo "nand write $SPL_MEM_ADDR 0x200000 $PADDED_SPL_SIZE" >> "${UBOOT_SCRIPT_SRC}"
echo "nand write $SPL_MEM_ADDR 0x300000 $PADDED_SPL_SIZE" >> "${UBOOT_SCRIPT_SRC}"
echo "nand write $SPL_MEM_ADDR 0x400000 $PADDED_SPL_SIZE" >> "${UBOOT_SCRIPT_SRC}"
echo "nand write $SPL_MEM_ADDR 0x500000 $PADDED_SPL_SIZE" >> "${UBOOT_SCRIPT_SRC}"
echo "nand write $SPL_MEM_ADDR 0x600000 $PADDED_SPL_SIZE" >> "${UBOOT_SCRIPT_SRC}"
echo "nand write $SPL_MEM_ADDR 0x700000 $PADDED_SPL_SIZE" >> "${UBOOT_SCRIPT_SRC}"
echo "sunxi_nand config default" >> "${UBOOT_SCRIPT_SRC}"
echo "nand write $UBOOT_MEM_ADDR 0x800000 $PADDED_UBOOT_SIZE" >> "${UBOOT_SCRIPT_SRC}"
echo "setenv bootargs root=ubi0:rootfs rootfstype=ubifs rw earlyprintk ubi.mtd=4" >> "${UBOOT_SCRIPT_SRC}"
echo "setenv bootcmd 'source \${scriptaddr}; nand slc-mode on; mtdparts; ubi part UBI; ubifsmount ubi0:rootfs; ubifsload \$fdt_addr_r /boot/sun5i-r8-chip.dtb; ubifsload \$kernel_addr_r /boot/zImage; bootz \$kernel_addr_r - \$fdt_addr_r'" >> "${UBOOT_SCRIPT_SRC}"
echo "saveenv" >> "${UBOOT_SCRIPT_SRC}"
echo "echo going to fastboot mode" >>"${UBOOT_SCRIPT_SRC}"
echo "fastboot 0" >>"${UBOOT_SCRIPT_SRC}"
echo "echo " >>"${UBOOT_SCRIPT_SRC}"
echo "echo *****************[ BOOT ]*****************" >>"${UBOOT_SCRIPT_SRC}"
echo "echo " >>"${UBOOT_SCRIPT_SRC}"
echo "boot" >>"${UBOOT_SCRIPT_SRC}"
mkimage -A arm -T script -C none -n "flash CHIP" -d "$UBOOT_SCRIPT_SRC" "$UBOOT_SCRIPT"
}
wait_for_fastboot() {
echo -n "waiting for fastboot...";
for ((i=$TIMEOUT; i>0; i--)) {
if [[ ! -z "$(fastboot devices)" ]]; then
echo "OK";
return 0;
fi
echo -n ".";
sleep 1
}
echo "TIMEOUT";
return 1
}
echo == preparing images ==
prepare_images
prepare_uboot_script
echo == upload the SPL to SRAM and execute it ==
${FEL} spl $SPL
sleep 1 # wait for DRAM initialization to complete
echo == upload spl ==
${FEL} write $SPL_MEM_ADDR "$PADDED_SPL"
echo == upload u-boot ==
${FEL} write $UBOOT_MEM_ADDR "$PADDED_UBOOT"
echo == upload u-boot script ==
${FEL} write $UBOOT_SCRIPT_MEM_ADDR "$UBOOT_SCRIPT"
echo == execute the main u-boot binary ==
${FEL} exe $UBOOT_MEM_ADDR
echo == waiting for fastboot ==
if wait_for_fastboot; then
fastboot -S 0 -u flash UBI "${BUILDROOT_OUTPUT_DIR}/images/rootfs.ubi"
fastboot continue
else
rm -rf "${TMPDIR}"
exit 1
fi

View File

@ -218,3 +218,6 @@ if [[ "${METHOD}" == "fel" ]]; then
fi
fi
rm -rf "${TMPDIR}"
ready_to_roll

11
chip-flash-nand-images.sh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/bash
SCRIPTDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source $SCRIPTDIR/common.sh
IMAGESDIR="$1"
ERASEMODE="$2"
PLATFORM="$3"
detect_nand
flash_images

159
chip-legacy-update.sh Executable file
View File

@ -0,0 +1,159 @@
#!/bin/bash
SCRIPTDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source $SCRIPTDIR/common.sh
if ! wait_for_fel; then
echo "ERROR: please jumper your CHIP in FEL mode then power on"
exit 1
fi
FLASH_SCRIPT=./chip-fel-flash.sh
WHAT=buildroot
BRANCH=stable
function require_directory {
if [[ ! -d "${1}" ]]; then
mkdir -p "${1}"
fi
}
function s3_md5 {
local URL=$1
curl -sLI $URL |grep ETag|sed -e 's/.*"\([a-fA-F0-9]\+\)["-]*.*/\1/;'
}
function cache_download {
local DEST_DIR=${1}
local SRC_URL=${2}
local FILE=${3}
if [[ -f "${DEST_DIR}/${FILE}" ]]; then
echo "${DEST_DIR}/${FILE} exists... comparing to ${SRC_URL}/${FILE}"
local S3_MD5=$(s3_md5 ${SRC_URL}/${FILE})
local MD5=$(md5sum ${DEST_DIR}/${FILE} | cut -d\ -f1)
echo "MD5: ${MD5}"
echo "S3_MD5: ${S3_MD5}"
if [[ "${S3_MD5}" != "${MD5}" ]]; then
echo "md5sum differs"
rm ${DEST_DIR}/${FILE}
if ! wget -P "${FW_IMAGE_DIR}" "${SRC_URL}/${FILE}"; then
echo "download of ${SRC_URL}/${FILE} failed!"
exit $?
fi
else
echo "file already downloaded"
fi
else
if ! wget -P "${FW_IMAGE_DIR}" "${SRC_URL}/${FILE}"; then
echo "download of ${SRC_URL}/${FILE} failed!"
exit $?
fi
fi
}
while getopts "ufdpb:w:B:" opt; do
case $opt in
u)
echo "updating cache"
if [[ -d "$FW_IMAGE_DIR" ]]; then
rm -rf $FW_IMAGE_DIR
fi
;;
f)
echo "fastboot enabled"
FLASH_SCRIPT_OPTION="-f"
;;
B)
BUILD="$OPTARG"
echo "BUILD = ${BUILD}"
;;
b)
BRANCH="$OPTARG"
echo "BRANCH = ${BRANCH}"
;;
w)
WHAT="$OPTARG"
echo "WHAT = ${WHAT}"
;;
d)
echo "debian selected"
WHAT="debian"
;;
p)
echo "PocketC.H.I.P selected"
WHAT="pocketchip"
BUILD=123
FLASH_SCRIPT=./chip-fel-flash.sh -p
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 1
;;
esac
done
FW_DIR="$(pwd)/.firmware"
FW_IMAGE_DIR="${FW_DIR}/images"
BASE_URL="http://opensource.nextthing.co/chip"
S3_URL="${BASE_URL}/${WHAT}/${BRANCH}/latest"
if [[ -z "$BUILD" ]]; then
ROOTFS_URL="$(wget -q -O- ${S3_URL})" || (echo "ERROR: cannot reach ${S3_URL}" && exit 1)
if [[ -z "${ROOTFS_URL}" ]]; then
echo "error: could not get URL for latest build from ${S3_URL} - check internet connection"
exit 1
fi
else
ROOTFS_URL="${S3_URL%latest}$BUILD"
fi
case "${WHAT}" in
"buildroot")
BR_BUILD="$(wget -q -O- ${ROOTFS_URL}/build)"
BUILD=${BR_BUILD}
ROOTFS_URL="${ROOTFS_URL}/images"
BR_URL="${ROOTFS_URL}"
;;
"debian")
BR_BUILD="$(wget -q -O- ${ROOTFS_URL}/br_build)"
BR_URL="${BASE_URL}/buildroot/${BRANCH%-gui}/${BR_BUILD}/images"
BUILD="$(wget -q -O- ${ROOTFS_URL}/build)"
;;
"pocketchip")
BR_BUILD=123
BUILD=123
ROOTFS_URL="http://opensource.nextthing.co/pocketchip"
BR_URL="$ROOTFS_URL"
;;
esac
echo "ROOTFS_URL=${ROOTFS_URL}"
echo "BUILD=${BUILD}"
echo "BR_URL=${BR_URL}"
echo "BR_BUILD=${BR_BUILD}"
require_directory "${FW_IMAGE_DIR}"
cache_download "${FW_IMAGE_DIR}" ${ROOTFS_URL} rootfs.ubi
cache_download "${FW_IMAGE_DIR}" ${BR_URL} sun5i-r8-chip.dtb
cache_download "${FW_IMAGE_DIR}" ${BR_URL} sunxi-spl.bin
cache_download "${FW_IMAGE_DIR}" ${BR_URL} sunxi-spl-with-ecc.bin
cache_download "${FW_IMAGE_DIR}" ${BR_URL} uboot-env.bin
cache_download "${FW_IMAGE_DIR}" ${BR_URL} zImage
cache_download "${FW_IMAGE_DIR}" ${BR_URL} u-boot-dtb.bin
BUILDROOT_OUTPUT_DIR="${FW_DIR}" ${FLASH_SCRIPT} ${FLASH_SCRIPT_OPTION} || echo "ERROR: could not flash" && exit 1
#if ! wait_for_linuxboot; then
# echo "ERROR: could not flash"
# exit 1
#else
# ${SCRIPTDIR}/verify.sh
#fi
exit $?

View File

@ -3,157 +3,219 @@
SCRIPTDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source $SCRIPTDIR/common.sh
if ! wait_for_fel; then
echo "ERROR: please jumper your CHIP in FEL mode then power on"
exit 1
fi
DL_DIR=".dl"
IMAGESDIR=".new/firmware/images"
DL_URL="http://opensource.nextthing.co/chip/images"
FLASH_SCRIPT=./chip-fel-flash.sh
WHAT=buildroot
WGET="wget"
FLAVOR=server
BRANCH=stable
function require_directory {
if [[ ! -d "${1}" ]]; then
mkdir -p "${1}"
fi
}
PROBES=(spl-40000-1000-100.bin
spl-400000-4000-500.bin
spl-400000-4000-680.bin
sunxi-spl.bin
u-boot-dtb.bin
uboot-40000.bin
uboot-400000.bin)
function s3_md5 {
local URL=$1
curl -sLI $URL |grep ETag|sed -e 's/.*"\([a-fA-F0-9]\+\)["-]*.*/\1/;'
}
UBI_PREFIX="chip"
UBI_SUFFIX="ubi.sparse"
UBI_TYPE="400000-4000-680"
function cache_download {
local DEST_DIR=${1}
local SRC_URL=${2}
local FILE=${3}
if [[ -f "${DEST_DIR}/${FILE}" ]]; then
echo "${DEST_DIR}/${FILE} exists... comparing to ${SRC_URL}/${FILE}"
local S3_MD5=$(s3_md5 ${SRC_URL}/${FILE})
local MD5=$(md5sum ${DEST_DIR}/${FILE} | cut -d\ -f1)
echo "MD5: ${MD5}"
echo "S3_MD5: ${S3_MD5}"
if [[ "${S3_MD5}" != "${MD5}" ]]; then
echo "md5sum differs"
rm ${DEST_DIR}/${FILE}
if ! wget -P "${FW_IMAGE_DIR}" "${SRC_URL}/${FILE}"; then
echo "download of ${SRC_URL}/${FILE} failed!"
exit $?
fi
else
echo "file already downloaded"
fi
else
if ! wget -P "${FW_IMAGE_DIR}" "${SRC_URL}/${FILE}"; then
echo "download of ${SRC_URL}/${FILE} failed!"
exit $?
fi
fi
}
while getopts "ufdpb:w:B:" opt; do
while getopts "sgpbfnrhB:N:F:L:" opt; do
case $opt in
u)
echo "updating cache"
if [[ -d "$FW_IMAGE_DIR" ]]; then
rm -rf $FW_IMAGE_DIR
fi
s)
echo "== Server selected =="
FLAVOR=server
;;
f)
echo "fastboot enabled"
FLASH_SCRIPT_OPTION="-f"
;;
B)
BUILD="$OPTARG"
echo "BUILD = ${BUILD}"
;;
b)
BRANCH="$OPTARG"
echo "BRANCH = ${BRANCH}"
;;
w)
WHAT="$OPTARG"
echo "WHAT = ${WHAT}"
;;
d)
echo "debian selected"
WHAT="debian"
g)
echo "== Gui selected =="
FLAVOR=gui
;;
p)
echo "PocketC.H.I.P selected"
WHAT="pocketchip"
BUILD=123
FLASH_SCRIPT=./chip-fel-flash.sh -p
echo "== Pocketchip selected =="
FLAVOR=pocketchip
;;
b)
echo "== Buildroot selected =="
FLAVOR=buildroot
;;
f)
echo "== Force clean and download =="
rm -rf .dl/ .new/
;;
n)
echo "== No Limit mode =="
NO_LIMIT="while itest.b *0x80400000 -ne 03; do i2c mw 0x34 0x30 0x03; i2c read 0x34 0x30 1 0x80400000; done; "
;;
r)
echo "== Reset after flash =="
RESET_COMMAND="reset"
;;
B)
BRANCH="$OPTARG"
echo "== ${BRANCH} branch selected =="
;;
N)
CACHENUM="$OPTARG"
echo "== Build number ${CACHENUM} selected =="
;;
F)
FORMAT="$OPTARG"
echo "== Format ${FORMAT} selected =="
;;
L)
LOCALDIR="$OPTARG"
echo "== Local directory '${LOCALDIR}' selected =="
;;
h)
echo ""
echo "== Help =="
echo ""
echo " -s -- Server [Debian + Headless] "
echo " -g -- GUI [Debian + XFCE] "
echo " -p -- PocketCHIP [CHIP on the go!] "
echo " -b -- Buildroot [Tiny, but powerful] "
echo " -f -- Force clean [re-download if applicable]"
echo " -n -- No limit [enable greater power draw]"
echo " -r -- Reset [reset device after flash] "
echo " -B -- Branch [eg. -B testing] "
echo " -N -- Build# [eg. -N 150] "
echo " -F -- Format [eg. -F Toshiba_4G_MLC] "
echo " -L -- Local [eg. -L ../img/buildroot/] "
echo ""
echo ""
exit 0
;;
\?)
echo "Invalid option: -$OPTARG" >&2
echo "== Invalid option: -$OPTARG ==" >&2
exit 1
;;
esac
done
FW_DIR="$(pwd)/.firmware"
FW_IMAGE_DIR="${FW_DIR}/images"
BASE_URL="http://opensource.nextthing.co/chip"
S3_URL="${BASE_URL}/${WHAT}/${BRANCH}/latest"
if [[ -z "$BUILD" ]]; then
ROOTFS_URL="$(wget -q -O- ${S3_URL})" || (echo "ERROR: cannot reach ${S3_URL}" && exit 1)
if [[ -z "${ROOTFS_URL}" ]]; then
echo "error: could not get URL for latest build from ${S3_URL} - check internet connection"
exit 1
function require_directory {
if [[ ! -d "${1}" ]]; then
mkdir -p "${1}"
fi
else
ROOTFS_URL="${S3_URL%latest}$BUILD"
fi
}
case "${WHAT}" in
"buildroot")
BR_BUILD="$(wget -q -O- ${ROOTFS_URL}/build)"
BUILD=${BR_BUILD}
ROOTFS_URL="${ROOTFS_URL}/images"
BR_URL="${ROOTFS_URL}"
;;
"debian")
BR_BUILD="$(wget -q -O- ${ROOTFS_URL}/br_build)"
BR_URL="${BASE_URL}/buildroot/${BRANCH%-gui}/${BR_BUILD}/images"
BUILD="$(wget -q -O- ${ROOTFS_URL}/build)"
;;
"pocketchip")
BR_BUILD=123
BUILD=123
ROOTFS_URL="http://opensource.nextthing.co/pocketchip"
BR_URL="$ROOTFS_URL"
;;
esac
function dl_probe {
echo "ROOTFS_URL=${ROOTFS_URL}"
echo "BUILD=${BUILD}"
echo "BR_URL=${BR_URL}"
echo "BR_BUILD=${BR_BUILD}"
if [ -z $CACHENUM ] && [ -z $LOCALDIR ]; then
CACHENUM=$(curl -s $DL_URL/$BRANCH/$FLAVOR/latest)
fi
require_directory "${FW_IMAGE_DIR}"
cache_download "${FW_IMAGE_DIR}" ${ROOTFS_URL} rootfs.ubi
cache_download "${FW_IMAGE_DIR}" ${BR_URL} sun5i-r8-chip.dtb
cache_download "${FW_IMAGE_DIR}" ${BR_URL} sunxi-spl.bin
cache_download "${FW_IMAGE_DIR}" ${BR_URL} sunxi-spl-with-ecc.bin
cache_download "${FW_IMAGE_DIR}" ${BR_URL} uboot-env.bin
cache_download "${FW_IMAGE_DIR}" ${BR_URL} zImage
cache_download "${FW_IMAGE_DIR}" ${BR_URL} u-boot-dtb.bin
if [[ ! -d "$DL_DIR/$BRANCH-$FLAVOR-b${CACHENUM}" ]] && [[ -z $LOCALDIR ]]; then
echo "== New image available =="
BUILDROOT_OUTPUT_DIR="${FW_DIR}" ${FLASH_SCRIPT} ${FLASH_SCRIPT_OPTION} || echo "ERROR: could not flash" && exit 1
rm -rf $DL_DIR/$BRANCH-$FLAVOR*
#if ! wait_for_linuxboot; then
# echo "ERROR: could not flash"
# exit 1
#else
# ${SCRIPTDIR}/verify.sh
#fi
mkdir -p $DL_DIR/${BRANCH}-${FLAVOR}-b${CACHENUM}
pushd $DL_DIR/${BRANCH}-${FLAVOR}-b${CACHENUM} > /dev/null
exit $?
echo "== Downloading.. =="
for FILE in ${PROBES[@]}; do
if ! $WGET $DL_URL/$BRANCH/$FLAVOR/${CACHENUM}/$FILE; then
echo "!! download of $BRANCH-$FLAVOR-$METHOD-b${CACHENUM} failed !!"
exit $?
fi
done
popd > /dev/null
else
echo "== Local/cached probe files located =="
fi
echo "== Staging for NAND probe =="
if [ -z $LOCALDIR ];then
ln -s ../../$DL_DIR/${BRANCH}-${FLAVOR}-b${CACHENUM}/ $IMAGESDIR
else
ln -s ../../$LOCALDIR $IMAGESDIR
fi
if [[ -f ${IMAGESDIR}/ubi_type ]]; then rm ${IMAGESDIR}/ubi_type; fi
if [ -z $FORMAT ]; then
detect_nand || exit 1
else
case $FORMAT in
"Hynix_8G_MLC")
echo hello
export nand_erasesize=400000
export nand_oobsize=680
export nand_writesize=4000
;;
"Toshiba_4G_MLC")
export nand_erasesize=400000
export nand_oobsize=500
export nand_writesize=4000
;;
"Toshiba_512M_SLC")
echo correct
export nand_erasesize=40000
export nand_oobsize=100
export nand_writesize=1000
;;
*)
echo "== Invalid format: $FORMAT =="
exit 1
;;
esac
UBI_TYPE="$nand_erasesize-$nand_writesize-$nand_oobsize"
echo $UBI_TYPE > ${IMAGESDIR}/ubi_type
fi
if [[ ! -f "$DL_DIR/$BRANCH-$FLAVOR-b${CACHENUM}/$UBI_PREFIX-$UBI_TYPE.$UBI_SUFFIX" ]] && [ -z $LOCALDIR ]; then
echo "== Downloading new UBI, this will be cached for future flashes. =="
pushd $DL_DIR/${BRANCH}-${FLAVOR}-b${CACHENUM} > /dev/null
if ! $WGET $DL_URL/$BRANCH/$FLAVOR/${CACHENUM}/$UBI_PREFIX-$UBI_TYPE.$UBI_SUFFIX; then
echo "!! download of $BRANCH-$FLAVOR-$METHOD-b${CACHENUM} failed !!"
exit $?
fi
popd > /dev/null
else
if [ -z $LOCALDIR ]; then
echo "== Cached UBI located =="
else
if [[ ! -f "$IMAGESDIR/$UBI_PREFIX-$UBI_TYPE.$UBI_SUFFIX" ]]; then
echo "Could not locate UBI files"
exit 1
else
echo "== Cached UBI located =="
fi
fi
fi
}
echo == preparing images ==
require_directory "$IMAGESDIR"
rm -rf ${IMAGESDIR}
require_directory "$DL_DIR"
##pass
dl_probe || (
##fail
echo -e "\n FLASH VERIFICATION FAILED.\n\n"
echo -e "\tTROUBLESHOOTING:\n"
echo -e "\tIs the FEL pin connected to GND?"
echo -e "\tHave you tried turning it off and turning it on again?"
echo -e "\tDid you run the setup script in CHIP-SDK?"
echo -e "\tDownload could be corrupt, it can be re-downloaded by adding the '-f' flag."
echo -e "\n\n"
exit 1
)
##pass
flash_images && ready_to_roll || (
##fail
echo -e "\n FLASH VERIFICATION FAILED.\n\n"
echo -e "\tTROUBLESHOOTING:\n"
echo -e "\tIs the FEL pin connected to GND?"
echo -e "\tHave you tried turning it off and turning it on again?"
echo -e "\tDid you run the setup script in CHIP-SDK?"
echo -e "\tDownload could be corrupt, it can be re-downloaded by adding the '-f' flag."
echo -e "\n\n"
)

188
common.sh
View File

@ -1,7 +1,21 @@
#!/bin/bash
TIMEOUT=30
FEL=fel
FEL=sunxi-fel
SPLMEMADDR=0x43000000
UBOOTMEMADDR=0x4a000000
UBOOTSCRMEMADDR=0x43100000
nand_erasesize=400000
nand_writesize=4000
nand_oobsize=680
if [[ -z $(which $FEL) ]]; then
echo " Error: Unable to locate FEL utility."
echo " Install FEL with:"
echo " CHIP-SDK setup script [github.com/NextThingCo/CHIP-SDK]"
echo " - or build from source [github.com/linux-sunxi/sunxi-tools]"
exit 1
fi
#------------------------------------------------------------
onMac() {
@ -53,12 +67,163 @@ wait_for_fel() {
return 1
}
#------------------------------------------------------------
detect_nand() {
local tmpdir=`mktemp -d -t chip-uboot-script-XXXXXX`
local ubootcmds=$tmpdir/uboot.cmds
local ubootscr=$tmpdir/uboot.scr
echo "nand info
env export -t -s 0x100 0x7c00 nand_erasesize nand_writesize nand_oobsize
reset" > $ubootcmds
mkimage -A arm -T script -C none -n "detect NAND" -d $ubootcmds $ubootscr || return 1
if ! wait_for_fel; then
echo "ERROR: please make sure CHIP is connected and jumpered in FEL mode"
return 1
fi
$FEL spl $IMAGESDIR/sunxi-spl.bin || return 1
# wait for DRAM initialization to complete
sleep 1
$FEL write $UBOOTMEMADDR $IMAGESDIR/u-boot-dtb.bin || return 1
$FEL write $UBOOTSCRMEMADDR $ubootscr || return 1
$FEL exe $UBOOTMEMADDR || return 1
if ! wait_for_fel; then
echo "ERROR: please make sure CHIP is connected and jumpered in FEL mode"
return 1
fi
$FEL read 0x7c00 0x100 $tmpdir/nand-info || return 1
echo "NAND detected:"
cat $tmpdir/nand-info || return 1
UBI_TYPE="$(cat $tmpdir/nand-info | awk -F= '/erase/ {print $2}')-$(cat $tmpdir/nand-info | awk -F= '/write/ {print $2}')-$(cat $tmpdir/nand-info | awk -F= '/oob/ {print $2}')"
echo "${UBI_TYPE}" > $IMAGESDIR/ubi_type || return 1
source $tmpdir/nand-info || return 1
rm -rf $tmpdir
return 0
}
#------------------------------------------------------------
flash_images() {
local RC=0
local tmpdir=`mktemp -d -t chip-uboot-script-XXXXXX`
local ubootcmds=$tmpdir/uboot.cmds
local ubootscr=$IMAGESDIR/uboot.scr
local ubootsize=`filesize $IMAGESDIR/uboot-$nand_erasesize.bin | xargs printf "0x%08x"`
local pagespereb=`echo $((nand_erasesize/nand_writesize)) | xargs printf "%x"`
local sparseubi=$tmpdir/ubi.sparse
if [ "x$ERASEMODE" = "xscrub" ]; then
echo "nand scrub.chip -y" > $ubootcmds
else
echo "nand erase.chip" > $ubootcmds
fi
if [ "$nand_oobsize" = "100" ];then
DTB_NAME="ntc-gr8-crumb.dtb"
else
DTB_NAME="sun5i-r8-chip.dtb"
fi
echo "nand write.raw.noverify $SPLMEMADDR 0x0 $pagespereb" >> $ubootcmds
echo "nand write.raw.noverify $SPLMEMADDR 0x400000 $pagespereb" >> $ubootcmds
echo "nand write $UBOOTMEMADDR 0x800000 $ubootsize" >> $ubootcmds
echo "setenv mtdparts mtdparts=sunxi-nand.0:4m(spl),4m(spl-backup),4m(uboot),4m(env),-(UBI)" >> $ubootcmds
echo "setenv bootargs root=ubi0:rootfs rootfstype=ubifs rw earlyprintk ubi.mtd=4" >> $ubootcmds
echo "setenv bootcmd 'gpio set PB2; if test -n \${fel_booted} && test -n \${scriptaddr}; then echo '(FEL boot)'; source \${scriptaddr}; fi; mtdparts; ubi part UBI; ubifsmount ubi0:rootfs; ubifsload \$fdt_addr_r /boot/$DTB_NAME; ubifsload \$kernel_addr_r /boot/zImage; bootz \$kernel_addr_r - \$fdt_addr_r'" >> $ubootcmds
echo "setenv fel_booted 0" >> $ubootcmds
echo "echo Enabling Splash" >> $ubootcmds
echo "setenv stdout serial" >> $ubootcmds
echo "setenv stderr serial" >> $ubootcmds
echo "setenv splashpos m,m" >> $ubootcmds
echo "echo Configuring Video Mode" >> $ubootcmds
if [ "$FLAVOR" = "pocketchip" ]; then
echo "setenv clear_fastboot 'i2c mw 0x34 0x4 0x00 4;'" >> $ubootcmds
echo "setenv write_fastboot 'i2c mw 0x34 0x4 66 1; i2c mw 0x34 0x5 62 1; i2c mw 0x34 0x6 30 1; i2c mw 0x34 0x7 00 1'" >> $ubootcmds
echo "setenv test_fastboot 'i2c read 0x34 0x4 4 0x80200000; if itest.s *0x80200000 -eq fb0; then echo (Fastboot); i2c mw 0x34 0x4 0x00 4; fastboot 0; fi'" >> $ubootcmds
echo "setenv bootargs root=ubi0:rootfs rootfstype=ubifs rw ubi.mtd=4 quiet lpj=501248 loglevel=3 splash plymouth.ignore-serial-consoles" >> $ubootcmds
echo "setenv bootpaths 'initrd noinitrd'" >> $ubootcmds
echo "setenv bootcmd '${NO_LIMIT}run test_fastboot; if test -n \${fel_booted} && test -n \${scriptaddr}; then echo (FEL boot); source \${scriptaddr}; fi; for path in \${bootpaths}; do run boot_\$path; done'" >> $ubootcmds
echo "setenv boot_initrd 'mtdparts; ubi part UBI; ubifsmount ubi0:rootfs; ubifsload \$fdt_addr_r /boot/$DTB_NAME; ubifsload 0x44000000 /boot/initrd.uimage; ubifsload \$kernel_addr_r /boot/zImage; bootz \$kernel_addr_r 0x44000000 \$fdt_addr_r'" >> $ubootcmds
echo "setenv boot_noinitrd 'mtdparts; ubi part UBI; ubifsmount ubi0:rootfs; ubifsload \$fdt_addr_r /boot/$DTB_NAME; ubifsload \$kernel_addr_r /boot/zImage; bootz \$kernel_addr_r - \$fdt_addr_r'" >> $ubootcmds
echo "setenv video-mode" >> $ubootcmds
echo "setenv dip_addr_r 0x43400000" >> $ubootcmds
echo "setenv dip_overlay_dir /lib/firmware/nextthingco/chip/early" >> $ubootcmds
echo "setenv dip_overlay_cmd 'if test -n \"\${dip_overlay_name}\"; then ubifsload \$dip_addr_r \$dip_overlay_dir/\$dip_overlay_name; fi'" >> $ubootcmds
echo "setenv fel_booted 0" >> $ubootcmds
echo "setenv bootdelay 1" >> $ubootcmds
else
echo "setenv bootpaths 'initrd noinitrd'" >> $ubootcmds
echo "setenv bootcmd '${NO_LIMIT}run test_fastboot; if test -n \${fel_booted} && test -n \${scriptaddr}; then echo (FEL boot); source \${scriptaddr}; fi; for path in \${bootpaths}; do run boot_\$path; done'" >> $ubootcmds
echo "setenv boot_initrd 'mtdparts; ubi part UBI; ubifsmount ubi0:rootfs; ubifsload \$fdt_addr_r /boot/$DTB_NAME; ubifsload 0x44000000 /boot/initrd.uimage; ubifsload \$kernel_addr_r /boot/zImage; bootz \$kernel_addr_r 0x44000000 \$fdt_addr_r'" >> $ubootcmds
echo "setenv boot_noinitrd 'mtdparts; ubi part UBI; ubifsmount ubi0:rootfs; ubifsload \$fdt_addr_r /boot/$DTB_NAME; ubifsload \$kernel_addr_r /boot/zImage; bootz \$kernel_addr_r - \$fdt_addr_r'" >> $ubootcmds
echo "setenv dip_addr_r 0x43400000" >> $ubootcmds
echo "setenv dip_overlay_dir /lib/firmware/nextthingco/chip/early" >> $ubootcmds
echo "setenv dip_overlay_cmd 'if test -n \"\${dip_overlay_name}\"; then ubifsload \$dip_addr_r \$dip_overlay_dir/\$dip_overlay_name; fi'" >> $ubootcmds
echo "setenv video-mode sunxi:640x480-24@60,monitor=composite-ntsc,overscan_x=40,overscan_y=20" >> $ubootcmds
fi
echo "saveenv" >> $ubootcmds
echo "echo going to fastboot mode" >> $ubootcmds
echo "fastboot 0" >> $ubootcmds
if [ -z $RESET_COMMAND ]; then
RESET_COMMAND="while true; do; sleep 10; done;"
fi
echo "$RESET_COMMAND" >> $ubootcmds
mkimage -A arm -T script -C none -n "flash $FLAVOR" -d $ubootcmds $ubootscr || RC=1
if ! wait_for_fel; then
echo "ERROR: please make sure CHIP is connected and jumpered in FEL mode"
RC=1
fi
$FEL spl $IMAGESDIR/sunxi-spl.bin || RC=1
# wait for DRAM initialization to complete
sleep 1
$FEL write $UBOOTMEMADDR $IMAGESDIR/uboot-$nand_erasesize.bin || RC=1
$FEL write $SPLMEMADDR $IMAGESDIR/spl-$nand_erasesize-$nand_writesize-$nand_oobsize.bin || RC=1
$FEL write $UBOOTSCRMEMADDR $ubootscr || RC=1
$FEL exe $UBOOTMEMADDR || RC=1
if wait_for_fastboot; then
fastboot -i 0x1f3a -u flash UBI $IMAGESDIR/chip-$nand_erasesize-$nand_writesize-$nand_oobsize.ubi.sparse || RC=1
fastboot -i 0x1f3a continue > /dev/null
else
echo "failed to flash the UBI image"
RC=1
fi
rm -rf $tmpdir
return $RC
}
#------------------------------------------------------------
wait_for_linuxboot() {
local TIMEOUT=100
echo -n "flashing...";
for ((i=$TIMEOUT; i>0; i--)) {
if lsusb |grep -q "0525:a4a7"; then
if lsusb |grep -q "0525:a4a7" ||
lsusb |grep -q "0525:a4aa"; then
echo "OK"
return 0;
fi
@ -70,3 +235,22 @@ wait_for_linuxboot() {
return 1
}
#------------------------------------------------------------
ready_to_roll() {
echo -e "\n\nFLASH VERIFICATION COMPLETE.\n\n"
echo " # # #"
echo " #########"
echo "### ###"
echo " # {#} #"
echo "### '%######"
echo " # #"
echo "### ###"
echo " ########"
echo " # # #"
echo -e "\n\nCHIP is ready to roll!\n\n"
return 0
}

File diff suppressed because it is too large Load Diff

155
verify.sh
View File

@ -1,118 +1,55 @@
#!/usr/bin/env python
#!/bin/bash
import io
import sys
import serial
import re
import time
#------------------------------------------------------------------
def answer_prompt(sio,prompt_to_wait_for,answer_to_write,send_cr=True):
#------------------------------------------------------------------
sio.flush()
prompt_found = False
data = ''
#if send_cr:
#sio.write(unicode('\n'))
d='something'
while not len(d)==0:
d = sio.read(2000);
data += d
time.sleep(1)
# print '-' * 50
# print ' %d bytes read' % (len(data))
# print '-' * 50
#print data
line=''
while not prompt_found:
d = sio.read(100);
data += d
# print '-' * 50
# print ' %d bytes read' % (len(data))
# print '-' * 50
# print data
# print '-' * 50
if len(data.split())>0:
line=data.split()[-1]
# print "matching [%s] against [%s]" % (line,prompt_to_wait_for)
if(re.match(prompt_to_wait_for,line,re.M)):
sio.write(unicode(answer_to_write+'\n'))
# print '-' * 50
# print ' detected [%s] ' % prompt_to_wait_for
# print '-' * 50
prompt_found = True
else:
if send_cr:
sio.write(unicode('\n'))
sio.flush()
#sys.stdin.readline()
#------------------------------------------------------------------
def scanfor(sio,regexp_to_scan_for,answer_to_write):
#------------------------------------------------------------------
prompt_found = False
data = ''
while not prompt_found:
data += sio.read(100);
# print '-' * 50
# print ' %d bytes read' % (len(data))
# print '-' * 50
# print data
if re.search(regexp_to_scan_for,data):
# print '-' * 50
# print ' detected [%s] ' % regexp_to_scan_for
# print '-' * 50
sio.write(unicode(answer_to_write+'\n'))
prompt_found = True
sio.flush()
return data
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
SCRIPT_NAME="$(basename $0)"
CHAT_SCRIPT="${SCRIPT_DIR}/${SCRIPT_NAME}.chat"
CHAT_BIN="$(which chat)"
CHAT_BIN="${CHAT_BIN:-/usr/sbin/chat}"
#------------------------------------------------------------------
def main():
#------------------------------------------------------------------
UART_DEVICE=ttyACM0
GETTY_UART_SERVICE="serial-getty@${UART_DEVICE}.service"
GETTY_DISABLED=0
if( len(sys.argv)>1 ):
serial_port=sys.argv[1]
else:
serial_port='/dev/ttyACM0';
export TIMEOUT=3
#print 'reading from %s:' % serial_port
#echo "DUT_UART_RUN=$DUT_UART_RUN"
ser = serial.Serial(serial_port,115200, timeout=1);
sio = io.TextIOWrapper(io.BufferedRWPair(ser,ser))
#login
print "login...",
sys.stdout.flush()
answer_prompt(sio,'.*login:','chip',True)
print "OK\npassword...",
sys.stdout.flush()
answer_prompt(sio,'.*Password:','chip',False)
print "OK\npoweroff...",
sys.stdout.flush()
answer_prompt(sio,'.*[\$#]','sudo poweroff')
answer_prompt(sio,'.*:','chip')
time.sleep(2)
print "OK\n",
#d=scanfor(sio,r'.*### [^#]+ ###.*','poweroff')
# if re.search(r'.*### ALL TESTS PASSED ###.*',d):
# print "---> TESTS PASSED"
# ser.close();
# return 0
ser.close();
# print "---> TESTS FAILED"
return 0
while getopts "t:" opt; do
case $opt in
t)
TIMEOUT="${OPTARG}"
echo "timeout set to ${TIMEOUT}"
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 1
;;
esac
done
shift $((OPTIND-1))
export DUT_UART_PARAMETER="$@"
if [[ "$(systemctl is-active $GETTY_UART_SERVICE)" == "active" ]]; then
echo "stopping $GETTY_UART_SERVICE"
systemctl stop $GETTY_UART_SERVICE
GETTY_DISABLED=1
fi
#------------------------------------------------------------------
if __name__ == "__main__":
#------------------------------------------------------------------
exit( main() )
[[ -r "${CHAT_SCRIPT}" ]] || (echo "ERROR: can not read ${CHAT_SCRIPT}" && exit 1)
[[ -r "${CHAT_BIN}" ]] || (echo -e "ERROR: ${CHAT_BIN} not found\n -- 'sudo apt-get install ppp'" && exit 1)
for i in `seq 1 3`;
do
echo -e "Waiting for serial gadget...Attempt(${i}/3)"
/usr/sbin/chat -t $TIMEOUT -E -V -f "${CHAT_SCRIPT}" </dev/${UART_DEVICE} >/dev/${UART_DEVICE}\
&& break\
|| (echo -e "ERROR: failed to verify\n" && exit 1)
done
echo "SUCCESS: CHIP is powering down"
if [[ ${GETTY_DISABLED} == 1 ]]; then
echo "starting $GETTY_UART_SERVICE"
systemctl start $GETTY_UART_SERVICE
fi

8
verify.sh.chat Normal file
View File

@ -0,0 +1,8 @@
SAY "\n [ACM] Trying to login..."
TIMEOUT 40
'' \n ogin:-\n-login: root\n assword: chip\n '# ' ''
SAY "\n [ACM] Successfully logged in"
TIMEOUT 40
'# ' '/sbin/poweroff'
SAY "\n [ACM] Powering off..."
TIMEOUT 40