ReferencePlatforms/Test/WindowsMobile

< ReferencePlatforms
Revision as of 13:36, 28 October 2009 by Jmaher (talk | contribs) (Created page with 'This document is designed to explain how to create the mozilla reference image for testing on maemo devices using a MiniSD card as the boot device. It will also describe how to i…')
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

This document is designed to explain how to create the mozilla reference image for testing on maemo devices using a MiniSD card as the boot device. It will also describe how to image this image to other N810 units for use in the production environment.

Reference Image

This section will explain the steps to go from a used N810 to a reference image. It will stop short of the actual imaging process but will set up the required tools to create the image.

Clear Device

If the device is working, open the App Menu (left side, 4 squares) -> Settings -> Control panel -> Menu (Bottom left of keyboard, below arrow pad) -> Tools -> Clear Device... -> OK -> Lock code is 12345. The device will restart. If the device is not working, flash the stock firmware and return to this step.

Flash Stock Firmware

To ensure you start from a clean slate, flash the stock Nokia firmware onto the device.

su -; ./flasher-3.0 --fiasco RX-44*.bin --flash

Initial Setup Wizard

Select English (USA) as the device language and click next. Set the correct time and date and click next. Set the device name to be 'maemo-n810-ref' and click next then finish. When the Phone Selection wizard starts click cancel. In the top right area of the screen there is a speaker icon. Click that and mute the sounds by clicking the picture of a speaker that open in that dialogue box.

Control Panel 1

Open the control panel again. Open Date and Time. Click 'Select home city' and set to Los Angeles, CA, USA. Correct the date and time as needed and click OK. Open Display and set "Display stays lit:" to "When charging".

In the connectivity section open 'Connectivity'. Click the connections button. When the wizard starts, click next. Name the connection "Mozilla-Build" and select "WLAN". It will ask to scan for networks, select no as the SSID is hidden. Type in the SSID (Mozilla-Build), network is hidden checked, mode infrastructure, security method should be set to 'WPA pre-shared key'. Click next. Type in the appropriate pre-shared key and click next. On the next screen click the advanced button and go to the Other tab. On this tab set WLAN Tx Power to 10mW and power saving to off. Click OK then click finish then click done then click ok.

Non-mozilla Software

Repositories

We need to have some software that does not come with the Nokia device. The easiest way to install the software is to install using Maemo extras. To enable the extras repository, select the App Menu -> settings -> Application Manager. Click the menu button -> Tools -> Application Catalog... To enable or disable a repository, select it and click edit. In the pop up either check or uncheck 'Disabled' as needed. The first time you run this, the extras repository may not be enabled. To set this up, open the browser and search for Maemo ssh. The first result should be for OpenSSH Client and Server on maemo.org. Open that page and click the large green arrow that has "Install" written on it. When there is a pop up for a file download, click open. The application manager will launch and begin to install OpenSSH. When asked for a root password provide the mobile password. Search for and install homeip. Search for and install "maemo nginx".

Click the menu button (bottom left on keyboard) and select "Select Applets". Uncheck all but homeip.

Moredimmingoptions

To install moredimmingoptions open the browser and search for moredimmingoptions maemo. The first result should be correct. On that page click the install arrow. Click open on the file download dialogue and ok on the install prompt. Open the display control panel and set the brightness period and switch off display time to 1440 minutes

Command Line Setup Steps

There are some command line applications which need to be installed

sudo gainroot # MUST BE IN RD MODE ./flasher-3.0 --enable-rd-mode
apt-get --force-yes -y install wget bzip2 gnutar x11vnc python2.5-dev hebrew libpcre3 libattr1 e2fsprogs ttf-droid ttf-dejavu 
wget http://repository.maemo.org/extras/pool/diablo/free/r/rsync/rsync_2.6.9-2_armel.deb
dpkg -i rsync_2.6.9-2_armel.deb
rm rsync_2.6.9-2_armel.deb
Correct nginx.conf
sed -e "s/application\/octet-stream/text\/plain/g" -i /etc/nginx/nginx.conf
Fix tar
rm /bin/tar
ln -s /bin/gtar /bin/tar
Set hostname
echo "maemo-n810-ref" > /etc/hostname
x11vnc setup

Set up the vnc password:

su user
x11vnc -storepasswd
# Enter your desired vnc password; save to /home/user/.vnc/passwd
exit

Create an /etc/init.d/x11vnc that looks like this:

#!/bin/sh
# built from /usr/bin/x11vnc.sh and /etc/init.d/ssh
#

test -x /usr/bin/x11vnc || exit 0

export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"

