Sunday, August 01, 2010

FreeBSD on the SheevaPlug HOWTO

Six months ago I purchaged a SheevaPlug computer. After sharing my experiences about the device with my friend Minas, he managed to get his hands on the similar Sheeva computer and he installed FreeBSD on it. The following article/HOWTO, on installing FreeBSD on the Sheeva is written by him. Minas is a FreeBSD advocate for many years now.

Recently my friend Jim, bought the plugcomputer Sheeva eSata, which is just like the SheevaPlug but with an eSata II port. My friend asked me to change the factory installed
operating system Ubuntu, with FreeBSD. In my opinion FreeBSD is better suited for 24h/365d servers. The installation process took me almost 3 days and had some difficult parts I needed to overcome. I will share this process here with other FreeBSD supporters. Following these steps you will have a running FreeBSD in less than a few hours.

At first, my friend and I, contacted our seller, requesting support for installing FreeBSD on the plug, but they responded that they could not offer such an option. However, they provided some URLs and instructions of how to do it. Unfortunately, not all the required information was found in a single page, but this hopefully will change with this article.

The Sheeva FreeBSD HOWTO:

  • A Running FreeBSD PC
  • eSata SheevaPlug
  • eSata external disk that supports USB also
  • Basic knowledge of FreeBSD (read at least 1 time the FreeBSD handbook)

There are 6 steps in my HOWTO. Do the 6 steps and you will 100% succeed.

1) Setting Up Console
The only way to change crucial parameters (specifically boot-up, firmware update)
is by connecting through a serial port emulator, using the USB cable provided by the company.

If you have a Windows PC then you just install the driver that is provided, you attach the cable to the plug and the computer, you open a terminal application and you see the login prompt. Of course Sheeva should be already powered on.

If you have successfully connected to the serial console of Sheeva go to step 2. If you were unable to connect to serial console of Sheeva, or want to use a FreeBSD machine to connect to Sheeva then continue.

In order to communicate with Sheeva using the tools of FreeBSD (I will name the FreeBSB box 'TerminalFreeBSD'), load the appropriate kernel modules. As root issue:

kldload ucom
kldload uftdi

ucom is required for USB tty support and uftdi is required for USB support for the serial adapter of SheevaPlug.

Attach the provided USB cable to the mini USB on the SheevaPlug and on a USB port on the computer which will be used as terminal (FreeBSD or windows).

After attaching this on the TerminalFreeBSD, you will see in the console messages such as:

ugen1.2: <FTDI> at usbus1
uftdi0: <SheevaPlug JTAGKey FT2232D B> on usbus1
uftdi1: <SheevaPlug JTAGKey FT2232D B> on usbus

and you will notice in the /dev directory the automatic creation of some special character devices that have a capital 'U' in the name (denoting USB). Verify this as:

