[Home]
Penguin carries Palm under arm
This page intended for people living in Linux and having Palm in hands.
Traditionally, for old Palm-like handhelds (Palm III*, Palm V*, Palm VII
goodies equipped with serial cradles/cables) these people uses well-known
pilot-link package, or, lesser-known (but well developed) coldsync.
But
Visors, modern Palms and Sony Clies have an USB cradle in-box; how to
play with these new goodies? Let's try to address this issue.
Or, another
question: how to connect Your cool new USB handheld to the Internet not
bying special modem and not using slo-o-ow connection via mobile phone?
Shortly speaking: This page is for people wishing to link USB-equipped handhelds
with/through Linux host using USB cradle.
2.1 Author does not take any responsibility for possible software crashes,
hardware destructions and brain damages, that may follows using tips/tricks/patches
mentioned in this document. Use it for You own risk.
2.2 Patches mentioned here is the quick and dirty hacks for long-existing
Open Source software. Altough these software packages are well known and
well tested tools, using my patches for tweaking these packages may cause
some strange/incorrect behavior. Authors/communities supporting these packages
does not have any guilties is these. Author of these patches have no guilty
too, because [You are warned in 2.1]. All abuse must be directed to /dev/null.
2.3 Author does not provide any form of support or advisory for patches/examples supplied on this page, nor software mentioned here. You must have basic skills in Unix/Linux and know how to configure/compile kernel, how to compile software under Linux, how to apply patches etc.
2.4 All patches/tricks/exapmles may be freely used, modified and improved
by anyone. If You found things are useful and wish to reference or quote
this page in any sort of information sources, notify me about this.
2.5 Author yields apologies for it's poor English.
3.1 Kernel configuration
In kernel configuration You need to turn on components of USB subsystem as follows:
# Core USB support
CONFIG_USB=m
CONFIG_USB_DEBUG=y
CONFIG_USB_DEVICEFS=y
# Host hardware (USB hub support); really, You need only one of
# these items, depending of Your chipset type. First two is for Intel chipsets,
# last - for ALi, VIA and so on.
CONFIG_USB_UHCI=m
CONFIG_USB_UHCI_ALT=m
CONFIG_USB_OHCI=m
# USB Serial Converter support; These modules needed for convert
# USB-connected device into serial-tty-like Linux device. First two modules
# is USB/serial redirector modules, third is "recognizer" of particular USB-connected
# device (if You look at drivers/usb/serial/ options, You will see many options,
# not only Palm handhelds)
CONFIG_USB_SERIAL=m
CONFIG_USB_SERIAL_GENERIC=y
CONFIG_USB_SERIAL_VISOR=m
I'll personally recommend use modularized USB-drivers when possible.
Then You will have more options for debugging Your configuration.
3.2 Kernel patching
If You use new production kernel tread 2.4.x and have fresh patchlevel
(at least 2.4.13), skip this paragraph. Otherwise, if You still
using old production thread 2.2.x, read more. USB support has been introduced
in 2.4.x (formely 2.3.x) kernels and then backported to 2.2.x production
tread. Because primary task of Linux kernel community is development a
new tread 2.5.x and fixing a modern production tread 2.4.x, backporting
new drivers into 2.2.x sometimes may be late (or they may not be backported
at all) and rarely stays in sync with 2.4.x... Therefore, if You want to
use Palm with 2.2.x system, apply this patch (backport of drivers/usb/serial/visor.{c,h} from 2.4.13 sources) to the Your kernel source tree.
Patch applicable to 2.2.20 source tree and may be applicable to some
patchlevels near around 20. After applying patch don't forget to perform
make dep && make clean
Then compile and install modules as usually.
make modules && su -c 'make modules_install'
Additional information from 20-05-2002.
A 2.4.x kernel branch have some drawbacks in visor module too. A first - it does not perform a tty_hangup call in visor_close and a second - it does not perform a correct closing a ports from visor_shutdown. First leads to "hanging" pppd after handheld device has been disconnected from bus. Second causes an infinite incrementing module usage count for visor.o and then leads to the impossibility of visor.o removal until kernel restart. Patch, that fixes these drawbacks is here. A second drawback is from category under question "It's a bug or a feature?", because it has been introduced in 2.4.17 version...
3.3 Loading drivers
Load modules needed for USB-support:
insmod usbcore.o
insmod usbserial.o
# one of these, depending of Your USB-hub hardware
insmod usb-uhci.o | uhci.o | usb-ohci.o
insmod visor.o
I suggest You to use kernel modules auto-loading support (CONFIG_KMOD=y). Add following /etc/modules.conf entries:
# USB handhelds support
alias char-major-188 visor
# one of these, depending of Your USB-hub hardware
post-install usbserial modprobe usb-uhci | uhci.o | usb-ohci.o
Some comments. 188 is major number of device special inodes of /dev/ttyUSB[0-9]+;
when kernel detects first request for /dev/ttyUSB, it tries to load visor
module, and if Your modules.dep is up to date (do not forget to issue depmod
-a after modules recompiling), recursive loads usbserial and usbcore.
3.4 Configuring coldsync.
Get coldsync, compile and install it. Prepare Your ~/.coldsyncrc file.
For example:
# Sample of ~/.coldsyncrc
listen serial {
protocol: simple;
device: "/dev/ttyUSB1";
}
pda "mypalm" {
directory: "/home/jsmith/palm/coldsync";
username: "jsmith";
userid: 501;
default;
}
Some notes.
- About protocol simple in listen section. It must present if You have
handheld with Palm OS 4.0 and above. Remove this statement if Your handheld
have Palm OS 3.5.
- About using /dev/ttyUSB1, not /dev/ttyUSB0. When handheld connects to host (sync button pressed or icon in HotSync
application tapped), serial redirector attaches two ttys: /dev/ttyUSB0
(used for control purposes, unknown for me), and /dev/ttyUSB1 (used for
data transmission). We supply second of these ttys to coldsync.
- About username/userid. If Your handheld already initialized via Palm's HotSync software (initializing means assigning some username and userid from desktop to handheld; remember
HotSync question about username at first syncing?), You can supply existing
username/userid to coldsync in pda section. Procedure for discovering
username/userid at handheld via special shortcut described in coldsync documentation. Optionally,
You may discover username/userid from binary file users.dat placed in Windows
Palm Desktop directory. Open this file in some hex viewer, find Your username,
then step back one-byte username length, then two-byte zero (may be this
is most significant word of userid) and see two-byte userid. Here is (euristically
discovered) partial users.dat record format:
struct users_dat {
u16 userid;
u16 zero_word; /* may be, this is MSW of userid, */
/* then userid has u32; Palm Desktop can
/* support up to 2^32 users? Cool! :) */
char name_len;
char name[];
char dir_name_len;
char dir_name[]; /* subdirectory where HotSync stores data */
/* for this user; at most 6 bytes length */
};
Do not forget about little-endianess of Intel architecture: swap bytes for
construct userid for ~/.coldsyncrc.
If Your handheld has not yet initialized (I use my old Palm V about
two years without without Palm Desktop software and, accordingly, without
"initialization"; I used pilot-link for backing up data and installing
applications/databases), You may:
select username/userid as You wish, write they in "pda" section and
issue
coldsync -mI
for initialization;
or, simply issue coldsync -mI for initialization handheld with Your
current Unix username and userid (not root, I hope)... Yea, coldsync must
be named COOLsync. :)
WARNING: Do not use userids with zero MSB (<=255), if You plan
to use Windows Palm Desktop software too; Palm Desktop treats these ids
as "profiles", not as users.
WARNING: Never use zero userid; see coldsync documentation
about this.
Perform first backup:
coldsync -mb ~/palm/coldsync
Now, You ready to run: simply start coldsync without parameters (ignore
it's warnings about non-existing /dev/ttyUSB1) and press sync button on
cradle.
3.5 Coldsyncing more comfortably (coldsync daemon mode).
If You are lazy, and do no like to run coldsync every time, when
syncing/installing is needed, You may use coldsync in daemon mode. First,
prepare /etc/palms (or /usr/local/etc/palms, depends on parameters, supplied
to configure):
# Sample of /etc/palms
123456789|jsmith|11000|501|mypalm
here:
- 123456789 - serial number of Your Palm (see info in App Launcher);
- jsmith - username of Your Palm;
- 11000 - userid of Your Palm; It may be same as Unix userid, 11000 given here for example only; See note in previous chapter about discovering/setting up of userid;
- 501 - Your Unix userid (coldsync performs setuid() and uses Your ~/.coldsyncrc);
- mypalm - name of pda section for this Palm in Your ~/.coldsyncrc.
Second, add following entry to /etc/inittab:
cs:235:respawn:/usr/local/bin/coldsync -v -t serial -P simple -l /syslog/coldsync.log -md ttyUSB1
and issue
init q
for re-reading inittab
Now press sync button... Yes, it's syncs. Good. After completion of
syncing, try to sync again. Oops! It's not working. Kill stucking coldsync
process, press button. Works again. And again - not working.
This strange behavior resulted from very fast respawning of coldsync
after termination. USB hot-sandwitch constructed from visor/usbserial/uhci/usbcore
does not have enough time to destroy ttyUSB's remained from previous session.
Coldsync successfully opens this "old" ttyUSB, then stucks in read() call.
How to address this issue? You can simply replace coldsync entry in inittab
with some script file, that does sleeps:
#!/bin/bash
#
# Give USB stack enough time to destroy old /dev/ttyUSB
sleep 20
/usr/local/bin/coldsync -v -t serial -P simple -l /syslog/coldsync.log -md ttyUSB1
In inittab:
cs:235:respawn:/usr/local/bin/coldsync-sleep.sh
Or, You may apply this patch to coldsync source tree and recompile
coldsync. Patch uses asyncronous read with select(). If nothing to read
from device for 15 seconds, we terminates with ETIMEDOUT status. Then init process
respawns coldsync and everything is ok. Moreover, this patch fixes unreliable read of
of packet header in netsync_read_method()@netsync.c Netsync protocol uses
in local exchange with Palm OS 4.0 devices and in network syncing with all Palms.
Original code does read of all header in one read() and fails if not all
bytes arrived at this moment.
Addtional information about daemon mode (21-Feb-2002) for people using a post-sync (dump) conduits.
Dump conduits is directed to exporting data from syncronized backup copies of Palm databases to various desktop formats. A comprehensive info about conduits with examples and documentation You may found here.
You are in trouble with both standard and patched version of coldsync. Coldsync runs dump conduits after main syncing is complete, device is disconnected from host and device filedescriptor is closed by coldsync. When disconnect event occurs at tty line, device driver send SIGHUP to process, which uses a tty line. Original coldsync does not install a handler of SIGHUP. When coldsync runs from shell, SIGHUP caught and handled by shell (at least BASH does such), but init reset all signal handlers to defaults before forking any process. Default action for SIGHUP is to terminate the process, then coldsync terminates and does not runs all things after close() call.
Theoretically, coldsync will demonstrate this behavior with any Palms, including serial-equipped, not only with USB. Unfortunately, I have no possibility for testing this assumption.
Two workarounds of this issue, without and with more hacking of coldsync:
4.1 Setting up PPP connection between Palm and Linux host.
Well, what need to us for using Palm networking applications such as Web
Clipping Applications, Browsers, AvantGo, MultiMail, etc? We need a PPP
connection to the Internet. How to connect? "Via Palm modem, via mobile
phone (infrared-equipped) or via serial cable+nullmodem converter+desktop modem",
User Guide responds to us. Palm modem is expensive; mobile connection is very slow
and expensive too (in Russia at least); necklace from cable, converter
and modem, larger than Palm itself... Brr. Not for us, right? And now we
connect our Palm to the Linux host over PPP through fast USB interface.
Software prerequisites:
- USB/serial redirector support in kernel (You already
have it, see Chapter 3),
- PPP support in kernel (CONFIG_PPP=m),
- PPP daemon,
- mgetty
.
Standard mgetty will not work over not existing tty device, bacuse USB/redirected
ttys exists only when Palm is active and destroyed when Palm disconnects.Therefore
You need another patch. This patch introduces new mgetty option nodevsleep;
default is no, if set to yes, mgetty will continuously trying to open()
tty when ENODEV || ENOENT || ENXIO is returned.
Think about IP address assingnment for You Palm. If You have only one
routable IP address and it's occupied with Linux host, then masquerading
is Your friend (CONFIG_IP_MASQUERADE=y). Compile and install all mentioned
software components and kernel modules. Mgetty must be compiled with -DAUTO_PPP in CFLAGS.
Turn on IP forwarding:
echo 1 > /proc/sys/net/ipv4/ip_forward.
Prepare configuration files:
for mgetty
#/etc/mgetty+sendfax/mgetty.config
port ttyUSB1
debug 3
direct yes
nodevsleep yes
modem-type data
toggle-dtr no
blocking yes
ignore-carrier yes
#/etc/mgetty+sendfax/login.config
/AutoPPP/ - - /usr/sbin/pppd auth login +pap -chap
* - - /bin/login @
for pppd
/etc/ppp/options.ttyUSB1
local
lock
crtscts
nodetach
asyncmap 00000000
:192.168.10.20
ms-dns 192.168.10.1
ms-dns 192.168.10.2
proxyarp
proxyarp needed only if Your Linux host connected to the broadcast
network (such as Ethernet) and Palm's IP address belongs to the same subnet
as host's IP without masquerading; Do not forget: HomePNA adapters and some of xDSL devices connects
Your host to broadcast network too.
Add inittab entry:
us1:235:respawn:/sbin/mgetty ttyUSB1
Configure network connection in Your Palm:
- run Prefs application;
- select Network in upper right combobox;
- enter something descriptive in Service: item;
- fill User Name: and Password: with values suitable for authorization of PPP link; You can use self username or create separate account especially for Your Palm;
- select Cable/Cradle in Connection: combo.
- tap Details;
- select PPP in Connection type: combo;
- check Query DNS and IP Address Automatic boxes;
- tap Script: button and make empty script, containing only End line.
Tap Connect.
If all things is correct then after sequential flashing Initializing
-> Signing on -> Established, Connect button will be replaced with
Disconnect.
Ping Palm from host. RTT must be around 10ms (as for HomePNA) for USB connection.
If something are wrong, add debug to pppd options file and raise debug level for mgetty (for example debug 8) and see logfiles.
Now You can browse WCA, refresh AvantGo channels and send/receive e-mail via MultiMail, or even syncing with Windows Palm Desktop somewhere in network (or, for example, inside VMWare box at same Linux host).
4.2. Seamless switching between coldsyncing and networking without tweaking /etc/inittab.
Now what about coldsync'ing again? Because Your ttyUSB is occupied by mgetty, You need to comment out mgetty in inittab, uncomment coldsync entry and issue
init q
Then when network connection needed, You must perform comment/uncomment again... This is very uncomfortable approach. The mgetty patch, mentioned above, helps lazy people to save itself from unnesessary motions. Recompile mgetty with -DAUTO_HOTSYNC added to CFLAGS in it's Makefile.
Tweak login.config:
#/etc/mgetty/login.config
/AutoPPP/ - - /usr/sbin/pppd auth login +pap -chap
/HotSync/ - - /usr/local/bin/coldsync -l/syslog/coldsync.log -tserial -Psimple -md -
* - - /bin/login @
Now mgetty will "automagically" detect type of Palm connection and execute appropriate daemon: coldsync or pppd. For pppd it exec'ed new process as usually, for coldsync, it stays alive, forks itself and feed datastream to/from child (coldsync really) via anonymous duplex pipe (socketpair).
Addtional information about daemon mode (21-Feb-2002) for people using a post-sync (dump) conduits.
Dump conduits will not work under coldsync running over socketpair pipe as STDIN, unless You apply modified patch mentioned above. After coldsync closes device (STDIN in this case), pipe() call founds a least numbered filedescriptor 0 and uses it for one of handles in pipe pair. This [by some strange reason] clashes with socketpair, which used to feed data stream from mgetty to coldsync and still alive at this time.
All mentioned products copyrighted by it's authors/communities and have appropriate licenses mentioned in accompaying documentation.
Arcady Stepanov may be reached via penguin at mol dot ru e-mail address.