Sitara AM335X – computer case mod and WOL

20140307_231303-200x200I have a computer at home that I mostly use for compiling, cuda processing etc. ( dual quad-core Xeon CPUs, ECC RAM).  I don’t want to keep it always on since it will accumulate dust, make noise etc. I thought .. well.. I’ll just use WOL to wake it up when I’m not at home, just use a smartphone/pc/laptop to connect to my router and send the magic packet. Although in the motherboard manualit shows that  there is an option in BIOS for enabling WOL, mine had no such option. The motherboard also had a dedicated WOL header present but that wasn’t working, probably because there is no option in BIOS to enable WOL functionality . Next step was to hook somethig between the router and the “target computer”. Sure, I could crack open the router  and use some GPIO to do this, but I had just bought the Asus RT-AC66U router and didn’t feel like tearing it apart. I could use some MCU board with ethernet but didn’t had one available,  I could hook up some MCU to the USB port of the router .. but I was too lazy for that. Just quickly looking at what I had available, and I found it:

http://processors.wiki.ti.com/index.php/AM335x_Starter_Kit

I had a Sitara AM335x starter kit, for which I had virtually no use at the time. The board has one AM3359 ARM Cortex-A8 CPU which can scale up to 720MHz, 256MB of RAM, dual gigabit ethernet, integrated WiFi and Bluetooth, micro-sd connector, one USB host port (which on this target died after a short period of time), some GPIOs (the ones used for the LEDs and on-board buttons),  it can run Linux. Some pictures with the kit:20131202_220026

20131202_220039

20131202_220119

Wouldn’t it be a shame to just hide the board inside the computer, when it could display some useful info on that LCD? I booted the Linux image that came with the board, behold the Matrix App. Launcher:

20131202_220304

The Matrix App Launcher is a nice piece of software, however I won’t use it. It works directly on top of the framebuffer, no X is involved, and I wanted X so I could run more xterms on the display. Sure, you can write some fancy application in QT to display goodies on the screen, but I wanted a quick way to do it, and some xterms + ssh sessions + some scripts will do the job fine. Now for the fun part. If you want to reproduce this, keep reading on, if not there are some pictures and a video at the end of the post.

I had no free space on the hard drive of my laptop, so I used a 32GB USB stick for this, which is mounted under /media/simi/dan, EXT4 formatted.

cd /media/simi/dan
wget http://software-dl.ti.com/sitara_linux/esd/AM335xSDK/06_00_00_00/exports//ti-sdk-am335x-evm-06.00.00.00-Linux-x86-Install.bin
chmod 755 ti-sdk-am335x-evm-06.00.00.00-Linux-x86-Install.bin
./ti-sdk-am335x-evm-06.00.00.00-Linux-x86-Install.bin

The setup will start, select yes, next, next, browse,  use /media/simi/dan/SDK, next, next, uncheck “install code composer”, next, next. After the setup finishes:

cd SDK/linux-devkit
chmod 755 environment-setup
. ./environment-setup
export ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
cd ../board-support/linux-3.2.0-psp04.06.00.11
make am335x_evm_defconfig
make -j8 uImage modules
mkdir -p /media/simi/dan/stuff
make modules_install INSTALL_MOD_PATH=/media/simi/dan/stuff/
cd ../../
./Graphics_SDK_setuplinux_4_09_00_01_hardfp_minimal_demos.bin

Another setup will start, yes, next, agree, next, browse, /media/simi/dan/GRSDK, next, check only “es8.x” and “sdk”. After it finishes:

cd ../GRSDK/
mcedit Rules.make

If you don’t like mcedit you can use whatever text editor you like.

Change the following:
HOME=$(SDK_INSTALL_DIR)/graphics
to
HOME=/media/simi/dan/GRSDK/

CSTOOL_DIR=$(LINUX_DEVKIT_PATH)
to
CSTOOL_DIR=/media/simi/dan/SDK/linux-devkit/

CSTOOL_PREFIX=`basename $CROSS_COMPILE`
to
CSTOOL_PREFIX=`basename arm-linux-gnueabihf-`

KERNEL_INSTALL_DIR=$(LINUXKERNEL_INSTALL_DIR)
to
KERNEL_INSTALL_DIR=/media/simi/dan/SDK/board-support/linux-3.2.0-psp04.06.00.11/

TARGETFS_INSTALL_DIR=$(DESTDIR)
to
TARGETFS_INSTALL_DIR=/media/simi/dan/stuff

GRAPHICS_INSTALL_DIR=$(HOME)/Graphics_SDK_4_09_00_01
to
GRAPHICS_INSTALL_DIR=$(HOME)/

Save and exit.

