--------
Overview
--------

These are a bunch of test scripts and executables to experiment on the PRS600.
Notable functionality:
 * programs/fb and fb.c: diagnostics and control of the screen, drawing a test
   pattern
 * g_serial.ko which gets loaded and enables a serial console over USB

DISCLAIMER: Provided "as is". No warranty or support provided.


------------
Requirements
------------

Sony reader PRS600 running the porkupan/boroda firmware with autorun support.
At the time of writing, that is 1.05d, available as PRS600.upd.1.05d.zip

The porkupan/igorsk test firmware loader with the RunSD script. At the time of
writing, that is 0.2b. See the README in that package for installation and
usage.

An SD card.

To get the USB console working from these instructions, you need a linux/unix
machine and minicom. The serial drivers need to support ACM. Most debian/ubuntu systems already have all this in a default install.
If you use windows, you can still get it working, but I can't write
authoritative instructions as I don't use windows.

------------
Installation
------------

Place the files in this directory on an SD card in the following location:
    /reader

Make sure you still have this file on the SD card:
    /Sony Reader/software/autorun.xml

-----
Usage - serial console via USB
-----

Place SD card into device, VOL+ and HOME keys pressed as per instructions for
loader. 

Press OPTION to execute the /reader/main.sh script on the SD card.

When you see "Running SD script", plug the USB cable into the device.

The script tries to do the following:
 * unload the existing USB gadget module (g_file_storage)
 * load g_serial.ko in its place
 * create the character device /dev/ttygserial
 * wait 20 seconds before trying to connect a shell to that device using getty

In those 20 seconds plus the timeout built in to getty, you have to do the
following:

1. Figure out which serial port on the PC it showed up as:
    dmesg|tail
    [448071.790082] usb 2-5: new high speed USB device using ehci_hcd and
    address 27
    [448071.954483] usb 2-5: configuration #2 chosen from 1 choice
    [448071.959565] cdc_acm 2-5:2.0: This device cannot do calls on its own. It
    is not a modem.
    [448071.959711] cdc_acm 2-5:2.0: ttyACM0: USB ACM device
  Here we see it's ttyACM0. It's usually ttyACM0, but depending on system 
  config and on the presence of other serial ports, it could be something else,
  so check.

2. Connect to that serial port:
    minicom -D /dev/ttyACM0
   This could be done more neatly, but it's enough.

When the 20 seconds is up, the device will connect a console to the serial port
and you will see the highly anticlimactic:
#
to make it more exciting, try running a command
# ls                                                 
Data     etc      linuxrc  opt0     root     tmp
bin      home     mnt      opt1     sbin     usr
dev      lib      opt      proc     sys      var
#
Yay! Now run /tmp/sd_card/reader/programs/fb and watch the pretty pattern.

NOTE: the getty command is executed as a daemon (via no_hup), which means that
killing its parent does it no harm. This means we can kill tinyhttp. If you
wish to do that, kill tinyhttp.sh first; it's a script that just respawns
tinyhttp should it die.

One more thing - if you want to put a file onto the device while you're running
the shell over USB, you don't need to disconnect. In the subdirectory lrzsz I
placed the Debian ARM ports of zmodem sending/receiving tools. This means that
you can run:
    /tmp/sd_card/reader/lrzsz/rz
    (which stands for "receive: ZMODEM")
You'll get something like:
    ??waiting to receive.**B0100000023be50
Now in minicom, hit "CTRL-a s", select "zmodem", pick a file (painful
interface, I'll admit) and hit Return, the file will get sent over to the
remote side. If you want to overwrite files or do other stuff, look at the man
page on rz.

-----
Notes
-----

Write new scripts, examine main.sh on how to make them go. Most simple
programs,like getting some diagnostics and logging them to the SD card, or
copying files out will work fine and you'll be able to get back to the home
screen and go back to reading.

This does not go for the nloading/loading/reloading kernel modules. This is all
fiddly and experimental, the device is likely to freeze.  Even if we recover
and you get back to the home screen, the most useful thing you might be able to
do is shut it down.

The worst part is that if the device freezes, it you have to reset it via the
magic reset button (use the stylus, it fits perfectly). The Sony Reader likes
to corrupt file systems when it's reset. The corruption usually shows up as
files being open at the time being messed up. If that happens, you need to do a
filesystem check, if any lost "files" or "chains" or whatever are found,
examine their contents to see which file they're from (likely one of the
scripts that was running at the time) and replace that file.

Try not to run scripts that might freeze the machine while test firmware is
loaded, because then you can corrupt the reader's internal file system and need
to reinstall loader files, or in the worst case, all your books and notes.

----------------------------------
Where to get an ARMv6 LE toolchain
----------------------------------

If you want to write your own programs (see the programs subdirectory) or
compile the kernel modules for this kernel, you need a toolchain for a
compatible architecture. This means ARMv6 little-endian.

