diff options
author | Richard Purdie <rpurdie@linux.intel.com> | 2010-08-27 15:14:24 +0100 |
---|---|---|
committer | Richard Purdie <rpurdie@linux.intel.com> | 2010-08-27 15:29:45 +0100 |
commit | 29d6678fd546377459ef75cf54abeef5b969b5cf (patch) | |
tree | 8edd65790e37a00d01c3f203f773fe4b5012db18 /meta/recipes-bsp/zaurus-updater | |
parent | da49de6885ee1bc424e70bc02f21f6ab920efb55 (diff) | |
download | openembedded-core-29d6678fd546377459ef75cf54abeef5b969b5cf.tar.gz openembedded-core-29d6678fd546377459ef75cf54abeef5b969b5cf.tar.bz2 openembedded-core-29d6678fd546377459ef75cf54abeef5b969b5cf.zip |
Major layout change to the packages directory
Having one monolithic packages directory makes it hard to find things
and is generally overwhelming. This commit splits it into several
logical sections roughly based on function, recipes.txt gives more
information about the classifications used.
The opportunity is also used to switch from "packages" to "recipes"
as used in OpenEmbedded as the term "packages" can be confusing to
people and has many different meanings.
Not all recipes have been classified yet, this is just a first pass
at separating things out. Some packages are moved to meta-extras as
they're no longer actively used or maintained.
Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'meta/recipes-bsp/zaurus-updater')
-rw-r--r-- | meta/recipes-bsp/zaurus-updater/encdec-updater.bb | 18 | ||||
-rw-r--r-- | meta/recipes-bsp/zaurus-updater/encdec-updater/encdec-updater.c | 80 | ||||
-rw-r--r-- | meta/recipes-bsp/zaurus-updater/zaurus-updater.bb | 36 | ||||
-rw-r--r-- | meta/recipes-bsp/zaurus-updater/zaurus-updater/gnu-tar.gz | bin | 0 -> 242146 bytes | |||
-rw-r--r-- | meta/recipes-bsp/zaurus-updater/zaurus-updater/updater.sh | 481 |
5 files changed, 615 insertions, 0 deletions
diff --git a/meta/recipes-bsp/zaurus-updater/encdec-updater.bb b/meta/recipes-bsp/zaurus-updater/encdec-updater.bb new file mode 100644 index 0000000000..c59d0e2976 --- /dev/null +++ b/meta/recipes-bsp/zaurus-updater/encdec-updater.bb @@ -0,0 +1,18 @@ +SECTION = "console/utils" +LICENSE = "GPL" +DESCRIPTION = "A tool to encode and decode the Sharp Zaurus updater.sh script" + +SRC_URI = "file://encdec-updater.c" + +COMPATIBLE_MACHINE = '(poodle|c7x0|spitz|akita|tosa)' + +do_compile() { + ${CC} -o encdec-updater ${WORKDIR}/encdec-updater.c +} + +do_install() { + install -d ${D}${bindir} + install -m 0755 encdec-updater ${D}${bindir}/ +} + +BBCLASSEXTEND = "native"
\ No newline at end of file diff --git a/meta/recipes-bsp/zaurus-updater/encdec-updater/encdec-updater.c b/meta/recipes-bsp/zaurus-updater/encdec-updater/encdec-updater.c new file mode 100644 index 0000000000..b894623c65 --- /dev/null +++ b/meta/recipes-bsp/zaurus-updater/encdec-updater/encdec-updater.c @@ -0,0 +1,80 @@ +// +// +// Sharp Zaurus SL-C7x0 updater.sh script encoder/decoder +// +// mailto:sash@cacko.biz +// +// + +#include <stdio.h> + +unsigned char enctab[] = { + 0x4a,0xf7,0x77,0x62,0xb0,0xe3,0xd8,0xf6,0xd1,0x98,0x09,0x2e,0x19,0x0c,0x0d,0x7c, + 0x04,0xe0,0x6b,0x22,0x10,0x08,0x15,0x16,0xb9,0x28,0x83,0x1f,0x91,0x06,0xfa,0xe8, + 0xbd,0xc6,0x21,0x32,0x23,0x6f,0x01,0x26,0x5f,0x03,0x33,0xb6,0x35,0xac,0x2d,0x0a, + 0x6e,0x6c,0xfc,0xc4,0x29,0x34,0x2b,0x42,0x25,0x66,0xc9,0x3e,0x87,0xb4,0x74,0xf2, + 0x11,0x20,0x41,0xb3,0x27,0x14,0xc1,0xcd,0x3d,0x80,0xd5,0x7f,0xcf,0x4c,0x4d,0xca, + 0x75,0x51,0xc8,0xa6,0x17,0xf0,0x55,0x82,0x79,0xdc,0x59,0x5a,0x5b,0xb8,0x5d,0x40, + 0x64,0x58,0xff,0xc5,0xab,0xc0,0xae,0xeb,0xa3,0xad,0xea,0x6a,0x37,0x3b,0x73,0x9a, + 0x88,0x3a,0xe1,0x68,0x0b,0xec,0xc7,0x76,0xf9,0x38,0x57,0xdd,0x49,0x96,0x95,0x7a, + 0x50,0x2a,0x4e,0xdb,0x00,0x48,0xd7,0x86,0x47,0x94,0xa0,0x1c,0x8b,0x8c,0x8d,0x92, + 0x45,0x90,0x7e,0x56,0x93,0xef,0x1a,0x52,0x97,0xbc,0x99,0xb5,0x7d,0x72,0x9d,0x9c, + 0xfb,0x24,0xa1,0xa2,0x07,0x46,0xa5,0x02,0x69,0xe6,0xa9,0xd3,0x30,0xba,0xd6,0x84, + 0x63,0x13,0x1b,0xb2,0x1d,0xaf,0x36,0x8e,0xb7,0x53,0x05,0xbb,0x12,0x78,0x8f,0xbe, + 0x71,0xbf,0xe4,0x1e,0x9e,0xa4,0xe5,0x2f,0x9b,0x31,0x67,0x4b,0xcb,0x43,0xc3,0xce, + 0x44,0x3c,0x0f,0xd2,0xaa,0xd4,0xed,0xa7,0x7b,0x18,0xd0,0xda,0x0e,0x54,0xf1,0xde, + 0xdf,0xa8,0x3f,0xe2,0x6d,0xcc,0xf8,0x70,0xe7,0x61,0xe9,0x85,0x65,0x2c,0x39,0xee, + 0x60,0x81,0x89,0xc2,0xf3,0xf4,0xf5,0x8a,0x5c,0x5e,0xd9,0x4f,0x9f,0xb1,0xfd,0xfe, +}; + +unsigned char decode_c(unsigned char c) +{ + int i; + for (i = 0; i < 256; i++) { + if (c == enctab[i]) return i; + } + printf("Internal bug: encode_c()\n"); + exit(1); + return 0; +} + +unsigned char encode_c(unsigned char c) +{ + int i; + return enctab[c]; +} + +int main(int argc, char *argv[]) +{ + int i, decode; + int c; + FILE *inf, *outf; + char name[256]; + + if (argc < 3) { + printf("Decode file:\n\tencsh -d file.sh\nEncode file:\n\tencsh -c file.sh\n"); + exit(1); + } + + if (strcmp(argv[1], "-d")) decode = 1; + else decode = 0; + + strcpy(name, argv[2]); + strcat(name, ".$$$$"); + + inf = fopen(argv[2], "rb"); + outf = fopen(name, "wb"); + + while ((c = fgetc(inf)) >= 0) { + if (decode) c = decode_c(c); + else c = encode_c(c); + fputc(c, outf); + } + + fclose(inf); + fclose(outf); + + rename(name, argv[2]); + + return 0; +} diff --git a/meta/recipes-bsp/zaurus-updater/zaurus-updater.bb b/meta/recipes-bsp/zaurus-updater/zaurus-updater.bb new file mode 100644 index 0000000000..a621761d66 --- /dev/null +++ b/meta/recipes-bsp/zaurus-updater/zaurus-updater.bb @@ -0,0 +1,36 @@ +DESCRIPTION = "Encrypted shellscript for the Zaurus ROM update" +DEPENDS = "encdec-updater-native" +LICENSE = "zaurus-updater" +PR = "r20" + +PACKAGES = "" +PACKAGE_ARCH = "${MACHINE_ARCH}" +COMPATIBLE_MACHINE = '(poodle|c7x0|spitz|akita|tosa)' + +SRC_URI = "file://updater.sh \ + file://gnu-tar.gz" +S = "${WORKDIR}" + +inherit deploy + +do_configure() { + sed -i "s/ZAURUS_UPDATER_VERSION/${PR}/" "${S}/updater.sh" +} + +do_compile() { + encdec-updater -e updater.sh +} + +do_deploy() { + install -m 0755 updater.sh ${DEPLOYDIR}/updater.sh.${MACHINE} + + case ${MACHINE} in + spitz ) + install -m 0755 gnu-tar ${DEPLOYDIR}/gnu-tar + ;; + *) + ;; + esac +} + +addtask deploy before do_populate_sysroot after do_compile diff --git a/meta/recipes-bsp/zaurus-updater/zaurus-updater/gnu-tar.gz b/meta/recipes-bsp/zaurus-updater/zaurus-updater/gnu-tar.gz Binary files differnew file mode 100644 index 0000000000..93d1a43704 --- /dev/null +++ b/meta/recipes-bsp/zaurus-updater/zaurus-updater/gnu-tar.gz diff --git a/meta/recipes-bsp/zaurus-updater/zaurus-updater/updater.sh b/meta/recipes-bsp/zaurus-updater/zaurus-updater/updater.sh new file mode 100644 index 0000000000..22d4b3914d --- /dev/null +++ b/meta/recipes-bsp/zaurus-updater/zaurus-updater/updater.sh @@ -0,0 +1,481 @@ +#!/bin/sh +# +# One updater.sh to rule them all +# +# 2006.10.24 Marcin 'Hrw' Juszkiewicz +# - started work on common updater.sh +# - works on poodle, c760, spitz +# - breaks on tosa +# +# 2007.10.08 Marcin 'Hrw' Juszkiewicz +# - do not allow to flash files bigger then partition size +# - created functions for common stuff +# +# 2007.11.18 Dmitry 'Lumag' Baryshkov +# - fixes +# - tosa unbreak +# +# 2007.11.19 Marcin 'Hrw' Juszkiewicz +# - size check unbreak +# - c760/c860 has bigger rootfs - use it +# +# 2007.11.23 Koen Kooi +# - consistent error messages +# - fix flashing from case sensitive filesystem (e.g. ext2) +# +# 2007.11.23 Matthias 'CoreDump' Hentges +# - Always treat MTD_PART_SIZE as HEX when comparing sizes +# - Thanks to ZeroChaos for debugging +# +# 2007.12.04 Matthias 'CoreDump' Hentges +# - Unb0rk flashing of Akita kernels +# +# 2007.12.10 Marcin 'Hrw' Juszkiewicz +# - Reformatted file - please use spaces not tabs +# - "version check" is only on Tosa and Poodle - breaks other machines +# +# 2007.12.23 Matthias 'CoreDump' Hentges +# - Fix kernel install on spitz machines +# - Unify format of do_flashing()... +# - Display ${PR} of zaurus-updater.bb to the user +# - Polish HDD installer messages +# +# 2007.12.25 Matthias 'CoreDump' Hentges +# -Add support for installing / updating u-boot + +# Set to "yes" to enable +ENABLE_UBOOT_UPDATER="no" + +DATAPATH=$1 +TMPPATH=/tmp/update +TMPDATA=$TMPPATH/tmpdata.bin +TMPHEAD=$TMPPATH/tmphead.bin + +FLASHED_KERNEL=0 +FLASHED_ROOTFS=0 +UNPACKED_ROOTFS=0 # spitz only + +RO_MTD_LINE=`cat /proc/mtd | grep "root" | tail -n 1` +if [ "$RO_MTD_LINE" = "" ]; then + RO_MTD_LINE=`cat /proc/mtd | grep "\<NAND\>.*\<2\>" | tail -n 1` +fi +RO_MTD_NO=`echo $RO_MTD_LINE | cut -d: -f1 | cut -dd -f2` +RO_MTD=/dev/mtd$RO_MTD_NO +ROOTFS_SIZE=`echo $RO_MTD_LINE | cut -d" " -f2` + +LOGOCAL_MTD=/dev/mtd1 + +VERBLOCK=0x48000 +MVRBLOCK=0x70000 + +RESULT=0 + +Cleanup() +{ + rm -f $VTMPNAME > /dev/null 2>&1 + rm -f $MTMPNAME > /dev/null 2>&1 + exit $1 +} + +trap 'Cleanup 1' 1 15 +trap '' 2 3 + +get_dev_pcmcia() +{ + while read SOCKET CLASS DRIVER INSTANCE DEVS MAJOR MINOR; + do + echo $DEVS + done +} + +get_dev_pcmcia_slot() +{ + grep "^$1" /var/lib/pcmcia/stab | get_dev_pcmcia +} + +check_for_hdd() +{ + IDE1=`get_dev_pcmcia_slot 1` + if [ "$IDE1" = "" ]; then + echo "Error: There is no microdrive. Retrying..." + while [ "$IDE1" = "" ]; do + IDE1=`get_dev_pcmcia_slot 1` + done + echo "Microdrive found." + fi + + LINUXFMT=ext3 + MKE2FSOPT=-j +} + +check_for_tar() +{ + ### Check that we have a valid tar + for TARNAME in gnu-tar GNU-TAR + do + if [ -e $DATAPATH/$TARNAME ] + then + TARBIN=$DATAPATH/$TARNAME + fi + done + + if [ ! -e $TARBIN ]; then + echo 'Error: Please place a valid copy of tar as "gnu-tar" on your card.' + echo 'Please reset' + while true + do + done + fi +} + +do_rootfs_extraction() +{ + UNPACKED_ROOTFS=1 + echo 'Installing HDD root file system' + if [ ! -f /hdd1/NotAvailable ]; then + umount /hdd1 + fi + echo -n '* Now formatting...' + mke2fs $MKE2FSOPT /dev/${IDE1}1 > /dev/null 2>&1 + e2fsck -p /dev/${IDE1}1 > /dev/null + if [ "$?" != "0" ]; then + echo "FAILED" + echo "Error: Unable to create filesystem on microdrive!" + exit "$?" + else + echo "Done" + fi + + mount -t $LINUXFMT -o noatime /dev/${IDE1}1 /hdd1 + if [ "$?" != "0" ]; then + echo "Error: Unable to mount microdrive!" + exit "$?" + fi + + cd /hdd1 + echo -n '* Now extracting (this can take over 5m)...' + gzip -dc $DATAPATH/$TARGETFILE | $TARBIN xf - + if [ "$?" != "0" ]; then + echo "FAILED" + echo "Error: Unable to extract root filesystem archive!" + exit "$?" + else + echo "Done" + fi + + echo 'HDD Installation Finished.' + + # remount as RO + cd / + umount /hdd1 + mount -t $LINUXFMT -o ro,noatime /dev/${IDE1}1 /hdd1 +} + +do_flashing() +{ + if [ $DATASIZE -gt `printf "%d" $MTD_PART_SIZE` ] + then + echo "Error: File is too big to flash!" + echo "$FLASH_TYPE: [$DATASIZE] > [`printf "%d" ${MTD_PART_SIZE}`]" + return + fi + + if [ "$ZAURUS" = "tosa" ] || [ "$ZAURUS" = "poodle" ] + then + #check version + /sbin/bcut -s 6 -o $TMPDATA $TMPHEAD + + if [ `cat $TMPDATA` != "SHARP!" ] > /dev/null 2>&1 + then + #no version info... + rm -f $TMPHEAD > /dev/null 2>&1 + DATAPOS=0 + fi + fi + + if [ $ISFORMATTED = 0 ] + then + /sbin/eraseall $TARGET_MTD > /dev/null 2>&1 + ISFORMATTED=1 + fi + + if [ -e $TMPHEAD ] + then + VTMPNAME=$TMPPATH'/vtmp'`date '+%s'`'.tmp' + MTMPNAME=$TMPPATH'/mtmp'`date '+%s'`'.tmp' + /sbin/nandlogical $LOGOCAL_MTD READ $VERBLOCK 0x4000 $VTMPNAME > /dev/null 2>&1 + /sbin/nandlogical $LOGOCAL_MTD READ $MVRBLOCK 0x4000 $MTMPNAME > /dev/null 2>&1 + + /sbin/verchg -v $VTMPNAME $TMPHEAD $MODULEID $MTD_PART_SIZE > /dev/null 2>&1 + /sbin/verchg -m $MTMPNAME $TMPHEAD $MODULEID $MTD_PART_SIZE > /dev/null 2>&1 + fi + + # Looks like Akita and Spitz are unique when it comes to kernel flashing + + if [ "$ZAURUS" = "akita" -o "$ZAURUS" = "c3x00" ] && [ "$FLASH_TYPE" = "kernel" ] + then +# echo $TARGETFILE':'$DATASIZE'bytes' + echo "" + echo -n "Installing SL-Cxx00 kernel..." + echo ' ' > /tmp/data + test "$ZAURUS" = "akita" && /sbin/nandlogical $LOGOCAL_MTD WRITE 0x60100 16 /tmp/data > /dev/null 2>&1 + /sbin/nandlogical $LOGOCAL_MTD WRITE 0xe0000 $DATASIZE $TARGETFILE > /dev/null 2>&1 + test "$ZAURUS" = "akita" && /sbin/nandlogical $LOGOCAL_MTD WRITE 0x21bff0 16 /tmp/data > /dev/null 2>&1 + echo "Done" + else + + echo '' + echo '0% 100%' + PROGSTEP=`expr $DATASIZE / $ONESIZE + 1` + PROGSTEP=`expr 25 / $PROGSTEP` + + if [ $PROGSTEP = 0 ] + then + PROGSTEP=1 + fi + + #loop + while [ $DATAPOS -lt $DATASIZE ] + do + #data create + bcut -a $DATAPOS -s $ONESIZE -o $TMPDATA $TARGETFILE + TMPSIZE=`wc -c $TMPDATA` + TMPSIZE=`echo $TMPSIZE | cut -d' ' -f1` + DATAPOS=`expr $DATAPOS + $TMPSIZE` + + #handle data file + if [ $ISLOGICAL = 0 ] + then + next_addr=`/sbin/nandcp -a $ADDR $TMPDATA $TARGET_MTD 2>/dev/null | fgrep "mtd address" | cut -d- -f2 | cut -d\( -f1` + if [ "$next_addr" = "" ]; then + echo "Error: flash write" + rm $TMPDATA > /dev/null 2>&1 + RESULT=3 + break; + fi + ADDR=$next_addr + else + /sbin/nandlogical $LOGOCAL_MTD WRITE $ADDR $DATASIZE $TMPDATA > /dev/null 2>&1 + ADDR=`expr $ADDR + $TMPSIZE` + fi + + rm $TMPDATA > /dev/null 2>&1 + + #progress + SPNUM=0 + while [ $SPNUM -lt $PROGSTEP ] + do + echo -n '.' + SPNUM=`expr $SPNUM + 1` + done + done + fi + echo '' + + #finish + rm -f $TMPPATH/*.bin > /dev/null 2>&1 + + if [ $RESULT = 0 ] + then + if [ -e $VTMPNAME ] + then + /sbin/nandlogical $LOGOCAL_MTD WRITE $VERBLOCK 0x4000 $VTMPNAME > /dev/null 2>&1 + rm -f $VTMPNAME > /dev/null 2>&1 + fi + + if [ -e $MTMPNAME ] + then + /sbin/nandlogical $LOGOCAL_MTD WRITE $MVRBLOCK 0x4000 $MTMPNAME > /dev/null 2>&1 + rm -f $MTMPNAME > /dev/null 2>&1 + fi + + [ "$FLASH_TYPE" != "kernel" ] && echo 'Done.' + else + echo 'Error!' + fi +} + +update_uboot() { + # The flashing part of this function is based on pdaXrom's + # updater.sh + + if test "$ENABLE_UBOOT_UPDATER" != "yes" -o -z "$1" + then + echo "u-boot updates not allowed." + return + fi + + echo "" + echo "Installing u-boot bootloader:" + + DATASIZE=`wc -c $TARGETFILE` + FSIZE=`echo $DATASIZE | cut -d' ' -f1` + + echo -n "* Creating backup ($FSIZE Bytes)..." + if ( nandlogical /dev/mtd1 READ 0 $FSIZE /tmp/sharploader.bin ) > /dev/null 2>&1 + then + echo "Ok" + + echo -n "* Flashing u-boot..." + if ( nandlogical /dev/mtd1 WRITE 0 $FSIZE $1 ) > /dev/null 2>&1 + then + echo "Success" + else + echo "FAILED" + echo "ERROR: Installation of u-boot failed!" + + echo -n "* Trying to restore backup..." + if ( nandlogical /dev/mtd1 WRITE 0 $FSIZE /tmp/sharploader.bin ) > /dev/null 2>&1 + then + echo "Success" + echo "Your old bootloader has been restored" + else + echo "FAILED" + echo "Sorry, it's NAND-Restore time for you =(" + fi + fi + else + echo "FAILED" + echo "Could not create backup, aborting!" + echo "Your bootloader has not been altered in any way." + exit 1 + fi +} + +### Check model ### +/sbin/writerominfo +MODEL=`cat /proc/deviceinfo/product` +case "$MODEL" in + SL-B500|SL-5600) + ZAURUS='poodle' + ;; + SL-6000) + ZAURUS='tosa' + ;; + SL-C1000) + ZAURUS='akita' + ;; + SL-C700|SL-C750|SL-7500|SL-C760|SL-C860) + ZAURUS='c7x0' + ;; + SL-C3000|SL-C3100|SL-C3200) + ZAURUS='c3x00' + check_for_hdd + check_for_tar + ;; + *) + echo 'MODEL: '$MODEL 'is unsupported' + echo '' + echo 'Please reset' + while true + do + done + ;; +esac + +clear +echo "---- Universal Zaurus Updater ZAURUS_UPDATER_VERSION ----" +echo 'MODEL: '$MODEL' ('$ZAURUS')' + +mkdir -p $TMPPATH > /dev/null 2>&1 + +cd $DATAPATH/ + +for TARGETFILE in u-boot.bin U-BOOT.BIN zimage zImage zImage.bin zimage.bin ZIMAGE ZIMAGE.BIN initrd.bin INITRD.BIN hdimage1.tgz HDIMAGE1.TGZ +do + if [ ! -e $TARGETFILE ] + then + continue + fi + + rm -f $TMPPATH/*.bin > /dev/null 2>&1 + DATASIZE=`wc -c $TARGETFILE` + DATASIZE=`echo $DATASIZE | cut -d' ' -f1` + + # make TARGETFILE lowercase + TARGETFILE_LC=`echo $TARGETFILE|tr A-Z a-z` + + case "$TARGETFILE_LC" in + + zimage|zimage.bin) + if [ $FLASHED_KERNEL != 0 ] + then + continue + fi + FLASHED_KERNEL=1 + ISLOGICAL=1 + MODULEID=5 + MTD_PART_SIZE=0x13C000 + ADDR=`dc 0xE0000` + ISFORMATTED=1 + DATAPOS=0 + ONESIZE=524288 + HDTOP=`expr $DATASIZE - 16` + /sbin/bcut -a $HDTOP -s 16 -o $TMPHEAD $TARGETFILE + FLASH_TYPE="kernel" + do_flashing + FLASH_TYPE="" + ;; + + initrd.bin) + if [ $FLASHED_ROOTFS != 0 ] + then + continue + fi + echo 'root file system' + FLASHED_ROOTFS=1 + ISLOGICAL=0 + MODULEID=6 + MTD_PART_SIZE="0x$ROOTFS_SIZE" + ADDR=0 + ISFORMATTED=0 + TARGET_MTD=$RO_MTD + DATAPOS=16 + ONESIZE=1048576 + /sbin/bcut -s 16 -o $TMPHEAD $TARGETFILE + FLASH_TYPE="rootfs" + do_flashing + FLASH_TYPE="" + ;; + + hdimage1.tgz) + if [ $UNPACKED_ROOTFS = 0 ] + then + do_rootfs_extraction + fi + ;; + + u-boot.bin) + if [ FLASHED_UBOOT != 1 ] + then + update_uboot "$TARGETFILE" + FLASHED_UBOOT="1" + fi + ;; + + *) + ;; + esac +done + +# reboot +exit 0 + +# bcut usage: bcut [OPTION] <input file> + +# -a: start position +# -s: cut size +# -o: output file + +# ModuleId informations used by verchg Sharp binary: +# +# 0 - master +# 1 - Maintaince +# 2 - Diagnostics +# 3 - rescue kernel +# 4 - rescue rootfs +# 5 - normal kernel +# 6 - normal rootfs +# 7 - /home/ +# 8 - parameter (whatever it means) +# |