case "$1" in
  start)
        echo -n "Starting VNC server: x11vnc"
        start-stop-daemon --start --quiet --pidfile /var/run/x11vnc.pid -b -c user --exec /usr/bin/x11vnc -- -cursor arrow -usepw > /var/log/x11vnc.log 2>&1
        echo "."
        ;;
  stop)
        echo -n "Stopping VNC server: x11vnc"
        start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/x11vnc.pid
        echo "."
        ;;

  restart)
        echo -n "Restarting VNC server: x11vnc"
        start-stop-daemon --stop --quiet --oknodo --retry 30 --pidfile /var/run/x11vnc.pid
        start-stop-daemon --start --quiet --pidfile /var/run/x11vnc.pid -b -c user --exec /usr/bin/x11vnc -- -cursor arrow -usepw > /var/log/x11vnc.log 2>&1
        echo "."
        ;;

  *)
        echo "Usage: /etc/init.d/x11vnc {start|stop|restart}"
        exit 1
esac
 
exit 0

Then make it executable:

chmod a+x /etc/init.d/x11vnc

We're not currently running this at boot, but we can start it at any point to debug.

Install PyYAML
cd /tools
#wget http://pyyaml.org/download/pyyaml/PyYAML-3.05.tar.gz
wget http://people.mozilla.com/~asasaki/maemo/PyYAML-3.05.tar.gz
tar zxvf PyYAML-3.05.tar.gz
cd PyYAML-3.05
python setup.py install
cd ..
rm -rf PyYAML*
Install twisted
wget http://people.mozilla.com/~asasaki/maemo/twisted-maemo-2.4.0.tgz
mkdir /tools
cd /tools
tar jxf twisted-maemo-2.4.0.tgz
rm twisted-maemo-2.4.0.tgz
echo export PYTHONPATH="/tools/twisted/twisted-2.4.0/lib/python2.5/site-packages:/tools/twisted/twisted-core-2.4.0/lib/python2.5/site-packages:/tools/twisted/zope-interface-3.3.0/lib/python2.5/site-packages" >> .bashrc
Clone Buildbot

On a real computer:

hg clone http://hg.mozilla.org/build/buildbot

and scp that to device.

Install Buildbot

On N810

cd /builds/buildbot
python setup.py install
cd ..
rm -rf buildbot
Make Slave
cd /builds
mkdir buildbot
buildbot create-slave --umask=022 /builds/buildbot staging-mobile-master.mv.mozilla.com `cat /etc/hostname` PASSWORD
cd buildbot
rm info/host
ln -s /etc/hostname info/host
Create Swap Service

Because we are changing how swap gets created and turned on, we need a swap service

#!/bin/sh                                                                       
                                                                                
DEV=/dev/mmcblk1p2
OUTFILE=/builds/standalone.txt                                                             
                                                                                
case $1 in                                                                      
 start)                                                                         
  echo -n "start swap"                                                          
  swapon $DEV                                                                   
  if [ $? -ne 0 ] ; then                                                          
   echo "`date` - SWAPFAIL - swapon" >> $OUTFILE                                        
   exit 1                                                                       
  fi
  ;;                                                                            
 stop)                                                                          
  echo -n "stop swap"                                                           
  swapoff $DEV                                                                  
  if [ $? -ne 0 ] ; then                                                          
   echo "`date` - SWAPFAIL - swapoff" >> $OUTFILE         
   exit 1                                                                       
  fi
  ;;                                                                            
 restart)                                                                       
  echo -n "start swap"                                                          
  swapon $DEV                                                                   
  if [ $? -ne 0 ] ; then                                                          
   echo "`date` - SWAPFAIL - swapon" >> $OUTFILE             
  fi                                                                            
  echo -n "stop swap"                                                           
  swapon $DEV                                                                   
  if [ $? -ne 0 ] ; then                                                          
   echo "`date` - SWAPFAIL - swapoff" >> $OUTFILE
   exit 1                                                                       
  fi
  ;;                                                                            
esac 

And we need to turn it on

chmod +x /etc/init.d/swap
update-rc.d swap defaults
Set up buildbot to start on boot

Create an /etc/init.d/buildbot:

#!/usr/bin/env python
### BEGING CONFIG
slavedir = '/builds/buildbot'
standalone = '/builds/standalone.txt'
logFile = '/builds/logs/buildbot-daemon.log'
max_try = 600
delay = 3
### END CONFIG

import sys, os, time, logging, logging.handlers
import subprocess, socket
sys.path.append(slavedir)
import host

n810 = socket.gethostname() 
master = host.buildmaster_host
port = host.port

log = logging.getLogger(n810)
log.setLevel(logging.DEBUG)
fileHandler = logging.handlers.TimedRotatingFileHandler(
    logFile, when='midnight',)
fileFormatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
fileHandler.setFormatter(fileFormatter)
consoleHandler = logging.StreamHandler()
consoleFormatter = logging.Formatter("%(levelname)s - %(message)s")
consoleHandler.setFormatter(consoleFormatter)
#networkHandler = logging.handlers.SocketHandler('johnford.info',
#                         logging.handlers.DEFAULT_TCP_LOGGING_PORT)
#networkFormatter = logging.Formatter("%(asctime)s -%(name)s - %(levelname)s" +
#                                     " - $(message)s")
#networkHandler.setFormatter(networkFormatter)
log.addHandler(fileHandler)
log.addHandler(consoleHandler)
#log.addHandler(networkHandler)

def post(msg):
    pass

def environment(ignoreVars=[]):
    """Set up the environment ignoring specified 
       environmental variables"""
    env = {}

    # Get environmental vars
    for i in os.environ:
      if i not in ignoreVars:
        env[i]=os.environ[i]

    # Our custom settings
    env['PYTHONPATH'] =  + \
      '/tools/twisted/twisted-2.4.0/lib/python2.5/site-packages:' + \
      '/tools/twisted/twisted-core-2.4.0/lib/python2.5/site-packages:' + \
      '/tools/twisted/zope-interface-3.3.0/lib/python2.5/site-packages'
    env['DBUS_SESSION_BUS_ADDRESS'] = 'unix:path=/tmp/session_bus_socket'
    env['GTK2_RC_FILES'] = '/home/user/.osso/current-gtk-theme:' + \
            '/home/user/.osso/current-gtk-key-theme'
    env['HOME'] = '/root'
    env['TMPDIR'] = '/var/tmp'
    env['USER'] = 'root'
    env['DISPLAY'] = ':0.0'
    return env

def connectable(hostname, port):
    """Test if a server is connectable by doing a DNS lookup
       and trying to establish a TCP connection.  TCP Connection
       does nothing"""
    try:
        ip = socket.gethostbyname(hostname)
    except socket.gaierror:
        log.error('Could not resolve %s' % hostname)
        return False
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((ip,int(port)))
        s.shutdown(2)
        log.info('Established TCP connection on %s:%s' % (hostname, port))
        return True
    except:
        log.error('Could not establish TCP connection on %s:%s' % (hostname, 
                                                                   port))
        return False

def standaloneTest():
    """Test that a blocking file is not present"""
    outcome = os.path.exists(standalone)
    if outcome is True:
        log.error('Found standalone blocking startup at %s' % standalone)
        exit(1)
    else:
        log.info('No standalone file blocking start')
    return outcome


def start():
    standaloneTest()
    i = 0
    while not connectable(master,port):
        if i > max_try - 1:
            log.error('Tried to connect and failed %d times' % i)
            log.info('rebooting')
            subprocess.call(["reboot"])
            exit(1)
        i+=1
        log.info('Connection test attempt %d' % i)
        time.sleep(delay)
    try:
        subprocess.check_call(["buildbot", "start", slavedir],
                   env=environment(ignoreVars=['CONSOLE']))
    except subprocess.CalledProcessError:
        log.error("Buildbot had non-zero return code")
        #except:
            #error("Failed to call buildbot start", critical=True)

def stop():
  subprocess.call(["buildbot", "stop", slavedir],
                  env=environment(ignoreVars=['CONSOLE']))

if __name__ == '__main__':
    usageString = 'Usage: %s start|stop|restart' % sys.argv[0]
    if len(sys.argv) is not 2:
        log.error("Not the correct number of arguments")
        log.error(usageString)
        exit(1)
    else:
        mode = sys.argv[1]
        log.info("N810=%s;BUILDMASTER_HOST=%s;PORT=%d" % (n810,
                                                          master, port))
        if mode == 'start':
            start()
        elif mode == 'restart':
            stop()
            start()
        elif mode == 'stop':
            stop()
        else:
            log.error("Specified argument '%s' is not valid" % mode)
            log.error(usageString)
            exit(1)


Now the service needs to have execute permissions and enabled

chmod a+x /etc/init.d/buildbot
update-rc.d buildbot defaults 99
Misc. Buildbot setup

To make it easier to set up the device, we are running a couple changes in our buildbot.tac. Here is an example buildbot.tac file:

from twisted.application import service
from buildbot.slave.bot import BuildSlave 
from socket import gethostname
from host import buildmaster_host, port

basedir = r'/builds/buildbot'
slavename = gethostname()
passwd = 'm0b1l3'
keepalive = None
usepty = 1
umask = 022
maxdelay = 300
rotateLength = 1000000
maxRotatedFiles = None 

application = service.Application('buildslave')
try:
  from twisted.python.logfile import LogFile
  from twisted.python.log import ILogObserver, FileLogObserver
  logfile = LogFile.fromFullPath("twistd.log", rotateLength=rotateLength,
                                 maxRotatedFiles=maxRotatedFiles)
  application.setComponent(ILogObserver, FileLogObserver(logfile).emit)