There are two ways I know to do this, apart from the painful "build it
yourself".

First option: install the toolchain from the Sony source code page for the
PRS600 (.rpm package, I did not try this as I run ubuntu):
    http://www.sony.net/Products/Linux/Audio/PRS-600.html

Second option: Debian have an ARMv4+ little-endian port going, and their embedded page has instructions:
    http://www.emdebian.org/tools/crossdev.html
Basically, add this repository:
    http://www.emdebian.org/debian/ lenny
then add their public key to your system:
    gpg --keyserver hkp://subkeys.pgp.net --recv-keys B5B7720097BB3B58
    gpg --export --armor B5B7720097BB3B58 | sudo apt-key add -
I installed the following packages:
    cpp-4.3-arm-linux-gnueabi
    gcc-4.3-arm-linux-gnueabi
    libc6-armel-cross
    libc6-dev-armel-cross
    libgcc1-armel-cross
    linux-libc-dev-armel-cross

The script "build" in the programs subdirectory invokes the debian armel tools
to cross-compile a program. You can run that to test if your debian toolchain
works.

-------------------------------
How to get g_serial.ko compiled (USB gadget serial port mode)
-------------------------------

g_serial.ko is the USB gadget serial port mode, making your device look like a
serial port dongle to a PC you plug it into. That's what allows us to run a
serial device over USB.

Compiling a kernel module is a bit tricky. You need the exact kernel version
(provided by Sony), any extra modules they might've added or modified (also
provided by Sony), and the exact kernel configuration (get from
/proc/config.gz).

We'll be getting files from this sony page:
    http://www.sony.net/Products/Linux/Audio/PRS-600.html
This might change locations again in the future, but Sony is under legal
obligation to provide these sources, so if that happens, it's just a question
of finding them again.

Assuming you have a working toolchain, get the linux source code:
    linux-2.6.23_090626.tgz

Unpack it in some location. For me this was in ~/PRS600/extra, making the path:
    ~/PRS600/extra/linux-2.6.23_090626
let's call this path KERNEL

Take your config.gz file, gunzip it, and place into KERNEL/ as config.
Exec:
    make arch=arm menuconfig
there's a menu option in there to use an alternate config file, select it, type
in "config". If it loads, exit and save the configuration (which will be saved
as KERNEL/.config).

Now you can build the kernel and/or modules. Let's try that. In KERNEL:
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- modules
note: if you did not install the Debian ARM toolchain, your CROSS_COMPILE prefix
will be different!

OK. Now, if you modify the config to select USB gadget serial (g_serial) as a module, you're going to be out of luck trying to install it, here's a log of my first attempt:
    g_serial: no version for "struct_module" found: kernel tainted.
    g_serial: disagrees about version of symbol usb_gadget_register_driver
    g_serial: Unknown symbol usb_gadget_register_driver
    g_serial: disagrees about version of symbol usb_gadget_unregister_driver
    g_serial: Unknown symbol usb_gadget_unregister_driver
I was panicking that my toolchain wasn't right and I'd never be able to load
kernel modules on my device. Not so, it was just that Sony went and modified
the underlying USB OTG driver.

Luckily, they provided the sources on their page:
    modules_090626.tgz
unpack that somewhere again, I put it in ~/PRS600/extra, so the path was:
    ~/PRS600/extra/modules
let's call that SONYMOD

To first test that everything is sane, let's build their modules as is. Go
to SONYMOD/usb_gadget:
    make -C KERNEL M=`pwd` ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
where KERNEL is the path to where you put the kernel, and same comment on
CROSS_COMPILE as above.
This will produce a g_file_storage.ko which I was able to successfully load on
the reader.

Now to make g_serial. First, grab the source from the kernel:
    cp KERNEL/drivers/usb/gadget/serial.c SONYMOD/usb_gadget/serial.c
Modify SONYMOD/usb_gadget/Makefile to build g_serial too:
    @@ -17,8 +17,11 @@
     gadgetfs-objs                  := inode.o
     g_file_storage-objs            := file_storage.o usbstring.o config.o \
                                            epautoconf.o usbtg_ebook5.o
    +g_serial-objs           := serial.o usbstring.o config.o epautoconf.o
    +
     
     obj-$(CONFIG_USB_FILE_STORAGE) += g_file_storage.o
    +obj-$(CONFIG_USB_G_SERIAL)  += g_serial.o
Now compile again in SONYMOD/usb_gadget:
    make -C KERNEL M=`pwd` ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-

Now you should have a g_serial.ko you can load on the device. Remember, on the
kernel on the PRS 600, only one USB Gadget module can be active at once. If you
want g_serial, you must remove g_file_storage, and vice-versa.

Future work idea: there is ether.c which compiles to g_ether.ko - this makes 
the device simulate being a network card. Thus, you can build a bridge over it 
on the PC, allowing ssh into the device, or even connecting from the device to
the internet.

-------------------
xaph.net - May 2010
