I 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:
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:
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.
0x10205
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:
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:
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:
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)):
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
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.
This looks like something from “Aliens” :
After I was pleased with it, I mounted it in place forever, by using some A+B epoxy:
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)
And the end product:
Now, when I want to remotely power up my computer, I just access my router, and hit the wake button:
And a video with the little beast:
And another one when the system was cross-compiling:
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!
I too would be interested in the specs of your computer!
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.
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…
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!
Wow that was unusual. I just wrote an extremely long comment but after I clicked
submit my comment didn’t show up. Grrrr… well I’m not writing all that over again. Anyways, just wanted
to say great blog!