top of page
Search
Writer's pictureterrycornall

Kindle 3 (the one with the keyboard) hacking

Updated: Sep 22

I have a spare Kindle 3 (the old one with the keyboard from 2011 or so) that I can play with to see if I can use it as an eink GPS device. (I got a Paperwhite to actually read on...)

It runs a Linux kernel that can be ssh'ed into via a serial port supplied by the USB and usbnet once jailbroken. (or via the internal serial port without the need for jailbreaking) onto and fiddled with. Here is a copy of the notes I've compiled so far (see the Jailbreaking Notes: section at the end for how to Jailbreak).


Offski:

BTW, there's something odd going on as to how to turn the Kindle off. If you just slide the power button for 8 seconds, the screen goes off but the Linux kernel keeps on truckin' (and in fact you can write to the eink screen even then if you know how). When you turn it on again by a short power slider action, the Kindle e-reader works as normal but you can also do things via the ssh (or plain serial connection) into the Linux. If you use something like "shutdown -h now" you do apparently turn of the power but it clobbers the jaibreak next time you turn it off. (My guess is that a powerup from state 0 runs something that cleans up the jailbreak)

Similarly, running "init 0" unjailbreaks and un-usbNetworks it too.


Trust the Process:

When the e-reader app is running, two processes seem to occupy most CPU time. /usr/bin/webreader and cvm (which is the Java virtual machine that does all the work for the e-reading, I think). When the speech synth is on (see Jabberwocky below), another process /usr/sbin/ttsd also uses a lot of CPU.



Serial Offender:

The Kindle 3 has a neat little hidden serial port accessible from outside the case. It lurks in the lower lefthand slot in the side of the case. Note it is 1.8V logic so you'll need an adapter. (Maybe CMOS level uart will work...) I found that a Moxa Uport 1110 usb-serial adapter followed by a homebrew rs232-ttl board using a MAX202 chip worked just fine. I did use a diode in the TX line to the Kindle to avoid exposing its TX input to 5V though. The RX to the PC, although only 1.8V, worked (with the help of the TTL to RS232 adapter and Moxa of course).


I found it expedient to remove that neat little connector and just solder wires to the pcb.


Here's a view from the back of the Kindle with the case open

This serial console is always available and if I can do useful things via it even if the jailbreak and usbnetwork stuff isn't there.


These lines in /etc/inittab are responsible for setting /dev/console to ttymxc0 and enabling login so to looks to me that (at least on the jailbroken Kindle) that a serial adapter connected here would allow logins. No need to change them.

~~:S:wait:/sbin/getty -L 115200 ttymxc0 -l /bin/login
...
inittab:mxc0:2345:respawn:/sbin/getty -L 115200 ttymxc0 -l /bin/login

UN-JAILBROKEN serial offender

This is what comes out at 115200 Baud from the UNJAILBROKEN Kindle on /dev/ttymx0 (i.e. NOT the USB but the tx,rx,gnd connectors shown in image above)