ls -l /dev/*U*

and you will see entries like the following:

crw-rw---- 1 uucp dialer 0, 80 Jul 28 12:25 /dev/cuaU0
crw-rw---- 1 uucp dialer 0, 81 Jul 28 12:25 /dev/cuaU0.init
crw-rw---- 1 uucp dialer 0, 82 Jul 28 12:25 /dev/cuaU0.lock
crw-rw---- 1 uucp dialer 0, 95 Jul 28 12:48 /dev/cuaU1
crw-rw---- 1 uucp dialer 0, 96 Jul 28 12:25 /dev/cuaU1.init
crw-rw---- 1 uucp dialer 0, 97 Jul 28 12:25 /dev/cuaU1.lock
crw------- 1 root wheel 0, 77 Jul 28 12:25 /dev/ttyU0
crw------- 1 root wheel 0, 78 Jul 28 12:25 /dev/ttyU0.init
crw------- 1 root wheel 0, 79 Jul 28 12:25 /dev/ttyU0.lock
crw------- 1 root wheel 0, 83 Jul 28 12:25 /dev/ttyU1
crw------- 1 root wheel 0, 84 Jul 28 12:25 /dev/ttyU1.init
crw------- 1 root wheel 0, 90 Jul 28 12:25 /dev/ttyU1.lock

Lets connect from the TerminalFreeBSD to the console of Sheeva. You have to use the 'cu' with appropriate parameters. After trial and error, I found that you have to use speed 115200 (otherwise it will show garbage or it wont work). In my example
I have two outgoing serial interfaces cuaU0 and cuaU1. In order to find out which one is attached to USB, I tried with cuaU0 but even though it said 'connected' pressing the enter did not reveal a 'login:' prompt. Using cuaU1 I worked. So in
my case in order to connect through terminal I issued:

cu -s 115200 -l /dev/cuaU1

If you give this command and after pressing enter nothing happens, press the
escape sequence by is issuing the following 3: (1) enter (2) ~ (3) ctrl+d
and you will escape to login prompt. Try next cuaU* port until you find the one working.

Remember: If you have windows as a terminal pc you dont need the above sequence. You
just install the drivers, plug the cable and you are ok.

2) Enabling the eSata drive

eSata Sheeva has a USB port and a eSata port. FreeBSD has to be installed on an
external storage, because it does not provide NAND support until this point.
You can install FreeBSD on USB or in eSata disk, but note the following:

  1. If you install on USB you will have a hard time to make it work, because during the kernel load, USB is detected after root mount, which means that you won't be able to mount the root partition/label unless using some special patches, which they have serious problems (they dont apply cleanly to stable version, because they target a specific version like 8.0). So DO NOT use USB.
  2. If you install on eSata this is the best. eSata is detected very early as an /dev/ad* disk, so you won't have any problem. Trust me. Go with the eSata and the procedure will be very easy.
From now on, I will assume that you continue with eSata.

Plug the eSata on the powered-off SheevaPlug, and power it on. In the Terminal console, you will see some boot up messages, and a prompt to press enter if you want to interrupt the boot loader. Press enter as soon as you see this prompt, to go to boot loader.

Issue the command:

ide reset

if you hard disk gets detected you are lucky to have the updated u-boot loader version. Skip to part 3.

If you see a message that reports nothing detected, then you have to go to step 2b to update the U-boot firmware. Dont worry is very easy.

2b) Updating the boot loader of eSata Sheeva in case your eSata disk is not detected

In order to update the U-boot firmware you will need a USB flash drive, that is FAT formatted.

Download from: the version that has eSata in the title. I download the file uboot-sata-090903.bin and also the md5 signature of this.

If you like, verify that the download is ok, by calculating the md5 of the file uboot-sata-090903.bin (issue: 'md5 uboot-sata-090903.bin') and compare it with the contents of the file: uboot-sata-090903.bin.md5

Place the file uboot-sata-090903.bin on the USB Flash drive and plug it on Sheeva.

In order to perform the update you have to (a) enable the USB (b) load the image (c) erase NAND memory (d) write u-boot image to NAND memory (e) reset the Sheeva. These 5 items are performed with the following commands, respectively:

usb start
fatload usb 0:1 0x0800000 uboot-sata-090903.bin
nand erase 0x0 0xa0000
nand write 0x0800000 0x0 0xa0000

ide reset

If you see your hard disk now (as in my case) you can continue to step 3. Otherwise check that your eSata has power, or it is working or perform again the update of sata u-boot with another version (if exist).

3) Partition (fdisk) & Labeling (bsdlabel) eSata hard disk

A common practice in installing FreeBSD is to have separate partitions of major areas of disk. Some people like to have one big flat partition, but I disagree with this. So in this step, we will partition the disk.

Plug the eSata disk on the FreeBSD in the USB port. USB port is hot plug and play, but eSata is not. eSata should be connected with PC powered-off.

After attaching the USB external disk you should see messages that da* disk was detected. If not, you should load kernel modules that support this

kldload usb
kldload umass

You should partition your disk using 'sysinstall'. Go to 'Configure', Then select 'fdisk' then select the da* disk.

In the fdisk screen you should create 2 partitions: One partition 20MB for FAT (for loading kernel) and leave the rest for freeBSD.
Save (write) and exit to command prompt.

You should label your FreeBSD slice as follows (this is not required but is very helpful to have different parts of the disk for different directories). Use 'sysinstall'. Go to 'Configure', Then select 'label' then select the da* disk.

The slices that you will create will be mounted temporary on the /mnt subdirectory. This will be done just for the installation.

Create the following slices:
  1. a label 512MB, without softupdates, mounted on /mnt
  2. a label 1G, for swap
  3. a label 512MB, mounted on /mnt/var
  4. a label 15GB, mounted on /mnt/usr

You can create a label for /mnt/home (as I did for home folders) and a label for /mnt/store (for the rest of the disk)

On a piece of paper write down all the label letters and the folders. In my case I had
  • slice: 2 label: d (root)
  • slice: 2 label: b (swap)
  • slice: 2 label: e (usr)
  • slice: 2 label: f (var)
  • slice: 2 label: g (home)
  • slice: 2 label: h (store)
Save(write) and exit to command prompt.

4) cross-building FreeBSD world and kernel for Sheeva

The following steps will be done on the TerminalFreeBSD.

Update your /usr/src to the latest version of FreeBSD. In my case I selected 8-STABLE.

Build world for Sheeva as follows:

cd /usr/src
make -j 8 buildworld TARGET_ARCH=arm

(remember if you have trouble compiling buildworld try to remove the '-j 8')

Build kernel for Sheeva as follows:
Create a kernel file named MYSHEEVA and place it on /usr/src/sys/arm/conf/

I optimized my Sheeva Kernel by removing lines that I did not need. I included support for 'ad', and specified the root device (ROOTDEVNAME=). I had to specify the ROOTDEVNAME because, by default FreeBSD kernel mounts the 'a' label of the currently slice. Unfortunately, I had created thelabel for root partition to be 'd' (*I tried with bsdlabel to change it but I had the error "GEOM Class not supported"),thus I had to hardcode in the FreeBSD the root device name.

NOTE: If your root device label is different than mine (mine was: d), then change appropriate the label ROOTDEVNAME=...

This is my MYSHEEVA:

------CUT HERE-----
include "../mv/kirkwood/std.sheevaplug"
options SCHED_4BSD #4BSD scheduler
options INET #InterNETworking
options FFS #Berkeley Fast Filesystem
device md
device ata
device atadisk # ATA disk drives
options ATA_STATIC_ID # Static device numbering
# Root fs on device
options ROOTDEVNAME=\"ufs:/dev/ad2s2d\"

options SYSVSHM #SYSV-style shared memory
options SYSVMSG #SYSV-style message queues
options SYSVSEM #SYSV-style semaphores
options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions

# Pseudo devices
device random
device pty
device loop

# Serial ports
device uart

# Networking
device ether
device mge # Marvell Gigabit Ethernet controller
device mii
device e1000phy
device bpf
options HZ=1000
device vlan
options USB_DEBUG # enable debug msgs
device usb
device ehci
device umass
device scbus
device pass
device da
------CUT HERE-----

Build kernel of MYSHEEVA as follows

cd /usr/src

5) Installing the world and kernel of Sheeva.

You have completed succesfully the cross-compilation of world+kernel. The next step is to install them. You have already mounted the slice and labels of the external disk to /mnt. Verify this by using


Issue the following commands to install the world.

make DESTDIR=/mnt TARGET=arm TARGET_ARCH=arm distrib-dirs
make DESTDIR=/mnt TARGET=arm TARGET_ARCH=arm distribution
make DESTDIR=/mnt TARGET=arm TARGET_ARCH=arm installworld

Create a basic fstab file on /mnt/etc and put the following (which you will have to change them accordingly to your case):

/dev/ad2s2d / ufs rw,noclusterr,noclusterw 0 0
/dev/ad2s2b none swap sw 0 0
/dev/ad2s2e /usr ufs rw,noclusterr,noclusterw 1 1
/dev/ad2s2f /var ufs rw,noclusterr,noclusterw 2 2
/dev/ad2s2g /home ufs rw,noclusterr,noclusterw 2 2
/dev/ad2s2h /store ufs rw,noclusterr,noclusterw 2 2

Note that our disk on SheevaPLUG will be on eSata so we have to use ad as the device name. You may have to change the number after 'ad', in case that your disk gets detected at other channel, as it will be shown. In my case, it was ad2.

Note also, that you have to issue the parameters 'noclusterr,noclusterw' in mount options, otherwise you will have corruption on file systems (as I find out after some hours of strange problems).

Edit /mnt/etc/ttys

and go to line that starts with


After the word vt100 there is a word 'off' or 'on'. Change this to 'on' because we would like to have a console on serial port. Also the other lines before this should have 'off' because there are no ttyv? devices.

The first lines of my file are:

console none unknown off secure
ttyv0 "/usr/libexec/getty Pc" cons25 off secure
# Virtual terminals
ttyv1 "/usr/libexec/getty Pc" cons25 off secure
ttyv2 "/usr/libexec/getty Pc" cons25 off secure
ttyv3 "/usr/libexec/getty Pc" cons25 off secure
ttyv4 "/usr/libexec/getty Pc" cons25 off secure
ttyv5 "/usr/libexec/getty Pc" cons25 off secure
ttyv6 "/usr/libexec/getty Pc" cons25 off secure
ttyv7 "/usr/libexec/getty Pc" cons25 off secure
#ttyv8 "/usr/local/bin/xdm -nodaemon" xterm off secure
# Serial terminals
# The 'dialup' keyword identifies dialin lines to login, fingerd etc.
ttyu0 "/usr/libexec/getty std.9600" vt100 on secure

At this point it will be very nice to update your /usr/ports tree and then copy to Sheeva.

cp -R /usr/ports /mnt/usr

In order to have the latest /usr/ports which is needed in order to install programs. Remember, that there are no pre-build packages for arm architecture, and thus you cannot do a 'pkg_add -r'. You have to build all packages by your own.

The installation is now complete, you have to umount the filesystems
of the external disk. In my case was:

umount /mnt/usr
umount /mnt/var
umount /mnt

The last step is to put the kernel file on the slice 1.

First you have to newfs as FAT partition the slice 1. Do this as:

newfs_msdos /dev/da0s1

(remember that if your USB disk is attached to other /dev/da? change the number accordingly).

Mount the slice as msdos

mount -t msdosfs /dev/da0s1 /mnt

and copy the kernel to fat partition.

cp /usr/obj/arm/usr/src/sys/MYSHEEVA/kernel.bin /mnt
umount /mnt

6) Connecting eSata on Sheeva and first boot of FreeBSD

umount all the da* partitions of /mnt and verify that there are no da* mounted by:


Connect the disk to the powered-off eSata.
Connect to the TerminalFreeBSD using the procedure highlighted in previous
step with 'cu'.

Power-on the Sheeva.
Interrupt the u-boot by pressing enter.

First take note of your existing uboot bootcmd environment variable using and placing it somewhere safe:

printenv bootcmd

The default should be something like:

bootcmd=nand read.e 0x800000 0x100000 0x400000; bootm 0x800000

Then in the loader issue the following to (a) change boot sequence, (b) save this so from now on you will be loading the kernel from the external device (c) boot the device

setenv bootcmd 'ide reset;fatload ide 1:1 900000 kernel.bin;go 900000'

NOTE: If you have an error on boot, like the image not found, check that you have copied the kernel.bin on the fat partition. Also you may change the 1:1 line to 0:0, 0:1, 1:0 , 1:1 . One of these combinations will surely work. This depends to what channel the hard disk is detected. Mine was on 1:1, and this was found as: ad2.

After issuing boot, then you see the kernel loading. You will see the line

ad? XXXX

If you see a line starting ad2:

ad2: 305245MB at ata1-master UDMA100 SATA 3Gb/s)

then you are ok for fstab, otherwise note the number of ad? and you have to put the drive back to the TerminalFreeBSD and mount the USB slice 2, label of rootpartition (you did not it previously) and change the /mnt/etc/fstab from ad2
to ad? with ? the number that is detected by the Sheeva. Also, you have to rebuild a kernel by changing the ROOTDEVNAME= to the new ad? number.

Congratulations. You should now have an up and running FreeBSD Sheeva!

Some workarounds are mentioned here for problems that I've encountered:

==workaround 1==
If you have not copied /usr/ports from your freebsd machine, you can do a 'portsnap fetch' which will fetch an updated /usr/ports.

Unfortunately, I found out the hard way that portsnap has a bug (not documented) that does not fetch an updated /usr/ports/Mk but an outdated (or buggy one).

This results in many errors when building ports like 'duplicate script' and other makefile options. In order to alleviate this problem, you should grab the /usr/ports/Mk from your updated TerminalFreeBSD, rm -rf your SheevaPlug /usr/ports/Mk and place it there. All the Makefile problems are now solved. If you had copied all the /usr/ports as I had suggested earlier then you are OK.

==workaround 2==
If you install some ports, that use the 'xz' compression, you will notice some core dumps. It seems that 'xz' compression that is included by default in 8 world is broken on ARM architecture. The workaround is to compile it from ports.

You can go to /usr/ports/archivers/xz but you cannot just do a 'make', because it will say that 'xz' is already in the base system'. So you have to do a simple trick. open the Makefile on this directory and before the end comment (put a '#') in front of the check of the operating system.

My lines are now:

#.if ${OSVERSION} >= 900012 || (${OSVERSION} <>= 800505)
#IGNORE= is already in the base system

Then do a

mv /usr/bin/xz /usr/bin/xz-2


cd /usr/ports/archivers/xz ; make ; make install

and xz now works flawlessly!

Additional Info:
The following URLs helped out, but most of the work was trial and error because a comprehensive how-to guide as this one was not found.


Tuesday, June 29, 2010

Wireless connection affected by neighbor

Something strange happed this evening. The wireless connection at home had such a bad signal quality that none of my devices could connect to the router.

At first, I did a router reset. Didn't help. Then I tried to reconnect the cables on the router, just in case. No success here also. Finally, I disabled all of the electronics around the router to make sure it wasn't an interference issue. This failed to solve the problem as well.

As I was troubleshooting the problem, I noticed a new wireless network scanned by laptop I had never seen before. It was broadcasting in the same channel with me (channel 11), and I was getting it with a signal quality comparable to that of mine. This seemed strange. Also the quality of my signal was fluctuating from medium to poor.

I looked it up online, and found that is possible for wireless networks to interfere with each other. I followed the suggestion in the article and changed my channel from automatic (resolved to 11 by the router) to 1. This did the job!

My router is Thomson tg585 v7.

Commands I used:
# sudo iwlist eth1 scan

Update 13 Nov 2010:
The same problem struck again. This time, I found it more convenient to do the scanning by using the "Wifi Analyzer" application, running on my Android Phone.

Thursday, April 29, 2010

Η εμπειρία μου με το Android. Ελλάδα, Ιούνιος 2009 - Απρίλιος 2010

Τον Ιούνιο του περασμένου χρόνου απέκτησα ένα HTC Magic 32A κινητό από την Cosmote. Μέχρι και σήμερα, είναι το πιο διαδεδομένο Android κινητό που πωλείται στην Ελλάδα από τις εταιρίες κινητής τηλεφωνίας. Στον τομέα της υποστήριξής του όμως αναγνωρίζω προβλήματα, κατά τη γνώμη μου σημαντικά, για την διάδοση της συγκεκριμένης πλατφόρμας στην Ελλάδα.

Το συγκεκριμένο τηλέφωνο το αγόρασα με Android v1.5 χωρίς Sense UI. Η έκδοση 1.5 ήταν περίπου ένα μήνα στην αγορά [1] και το Sense αναμενόταν. Το μοντέλο Magic το επέλεγαν τότε σαν τηλέφωνο κυρίως ενθουσιώδεις νέοι που ήθελαν να δουν, να πειραματιστούν, ακόμα και να δουλέψουν πάνω στην πλατφόρμα Android. Αμφίβολη επιλογή για το ευρύ κοινό, αφού επίσημα δεν υποστηρίζονταν τα ελληνικά.

Όλοι όμως αυτοί οι κάτοχοι των Magics περιμέναν 3 πράγματα:
i) την ελληνική ROM, που είχε ανακοινωθεί για τέλος Αυγούστου [2]
ii) το Sense UI, στο οποίο η HTC δίνει μεγάλο βάρος και πιστεύω δικαιολογημένα
iii) την αναβάθμιση σε Android v1.6, όταν την έδινε η Google.

Τον Οκτώβριο του 2009 δόθηκε το Android v1.6 [3] στην Ελλάδα ακόμα περιμέναμε το i) και το ii).

Τον Νοέμβριο του 2009 δόθηκε το Android 2.0 [4] και τον Ιανουάριο του 2010 το Android 2.1 [5]. Για την Ελλάδα δόθηκε επίσημη ROM v1.5 με Sense UI στις 28 Ιανουαρίου [6]. Όχι όμως σαν 'Over the air Update', πρακτική που είχε ακολουθηθεί σε αγορές άλλων χωρών.

Μέχρι όμως να δοθεί επίσημη updated v1.5 ROM με Sense, κυκλοφορούσαν "custom ROMs" για τη συσκευή που υποστήριζαν και ελληνικά και v1.6. Τα forums σφίζαν από συζητήσεις πια είναι η καλύτερη ανεπίσημη ROM και πως να την περάσει κανείς. Οι τολμηροί απολάμβαναν τα οφέλη. Η HTC Ελλάδας, όταν τους ρώτησα γιατί καθυστερεί η έκδοση αναβάθμισης της ROM, μου είπαν πως πρέπει να γίνουν δοκιμές για στην υποστήριξη των ελληνικών. Αυτό δικαιολογία μου φαινόταν εμένα, από την στιγμή που η συσκευή όταν είχε πρωτοκυκλοφορήσει δεν είχε καν ελληνικό πληκτρολόγιο.

Σήμερα πάλι, η HTC δηλώνει, αλλά δεν υπόσχεται, πως μπορεί να δοθεί Android v2.1 ROM για Magic. Θα την αντέξουμε τέτοια αναβάθμιση;

Και αν αναρωτιέστε τι την θέλω την αναβάθμιση, εν μέρη οι λόγοι δίνονται στα Release notes των εκδόσεων του Android. Συνοπτικά, δείτε στην wikipedia τον σχετικό πίνακα [6].

Η δυνατότητα αγοράς εφαρμογών από το Antroid Market είναι μια ακόμα έλλειψη της ελληνικής αγοράς, μετά την έλλειψη (over the air ή wired) αναβαθμίσεων. Αυτή τη στιγμή οι εταιρείες κινητής τηλεφωνίας δεν έχουν προβεί στις απαραίτητες διαδικασίες για να επιτραπεί κάτι τέτοιο. Έτσι είναι αδύνατο να αναπτυχθεί επιχειρηματικότητα στο πεδίο αυτό από τους Έλληνες προγραμματιστές. Επίσης, οι εταιρίες κινητής θα δικαιούνταν, αλλά σήμερα χάνουν, ποσοστά (30% νομίζω) από της αγορές εφαρμογών μέσω του Market. Και θα ήταν καλό να τα παίρναν. Θα όφειλαν τότε, κατά την γνώμη μου, να μειώσουν το κόστος απόκτησης και διατήρησης τέτοιων συσκευών από τους πελάτες τους.

Ελπίζω οι σκέψεις αυτές να φτάσουν στην HTC και να συμβάλουν στην βελτίωση της 'quietly brilliant' εμπειρίας στη χώρα μας. Επίσης, ελπίζω οι πρακτικές που περιέγραψα παραπάνω να μην ισχύσουν και για οι νέες συσκευές που έρχονται στην Ελλάδα. Έτσι, τα νέα Android τηλέφωνα θα έχουν καλύτερη τύχη και μαζί με αυτά ας το κάνουν και για τα παλιότερα, σαν το δικό μου.

Μιχάλης Γιαννακίδης

Sunday, February 14, 2010

Feeding images to a digital picture frame

My digital picture frame has a limited amount of build in memory. In order to put more pictures on the frame, I choose to resize them to the frame's native resolution of 800x480.

I' m pretty sure that there are applications that manage image collections on Linux and also do image resizing. However, I prefered to use ImageMagic and some scripting to do the job.

My script,, takes files from a source directory. These may be images and videos mixed together. Then it resizes JPEG files and copies all others (possibly videos) to the current directory. The target resolution for the images is hard coded to 800x480 in the script, but changing this is trivial.

Here is a usage example. We have the original folder as taken from the digital camera in 'camera' and a destination folder 'picture_frame' that will consist of the contents to place on the frame.

$ ls
camera/ picture_frame/
$ cd picture_frame
$ ../camera/*

... when done, you can browse through picture_frame to see the result.

# Written by Michalis Giannakidis - 2009 -
# Released in the public domain as is, without any warranties. Feb 2010

set resolution="800x400"

if ( $# == 0 ) then
echo "Convert images to $resolution and copy to current directory."
echo "usage: `basename $0` source_files"
echo "example: `basename $0` ../original/*"
echo "Current directory needs to be different than the source."

set counter = 0

foreach i ( $* )
set counter = `expr $counter + 1`

set bfile = `basename $i`
set bdest = `python -c 'import sys; print sys.argv[1].decode("utf-8").lower().encode("utf-8"),' $bfile`

if ( -f s_$bdest || -f $bfile || -f s_$bfile ) then
echo $counter/$# s_$bdest exists. I refuse to copy.

file $i |grep -q "JPEG image data"
if ( $status == 0 ) then
echo $counter/$# s_$bdest
convert $i -resize $resolution^ -gravity center -extent $resolution s_$bdest
echo $counter/$# $bdest copied.
cp -f $i $bdest