except ImportError:
  # probably not yet twisted 8.2.0 and beyond, can't set log yet
  pass
s = BuildSlave(buildmaster_host, port, slavename, passwd, basedir,
               keepalive, usepty, umask=umask, maxdelay=maxdelay)
s.setServiceParent(application)

and create a /builds/buildbot/host.py:

buildmaster_host = 'staging-mobile-master.mv.mozilla.com'
port = 9010
Daily Reboot

put this script in /tools/daily_reboot.sh It is invoked over ssh by the buildbot master

#!/bin/sh

REBOOT=0
UPTIME=`uptime | sed -e 's/^.*up *\([^,]*\).*$/\1/'`
BUILDBOT_PROCS=`ps | grep buildbot | grep -v grep | wc -l`
HOSTNAME=`hostname`
STANDALONE_FILE="/builds/standalone.txt"

# Respect the no-go file
if [ -f $STANDALONE_FILE ] ; then
        echo "`hostname` Not starting buildbot: `cat $STANDALONE_FILE`"
        exit
fi

echo $UPTIME | grep 'day' >/dev/null 2>&1
if [ $? -eq 0 ] ; then
        echo "$0: $HOSTNAME has been up over a day."
        REBOOT=1
fi

if [ $BUILDBOT_PROCS -lt 1 ] ; then
        echo $UPTIME | grep ':' >/dev/null 2>&1
        if [ $? -eq 0 ] ; then
                echo "$0: $HOSTNAME up for over an hour with no buildbot!"
                REBOOT=1
        else
                MIN_UPTIME=`echo $UPTIME | sed -e 's/ *min$//'`
                if [ $MIN_UPTIME -gt 30 ] ; then
                        echo "$0: $HOSTNAME up for over 30 min with no buildbot!"
                        REBOOT=1
                fi
        fi
fi

if [ $REBOOT -gt 0 ] ; then
        echo "$0: $HOSTNAME rebooting!"
        reboot
        sleep 600
fi

Prepare it for use with

ln -s /tools/daily_reboot.sh /etc/cron.daily/daily_reboot.sh
chmod +x /tools/daily_reboot.sh
Talos

Upload the tp4 pageset to /tools/tp4, then

ln -s /builds/talos/page_load_test /var/www/html/
Maemkit

On a pc get maemkit and put it onto the N810. Modify maemkit.cfg

hg clone http://hg.mozilla.org/qa/maemkit 
vim maemkit.cfg # run :%s'/media/mmc1/release'/builds/unittest'g
scp -r maemkit root@${DEVIP}:/tools/maemkit
Misc

Disable all catalogs in the Application Manager.

It seems that the keybindings.rc file isn't set up as needed using this imaging method. Copy it from a stock firmware image.

binding "task-switcher-shortcut" {
        bind "<ctrl><alt>y" { "cancel" () }
}
class "GtkMenuShell" binding "task-switcher-shortcut" 

binding "task-launcher-shortcut" {
        bind "<ctrl><shift>Tab" { "cancel" () }
}
class "GtkMenuShell" binding "task-launcher-shortcut" 

binding "application-menu-shortcut" {
        bind "<ctrl><shift>M" { "cancel" () }
}
class "GtkMenuShell" binding "application-menu-shortcut"

It goes into /home/user/.osso/keybindings.rc

Clone Filesystem

Using parted, set up the filesystem on the target card

parted --script /dev/sdb mklabel msdos
parted --script /dev/sdb mkpartfs primary ext2 0 3500
parted --script /dev/sdb mkpartfs primary linux-swap 3500 3900
mkfs.ext2 -L maemo-n810-ref /dev/sdb1
mkswap /dev/sdb2

Then insert the MiniSD card into the device. Now image the device

mount -t jffs2 /dev/mtdblock4 /opt
mount /dev/mmcblk1p1 /floppy
rsync -a /opt/. /floppy/.
umount /floppy

On the real computer, mount the flash drive and sync the filesystem to a directory on the drive

mkdir /flashing/tmp /flashing/moz-ref-image-v1
mount /dev/sdb1 /flashing/tmp
rsync -a /flashing/tmp/. /flashing/moz-ref-image-v1/.
sync
umount /flashing/tmp

On the real computer, install the talos pagesets

cd moz-ref-image-v1/tools
cp -r /flashing/mmc2/pages .
cp -r /flashing/mmc2/tp4 .

rm -f /flashing/moz-ref-image-v1/var/www/page_load_test
ln -s /tools/talos/page_load_test /var/www/page_load_test
ln -s /tools/pages /tools/page_load_test/pages
ln -s /tools/pages /tools/talos/page_load_test/tp3
ln -s /tools/tp4 /tools/talos/page_load_test/tp4