make BUILD=release OMAPES=8.x SUPPORT_XORG=1 all
mkdir -p /media/simi/dan/stuff/etc/init.d
mkdir -p /media/simi/dan/stuff/usr/local
make BUILD=release OMAPES=8.x SUPPORT_XORG=1 install
cd ../SDK/board-support/linux-3.2.0-psp04.06.00.11/
make clean
make -j8 uImage modules
make modules_install INSTALL_MOD_PATH=/media/simi/dan/stuff/
cd ../../../
mkdir rootfs
cd rootfs
sudo tar -zxvf ../SDK/filesystem/tisdk-rootfs-image-am335x-evm.tar.gz -C .
sudo cp -rf ../stuff/* .

Next the startx script is needed, I will comment on that later in this post.

wget http://hackingbeaver.com/startx
sudo mv startx bin/
sudo chmod 755 bin/startx

Next, download some armhf debs from the Ubuntu repository since we are lazy to cross-compile packages:

sudo wget http://launchpadlibrarian.net/117644730/xterm_278-1ubuntu2_armhf.deb
sudo  ar x xterm_278-1ubuntu2_armhf.deb
sudo tar -zxvf data.tar.gz -C .
sudo rm xterm_278-1ubuntu2_armhf.deb control.tar.gz data.tar.gz
sudo wget http://launchpadlibrarian.net/103690734/libxaw7_1.0.10-2_armhf.deb
sudo  ar x libxaw7_1.0.10-2_armhf.deb
sudo tar -zxvf data.tar.gz -C .
sudo rm libxaw7_1.0.10-2_armhf.deb control.tar.gz data.tar.gz
sudo  wget http://launchpadlibrarian.net/118450682/libutempter0_1.1.5-4build1_armhf.deb
sudo  ar x libutempter0_1.1.5-4build1_armhf.deb
sudo tar -zxvf data.tar.gz -C .
sudo rm libutempter0_1.1.5-4build1_armhf.deb control.tar.gz data.tar.gz
sudo wget http://launchpadlibrarian.net/108685163/libxft2_2.3.1-1_armhf.deb
sudo  ar x libxft2_2.3.1-1_armhf.deb
sudo tar -zxvf data.tar.gz -C .
sudo rm libxft2_2.3.1-1_armhf.deb control.tar.gz data.tar.gz
sudo mv usr/lib/arm-linux-gnueabihf/* usr/lib

Now get a 2GB micro-sd card, insert it in the host pc and format it like this:
1st partition, 100MB FAT32, marked as bootable, with label “boot”
2nd partition, the rest of available spakce, EXT3 formatted, with label “rootfs”

This can be done by using gparted, fdisk, etc. Just use the tool you like.

After the process is complete, mount the two partitions, in my case the mount points are /media/simi/boot and /media/simi/rootfs
Copy the generated rootfs on the sd card rootfs partition:

sudo cp -r /media/simi/dan/rootfs/* /media/simi/rootfs/

Copy the prebuild MLO and uboot on the first partition of the sd card (fat32, bootable):

sudo cp /media/simi/dan/SDK/board-support/prebuilt-images/MLO-am335x-evm /media/simi/boot/MLO
sudo cp /media/simi/dan/SDK/board-support/prebuilt-images/u-boot-am335x-evm.img /media/simi/boot/u-boot.img

After this, remove the sd card and place it in the Sitara EVB, connect a micro usb cable to the Sitara EVB and plug the other end in the host pc, connect an ethernet cable (from the router)  to the EVB (J7 connector) and press the power button.

At this stage you should see the board booting and a touch screen calibration application will start, touch the screen where indicated  preferably with a pointy object (as in not a finger, seriously, use a pen or something).

After this step is complete, the matrix gui will start, everything is ok until this step.

On the host PC, open up minicom , serial port /dev/ttyUSB1 (not 0) and 115200 8n1, no hardware flow control. Login with user root and password root. On the target (EVB) do :

ifconfig eth0 up &
udhcpc -i eth0

If everything is ok, it will exit with:

udhcpc (v1.20.2) started
Sending discover…
Sending discover…
Sending select for 192.168.1.85…
Lease of 192.168.1.85 obtained, lease time 86400

After this you can ssh into the EVB, open a terminal on the host PC, user is root, password is root:

ssh root@192.168.1.85

Leave this terminal alone for now.

Open another terminal and login to the “target target” computer, in my case the PC I use for builds.

ssh user@host

And add some users:

sudo adduser htop
sudo adduser df
sudo adduser tmpmon

Create the following scripts and put them on the “target computer” under /bin directory.

df-mon.sh

#!/bin/sh
watch -t -n1 df -h -x tmpfs

temp-mon.sh

#!/bin/bash
inc=0
sensors | grep "Core"| grep -o '+[0-9.]\+' | sed '1~3!d; s/+//' > /tmp/temperature

while read p; do
if [ $inc -eq 0 ]; then
CPU0=$p
fi
if [ $inc -eq 1 ]; then
CPU1=$p
fi
if [ $inc -eq 2 ]; then
CPU2=$p
fi
if [ $inc -eq 3 ]; then
CPU3=$p
fi
if [ $inc -eq 4 ]; then
CPU4=$p
fi
if [ $inc -eq 5 ]; then
CPU5=$p
fi
if [ $inc -eq 6 ]; then
CPU6=$p
fi
if [ $inc -eq 7 ]; then
CPU7=$p
fi
((inc++))
done < /tmp/temperature

echo " CPU0: +$CPU0"C"  CPU4: +$CPU4"C""
echo " CPU1: +$CPU1"C"  CPU5: +$CPU5"C""
echo " CPU2: +$CPU2"C"  CPU6: +$CPU6"C""
echo " CPU3: +$CPU3"C"  CPU7: +$CPU7"C""

temp-mon2.sh

#!/bin/bash

watch -t -n1 /bin/temp_mon.sh

inc=0
sensors | grep "Core"| grep -o '+[0-9.]\+' | sed '1~3!d; s/+//' > /tmp/temperature

while read p; do
if [ $inc -eq 0 ]; then
CPU0=$p
fi
if [ $inc -eq 1 ]; then
CPU1=$p
fi
if [ $inc -eq 2 ]; then
CPU2=$p
fi
if [ $inc -eq 3 ]; then
CPU3=$p
fi
if [ $inc -eq 4 ]; then
CPU4=$p
fi
if [ $inc -eq 5 ]; then
CPU5=$p
fi
if [ $inc -eq 6 ]; then
CPU6=$p
fi
if [ $inc -eq 7 ]; then
CPU7=$p
fi
((inc++))
done < /tmp/temperature

echo "CPU0: $CPU0  CPU4: $CPU4"
echo "CPU1: $CPU1  CPU5: $CPU5"
echo "CPU2: $CPU2  CPU6: $CPU6"
echo "CPU3: $CPU3  CPU7: $CPU7"

After creating the scripts, make them executable :

chmod 755 /bin/df-mon.sh
chmod 755 /bin/temp-mon.sh
chmod 755 /bin/temp-mon2.sh

Leave this console open, and go back to the console connected via ssh to the Sitara EVB and type :

startx

The startx doesn’t just start X, it does the initial one-time set-up and after that at each boot it will start everything that’s needed.

You will see this kind of output when running startx for the first time (ignore any errors/failues and messages to reboot, it will reboot itself):

First time setup
This will take a few minutes followed by a restart
Stopping Matrix GUI application.
0×10205
release8.x
installing 8.x SGX release user libraries

Installing PowerVR Consumer/Embedded DDK ‘sgxddk_1.9@2188537′ on target

File system installation root is /

Nothing to un-install.
boot script rc.pvr -> /etc/init.d/rc.pvr
kernel module drm.ko -> /lib/modules/3.2.0/extra/drm.ko
kernel module pvrsrvkm.ko -> /lib/modules/3.2.0/extra/pvrsrvkm.ko
shared library libGLES_CM.so -> /usr/lib/libGLES_CM.so.1.9.2188537
shared library libusc.so -> /usr/lib/libusc.so.1.9.2188537
shared library libGLESv2.so -> /usr/lib/libGLESv2.so.1.9.2188537
shared library libglslcompiler.so -> /usr/lib/libglslcompiler.so.1.9.2188537
shared library libIMGegl.so -> /usr/lib/libIMGegl.so.1.9.2188537
shared library libEGL.so -> /usr/lib/libEGL.so.1.9.2188537
shared library libpvr2d.so -> /usr/lib/libpvr2d.so.1.9.2188537
shared library libpvrPVR2D_BLITWSEGL.so -> /usr/lib/libpvrPVR2D_BLITWSEGL.so.1.9.2188537
shared library libpvrPVR2D_FLIPWSEGL.so -> /usr/lib/libpvrPVR2D_FLIPWSEGL.so.1.9.2188537
shared library libpvrPVR2D_FRONTWSEGL.so -> /usr/lib/libpvrPVR2D_FRONTWSEGL.so.1.9.2188537
shared library libpvrPVR2D_LINUXFBWSEGL.so -> /usr/lib/libpvrPVR2D_LINUXFBWSEGL.so.1.9.2188537
shared library libpvrPVR2D_DRIWSEGL.so -> /usr/lib/libpvrPVR2D_DRIWSEGL.so.1.9.2188537
shared library libsrv_um.so -> /usr/lib/libsrv_um.so.1.9.2188537
shared library libsrv_init.so -> /usr/lib/libsrv_init.so.1.9.2188537
shared library libPVRScopeServices.so -> /usr/lib/libPVRScopeServices.so.1.9.2188537
binary pvrsrvctl -> /usr/local/bin/pvrsrvctl
binary sgx_init_test -> /usr/local/bin/sgx_init_test
binary services_test -> /usr/local/bin/services_test
binary sgx_blit_test -> /usr/local/bin/sgx_blit_test
binary sgx_clipblit_test -> /usr/local/bin/sgx_clipblit_test
binary sgx_flip_test -> /usr/local/bin/sgx_flip_test
binary sgx_render_flip_test -> /usr/local/bin/sgx_render_flip_test
binary pvr2d_test -> /usr/local/bin/pvr2d_test
binary gles1test1 -> /usr/local/bin/gles1test1
binary gles2test1 -> /usr/local/bin/gles2test1
shader glsltest1_vertshader.txt -> /usr/local/bin/glsltest1_vertshader.txt
shader glsltest1_fragshaderA.txt -> /usr/local/bin/glsltest1_fragshaderA.txt
shader glsltest1_fragshaderB.txt -> /usr/local/bin/glsltest1_fragshaderB.txt
binary eglinfo -> /usr/local/bin/eglinfo
binary xeglinfo -> /usr/local/bin/xeglinfo
binary xgles1test1 -> /usr/local/bin/xgles1test1
binary xgles2test1 -> /usr/local/bin/xgles2test1
X.Org PVR DDX video module pvr_drv.so -> /usr/local/XSGX/lib/xorg/modules/drivers/pvr_drv.so
X.Org configuration file xorg.conf -> /usr/local/XSGX/etc/xorg.conf

Installation complete!
You may now reboot your target.

Loaded PowerVR consumer services.
_XSERVTransSocketOpenCOTSServer: Unable to open socket for inet6
_XSERVTransOpen: transport open failed for inet6/am335x-evm:0
_XSERVTransMakeAllCOTSServerListeners: failed to open listener for inet6

X.Org X Server 1.12.0
Release Date: 2012-03-04
X Protocol Version 11, Revision 0
Build Operating System: Linux 2.6.35-30-generic-pae i686
Current Operating System: Linux am335x-evm 3.2.0 #2 Wed Jan 8 18:00:21 EET 2014 armv7l
Kernel command line: console=ttyO0,115200n8 root=/dev/mmcblk0p2 ro rootfstype=ext3 rootwait ip=none
Build Date: 04 December 2012  07:46:23PM

Current version of pixman: 0.24.4
Before reporting problems, check http://wiki.x.org
to make sure that you have the latest version.
Markers: (–) probed, (**) from config file, (==) default setting,
(++) from command line, (!!) notice, (II) informational,
(WW) warning, (EE) error, (NI) not implemented, (??) unknown.
(==) Log file: “/usr/local/XSGX/var/log/Xorg.0.log”, Time: Tue Jun 25 23:21:46 2013
(++) Using config file: “/usr/local/XSGX/etc/xorg.conf”
(==) ServerLayout “Server Layout”
(**) |–>Screen “Screen” (0)
(**) |   |–>Monitor “<default monitor>”
(**) |   |–>Device “Video Device”
(==) No monitor specified for screen “Screen”.
Using a default monitor configuration.
(**) |–>Input Device “Keyboard”
(**) |–>Input Device “Main Touch Screen”
(==) Not automatically adding devices
(==) Not automatically enabling devices
(WW) The directory “/usr/local/XSGX/share/fonts/X11/TTF/” does not exist.
Entry deleted from font path.
(WW) The directory “/usr/local/XSGX/share/fonts/X11/OTF/” does not exist.
Entry deleted from font path.
(==) FontPath set to:
/usr/local/XSGX/share/fonts/X11/misc/,
/usr/local/XSGX/share/fonts/X11/Type1/,
/usr/local/XSGX/share/fonts/X11/100dpi/,
/usr/local/XSGX/share/fonts/X11/75dpi/
(==) ModulePath set to “/usr/local/XSGX/lib/xorg/modules”
(II) Loading /usr/local/XSGX/lib/xorg/modules/extensions/libextmod.so
(II) Module extmod: vendor=”X.Org Foundation”
compiled for 1.12.0, module version = 1.0.0
(II) Loading /usr/local/XSGX/lib/xorg/modules/extensions/libdbe.so
(II) Module dbe: vendor=”X.Org Foundation”
compiled for 1.12.0, module version = 1.0.0
(II) Loading /usr/local/XSGX/lib/xorg/modules/extensions/libglx.so
(II) Module glx: vendor=”X.Org Foundation”
compiled for 1.12.0, module version = 1.0.0
(==) AIGLX enabled
(II) Loading /usr/local/XSGX/lib/xorg/modules/extensions/librecord.so
(II) Module record: vendor=”X.Org Foundation”
compiled for 1.12.0, module version = 1.13.0
(II) Loading /usr/local/XSGX/lib/xorg/modules/extensions/libdri.so
(II) Module dri: vendor=”X.Org Foundation”
compiled for 1.12.0, module version = 1.0.0
(II) Loading /usr/local/XSGX/lib/xorg/modules/extensions/libdri2.so
(II) Module dri2: vendor=”X.Org Foundation”
compiled for 1.12.0, module version = 1.2.0
(II) Loading /usr/local/XSGX/lib/xorg/modules/drivers/pvr_drv.so
(II) Module PVR: vendor=”X.Org Foundation”
compiled for 1.12.0, module version = 109.218.8537
(II) Loading /usr/local/XSGX/lib/xorg/modules/input/evdev_drv.so
(II) Module evdev: vendor=”X.Org Foundation”
compiled for 1.12.0, module version = 2.6.0
(II) pvr: Driver for PowerVR chipsets: PowerVR SGX
(–) using VT number 2

(WW) xf86OpenConsole: setpgid failed: Operation not permitted
(WW) Falling back to old probe method for pvr
(EE) Couldn’t get PVR Services status
(EE) No devices detected.

Fatal server error:
no screens found

Please consult the The X.Org Foundation support
at http://wiki.x.org
for help.
Please also check the log file at “/usr/local/XSGX/var/log/Xorg.0.log” for additional information.

Server terminated with error (1). Closing log file.
Will output 1024 bit rsa secret key to ‘/home/root/.ssh/id_rsa’
Generating key, this may take a while…
Couldn’t create new file /home/root/.ssh/id_rsa
Reason: No such file or directory
Failed reading ‘/home/root/.ssh/id_rsa’

Host ’192.168.1.2′ is not in the trusted hosts file.
(fingerprint md5 bb:43:d2:5f:13:42:7e:e5:11:1a:09:54:21:14:b3:37)
Do you want to continue connecting? (y/n) y
htop@192.168.1.2′s password:
authorized_keys                               100%  229     0.2KB/s   00:00
df@192.168.1.2′s password:
authorized_keys                               100%  229     0.2KB/s   00:00
tmpmon@192.168.1.2′s password:
authorized_keys                               100%  229     0.2KB/s   00:00

192.168.1.2 is the IP address of the “target computer”.

At which point it will try to pair with the build pc so that it can automatically ssh, press “y” , enter and enter the password for the users created earlier.

After doing this for the three users created, the board will automatically reboot and the matrixgui will not start anymore, however X11 and some xterms with ssh to the “target computer” will start.

Now go back to the terminal connected to “target computer” and do:

sudo mcedit /etc/passwd

Modify the entries for the htop, df, tmpmon users, by replacing the /bin/bash with htop binary and our scripts:

htop:x:1001:1001:,,,:/home/htop:/usr/bin/htop
df:x:1002:1002:,,,:/home/df:/bin/df-mon.sh
tmpmon:x:1003:1003:,,,:/home/tmpmon:/bin/temp_mon2.sh

Save this file and reboot the Sitara EVB. And:

20140307_205411

There are three exterms, the one on top, full width – with htop, bottom left – disk usage, bottom right -  temperatures.

When the “target computer” is offline, it will display the following screen:

20140307_205815

And it will do the following:

- if the touchscreen is pressed, it will power-up the “target computer”, after the system is booted-up, it will connect to it and display htop, temperatures, disk usage.

- if the WOL packet is received, it will power-up the “target computer”, after the system is booted-up, it will connect to it and display htop, temperatures, disk usage.

- if the computer is powered-on externally (by using the button or self power-up in case of previous power failure), after the system is booted up, it will connect to it and display htop, temperatures, disk usage.

In the previous photos, the board is mounted inside the computer, and it is powered by the computer’s 5V stand-by supply, so even if the computer is off, it still has power. If there is a power-loss it will power itself up. I will cover that a bit later, for now the software.

As I mentioned earlier, on the AM335X board, the startx script does mostly everyting, let’s take a look at it:

#!/bin/sh

if [ ! -f /etc/setup_done ]; then
echo "First time setup"
echo "This will take a few minutes followed by a restart"
sleep 2
/etc/init.d/matrix-gui-2.0 stop
mv /etc/init.d/matrix-gui-2.0 /home/root/matrix-gui-2.0-bak

/etc/init.d/335x-demo
depmod -a
cp /usr/local/XSGX/lib/*so* /lib/
mv /usr/local/XSGX/etc/xorg.conf /usr/local/XSGX/etc/xorg.conf.old
cat > /usr/local/XSGX/etc/xorg.conf <<'DELIM'
# X.Org X server configuration file

Section "Device"
Identifier    "Video Device"
Driver         "pvr"
Option        "FlipChain"    "true"
Option        "NoAccel"    "false"
EndSection

Section "Monitor"
Identifier    "Main Screen"
EndSection

Section "InputDevice"
Identifier    "Main Touch Screen"
Driver        "evdev"
Option        "Device"    "/dev/input/event1"
Option         "InvertX" "true"
Option        "InvertY" "true"
EndSection

Section "Screen"
Identifier    "Screen"
Monitor        "Monitor"
Device        "Video Device"
EndSection

Section "ServerLayout"
Identifier    "Server Layout"
Screen        "Screen"
InputDevice    "Main Touch Screen"    "CorePointer"
Option          "BlankTime"     "0"
Option          "StandbyTime"   "0"
Option          "SuspendTime"   "0"
Option          "OffTime"       "0"
Option          "dpms" "false"

EndSection
DELIM

cat > /bin/xeon_power_udp_wol.sh <<'DELIM2'
#!/bin/sh

echo 2500 > /proc/sys/net/core/netdev_max_backlog
echo 2500 > /proc/sys/net/core/netdev_budget
rm /tmp/tcp_wol.fifo

mkfifo /tmp/tcp_wol.fifo
tcpdump -i eth1 2>&1 | tee > /tmp/tcp_wol.fifo &

while [ 1 -eq 1 ]; do

grep -m 1 "ffff ffff ffff 0030 4832 1d65 0030 4832" /tmp/tcp_wol.fifo

if [ $? -eq 0 ]; then
echo "timer" > /sys/class/leds/am335x:EVM_SK:usr0/trigger
sleep 1
echo "none" > /sys/class/leds/am335x:EVM_SK:usr0/trigger
echo "" > /tmp/tcp_wol
fi

#size=`cat /tmp/tcp_wol2 | wc -c`
#size_cap=909756
#if [ $size -gt $size_cap ]; then
#echo "" > /tmp/tcp_wol
#fi

sleep 1
done

DELIM2

cat > /bin/xeon_power_tsc.sh <<'DELIM3'
#!/bin/sh

mkfifo /tmp/tsc.fifo
evtest /dev/input/touchscreen0 2>&1 | tee > /tmp/tsc.fifo &

while [ 1 -eq 1 ]; do

grep -m 1 "code 24" /tmp/tsc.fifo

if [ $? -eq 0 ]; then
echo "timer" > /sys/class/leds/am335x:EVM_SK:usr0/trigger
sleep 1
echo "none" > /sys/class/leds/am335x:EVM_SK:usr0/trigger
fi
sleep 1
done

DELIM3

cat > /bin/startx_wrapper <<'DELIM4'
#!/bin/sh
/bin/startx &
disown
exit
DELIM4

chmod 777 /bin/xeon_power_udp_wol.sh
chmod 777 /bin/xeon_power_tsc.sh
chmod 777 /bin/startx_wrapper

ln -s /bin/startx_wrapper /etc/init.d/startx_wrapper
ln -s /etc/init.d/startx_wrapper /etc/rc5.d/S100startx_wrapper

touch /etc/setup_done
sync
dropbearkey -t rsa -f ~/.ssh/id_rsa
dropbearkey -y -f ~/.ssh/id_rsa | grep "^ssh-rsa " >> ~/.ssh/authorized_keys
scp ~/.ssh/authorized_keys htop@192.168.1.2:/home/htop/.ssh/authorized_keys
scp ~/.ssh/authorized_keys df@192.168.1.2:/home/df/.ssh/authorized_keys
scp ~/.ssh/authorized_keys tmpmon@192.168.1.2:/home/tmpmon/.ssh/authorized_keys
reboot && exit
fi

echo 2500 > /proc/sys/net/core/netdev_max_backlog
echo 2500 > /proc/sys/net/core/netdev_budget

#/etc/init.d/matrix-gui-2.0 stop
modprobe drm
modprobe pvrsrvkm
/usr/local/XSGX/bin/X -verbose -config /usr/local/XSGX/etc/xorg.conf &
ifconfig eth1 up
sleep 1
udhcpc -i eth1

/bin/xeon_power_udp_wol.sh &
/bin/xeon_power_tsc.sh &

export DISPLAY=:0

echo 275000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed

function start_stuff {
ping -w 1 192.168.1.2  >> /dev/null
RETVAL=$?
if [ ! $RETVAL -eq 0 ]; then
xterm  -geometry 80x12+0+0  -bg black -fg white -e htop&
xterm  -geometry 80x8+0-0  -bg black -fg white  -e "echo 'System offline. Press screen to power up' &&  ping 192.168.1.2"&
fi

while [ 1 -eq 1 ]; do
ping -w 1 192.168.1.2 >> /dev/null
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
killall xterm
xterm  -geometry 80x16+0+-12  -bg black -fg white -e "ssh htop@192.168.1.2 -i /home/root/.ssh/id_rsa -y" &
xterm  -geometry 48x5+0-0 -bg black -fg white -e "ssh df@192.168.1.2 -i /home/root/.ssh/id_rsa -y" &
xterm  -geometry 30x5-0-0 -bg black -fg white -e "ssh tmpmon@192.168.1.2 -i /home/root/.ssh/id_rsa -y" &
break
fi
done
}

start_stuff

while [ 1 -eq 1 ]; do
ping -w 1 192.168.1.2  >> /dev/null
RETVAL=$?
if [ ! $RETVAL -eq 0 ]; then
start_stuff
fi
done

#root@am335x-evm:/sys/class/leds/am335x:EVM_SK:usr0/trigger    timer

#tcpdump -vv
#02:28:12.873337 60:a4:4c:a0:87:e8 (oui Unknown) > 5c:26:0a:59:77:06 (oui Unknown), ethertype Unknown (0x0842), length 116:
#    0x0000:  ffff ffff ffff 5c26 0a59 7706 5c26 0a59  ......\&.Yw.\&.Y
#    0x0010:  7706 5c26 0a59 7706 5c26 0a59 7706 5c26  w.\&.Yw.\&.Yw.\&
#    0x0020:  0a59 7706 5c26 0a59 7706 5c26 0a59 7706  .Yw.\&.Yw.\&.Yw.
#    0x0030:  5c26 0a59 7706 5c26 0a59 7706 5c26 0a59  \&.Yw.\&.Yw.\&.Y
#    0x0040:  7706 5c26 0a59 7706 5c26 0a59 7706 5c26  w.\&.Yw.\&.Yw.\&
#    0x0050:  0a59 7706 5c26 0a59 7706 5c26 0a59 7706  .Yw.\&.Yw.\&.Yw.
#    0x0060:  5c26 0a59 7706                           \&.Yw.

#sudo tcpdump -vv | grep "0x0000:  ffff ffff ffff 5c26 0a59 7706 5c26 0a59"

# set LCD brightness
#echo 0-100 > /sys/devices/platform/pwm-backlight/backlight/pwm-backlight/brightness

The first part of the scripts is the setup, first it checkes if a setup_done is present, if not it sets everything up and creates the file, so that the next time the board boots it will skip this part.

In this first part /etc/init.d/335x-demo is started (from the GDK),  a xorg.conf file is created under /usr/local/XSGX/etc/xorg.conf , a couple of scripts are created, init script is created, and the pairing with the target computer is done. First, the scripts:

/bin/xeon_power_udp_wol.sh

#!/bin/sh

echo 2500 > /proc/sys/net/core/netdev_max_backlog
echo 2500 > /proc/sys/net/core/netdev_budget
rm /tmp/tcp_wol.fifo

mkfifo /tmp/tcp_wol.fifo
tcpdump -i eth1 2>&1 | tee > /tmp/tcp_wol.fifo &

while [ 1 -eq 1 ]; do

grep -m 1 "ffff ffff ffff 0030 4832 1d65 0030 4832" /tmp/tcp_wol.fifo

if [ $? -eq 0 ]; then
echo "timer" > /sys/class/leds/am335x:EVM_SK:usr0/trigger
sleep 1
echo "none" > /sys/class/leds/am335x:EVM_SK:usr0/trigger
echo "" > /tmp/tcp_wol
fi

#size=`cat /tmp/tcp_wol2 | wc -c`
#size_cap=909756
#if [ $size -gt $size_cap ]; then
#echo "" > /tmp/tcp_wol
#fi

sleep 1
done

In this script a fifo is created where the output of tcpdump is dumped.  For whatever reason tcpdum | grep was not working properly, and would have a “miss” rate of about 50%.  So tcpdump output is dumped in the fifo:

tcpdump -i eth1 2>&1 | tee > /tmp/tcp_wol.fifo &

and it’s grepped in a loop, when the magic packet (see http://en.wikipedia.org/wiki/Wake-on-LAN) is found , a led is triggered, thus powering-up the computer (with a driver and relay, will come back at this). grep -m 1 is the max count, after 1 match it exits.

while [ 1 -eq 1 ]; do

grep -m 1 "ffff ffff ffff 0030 4832 1d65 0030 4832" /tmp/tcp_wol.fifo

if [ $? -eq 0 ]; then
echo "timer" > /sys/class/leds/am335x:EVM_SK:usr0/trigger
sleep 1
echo "none" > /sys/class/leds/am335x:EVM_SK:usr0/trigger
echo "" > /tmp/tcp_wol
fi

#size=`cat /tmp/tcp_wol2 | wc -c`
#size_cap=909756
#if [ $size -gt $size_cap ]; then
#echo "" > /tmp/tcp_wol
#fi

sleep 1
done

/bin/xeon_power_tsc.sh

#!/bin/sh

mkfifo /tmp/tsc.fifo
evtest /dev/input/touchscreen0 2>&1 | tee > /tmp/tsc.fifo &

while [ 1 -eq 1 ]; do

grep -m 1 "code 24" /tmp/tsc.fifo

if [ $? -eq 0 ]; then
echo "timer" > /sys/class/leds/am335x:EVM_SK:usr0/trigger
sleep 1
echo "none" > /sys/class/leds/am335x:EVM_SK:usr0/trigger
fi
sleep 1
done

In this script, at any touchscreen event the led will be triggered the same as in the previous script, in the future I will parse the events so that just one section of the touchscreen will power up the system, and the rest can be used for other things, like controlling the backlight.

/bin/startx_wrapper

#!/bin/sh
/bin/startx &
disown
exit

Just a small wrapper over the main script, for init purposes.

The second part of the main script (startx)  loads the needed kernel modules (drm and pvrsrvkm), startx X server with the previous created xorg.conf file, brings up the ethernet interface (eth1) and runs a dhclient, executes the xeon_power_udp_wol.sh and xeon_power_tsc.sh scripts.

modprobe drm
modprobe pvrsrvkm
/usr/local/XSGX/bin/X -verbose -config /usr/local/XSGX/etc/xorg.conf &
ifconfig eth1 up
sleep 1
udhcpc -i eth1
/bin/xeon_power_udp_wol.sh &
/bin/xeon_power_tsc.sh &
export DISPLAY=:0

In the next step, the CPU is scaled down, no need to run it at 800MHz, 275MHz are more than enough:

echo 275000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed

Next, the “start_stuff” function:

function start_stuff {
ping -w 1 192.168.1.2  >> /dev/null
RETVAL=$?
if [ ! $RETVAL -eq 0 ]; then
xterm  -geometry 80x12+0+0  -bg black -fg white -e htop&
xterm  -geometry 80x8+0-0  -bg black -fg white  -e "echo 'System offline. Press screen to power up' &&  ping 192.168.1.2"&
fi

while [ 1 -eq 1 ]; do
ping -w 1 192.168.1.2 >> /dev/null
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
killall xterm
xterm  -geometry 80x16+0+-12  -bg black -fg white -e "ssh htop@192.168.1.2 -i /home/root/.ssh/id_rsa -y" &
xterm  -geometry 48x5+0-0 -bg black -fg white -e "ssh df@192.168.1.2 -i /home/root/.ssh/id_rsa -y" &
xterm  -geometry 30x5-0-0 -bg black -fg white -e "ssh tmpmon@192.168.1.2 -i /home/root/.ssh/id_rsa -y" &
break
fi
done
}

start_stuff

It pings the target computer, if it’s offline, it will start a local htop in the upper xterm, and in the lower xterm it will display a message (System offline. Press screen to power up).

If the target computer is online (it responds to ping),  it will kill all previous xterms and start three xterms in which it will ssh on the target computer, and it will look like this:

20140307_205411

Next, in the script, after the start_stuff function is called, there is a main loop in which the target computer is pinged, if it’s offline, the function is called again:

while [ 1 -eq 1 ]; do
ping -w 1 192.168.1.2  >> /dev/null
RETVAL=$?
if [ ! $RETVAL -eq 0 ]; then
start_stuff
fi
done

This pretty much covers the software part, the scripts that run on the target computer are not explained here, but they’re very simple, just cat, grep, and display some info.

Now for the hardware part.

To turn on the target computer I used a LED from the AM335X board, an inverter, uln2003 and a relay connected to the terminals of the computer’s power button.

For the self power-up, I wasn’t in the mood of investigating how the power IC was working. If the power button is pressed, after 3 seconds, the board will start, and a LED will be on. If the button is still pressed, the board will shut itself down. I used a relay with normal closed contacts, connected to the pins of the power button, so that when the main power is present, the board will start itself, after that the LED will be on. I connected an ULN2003 to the LED and it’s output to the relay coil. By doing this, when the board starts and the power LED is on, the relay will disconnect, thus not shutting down the board. Some pictures with the “masterpiece” ( I’m not proud of it, in my defense I  mention that when I was working on this, the  ethanol level in my blood  was quite elevated ) ((Sorry for the quality, pictures made with my blackberry)):

IMG-20131102-00060

IMG-20131102-00061

Although it looks bad.. it works like a charm.

The next part was “inserting” this thing in my computer. The case is a full tower, In Win Dragon Rider (I love this case). Link here : http://www.inwin-style.com/en/goods.php?act=view&id=Dragon%20Rider

139208548007VIM0

I hacked two bay covers to do this. The hard part is that the bay covers have three layers : metal grid, plastic, metal grid again. Those layers have quite a distance between, and also the whole thing is curved. This part took a couple of hours. Tools needed were dremel, pliers, cutter.

IMG-20131102-00056

IMG-20131102-00057

This looks like something from “Aliens” :

IMG-20131102-00058

IMG-20131102-00063

After I was pleased with it, I mounted it in place forever, by using some A+B epoxy:

IMG-20131102-00066

IMG-20131102-00070

And from the inside of the case (note that it is not glued to the case itself, this can be removed like a normal bay cover)

IMG-20131102-00072

IMG-20131102-00071

And the end product:

20140307_231255

20140307_231303

small_v

Now, when I want to remotely power up my computer, I just access my router, and hit the wake button:

Selection_001

And a video with the little beast:

And another one when the system was cross-compiling:

7 comments on “Sitara AM335X – computer case mod and WOL

  1. Michael May 20, 2014 6:25 am

    Great project! Care to share about how your computer came to be (specs etc.)? I built my desktop to similar ends, but it doesn’t have nearly the muscle yours has!

  2. tony May 20, 2014 11:48 am

    I too would be interested in the specs of your computer!

  3. Daniel May 20, 2014 12:09 pm

    It is an older system, dual Xeon E5450, each CPU has 4 cores@3GHz, 12MB cache, the motherboard is made by Supermicro, model X7DVA, 12GB of DDR2 ECC FB-DIMM, (5 were installed when making the videos), two GTX560TI OC or one GTX560 + one GTX650, a bunch of hard drives, 850W Corsair PSU, about 16 coolers. I think this is about it.

  4. molli123 May 26, 2014 10:23 am

    did you know there are Management Cards sold quite cheap on ebay called SIMLP-3 that can do complete monitoring, powering UP/Down via IPMI etc? But that would have been less than half the fun…

    • Daniel May 27, 2014 3:02 am

      I knew that the motherboard had a IPMI slot for stuff like this, but I never searched for a card. I needed a quick solution and this was what I had available at that moment. The bonus part is that this looks great :)
      Thanks for your message!

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>