when you hold the power slider for more than 30 sec. (I used a MAX202 ttl to rs23s converter then a Moxa/Uport 1110 serial/USB converter and got 5V for the ttl converter from the VBUS pins of a LilyGo t3 amoled dev board. And using Mobaxterm to connect to com2 which is where the io from the Moxa/Uport 1110 serial/USB converter goes. Fortunately the 1.8V output from the Kindle TX pin is enough even though normally you'd expect 3V-ish into the TTL to RS232. Going the other way, i.e transmitting to the Kindle from the PC via the serial-ttl adapter, you will need to be more careful to cut the 5V down to 1.8V.


U-Boot 1.3.0-rc3-lab126 (Apr 16 2011 - 20:15:23)
CPU:   Freescale i.MX35 at 532 MHz
Board: MX35 Luigi [ POR]
WDOG_WCR = 0xff31
WDOG_WMCR = 0x0
Board Id: SP1B000000000000
S/N: B00AD0B113220CMC                     #########Note serial number!!!!!
DRAM:  256 MB
Using default environment
In:    serial
Out:   serial
Err:   serial
stuff....
Uncompressing Linux.......................................................................................................... done, booting the kernel.
lots more stuff...
Welcome to Kindle!
kindle login:      #here's where you type root and the password to log in

By the look of it (kindle login: start.sh: starting framework), the serial port gives me a shell that I can log into! I need to connect the serial input to the kindle now to see if it will accept commands.... Seems that the RX line INTO the kindle floats at 1.8V when nothing is connected so I suspect a pullup resistor is already there. Maybe pull-down diode from the RX line OUT of the TTL level adapter is all that is needed? If not, here's an idea Kindle serial adapter level shifter circuit - MobileRead Forums  I'm hoping this will allow me to access a shell via this serial port. Note that I might need a password and I only have a short period after boot to login.... See You Shall -N-o-t- Pass! below.

NOTE: According to Kindle 3 serial plug designs - Page 2 - MobileRead Forums "You can see activity on this port only 1-2 min after beginning reboot. After loading framework, you have ~60sec to enter login and password in console, if not, port will be disabled." Hmmmm, password. I've read elsewhere it is a hash of the devices serial number and there is python code to lookup the hash. See You Shall -N-o-t- Pass! below.


Logging into the UNJAILBROKEN Kindle

Further to the section above, once I connected the usb-serial and ttl-rs232 adapters I added a pulldown diode in series with the ttl-level output of the ttl adapter to allow me to connect it to the 1.8V input of the RX line on the Kindle.

When I provoked a reboot on the Kindle by holding the slider for 20-ish seconds and then hit return on the Moxa serial terminal to send a return to the Kindle after I was the "bcut:C def:pcut:pending 15 second cut:" message, it gave me a login prompt!

I tried user root and an empty password but that didn't work. Looks like I will need that serial-number to password unhasher mentioned You Shall -N-o-t- Pass! below.. This login opportunity times out eventually and the Kindle stops responding to keystrokes. However a simple momentary power slide and release then gets it to re-issue the login prompt.


U-BOOTY!

A long power-slide hold (30 seconds) and release causes a whole reboot and I wonder if a return can interrupt that somewhere useful? Yes! I got it to stop at uboot!


If you send a '?' when at the uboot prompt, you get this help.

I'm sure if I knew enough, I could get it to single user mode without a password here, (tried unsuccessfully using "setenv bootargs_base ${bootargs_base} single init=/bin/sh" followed by "boot") but at this point all I know is to issue 'boot' and let it continue until it finishes, then hit return and get a login prompt but which still needs that password. (Read on for how to get it)


You Shall -N-o-t- Pass!

It lets me post my serial number and suggests passwords. One of which worked!

However, there is still a timeout of some sort. I was busy celebrating and after a about 15 seconds of inactivity, I couldn't type anything into the shell! Good news is that just momentary power-slider and release gets it going again. (Have to hit return to get it to do anything, then you can type commands)

Now I can run code from the command line such as writing to the display using eips (See below) So it appears I don't need to jailbreak the kindle at all, I can just login via the serial port. Of course with only one serial port available, and it in use as the console, doe s make it hard to connect a serial GPS at the same time... However I noticed something in /dev/i2c so if I can find the right signals in the hardware, I might be able to add an i2c GPS... (I have one and although it's not as good as the uart GPS it works ok-ish...) I have an i2c compass/accel/gyro that works really well too. Hmm.


Console timeout (bodged but not solved)

There is an annoying thing that happens when you log into the Kindle via the serial port. If there is no serial port activity (either way) for 20 seconds, it stops responding to the console. Momentary sliding the power slide fixes it but I'm looking for whatever it is that is doing this so I can disable it. Not sure if it is a sysctl thing (i.e. something in the running kernel that I can change via sysctl) or something higher up that is say, sleeping the shell. Maybe a software timer? It might be something to do with power saving?

I found different behaviours for this timeout. If the Kindle is still mounted to the PC as a storage device, the home button doesn't restart the console, and you have to use the power slide. But if you eject the Kindle it starts the 'framework' I think (displays book choice menu) and after that the home button will sometimes work to restart the console. But not always.

