diff options
-rwxr-xr-x | scripts/poky-qemu | 44 | ||||
-rwxr-xr-x | scripts/poky-qemu-internal | 253 | ||||
-rwxr-xr-x | scripts/runqemu-nfs | 103 |
3 files changed, 140 insertions, 260 deletions
diff --git a/scripts/poky-qemu b/scripts/poky-qemu index 6fe6f5e99..111aa15b7 100755 --- a/scripts/poky-qemu +++ b/scripts/poky-qemu @@ -20,40 +20,42 @@ if [ "x$1" = "x" ]; then MYNAME=`basename $0` - echo "Run as MACHINE=xyz $MYNAME ZIMAGE IMAGEFILE [OPTIONS]" + echo "Run as MACHINE=xyz $MYNAME KERNEL ROOTFS [OPTIONS]" echo "where:" - echo " ZIMAGE - the kernel image file to use" - echo " IMAGEFILE - the image file/location to use" - echo " (NFS booting assumed if IMAGEFILE not specified)" - echo " MACHINE=xyz - the machine name (optional, autodetected from ZIMAGE if unspecified)" + echo " KERNEL - the kernel image file to use" + echo " ROOTFS - the rootfs image file or nfsroot directory to use" +# echo " (NFS booting assumed if ROOTFS not specified)" + echo " MACHINE=xyz - the machine name (optional, autodetected from KERNEL filename if unspecified)" echo " OPTIONS - extra options to pass to QEMU" exit 1 else - ZIMAGE=$1 + KERNEL=$1 shift fi if [ "x$MACHINE" = "x" ]; then - MACHINE=`basename $ZIMAGE | sed -r -e 's#.*-([a-z]+[0-9]*)-?[0-9]*..*#\1#'` + MACHINE=`basename $KERNEL | sed -r -e 's#.*-([a-z]+[0-9\-]*)-?[0-9]*..*#\1#'` fi if [ "x$1" = "x" ]; then - TYPE="nfs" + FSTYPE="nfs" + echo "Error: NFS booting without an explicit ROOTFS path is not yet supported" + exit 1 else - TYPE="ext3" - if [ "$MACHINE" = "akita" ]; then - TYPE="jffs2" - fi - if [ "$MACHINE" = "spitz" ]; then - TYPE="ext3" - fi - if [ "$MACHINE" = "nokia800" ]; then - TYPE="jffs2" - fi - if [ "$MACHINE" = "nokia800-maemo" ]; then - TYPE="jffs2" + ROOTFS=$1 + + if [ -d "$1" ]; then + echo "$ROOTFS is a directory, assuming nfsroot" + FSTYPE="nfs" + else + FSTYPE="ext3" + EXT=${ROOTFS##.*} + if [[ "x$EXT" == "xext2" || "x$EXT" == "xext3" || + "x$EXT" == "xjffs2" ]]; then + FSTYPE=$EXT + fi + echo "Using $FSTYPE as filesytem type for $ROOTFS" fi - HDIMAGE=$1 shift fi diff --git a/scripts/poky-qemu-internal b/scripts/poky-qemu-internal index 30e90df0b..c65e0f1de 100755 --- a/scripts/poky-qemu-internal +++ b/scripts/poky-qemu-internal @@ -17,7 +17,6 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - # Call setting: # QEMU_MEMORY (optional) - set the amount of memory in the emualted system. # SERIAL_LOGFILE (optional) - log the serial port output to a file @@ -25,35 +24,37 @@ # # Image options: # MACHINE - the machine to run -# TYPE - the image type to run -# ZIMAGE - the kernel image file to use -# HDIMAGE - the disk image file to use +# FSTYPE - the image type to run +# KERNEL - the kernel image file to use +# ROOTFS - the disk image file to use # if [ -z "$QEMU_MEMORY" ]; then - case "$MACHINE" in - "qemux86") - QEMU_MEMORY="128M" - ;; - "qemux86-64") - QEMU_MEMORY="128M" - ;; - "qemumips") - QEMU_MEMORY="128M" - ;; - "qemuppc") - QEMU_MEMORY="128M" - ;; - *) - QEMU_MEMORY="64M" - ;; - esac + case "$MACHINE" in + "qemux86") + QEMU_MEMORY="128M" + ;; + "qemux86-64") + QEMU_MEMORY="128M" + ;; + "qemumips") + QEMU_MEMORY="128M" + ;; + "qemuppc") + QEMU_MEMORY="128M" + ;; + *) + QEMU_MEMORY="64M" + ;; + esac fi QEMUIFUP=`which poky-qemu-ifup` QEMUIFDOWN=`which poky-qemu-ifdown` +NFSRUNNING="false" + LOCKDIR="/tmp/qemu-tap-locks" [ ! -d "$LOCKDIR" ] && mkdir $LOCKDIR @@ -63,8 +64,8 @@ LOCKFILE="" for tap in $POSSIBLE; do LOCKFILE="$LOCKDIR/$tap" if lockfile -2 -r 1 $LOCKFILE; then - TAP=$tap - break; + TAP=$tap + break; fi done @@ -79,8 +80,7 @@ if [ "$TAP" = "" ]; then fi LOCKFILE="$LOCKDIR/$tap" if lockfile $LOCKFILE; then - TAP=$tap - break; + TAP=$tap fi else echo "Using preconfigured tap device '$TAP'" @@ -93,6 +93,12 @@ release_lock() { echo "Releasing lockfile of preconfigured tap device '$TAP'" rm -f $LOCKFILE fi + + if [ "$NFSRUNNING" = "true" ]; then + echo "Shutting down the userspace NFS server:" + echo "poky-export-rootfs stop $ROOTFS" + poky-export-rootfs stop $ROOTFS + fi } n1=$[ (`echo $TAP | sed 's/tap//'` * 2) + 1 ] @@ -110,44 +116,62 @@ if [ "x$SERIAL_LOGFILE" != "x" ]; then fi case "$MACHINE" in - "qemuarm") ;; - "qemumips") ;; - "qemuppc") ;; - "qemuarmv6") ;; - "qemuarmv7") ;; - "qemux86") ;; - "qemux86-64") ;; - "akita") ;; - "spitz") ;; - "nokia800") ;; - "nokia800-maemo") ;; - *) - echo "Error: Unsupported machine type $MACHINE" - return - ;; + "qemuarm") ;; + "qemumips") ;; + "qemuppc") ;; + "qemuarmv6") ;; + "qemuarmv7") ;; + "qemux86") ;; + "qemux86-64") ;; + "akita") ;; + "spitz") ;; + *) + echo "Error: Unsupported machine type $MACHINE" + return + ;; esac -if [ "$TYPE" != "nfs" -a ! -f "$HDIMAGE" ]; then - echo "Error: Image file $HDIMAGE doesn't exist" +if [ ! -f "$KERNEL" ]; then + echo "Error: Kernel image file $KERNEL doesn't exist" release_lock return fi -if [ "$TYPE" = "nfs" ]; then +if [ "$FSTYPE" != "nfs" -a ! -f "$ROOTFS" ]; then + echo "Error: Image file $ROOTFS doesn't exist" + release_lock + return +fi + +if [ "$FSTYPE" = "nfs" ]; then NFS_SERVER="192.168.7.1" - NFS_DIR=`echo $HDIMAGE | sed 's/^[^:]*:\(.*\)/\1/'` + NFS_DIR=`echo $ROOTFS | sed 's/^[^:]*:\(.*\)/\1/'` UNFS_OPTS="nfsvers=2,mountprog=21111,nfsprog=11111,udp" + + PSEUDO_LOCALSTATEDIR=~/.poky-sdk/pseudo + export PSEUDO_LOCALSTATEDIR + + rpcbind_running=`ps ax | grep rpcbind | grep -v grep | wc -l` + portmap_running=`ps ax | grep portmap | grep -v grep | wc -l` + if [[ $rpcbind_running == 0 && $portmap_running == 0 ]]; then + echo "You need to be running either rpcbind or portmap to continue" + release_lock + return + fi + + # Start the userspace NFS server + echo "poky-export-rootfs restart $ROOTFS" + poky-export-rootfs restart $ROOTFS + if [ $? != 0 ]; then + release_lock + return + fi + NFSRUNNING="true" fi if [ "$NFS_SERVER" = "" ]; then NFS_SERVER="192.168.7.1" - NFS_DIR=$HDIMAGE -fi - -if [ ! -f "$ZIMAGE" ]; then - echo "Error: Kernel image file $ZIMAGE doesn't exist" - release_lock - return + NFS_DIR=$ROOTFS fi if [ "$MACHINE" = "qemuarm" -o "$MACHINE" = "qemuarmv6" -o "$MACHINE" = "qemuarmv7" ]; then @@ -162,37 +186,37 @@ if [ "$MACHINE" = "qemuarm" -o "$MACHINE" = "qemuarmv6" -o "$MACHINE" = "qemuarm MACHINE_SUBTYPE=versatilepb QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS" # QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS -force-pointer" - if [ "$TYPE" = "ext3" ]; then + if [ "$FSTYPE" = "ext3" ]; then KERNCMDLINE="root=/dev/sda console=ttyAMA0,115200 console=tty $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY highres=off" - QEMUOPTIONS="$QEMU_NETWORK_CMD -M versatilepb -hda $HDIMAGE -no-reboot $QEMU_UI_OPTIONS" + QEMUOPTIONS="$QEMU_NETWORK_CMD -M versatilepb -hda $ROOTFS -no-reboot $QEMU_UI_OPTIONS" fi - if [ "$TYPE" = "nfs" ]; then + if [ "$FSTYPE" = "nfs" ]; then if [ "$NFS_SERVER" = "192.168.7.1" -a ! -d "$NFS_DIR" ]; then - echo "Error: NFS mount point $HDIMAGE doesn't exist" + echo "Error: NFS mount point $ROOTFS doesn't exist" release_lock return fi KERNCMDLINE="root=/dev/nfs nfsroot=$NFS_SERVER:$NFS_DIR,$UNFS_OPTS rw $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY" QEMUOPTIONS="$QEMU_NETWORK_CMD -M versatilepb --no-reboot $QEMU_UI_OPTIONS" fi - if [ "$MACHINE" = "qemuarmv6" ]; then - QEMUOPTIONS="$QEMUOPTIONS -cpu arm1136" - fi - if [ "$MACHINE" = "qemuarmv7" ]; then - QEMUOPTIONS="$QEMUOPTIONS -cpu cortex-a8" - fi + if [ "$MACHINE" = "qemuarmv6" ]; then + QEMUOPTIONS="$QEMUOPTIONS -cpu arm1136" + fi + if [ "$MACHINE" = "qemuarmv7" ]; then + QEMUOPTIONS="$QEMUOPTIONS -cpu cortex-a8" + fi fi if [ "$MACHINE" = "qemux86" ]; then QEMU=qemu QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS -vga vmware -enable-gl" - if [ "$TYPE" = "ext3" ]; then + if [ "$FSTYPE" = "ext3" ]; then KERNCMDLINE="vga=0 root=/dev/hda mem=$QEMU_MEMORY $KERNEL_NETWORK_CMD" - QEMUOPTIONS="$QEMU_NETWORK_CMD -hda $HDIMAGE $QEMU_UI_OPTIONS" + QEMUOPTIONS="$QEMU_NETWORK_CMD -hda $ROOTFS $QEMU_UI_OPTIONS" fi - if [ "$TYPE" = "nfs" ]; then + if [ "$FSTYPE" = "nfs" ]; then if [ "$NFS_SERVER" = "192.168.7.1" -a ! -d "$NFS_DIR" ]; then - echo "Error: NFS mount point $HDIMAGE doesn't exist." + echo "Error: NFS mount point $ROOTFS doesn't exist." release_lock return fi @@ -204,16 +228,16 @@ fi if [ "$MACHINE" = "qemux86-64" ]; then QEMU=qemu-system-x86_64 QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS -vga vmware -enable-gl" - if [ "$TYPE" = "ext3" ]; then + if [ "$FSTYPE" = "ext3" ]; then KERNCMDLINE="vga=0 root=/dev/hda mem=$QEMU_MEMORY $KERNEL_NETWORK_CMD" - QEMUOPTIONS="$QEMU_NETWORK_CMD -hda $HDIMAGE $QEMU_UI_OPTIONS" + QEMUOPTIONS="$QEMU_NETWORK_CMD -hda $ROOTFS $QEMU_UI_OPTIONS" fi - if [ "$TYPE" = "nfs" ]; then - if [ "x$HDIMAGE" = "x" ]; then - HDIMAGE=/srv/nfs/qemux86-64 + if [ "$FSTYPE" = "nfs" ]; then + if [ "x$ROOTFS" = "x" ]; then + ROOTFS=/srv/nfs/qemux86-64 fi - if [ ! -d "$HDIMAGE" ]; then - echo "Error: NFS mount point $HDIMAGE doesn't exist." + if [ ! -d "$ROOTFS" ]; then + echo "Error: NFS mount point $ROOTFS doesn't exist." release_lock return fi @@ -224,15 +248,15 @@ fi if [ "$MACHINE" = "spitz" ]; then QEMU=qemu-system-arm - if [ "$TYPE" = "ext3" ]; then - echo $HDIMAGE - HDIMAGE=`readlink -f $HDIMAGE` - echo $HDIMAGE - if [ ! -e "$HDIMAGE.qemudisk" ]; then + if [ "$FSTYPE" = "ext3" ]; then + echo $ROOTFS + ROOTFS=`readlink -f $ROOTFS` + echo $ROOTFS + if [ ! -e "$ROOTFS.qemudisk" ]; then echo "Adding a partition table to the ext3 image for use by QEMU, please wait..." - poky-addptable2image $HDIMAGE $HDIMAGE.qemudisk + poky-addptable2image $ROOTFS $ROOTFS.qemudisk fi - QEMUOPTIONS="$QEMU_NETWORK_CMD -M spitz -hda $HDIMAGE.qemudisk -portrait" + QEMUOPTIONS="$QEMU_NETWORK_CMD -M spitz -hda $ROOTFS.qemudisk -portrait" fi fi @@ -243,11 +267,11 @@ if [ "$MACHINE" = "qemumips" ]; then if [ "$TYPE" = "ext3" ]; then #KERNCMDLINE="root=/dev/hda console=ttyS0 console=tty0 $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY" KERNCMDLINE="root=/dev/hda console=ttyS0 console=tty $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY" - QEMUOPTIONS="$QEMU_NETWORK_CMD -M $MACHINE_SUBTYPE -hda $HDIMAGE -no-reboot $QEMU_UI_OPTIONS" + QEMUOPTIONS="$QEMU_NETWORK_CMD -M $MACHINE_SUBTYPE -hda $ROOTFS -no-reboot $QEMU_UI_OPTIONS" fi - if [ "$TYPE" = "nfs" ]; then + if [ "$FSTYPE" = "nfs" ]; then if [ "$NFS_SERVER" = "192.168.7.1" -a ! -d "$NFS_DIR" ]; then - echo "Error: NFS mount point $HDIMAGE doesn't exist" + echo "Error: NFS mount point $ROOTFS doesn't exist" release_lock return fi @@ -262,13 +286,13 @@ if [ "$MACHINE" = "qemuppc" ]; then CPU_SUBTYPE=603e BIOS=powerpc_rom.bin QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS -nographic" - if [ "$TYPE" = "ext3" ]; then + if [ "$FSTYPE" = "ext3" ]; then KERNCMDLINE="root=/dev/hda console=ttyS0 console=tty0 $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY" - QEMUOPTIONS="$QEMU_NETWORK_CMD -cpu $CPU_SUBTYPE -M $MACHINE_SUBTYPE -bios $BIOS -hda $HDIMAGE -no-reboot $QEMU_UI_OPTIONS" + QEMUOPTIONS="$QEMU_NETWORK_CMD -cpu $CPU_SUBTYPE -M $MACHINE_SUBTYPE -bios $BIOS -hda $ROOTFS -no-reboot $QEMU_UI_OPTIONS" fi - if [ "$TYPE" = "nfs" ]; then + if [ "$FSTYPE" = "nfs" ]; then if [ "$NFS_SERVER" = "192.168.7.1" -a ! -d "$NFS_DIR" ]; then - echo "Error: NFS mount point $HDIMAGE doesn't exist" + echo "Error: NFS mount point $ROOTFS doesn't exist" release_lock return fi @@ -279,56 +303,13 @@ fi if [ "$MACHINE" = "akita" ]; then QEMU=qemu-system-arm - if [ "$TYPE" = "jffs2" ]; then - HDIMAGE=`readlink -f $HDIMAGE` - if [ ! -e "$HDIMAGE.qemuflash" ]; then + if [ "$FSTYPE" = "jffs2" ]; then + ROOTFS=`readlink -f $ROOTFS` + if [ ! -e "$ROOTFS.qemuflash" ]; then echo "Converting raw image into flash image format for use by QEMU, please wait..." - raw2flash.akita < $HDIMAGE > $HDIMAGE.qemuflash - fi - QEMUOPTIONS="$QEMU_NETWORK_CMD -M akita -mtdblock $HDIMAGE.qemuflash -portrait" - fi -fi - -if [ "$MACHINE" = "nokia800" ]; then - QEMU=qemu-system-arm - if [ "$TYPE" = "jffs2" ]; then - HDIMAGE=`readlink -f $HDIMAGE` - if [ ! -e "$HDIMAGE.qemuflash" ]; then - echo "'Flashing' rootfs, please wait..." - poky-nokia800-flashutil $HDIMAGE $HDIMAGE.qemuflash - fi - KERNCMDLINE="root=/dev/mtdblock4 rootfstype=jffs2" - QEMU_NETWORK_CMD="-net nic,model=usb,vlan=0 $QEMU_TAP_CMD" - QEMUOPTIONS="$QEMU_NETWORK_CMD -M n800 -mtdblock $HDIMAGE.qemuflash -serial vc -m 130 -serial vc -serial vc -serial vc -usb -usbdevice net:0" - fi -fi - -if [ "$MACHINE" = "nokia800-maemo" ]; then - QEMU=qemu-system-arm - if [ "$TYPE" = "jffs2" ]; then - HDIMAGE=`readlink -f $HDIMAGE` - if [ ! -e "$HDIMAGE.qemuflash" ]; then - if [ ! -e "$HDIMAGE.initfs" ]; then - echo "Error, $HDIMAGE.initfs must exist!" - release_lock - return - fi - if [ ! -e "$HDIMAGE.config" ]; then - echo "Error, $HDIMAGE.config must exist!" - echo "To generate it, take an n800 and cat /dev/mtdblock1 > $HDIMAGE.config" - release_lock - return - fi - echo "'Flashing' config partition, please wait..." - poky-nokia800-flashutil $HDIMAGE.config $HDIMAGE.qemuflash config - echo "'Flashing' initfs, please wait..." - poky-nokia800-flashutil $HDIMAGE.initfs $HDIMAGE.qemuflash initfs - echo "'Flashing' rootfs, please wait..." - poky-nokia800-flashutil $HDIMAGE $HDIMAGE.qemuflash + raw2flash.akita < $ROOTFS > $ROOTFS.qemuflash fi - KERNCMDLINE="" - QEMU_NETWORK_CMD="-net nic,model=usb,vlan=0 $QEMU_TAP_CMD" - QEMUOPTIONS="$QEMU_NETWORK_CMD -M n800 -mtdblock $HDIMAGE.qemuflash -serial vc -m 130 -serial vc -serial vc -serial vc -usb -usbdevice net:0 -show-cursor" + QEMUOPTIONS="$QEMU_NETWORK_CMD -M akita -mtdblock $ROOTFS.qemuflash -portrait" fi fi @@ -384,8 +365,8 @@ else fi echo "Running $QEMU..." -echo $QEMUBIN -kernel $ZIMAGE $QEMUOPTIONS $SERIALOPTS $* --append '"'$KERNCMDLINE'"' -$QEMUBIN -kernel $ZIMAGE $QEMUOPTIONS $SERIALOPTS $* --append "$KERNCMDLINE" || /bin/true +echo $QEMUBIN -kernel $KERNEL $QEMUOPTIONS $SERIALOPTS $* --append '"'$KERNCMDLINE'"' +$QEMUBIN -kernel $KERNEL $QEMUOPTIONS $SERIALOPTS $* --append "$KERNCMDLINE" || /bin/true release_lock diff --git a/scripts/runqemu-nfs b/scripts/runqemu-nfs deleted file mode 100755 index 19943a764..000000000 --- a/scripts/runqemu-nfs +++ /dev/null @@ -1,103 +0,0 @@ -#!/bin/bash - -# Copyright (c) 2010 Intel Corp. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -function usage() { - echo "Usage: $0 {machine-type} <kernel> <rootfs-dir>" - echo "Where <rootfs-dir> is a rootfs directory that was created using the poky-extract-sdk utility" - echo "machine-type is optional if the kernel file is named according to Poky conventions" -} - -if [[ $# -lt 2 || $# -gt 3 ]]; then - usage - exit 1 -fi - -if [ $# -eq 3 ]; then - QEMUARCH=$1 - ZIMAGE=$2 - SDK_ROOTFS_DIR=$(cd "$3" && pwd) -else - ZIMAGE=$1 - SDK_ROOTFS_DIR=$(cd "$2" && pwd) - - QEMUARCH=`basename $ZIMAGE | sed -r -e 's#.*-([a-z]+[0-9]*)-?[0-9]*..*#\1#'` - if [ -z "$QEMUARCH" ]; then - echo "Error: Unable to determine machinetype from filename '$ZIMAGE'" - usage - exit 1 - fi -fi - -if [ ! -e "$ZIMAGE" ]; then - echo "Error: kernel file '$ZIMAGE' does not exist" - usage - exit 1 -fi - -QEMU_INTERNAL_SCRIPT=`which poky-qemu-internal` -if [ -z "$QEMU_INTERNAL_SCRIPT" ]; then - echo "Error: Unable to find the poky-qemu-internal script" - exit 1 -fi - -SYSROOT_SETUP_SCRIPT=`which poky-find-native-sysroot` -if [ -z "$SYSROOT_SETUP_SCRIPT" ]; then - echo "Error: Unable to find the poky-find-native-sysroot script" - echo "Did you forget to source your Poky environment script?" - exit 1 -fi -. $SYSROOT_SETUP_SCRIPT - -PSEUDO_LOCALSTATEDIR=~/.poky-sdk/pseudo -export PSEUDO_LOCALSTATEDIR - -RPC=`which rpcbind` -if [ "x$RPC" = "x" ]; then - RPC=`which portmap` - if [ "x$RPC" = "x" ]; then - echo "You need rpcbind or portmap installed and running to run the" - echo "userspace NFS server." - exit 1 - fi -fi - -rpcbind_running=`ps ax | grep rpcbind | wc -l` -portmap_running=`ps ax | grep portbind | wc -l` -if [ rpcbind_running == 1 -a portmap_running == 1 ]; then - echo "You need to be running either rpcbind or portmap to continue" - exit 1 -fi - -# Start the userspace NFS server -echo "poky-export-rootfs restart $SDK_ROOTFS_DIR" -poky-export-rootfs restart $SDK_ROOTFS_DIR -if [ $? != 0 ]; then - exit 1 -fi - -# Run QEMU -MACHINE=$QEMUARCH -TYPE="nfs" -HDIMAGE=$SDK_ROOTFS_DIR -CROSSPATH=$POKY_NATIVE_SYSROOT/usr/bin -. $QEMU_INTERNAL_SCRIPT - -# Cleanup -echo "poky-export-rootfs stop $SDK_ROOTFS_DIR" -poky-export-rootfs stop $SDK_ROOTFS_DIR - -exit 0 |