Hi! We're discussing a clarification of the content license; please look over to Current events if you're interested in editing.
Ubuntu/Leo
From Htc-linux
Contents |
Ubuntu on the HTC HD2 aka HTC Leo smart phone
This outlines the creation of a complete Ubuntu system for the HTC HD2 device.
Much of the following is hacky and should be improved or should be fixed in the according upstream / Ubuntu project. Ubuntu Launchpad is a good place to discuss such upstream problems.
Check https://launchpad.net/smartphone - a launchpad project for related issues !
Ready made images for download
An example of what this could look like once you finished: http://www.youtube.com/watch?v=tOPu6DgbOs4 An example of ubuntu 0.3 by Jaxbot from windowsphonehacker.com: http://www.youtube.com/watch?v=tOPu6DgbOs4
Important
- Read Rootfs/Userfriendly first for how to boot from SD !
- You must be root during the entire process.
- All absolute pathnames must be appended to the mount point of your rootfilesystem! Running any of the listed commandlines as is might destroy your host computer.
rootfilesystem
This howto assumes a present base rootfilesystem. There are two options to obtain a Ubuntu rootfilesystem as follows.
Rootstock
Rootstock is a program that allows download and configuration of Ubuntu packages with the aim to create a Ubuntu rootfilesystem. Further information:
https://launchpad.net/project-rootstock/
https://wiki.ubuntu.com/ARM/RootfsFromScratch
Prebuilt
Ubuntu offers images for ARM devices that are completely usable on a specific device.
Following image is the Ubuntu 10.10 Maverick Meerkat release image for a board with a similar processor like the one in HD2 and thus a good base to start from:
Prebuilt image extraction
Prebuilt ubuntu ports images come as flashable, partitioned SD card or USB images with and initrd and rootfs included. You can extract the actual rootfs -the vital part- as follows.
- unzip the image
gunzip foo.img.gz
- check where the rootfs partition is located using parted:
parted foo.img
- set the file size unit to byte so you can copy paste the value for use in mount
u b
- print the partition table
- the rootfs is the large, second partition.
- copy the value!
- mount the rootfs partition from the image file using the offset value.
mount -o loop,offset=<bytesizeoffset> foo.img /mnt/my-ubuntu-rootfs
Prebuilt cosmetics remove all unneeded kernel headers, binaries, modules
it is save to remove any kernel package that is installed!
apt-get remove linux-omap linux-foo linux-headers-bar etc
less elegant:
rm -rf /lib/modules/* /boot/* /usr/src/*
obviously do that before installing your modules and please avoid putting those commands as is cause you will not be able to boot on your host computer
In order to boot the image, you need to copy the files to a filesystem 'container file'. See Rootfs/Userfriendly for how to create such a file. Once you're done and mounted the target container file you can copy the prebuilt image contents to it like so:
cp -rva /media/prebuilt-rootfs-mountpoint/* /media/target-rootfs-mountpoint/
Kernel
Several kernel source trees are available for the HTC HD2. You must download or compile kernel image (zImage) and place it as explained at Rootfs/Userfriendly. In order to use kernel modules, you must download or compile them as well and install them as explained in the Leo/UpdateKernel page.
NOTE: It is possible to use USB Host mode in order to attach extra devices. This works like a charm. It is mandatory to use the htc-msm-2.6.32 kernel with htcleo_defconfig . See Msm_Usb_Host for further information!
NOTE: A big kernel level problem is the lack of sound. Most of the kernels we use as a base for our ports are designed for Google Android. Android doesn't use the standard Linux sound System ALSA. An ALSA wrapper for the HD2 DSP kernel system must be written. If you want to contribute in this see Contact. If you think you totally need sound now you can use the usb host functionality of the HD2 in order to attach an USB sound device! The htc-msm-2.6.32 allows this.
Prebuilt kernel and modules
How to install prebuilt kernel and modules: Leo/UpdateKernel
Compiling own kernel binaries
How to roll your own kernel and modules: QuickDeveloperStartGuide#Kernel NOTE: use htcleo_defconfig . it is designed for use with non-android (GNU/Linux) user space !
Available kernel sources: Leo#Kernel Use htc-msm-2.6.32 branch kernel only! With the "evo" kernel you will run into problems with touchscreen, backlight, networking etc.
NOTE: If you ever start a new kernel/configuration from scratch and run into a problem with only root being able to use networking: turn off the android paranoid networking kernel configuration!!!
oem-config
only interesting when using prebuilt image! Ubuntu uses a program called oem-config to add a user account, set languages and do other tasks. When using a prebuilt image instead of rootstock, it is necessary to start it the first time you boot your image. Else you cannot login.
using oem-config
oem-config is only executed when the file /var/lib/oem-config/run exists. So do a
touch /var/lib/oem-config/run
note: oem-config will not give you an on-screen keyboard which makes it impossible to use it when you only have the touchscreen as input device. This should either be fixed upstream (Ubuntu Launchpad bugtracking system) or locally either a workaround TODO: find out how to add onboard in oem-config / what configuration is in charge for that.
Xorg
Configuring Display and input devices
xorg.conf
This xorg.conf will use landscape display: /etc/X11/xorg.conf
Section "Monitor"
Identifier "Monitor0"
Mode "480x800"
DotClock 0
HTimings 480 480 480 480
VTimings 800 800 800 800
Flags "-HSync" "-VSync"
EndMode
EndSection
Section "Device"
Identifier "fbdev"
Driver "fbdev"
Option "ShadowFB" "on"
Option "Rotate" "CW"
Option "RandRRotation" "true"
EndSection
Section "Screen"
Identifier "Framebuffer"
Device "fbdev"
Monitor "Monitor"
DefaultFbBpp 16
SubSection "Display"
Depth 16
Modes "480x800"
EndSubSection
EndSection
Section "InputDevice"
Identifier "htcleo-ts"
Driver "evdev"
Option "Device" "/dev/input/event0"
Option "InvertX"
Option "SwapAxes"
Option "Calibration" "972 4 569 15"
EndSection
#Section "InputDevice"
# Identifier "htcleo-keypad"
# Driver "evdev"
# Option "Device" "/dev/input/event4"
#EndSection
#Section "InputDevice"
# Identifier "Keyboard"
# Driver "kbd"
# Option "XkbLayout" "en_US"
#EndSection
Section "ServerLayout"
Identifier "Builtin Default Layout"
Screen "Framebuffer"
InputDevice "htcleo-ts"
EndSection
#Section "ServerFlags"
# Option "AutoAddDevices" "false"
#EndSection
Touchscreen
Specific touchscreen config in Xsession.d is not required with the above xorg.conf.
xinput.d
This is important to put when using the landscape rotation xorg.conf . It will rotate the touchscreen input device and put according calibration:
/etc/X11/Xsession.d/53rotate-touchscreen
xinput set-prop leo-touchscreen "Evdev Axis Calibration" 972 4 569 15 xinput set-prop leo-touchscreen "Evdev Axis Inversion" 1, 0 xinput set-prop leo-touchscreen "Evdev Axes Swap" 1
Keypad
With the latest htc-msm-2.6.32 kernel and maverick prebuilt image as rootfs base, they keypad does not work. It is detected and registered by Xorg but doesn't show any output in X. With showkeys and on ttys it works without problems.
TODO: Append xorg log TODO: Solve no keypad in Xorg problem
keymapping when using htc-msm-2.6.32 Kernel with htcleo_defconfig configuration.
Multitouch
Since Ubuntu 10.10 Maverick, a multi touch function was implemented in Ubuntu. Making this available to the touchscreen found in the HD2 is a work in progress. I documented everything here:
https://bugs.launchpad.net/utouch/+bug/627629
WLAN
WLAN firmware
find leo firmware binaries here LeoWifi
TODO: clarify what firmware file to pick for what driver TODO: avoid firmware binary and put fetch it using some fw-cutter script to avoid possible legal issues! problem: assumes availability of 3g plan to the user.
wicd VS network-manager
note: network-manager has some nasty problems with detecting our bcm4329 driver interface. well, broadcom's driver has nasty problems identifying the interface conventionally cause they designed it for android :P
further information and attempt to solve the problem on driver level
workaround solution: use wicd instead:
apt-get install wicd
this will remove network-manager and install and configure wicd
WLAN script
this script will kill the 3g session and switch to ppp mode. I know this stuff is horrible :D feel free to fix it if you know bash scripting better than me.
place this script in
/usr/sbin/wifi-gtk
and make it exectuable using
chmod +x /usr/sbin/wifi-gtk
#!/bin/sh
zenity --question --title "Confirm" --text "This will close any active 3G sessions and switch to WiFi mode. Succeed?"
if [ $? = "0" ]
then
killall pppd
ifconfig eth0 down
ifconfig eth1 down
ifconfig eth2 down
sleep 2
modprobe bcm4329
echo 75 > /sys/devices/virtual/timed_output/vibrator/enable
sleep 0.2
echo 75 > /sys/devices/virtual/timed_output/vibrator/enable
# zenity --info --text "To scan and connect tap the monitor icon in the top bar"
wicd-gtk --no-tray
elif [ $? = "1" ]
then
echo "Aborted"
fi
exit
3G
3G Script
put this script into
/usr/sbin/ppp-gtk
and make it exectuable with
chmod +x /usr/sbin/ppp-gtk
#!/bin/sh #ppp-gtk script by Lukas-David Gorris. Based on the original htc kaiser ppp.notsh script from Barry Carter ( http://www.headfuzz.co.uk ) Released under Gnu Public License v2 #kill remaining ppp and other interfaces killall pppd ifconfig eth0 down ifconfig eth1 down ifconfig eth2 down # Get apn user password information apn=$(zenity --entry --title "3G APN" --text "Type in your 3g Access Point Name" --entry-text "$(cat /etc/ppp/apn)") echo "apn is $apn" user=$(zenity --entry --title "3G Username" --text "Type in your 3g username. Leave blank for none." --entry-text "$(cat /etc/ppp/user)") echo "user is $user" pass=$(zenity --entry --title "3G Password" --text "Type in your 3g password. Leave blank for none." --entry-text "$(cat /etc/ppp/papsecrets)") echo "pass is $pass" # Save apn, user, password echo $apn > /etc/ppp/apn echo $user > /etc/ppp/user echo "$pass" > /etc/ppp/papsecrets echo "$pass" > /etc/ppp/chapsecrets # Send the modem init and access point name /bin/echo -e "AT+CGDCONT=1,\"IP\",\"$apn\",\"\",0,0\r" > /dev/smd0 sleep 1 # Dial up the connection /bin/echo -e 'ATD*99***1#\r' > /dev/smd0 # Start pppd pppd /dev/smd1 debug defaultroute local usepeerdns name $user noipdefault unit 0 linkname gprs novj persist # Wait for the net to come up sleep 10 # Use OpenDNS servers in case provider does not give you DNS #/bin/echo -e "nameserver 208.67.222.222\n\r nameserver 208.67.220.220\n\r" > /etc/resolv.conf # Success. echo 75 > /sys/devices/virtual/timed_output/vibrator/enable sleep 0.2 echo 75 > /sys/devices/virtual/timed_output/vibrator/enable zenity --info --text "3G Initialized" # Update systm time ntpdate pool.ntp.org
Once you've entered your apn, username and password into the 3G Mode script, it saves your entries. Next time you run it, you just need to click OK three times. If you get tired of clicking OK, here's a patch for a one-click connection with a progress dialog.
- Make sure you already have /usr/sbin/ppp-gtk
- Save the patch below as /usr/sbin/ppp-gtk.patch
- Then run patch -p0 < /usr/sbin/ppp-gtk.patch
TODO: compare the file modification time to something more appropriate than /etc/ppp/pap-secrets
--- /usr/sbin/ppp-gtk 2010-12-26 14:07:41.000000000 -0800 +++ /usr/sbin/ppp-gtkonprogress 2011-02-21 21:44:43.000000000 -0800 @@ -1,23 +1,42 @@ #!/bin/sh #ppp-gtk script by Lukas-David Gorris. Based on the original htc kaiser ppp.notsh script from Barry Carter ( http://www.headfuzz.co.uk ) Released under Gnu Public License v2 - +( #kill remaining ppp and other interfaces rmmod bcm4329 killall pppd killall wicd +echo 10 ifconfig eth0 down ifconfig eth1 down ifconfig eth2 down # previous usbnet connection will sometimes mess up routing so I'm killing the interface for now. it would be nice to use the host's internet. if you know how to resolve this please let me know. ifconfig usb0 down +sleep 3 +echo 20 # Get apn user password information -apn=$(zenity --entry --title "3G APN" --text "Type in your 3g Access Point Name" --entry-text "$(cat /etc/ppp/apn)") +# if apn file is newer than pap-secrets, don't ask the user again +if [ /etc/ppp/apn -nt /etc/ppp/pap-secrets ] +then + apn=$(cat /etc/ppp/apn) +else + apn=$(zenity --entry --title "3G APN" --text "Type in your 3g Access Point Name" --entry-text "$(cat /etc/ppp/apn)") +fi echo "apn is $apn" -user=$(zenity --entry --title "3G Username" --text "Type in your 3g username. Leave blank for none." --entry-text "$(cat /etc/ppp/user)") +if [ /etc/ppp/user -nt /etc/ppp/pap-secrets ] +then + user=$(cat /etc/ppp/user) +else + user=$(zenity --entry --title "3G Username" --text "Type in your 3g username. Leave blank for none." --entry-text "$(cat /etc/ppp/user)") +fi echo "user is $user" -pass=$(zenity --entry --title "3G Password" --text "Type in your 3g password. Leave blank for none." --entry-text "$(cat /etc/ppp/papsecrets)") +if [ /etc/ppp/papsecrets -nt /etc/ppp/pap-secrets ] +then + pass=$(cat /etc/ppp/papsecrets) +else + pass=$(zenity --entry --title "3G Password" --text "Type in your 3g password. Leave blank for none." --entry-text "$(cat /etc/ppp/papsecrets)") +fi echo "pass is $pass" # Save apn, user, password @@ -31,28 +50,45 @@ /bin/echo -e "AT+CGDCONT=1,\"IP\",\"$apn\",\"\",0,0\r" > /dev/smd0 sleep 1 +echo 25 # Dial up the connection /bin/echo -e 'ATD*99***1#\r' > /dev/smd0 # Start pppd pppd /dev/smd1 debug defaultroute local usepeerdns name $user noipdefault unit 0 linkname gprs novj persist +echo 30 # Wait for the net to come up -sleep 8 +sleep 4 +echo 50 +sleep 4 +echo 70 # Use OpenDNS servers in case provider does not give you DNS #/bin/echo -e "nameserver 208.67.222.222\n\r nameserver 208.67.220.220\n\r" > /etc/resolv.conf # Update systm time -ntpdate pool.ntp.org +if ntpdate pool.ntp.org +then +echo 95 echo 75 > /sys/devices/virtual/timed_output/vibrator/enable sleep 0.2 echo 75 > /sys/devices/virtual/timed_output/vibrator/enable -zenity --info --text "3G Initialized" - +echo 100 +zenity --info --text "3G Initialized" --timeout=1 +else + zenity --info --text "3G Failed" +fi + +) | +zenity --progress \ + --title="Connecting 3G" \ + --text="Connecting..." \ + --percentage=0 \ + --auto-close
1) add the dummy sound card in your kernel configuration option
2) add the following in /etc/asound.conf
pcm.qsd8k {
type plug
slave {
pcm "file:/dev/msm_pcm_out,raw"
format S16_LE
rate 44100
channels 2
}
}
# Device for playing media audio
pcm.softvol {
type softvol
slave.pcm "qsd8k"
control.name "PCM"
control.card 0
}
pcm.!default {
type plug
slave.pcm "softvol"
}
3) for in call audio handling you need an "audio routing" program,. check back later for detail !
USBNET
To set up USB networking, you will run usbnet-gtk from the command line. The script usbnet-gtk will setup usb ethernet in order to gain access from a host computer. The Leo usb0 interface will be configured with the IP 192.168.0.206. Here are the steps.
- On Leo, run
usbnet-gtk - Connect a USB cable from Leo to your host PC
- On the host PC run
ifconfig usb0 up 192.168.0.200to bring up the link - On the host PC, connect to Leo by running
ssh htc-linux@192.168.0.206. - Type ubuntu as the password for the htc-linux user
TODO: add USB tethering instructions using iptables and route
Bluetooth
It's possible to activate the internal Ubuntu/Leo/Bluetooth interface.
Cosmetics
GUI modifications etc. Assuming gnome usage.
TODO: identify, locate and add critical gdm configuration files here
on screen keyboard
It is recommended to setup an onscreen keyboard to startup with your X session. Notiche this keyboard has 2 tabs which give access to the standard features wich full size keyboards have, including some extra's like code snipets and middle and right click on the mouse.
onboard is available in Ubuntu >= maverick but has some problems that are documented in Launchpad.
maximus
To save some screen real estate, maximus can remove the title bars of windows and display them in the panel. In System/Preferences/Startup applications, add maximus. Then run gconf-editor and go to Apps/maximus and find exclude_class. Add the value onboard so the onscreen keybaord doesn't maximize. Or apply this patch
--- .gconf/apps/maximus/old_gconf.xml 2011-03-19 08:05:42.000000000 -0700 +++ .gconf/apps/maximus/%gconf.xml 2011-03-19 07:39:26.000000000 -0700 @@ -4,5 +4,8 @@ <li type="string"> <stringvalue>Totem</stringvalue> </li> + <li type="string"> + <stringvalue>onboard</stringvalue> + </li> </entry> </gconf>
right click
In order to use right click function it is useful to enabled the click and hold => right click feature in the gnome mouse settings.
cursor
Some prefer to remove the cursor when using touchscreen device. It is possible to put a transparent cursor image file for that purpose.
TODO: Please add how to for transparent cursor here.
Leo Battery Applet
The standard Ubuntu Indicator panel applet doesn't display the battery charge state correctly. Here's a simple applet to display the charge percentage in the GNOME panel
Copy the following lines of code into a new file called
/usr/lib/bonobo/servers/leo_battery.server
<oaf_info> <oaf_server iid="OAFIID:LeoBatteryApplet_Factory" type="exe" location="/home/htc-linux/applet/leo_battery_applet.py"> <oaf_attribute name="repo_ids" type="stringv"> <item value="IDL:Bonobo/GenericFactory:1.0"/> <item value="IDL:Bonobo/Unknown:1.0"/> </oaf_attribute> <oaf_attribute name="name" type="string" value="Leo Battery Applet factory"/> <oaf_attribute name="description" type="string" value="Displays Leo battery charge percentage"/> </oaf_server> <oaf_server iid="OAFIID:LeoBatteryApplet" type="factory" location="OAFIID:LeoBatteryApplet_Factory"> <oaf_attribute name="repo_ids" type="stringv"> <item value="IDL:GNOME/Vertigo/PanelAppletShell:1.0"/> <item value="IDL:Bonobo/Control:1.0"/> <item value="IDL:Bonobo/Unknown:1.0"/> </oaf_attribute> <oaf_attribute name="name" type="string" value="Leo Battery Applet"/> <oaf_attribute name="description" type="string" value="Displays Leo Battery charge percentage"/> <oaf_attribute name="panel:category" type="string" value="Utility"/> <oaf_attribute name="panel:icon" type="string" value="gnome-laptop.png"/> </oaf_server> </oaf_info>
Copy the following lines of code into a new file called /usr/bin/leo-battery-applet.py and then run sudo chmod a+x /usr/bin/leo-battery-applet.py
#!/usr/bin/env python
#leo-battery-applet.py by Roy Shahbazian. Based on example from
# http://www.pygtk.org/articles/applets_arturogf/
# Released under Gnu Public License v2
import pygtk
pygtk.require('2.0')
import gtk
import gnomeapplet
import sys
import gobject
label = gtk.Label("")
def applet_factory(applet, iid):
hbox = gtk.HBox()
icon = gtk.Image()
icon.set_from_file("/usr/share/icons/Humanity/apps/24/gnome-power-manager.svg")
hbox.add(icon)
hbox.add(label)
applet.add(hbox)
applet.show_all()
return gtk.TRUE
def update_battery():
with open("/sys/class/power_supply/battery/capacity","r") as f:
battery_percent = f.read()
f.closed
battery_percent= battery_percent.replace("\n","")
battery_percent+="%"
label.set_markup(battery_percent)
print(battery_percent)
return True
gobject.timeout_add(120*1000,update_battery)
update_battery()
gnomeapplet.bonobo_factory('OAFIID:LeoBatteryApplet_Factory',
gnomeapplet.Applet.__gtype__,
'Leo Battery applet', "0.1", applet_factory)
shortcuts
TODO: copy paste menu entries so that things like the ppp-gtk and wifi-gtk scripts appear in the main menu, netbook-launcher-efl etc.
ADB
If you have ADB enabled kernel you can use android ADB tools for accessing Ubuntu via USB or network interfaces. First copy android adbd (you can find it in /sbin/ of any android phone or you can compile it using android source) to /bin/ then make a static link like this:
ln -s / system
Now all that left is running adb daemon on your phone by running the following in a terminal:
/bin/adbd&
If you want to make the adbd run on startup, paste the following code to /etc/init.d/adb.d
#! /bin/sh
do_stop(){
#look if adbd is already running
PS=$(ps -A | grep " adbd\>")
if [ -n "$PS" ]; then
echo " * Stoping ADB Deamon..."
killall adbd
fi
}
do_start(){
#if already started then stop first
do_stop
#now start adbd
echo " * Starting ADB Deamon..."
/bin/adbd&
# little vibrate so we know adbd started in case we dont have console output
echo 200 > /sys/devices/virtual/timed_output/vibrator/enable
}
case $1 in
start | restart)
do_start
;;
stop)
do_stop
;;
esac
set the file permission to make it executable
chmod +x /etc/init.d/adb.d
now type the following command on console
update-rc.d adb.d defaults
nice programs
multimedia
Ubuntu Ubuntu >= 10.10 maverick has an mplayer package available that runs real fast on HTC HD2's processor. It can be used with the gnome-mplayer GUI:
apt-get install gnome-mplayer
accessibility
apt-get install onboard
SMS & Calls
sphone, an implementation based on ofono by XDA-DEVELOPERS user AMIPRO.
- Download and install the patched ofono and sphone from here:
http://github.com/amipro/sphone/downloads
wget http://github.com/downloads/amipro/sphone/ofono_0.25-1_armel.deb http://github.com/downloads/amipro/sphone/sphone-0.04_armel.deb dpkg -i ofono_0.25-1_armel.deb sphone-0.04_armel.deb *Include sphone with your gnome session startup. *Enjoy SMS sending/receiving and don't miss calls in Ubuntu on your HTC HD2 thanks to AMIPRO! NOTE: No calling yet due to lack of Audio (see Kernel section)
Sphone can be reconfigured to vibrate on receiving an SMS or call by changing the vibrate device in the sphone.conf file /etc/xdg/sphone/sphone.conf
At the top of the file:
[action.vibrate] path=/sys/devices/virtual/timed_output/vibrator/enable on.value=200 off.value=0
Where on.value is the length of the vibration pulse.