The console timeout is usually 20s -ish. (but I am sure I've seen much shorter times....)

Perhaps I could run a backgrounded script that sends nulls to serial port...

Yeah, this worked. Made a script called dot.sh and made it executable:

while true
do
        echo -n -e '\x00'  #non-printing null char
        sleep 10  #20 works too but 60 is too long
done

and then issue:

./dot.sh &

from commandline to get it to run in background.

You have to fiddle around with mntroot to make the fs writable to get your script code to persist. Normally you'd want a non-printable char to be echoed so it doesn't show on the console which is why I used '\x00' or null. The -n stops it sending a crlf and the -e allows the use of escape sequences (i.e. the \x00)


You can kill this by running jobs to get the job number (say 1) and then 'kill %1' to stop it. (The '%' is important! )


I could conceivable run this a background job from /etc/rc5.d/S99myscript or as part of the root login profile but I'd rather address (hunt down and kill) the real cause of it and turn that off if possible...


Titty titty boom bah

Here is a link to a script called titty by Geekmaster that displays tiny text on the eink.

Some nice ideas there. Especially about using an image file to generate text chars.


Tinysh

At tinysh - tiny limited onscreen shell - MobileRead Forums there's a complete small script (by Geekmaster again!) for getting the K3 keyboard, using that as a console input and and displaying on the eink.


I put it in roots home as tinysh.sh Works! (though some characters are a complete pain to enter!)


One thing whilst trying to paste from windows into a vi session using Mobaxterm is to turn off the autoindent using

:set noai


#!/bin/sh
#===================================================
# tinysh - tiny limited onscreen shell (v1.0) for K3
#---------------------------------------------------
# Copyright (C) 2012 geekmaster
# MIT License: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#===========================
# initvar - init global vars
#---------------------------
initvar() {
  SYM=126 ENT=28 SHFT=42 SPC=57 DEL=14
  DN=/dev/null
  KN="1234567890____qwertyuiop____asdfghjkl_____zxcvbnm_."
  KS="1234567890____QWERTYUIOP____ASDFGHJKL_____ZXCVBNM_,"
  KP="1234567890____~@#$%^&*()____<>[]{}?/\_____;:'|-+=_?"
  KM=$KN
  B="     ";B="$B$B$B$B$B";B="$B$B"
  CMD= # cmd line
}

#=============================================
# shcmd - emit shell command, preceeded by pwd
#---------------------------------------------
shcmd() {
  echo "echo \"\$(pwd)> $CMD\";$CMD"
  CMD=
}

#===================================================
# getkb - get translated ascii keys from K3 keyboard
#---------------------------------------------------
getkb() {
  shcmd
  while :;do
    A="_"
    set $(waitforkey); K=$1 D=$2
    [[ $D -eq 0 ]]&& continue
    [[ $K -eq $ENT ]]&& shcmd && continue
    [[ $K -eq $SHFT ]]&& KM=$KS && continue
    [[ $K -eq $SYM ]]&& KM=$KP && continue
    [[ $K -eq $DEL ]]&& if [[ ${#CMD} -gt 1 ]];
      then CMD=$(echo "$CMD"|cut -b-$((${#CMD}-1)))
      else CMD=; fi
    [[ $K -eq $SPC ]]&& A=" "
    [[ $K -le 52 ]]&& A="$(echo \"$KM\"|cut -b$K-$K)"
    [[ "$A" == "_" ]]&& A=""
    CMD="$CMD$A"
    eips "$(echo "~~~> $CMD$B"|cut -b-50)"
    KM=$KN
  done
}

#====================
# eicho - eink echo
# usage: eicho "text"
#--------------------
eicho() {
  eips -z 2 38
  eips 0 39 "$(echo "$1"|tr ";{}\\\`!#$%^" _|cut -b-50)"
}

initvar # init global vars
killall -stop cvm launchpad 2>$DN 
eips -c;eips "~~~~~~~~~~~~ Geekmaster Tiny Shell 1.0 ~~~~~~~~~~~"
getkb|sh 2>&1|while read l;do eicho "$l";done
killall -cont cvm launchpad 2>$DN

Waitforkey

There's a builtin /usr/bin/waitforkey that does just that, waits for a (kindle) keyboard entry and returns some codes (not ascii)

e.g.

30 1 #"A" key. The second code is always 1?


Wake up sleepy head

There's a function called /etc/rc.d/keep_awake that looks like it keeps things awake by posting fake user events.


/etc/rc.d/keep_awake &   #run it in backgound

Hmmm, this doesn't keep the console awake though, whatever else it does...

Running ./dot.sh & and /etc/rc.d/keep_awake & and ./date_and_bat_eink.sh (See section A little Flattery goes a long way) seems to keep the battery/date reporting and the console all going and I guess the keep_awake stops it from going to the screen-saver. Maybe?


Init and Runlevels

If I run 'runlevel' I get the response 'unknown'. This is unexpected.


Settings in /etc/inittab tell what scripts to run (usually the ones in /etc/rc?.d where ? is the target runlevel) and the scripts are usually run in order of all the Knn.. scripts then all the Snn... scripts, so S99something (or whatever is the 'last' Snn script) is usually the last one.


If I run "init 2" to send it to runlevel 2. I get a bunch of output telling me what it's doing.

Then when that settles down I execute 'runlevel' and it returns "2 5" indicating that it progresses to runlevel 5 after going to 2. This would be because of the functions in /etc/rc2.d (S50battcheck goes to 'normal' runlevel if battery is OK.)


"Init 0" powers it down because of /etc/rc0.d/S95poweroff. A momentary powerslide will restart it. You'll need the root password again when it reboots.

"init 3" ends up in runlevel 5

"init 1" breaks the console. A 20 sec powerslide is needed to reboot it.

"init 4" causes a reboot due to S99diag_reboot

"init 6" should be a reboot due to /etc/rc6.d/S95reboot

"init 5" nothing happens. I think even though 'runlevel' returns 'unknown' that it is in runlevel 5 already.

"init 7" just kills all processes and hangs. 20s powerslide needed. Probably because there is no entry in /etc/initab for l7 and above...


Infernal devices

/usr/sbin/udevmonitor

Gives a lot of info when an even happens, like a Kindle button pressed.

e.g. A keyboard button. (I think it was the Aa button)

UEVENT[1724224107.183006] change   /devices/virtual/input/input1 (input)
UEVENT[1724224109.046666] change   /devices/virtual/input/input2 (input)

However, I find it impossible to tell which key it was from the info that udevmonitor puts out. As far as I can tell it's the same stuff for any key. Does differ if I hit the 5-way button which is a different 'device'. I guess I'd have to somehow read that device to find out.

BTW, those 'paths' like /devices/virtual/... are not actual file of device paths. They are 'devpaths' and are a name internal to the kernel. I tried to use commands like udevinfo to connect them to a block device in /dev but so far I've had little luck.

In fact I get something contrary like:

udevinfo --query=all --path=/devices/virtual/input/input1
no record for '/devices/virtual/input/input1' in database

On the other hand, I had some success going the other way (from /dev/block-device to devpath):

[root@kindle root]# udevinfo --query=all --name=/dev/console
P: /devices/virtual/tty/console
N: console

I believe udevd is the daemon that handles passing events to the kernel and that somewhere there is a rules file for it... maybe, e.g. in /etc/udev/rules.d/XX-luigi.rules

(luigi is a name associated with the Kindle main board...)


Accessing functions in a script

There are lots of nice scripts in /etc/rc* that have functions I'd like to be able to run from the commandline. That can be done using

sh -c "source script;function"

e.g.

sh -c "source /etc/rc.d/features;memorysize"

Some of these give a text result (like the memorysize) and some just give true or false. A way to call this and deal with a true/false result from the command line is something like:

sh -c "source /etc/rc.d/features;is_Shasta" && echo "isShasta" || echo "notShasta"   #It appears to be Shasta...Deity, mountain or drink?

Terminal condition

There's an annoying 'feature' with the MobaXterm window. If I use up-arrow to get the last command line and it is fairly long and then if I back-arrow or backspace to move back along the command the little cursor jumps up a line. To defeat this, make the terminal window slightly narrower. (80chars?)

I can't see anyway to set this so I just have to drag it narrower.


Mount up

According to Turning an old Amazon Kindle into a eink development platform – adq (lidskialf.net) which is useful source of other info. I can use

mntroot rw

mntroot ro

to change the read only nature of the filesystem.


I tested this my making the fs RW, then making a script in /etc/rc5.9/S99myscript that did an "echo "Hello" and then making the script executable then changing the fs to RO again and then doing reboot. The script executed as expected. This proves two things. 1) the script persisted and 2) I can make changes that will affect the bootup sequence.

It also survived a 'hold power slide for 30 seconds' type reboot.


Gettin' de message mon.


If I run 'dmesg' I can see info about devices as they have started up.

I see things like:

mxc_keyb: I def:drv::Keypad driver loaded
input: mxckpd as /devices/virtual/input/input1
fiveway: I def:probe0::Starting...
fiveway: I def:probe_done::GPIOs and IRQs have been set up
input: fiveway as /devices/virtual/input/input2

This gave me a clue to do

cat /dev/input/event0

and when I do I see stuff happen on the console when I press a Kindle keyboard alpha key or page-turn buttons. It's not easy to interpret, being a bunch of apparent binary, but at least something happened.

Similarly with /dev/input/event1 which responds to the 5-way button.

I tried /dev/input/event2 as well and it is apparently the volume rocker

Also cat /var/log/messages: It gets a bit more interesting when you pull out the USB cable from the PC.


It's a date!

This little script puts the date and time onto the eink display. It doesn't work (except for a few tens of seconds at the start) when the Kindle has been put into its sleep mode by holding the power-slide for more than 8 seconds.

It also doesn't keep running if you just momentarily slide the power or let the Kindle go to 'screen-saver'. I though tit did but it only seems to do this once or twice and then stops. The task is still running when you power-slide again, but when 'idle' it seems to stop. Looks like the power-saving mode is even more stingy than I thought.

I wonder what it'd cost in battery life? Also, I wonder how to control the font to make it bigger?

while true
do
        datemsg=$(date)  #execute the 'date' command and get the result
        echo $datemsg   #show me on the serial console
        eips 10 10 "$datemsg" #stick it on the eink display. Needs the ""
        sleep 10    #could make this 60 secs instead of 10
done

Home again home again Jiggety Jig

I made a directory /usr/home/root and edited /etc/passwd to make that where root logs in.

This way files I make there won't disappear.

Have to use mntroot rw/ro.


A little Flattery goes a long way

Similarly to the date display above, it'd be interesting to have the battery status showing on the eink. Especially as I wanna monitor the battery whilst I am running these background scripts on an otherwise stood-by Kindle to see how fast they drain the flattery. What I need is a command that returns the battery status as a string. Oh, here's one I found in /etc/rc5.d/S90power


/etc/rc5.d/S90power start
Battery Level: 80%
Sun Aug 25 10:13:52 2024  INFO:battery charge: 80%

Note that I see in /etc/rc5.d/S95framework that there is a check for the battery ID from a list of 'valid' ones. This might be useful if I ever need to run from a non-standard power source.


With a bit of jigger-pokery with 'sed' because apparently /bin/sh doesn't have nice substitution command like bash does, I get this script (that I put in date_and_bat_eink.sh in roots home folder (which I changed to /usr/home/root):

while true
do
        datemsg=$(date)
#       echo -n -e $datemsg
        eips 10 10 "$datemsg"
        batmsg=$(/etc/rc5.d/S90power start)
        mbat=$(echo "$batmsg" | sed "s/%/./g") #eips doesnt have '%'
        echo $mbat
        eips 10 12 "$mbat"
        sleep 60
done

Interesting that /etc/rc5.d/S90power reads the battery status from /dev/i2c/0 but in a way I don't understand yet. (Just 'cat /dev/i2c/0' gets a bunch of binary chars)


I think that /usr/bin/gasgauge-info might be useful. It is a binary exe not a script.

Running it can give battery capacity as a percent. e.g

/usr/bin/gasgauge-info -c    #-v gives it as voltage
100%

JAVA

I see when I run top that cvm appears every now and then, and especially if I poke a button on the Kindle. I think that this is /usr/java/bin/cvm and I think that is the Java virtual machine so it looks like the VM is handling the buttons.

Note that there is no javac (java compiler) so you can't do development all on the Kindle. I've read that using Java 8 on the PC works ok for K3. You need a file from the kindle, which is

/opt/amazon/ebook/lib/Kindlet-1.2.jar



Kindlets

You can run Java code of your own using the provided Java interpreter. These applets are called Kindlets. For e.g. there is one that plays chess.


Hello Wordl

eips 10 10 "HELLO WORDL"

will write the string to the 10th char column of the 10th row

Something similar with a jpg file will write the image.


See the website for info on the file buffer direct access:

e.g. the following puts greyscale noise on the screen.


dd if=/dev/urandom of=/dev/fb0 bs=600 count=400/
echo 1 > /proc/eink_fb/update_display

To fill it with black use zero and transform them into all 1s using tr. Hmm:
dd if=/dev/zero bs=600 count=400 | tr "\x00" "\xff" > /dev/fb0
echo 1 > /proc/eink_fb/update_display

In /opt/eink/scripts/diags is an executable (/bin/sh) script file you can run to exercise the eink screen (let it run to completion so you don't leave the eink screen in a strange state...). It will no doubt have lots of goodies about how to write to the screen. (BTW, it comes up with alarming error screens but I'm sure these are just fake test screens...)


EIPS

Is a built-in function on Kindle 3 that puts text and images on eink. Is a bit limited but useful as a start. Look at MobileRead Wiki - Eips for doco. Note that some don't work, like -d

usage: eips [-c|-n|-i [1]|-f] [-b|-g|-o|-m|-p|-s|-z] [[xpos ypos string|file]|num|[row count [stop]]] [[-n ]-r <string>]
  • eips 20 10 hello #puts the text hello at line 10 character position 20

  • -r puts a barcode on screen. e.g. eips -r 123456

  • -n Just writes to buffer. Doesn't refresh screen yet

  • eips '' refreshes and updates display

  • -c clears screen and displays it

  • -i returns info about the screen, sizes etc. 600x800 4 bit, 91chx121 lines

  • -f full update (default is partial update which is nice, no black flicker!)

  • -b looks for a file (bitmap)

  • -g looks for an image file (png or jpg)

  • eips -z first 10 20 scrolls lines between 10 and 20 up one line

  • -s seems to be redundant. eips -s 10 10 hello does the same as eips 10 10 hello Except that eips -s hello clears the screeen and displays nothing but eips hello shows the word hello in top left corner. So not quite the same


Silly old buffer

To save frame buffer contents and then restore them, consider:

dd if=/dev/fb0 bs=600 count=800 > /mnt/us/fb0.raw  #copy framebuffer
#note that a count of 20 rather than 800 gets just one line. 
#Changing bs might allow copying a rectangle out of the middle?
#and restore it to previous contents like this:
cat /mnt/us/fb0.raw > /dev/fb0    #but that starts at top of fb so if
			#restoring a chunk, need to use dd somehow
eips ''   #refresh display

Get the picture

eips has a -g option to load a .png file and it 'works' kinda but not quite.

The png has to be exported as an 8bpc gray type from Gimp.

A 200 by 100 pixel size for the image in gimp results in about a 3cm high 1.5cm wide image on the eink.

Plug the Kindle into the PC so it shows as a folder and put the image in documents. I used a file called 1.png (It has the character "1" in it).

Then eject the kindle drive else the following command can't read the /mnt/us/documents folder.

eips -g 100 100 /mnt/us/documents/1.png  #does display w partial refresh

BUT, here's the kicker, it ignores the first number (xpos) value and always treats xpos as if it was 0. It obeys the second number's value for a Y position in pixels (top left of screen is 0 0 bottom right is 600 800). Does still need the two args after the -g and a filename else it ignores you completely.


I wanted to make a clock this way, and I still could as long as I was happy to make the numbers sideways and turn the Kindle on its side to display just one line along the now top (which was the lh side when in portrait) It'd work but it is irritating that eips ignores the xpos setting. Grr. Look, it even says that I can specify xpos but it doesn't work.


usage: eips [-c|-n|-i [1]|-f] [-b|-g|-o|-m|-p|-s|-z] [[xpos ypos string|file]|num|[row count [stop]]] [[-n ]-r <string>]


BTW, I haven't worked out how to use bitmap images yet. I suspect I've got the format/image type wrong.


Great big clock

As discussed above in EIPS I decided to make a clock (what else to do with a low-power microcontroller with a daylight readable display when I haven't worked out how to connect a GPS to it yet?)

Uses sideways .png files called 1.png, 2.png etc each made in Gimp and exported as 8bpc gray pngs, each 300 x 150 pixels (when rotated. Can make them 150x300, write the char into it, position it, then rotate image before export.)

Loaded into the frame buffer at 0,650 0,450 : 0,200 0,0 I can fit 4 digits nicely. Will need a ':' in between digits 2 and 3 at 0,350 or so but it can be a much skinnier char, say 300x50 (when rotated)

If I wanted to position the clock in the centre of the display, I could make the char images 600x150 but only put black pixels in the central 300x150 section.


It's EINK time

Here's the code (parseDatetime.sh) for a script that will display the time on the eink screen.

It uses .png files for the large digits. It's not fast or efficient but it is simple! (some of the tests like if [[ -n $dig ]] might not be necessary whcih could simplify it even more. Note it assumes that time +%H:%M always returns two digits each for hour and mins. It does on mine...) Note also that although eips takes arguments for both x and y position of an image, it ignores the x argument and treats it like 0 all the time. So this is a single-line display and the images have to be sideways. Also the device has to be in portrait mode (the default) even though the time display will appear in landscape orientation. The display blinks as the screen clears before update so you wouldn't want to run this at a short interval. 60 secs is fine. You might skip a minute though.

#This gives hours and minutes separately and only calls date once
#to avoid an issue at change of hour.
nowtime=`date +%H:%M`  #get time as hrs:mins
echo $nowtime
nowhour=`echo $nowtime |sed 's/[:].*$//` #remove :followed by anything to end
echo hour=$nowhour
#nowmin=`echo $nowtime |sed 's/[^:]*://` #remove anything up to a :
nowmin=`echo $nowtime |sed 's/.*://` #remove anything up to a :
echo min=$nowmin
#clear eink
`eips -c`
#note that the -o option for grep returns only the matching part
#there are always 2 digits, 0 led
dig=`echo $nowhour |grep -o '^[0-9]' ` #retrn leftmost digit
if [[ -n $dig ]] #needs a space after [[
then
        echo "first digit=$dig"
       `eips -g 0 600 /mnt/us/documents/$dig.png` #show the digit on the eink
fi

dig=`echo $nowhour |grep -o '[0-9]$' ` #retrn last digit
if [[ -n $dig ]] #was there a second digit?
then
        echo "second digit=$dig"
        `eips -g 0 450 /mnt/us/documents/$dig.png` #show the digit on the eink
fi
#now the colon
`eips -g 0 325 /mnt/us/documents/colon.png` #show the digit on the eink
#now get minutes digits
#note also that always 2 minute digits, 0 leading if needed
dig=`echo $nowmin |grep -o '^[0-9]' ` #retrn leftmost digit
if [[ -n $dig ]]
then
       echo "first digit=$dig"
        `eips -g 0 150 /mnt/us/documents/$dig.png` #show the digit on the eink
fi
dig=`echo $nowmin |grep -o '[0-9]$' ` #retrn last digit
if [[ -n $dig ]] #was there a second digit?
then
        echo "second digit=$dig"
        `eips -g 0 0 /mnt/us/documents/$dig.png` #show the digit on the eink
fi

Wrapping it up

I wrap the parseDatetime.sh in another command that does things like stopping the devoice from going into low power sleep mode and then calls the code to get and display the time every 60 seconds and sleep in between.

`./keep_awake.sh &`  #stop it from going to sleep
while [ -x ./parseDatetime.sh ] #if the executable exists and is executable
do
        time=`./parseDatetime.sh`
        `sleep 60`
done

However there might be something wrong with the ./keep_awake.sh & (which calls /etc/rc.d/keep_awake 20 to stop the device powering down to sleep. It seems to hang on this. Maybe don't use the '&' to background it? Maybe it's a problem if keep_awake has been called already? Dunno yet...


Inversion layer

I'd like my clock screen to be inverted, i.e. mostly black but with white text. This is so it doesn't appear so bright from reflected light when I wanna go to sleep.

Is there a setting for eips that says 'invert the pixels on the screen?' (Otherwise I gotta redraw my digit images as white on black...)

Can't see anything yet... eips might have a -v option for 'inverted picture' but this K3 ignores it.

Other option would be to run through the fb and invert every bit but that's gonna be slooow.



Sounds like fun

Jabberwocky

Just for fun try running 'jabberwocky' It starts the text to speech engine and recites The Jabberwocky.

Looking at the program, it is a script that pipes text into the tts thing.

You can also do:

echo '{ id=(0),text="hello"}'|lipc-hash-prop com.lab126.ttsd enqueueSnippet

Green LED is a Class act

In /sys/class there are a bunch of interesting directories like 'leds', 'i2c-dev' and so on. I think they might give access to devices like the power led(s) (there's a ledsr a ledsg and a ledsb i.e. RGB mentioned in this directory)

I found some maybe useful info about the use of the leds class here:

e.g. if I read one of them:

cat /sys/class/leds/pmic_ledsg/brightness it returns 0 (the led was off at the time)

and if I did this:

echo 10 > /sys/class/leds/pmic_ledsg/brightness

it came on dimly!

It seems that 255 (brightest) is the most it can be set to.

Looks like an RGB led but only pmic_ledsg does anything. pmic_ledsb and r don't affect it. Which is odd because that power LED can be amber as well as green when it is not yet fully charged. Hmmm.


Now, if I could just pipe this LED to make it act like a front-light. I want a very dim one for nighttime and this looks like it could provide about the right brightness (it may be slightly too dim 'cos it's only one weeny little led) but I'd need some sort of light guide/foptic thingy to get the photons where I want them to bounce of the big white clock digits I've programmed it to display. And any losses would make it probably too dim even when set to 255. I could rewire it I suppose to bring it out and maybe even have a parallel led string like a nOOd from Adafruit if the hardware is up to it.

Also, if you have the power plugged in, which it will be mostly when this is in use, the led is lit green anyway but you can turn down its brightness this way. (PWM, I guess)

I should look for a cheap fibre-optic toy from a $2 shop to take apart and re-use. I used to have a bunch of foptic cables for high-speed serial interfaces from work but I returned them all when I retired. Damn my honesty....


I haven't found a 'gpio' this way though. Sad.

However, doing 'find / -name "*gpio*"

resulted in a number of hits like:

/sys/devices/system/mxc_gpio/

but it appears to be an empty directory so I dunno what that means.



Jailbreaking Notes:

Although most of the above stuff can be done without jailbreaking, just using the serial port, a jailbreak and the use of usbnet lets you use the usb port for sshing into and do other stuff. Just be aware that it all seems to go away if I have to long-reset the Kindle or if its battery goes flat.

Terry Cornall wrote this using info from https://www.mobileread.com/forums/showthread.php?t=88004:
To jailbreak your kindle and run usbNetwork:
Plug it into the PC via usb. Use PC File Explorer to open the un-jailbroken kindle that appears as a mass storage. 
Put Update_jailbreakxxx.N_K3gb_install.bin and Update_usbnetworkxxxx.bin in the Kindle's apparent top directory, then on the Kindle (you might need to unplug it and do a power-slide to turn it on)
do a menu->settings->menu->update
Then read on below:
After doing menu->settings->menu->update on the usbNetwork file you copied to the Kindle, eject and unplug it (you might need to momentarily slide the power slider to get the e-reader going to get to menu)
 and then wait for it to stop spinning its cursor. (yes it takes a while. Yes you do need to wait)
You'll need to be in debug mode to run private commands, so, on the Home screen, bring up the
search bar (by hitting [DEL] on Kindle 3 keyboard for example), and enter (in my case using the keyboard on the Kindle but if yours doesn't have one, dunno...):
;debugOn   //note that the ';' is needed. Use SYM button to find a ';'
* And now we can enable usbnet:
~usbNetwork  //note that the '~' is needed too
(Or `usbNetwork on FW 2.x)
* Your Kindle should now be detected by the PC as something like a RNDIS/Ethernet Gadget or CDC Ethernet Device network adapter when you plug it back into usb. (You might need to install a driver...)
* If you don't need to enter any more private commands, switch debug off.
;debugOff  //again, this is using Kindle keyboard. Dunno if there's a linux command you could issue via ssh)
Then plug kindle back into USB on PC and note that it doesn't appear as a disk drive. You should be able to ssh to it now...
USBnetwork
Then see if a new serial device has appeared in deviceManager (this is on WindowsPC )
It does, on USB serial on COM9 but I can't open a serial session to it on any baud rate.
Opening that port in device manager says its baud rate is 9600 but that doesn't work.
I tried to open a serial terminal to it using MobaXterm but it said it couldn't configure it.
I checked in the device manager Network adapters and I don't see any unidentified network
that might be the kindle (and nothing changed when I removed it from USB) so
I think I need to do ethernet over USB with RNDIS driver. https://www.mobileread.com/forums/showthread.php?t=272170
and then use device manager to update the com9 driver and assign an ip address. Did that and
now I see Kindle USB RNDIS device in devicemanager->network adapters.
Gave THE ADAPTER (not the kindle) an IP of 192.168.2.1 using:
 pc->settings->network adapters->ethernet->change adapter options->ethernet3 (kindle..)
->properties->ip4->properties->gave it 192.168.2.1 and mask 255.255.255.0
Now I can ping 192.168.2.1 (this is the interface on the PC)
and I can ping 192.168.2.2 (this is what the kindle thinks it is)
Using a mobaxterm bash terminal session I tried:
ssh root@192.168.2.2  and XXXXXXX (not literally) when asked for password and I'm in!!!!
Wifi network:
From a console running on the Kindle (see section above) I can run:
ifconfig -a and it shows wlan0  (after I turned on the wifi in the kindle menu)
I can ping google.com for example, so it is network connected.
I could do apt get installations now! (Have to make root writable though... mntroot rw? Also, there's no apt installed...)
Uninstallers
I put the uninstallers in /mnt/us/uninstallers using something like:
scp Update_jailbreak_0.13.N_k3g_uninstall.bin root@192.168.2.2:/mnt/us/uninstallers/
Disconnecting:
Even when the kindle is supposedly off (i.e. slide right for 8 seconds and screen goes blank)
The ssh session from the PC still stays on. Weird. And I can plug in the usb and re-establish
the ssh even without turning the Kindle on. Obviously off is not really off.
(NOTE: Don't do this!) I wonder if I run shutdown to completely turn it off?
Hmm, that kicked me off and
now I can't log back in. And the kindle won't come on even if I right slide the kindle
 power switch momentarily. Even holding it right for 30 secs doesn't turn it back on.
Oh, wait, after that it did come back, but took a while! Scary. Acting like a flat-battery recovery.
The black tree and progress bar. Takes a while. but then can I ssh back in... No!
It has reset everything I just did.... Yes, yes it did. Dang it! Shows up as a storage device again. At least the files I put in the uninstallers dir are still there so I can do this all again if I want.

Comments:
NOTE: You can turn off the Kindle using the 'hold slider right for 8 secs' method. (However the Linux keeps running so all you've turned off is the e-reader app, I think) I suspect that leaving it in this state for too long (a few days, a week, a month? Dunno yet) will flatten the battery and you'll have to jailbreak and usbNetwork again...

BUT if you are silly enough to run 'shutdown -h now' on the kindle via a ssh shell then it will undo all the stuff you do below and you'll have to go thru it again. Similarly if you let the battery go flat or do a factory reset (i.e. hold slider for 30 secs)

You can find the jailbreak files in the /mnt/us/uninstallers dir. (The /mnt/us folder appears as the top folder on the Kindle when it is acting as mass storage, i.e. not jailbroken)

I left the Kindle alone for a few days, then opened the case. It didn't seem to work after that... So I charged it a bit and fiddled around with the power switch (off oand on, not a 30 second factory reset yet) and eventually got the usb console ssh to connect to it again. Was it flat battery? Can't seem to get the e-reader functionality to come up. However, using eips 10 101 "HELLO WORDL" works to write to the screen, though oddly it is sideways now. I suspect that running /opt/eink/scripts/diags has left it in a strange state. Maybe ctrl-c-ing out of that caused a problem.
Possibly an init 0 is needed? (NO that unjailbreaks it similar to shutdown -h...)  Instead I ran /opt/eink/scripts/diags again and (tried to) let it run to completion... Hmm, does it ever complete or does it run forever... certainly goes on and on.... ctrl-c required and then I'll have to work out how to get it back in its init state.

init 0 wasn't a good idea. Can't connect the usb ssh console now and when I slid the power for 8 secs, it came back with the black tree screen. I think I've unjailbroken it again....

SSSSSSSH be vewy quite:

Once jailbroked and usbnet is running, to ssh into it, just plug it into the PC via usb, (It needs to be on a particular USB port in order to get the right driver for the adapter...) start an MobaXterm or similar shell, and proceed to ssh. (you need to know what user, what password, what IP address and I'm not gonna tell you mine...)

8 views

Recent Posts

See All
bottom of page