Writing a kindlet

Kindle 提供了一个 Java 的编程接口,有点类似于网页的 Applet,于是 我就尝试如何写一个程序放上去。

基本流程

Kindlet 的主要类库是 KDK,可以从 Kindle 里面直接拷贝出来,位置是

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

编写一个 Main.java

package test;

import com.amazon.kindle.kindlet.AbstractKindlet;
import com.amazon.kindle.kindlet.KindletContext;
import com.amazon.kindle.kindlet.ui.KTextArea;

public class Main  extends AbstractKindlet {

    private KindletContext ctx;

    public void create(KindletContext context) {
            this.ctx = context;
    }

    public void start() {
            try {
                    ctx.getRootContainer().add(new KTextArea("Hello World!"));
            } catch (Throwable t) {
                    t.printStackTrace();
            }
    }
}

设置 CLASSPATH 包含 KDK,然后就可以直接用 javac 编译代码,但这里要 指定 java 的版本:

$ javac -target 1.4 -source 1.4 Main.java

再写一个 MANIFEST.MF 文件,注意 Main-Class 的部分

Manifest-Version: 1.0
Main-Class: test.Main
Implementation-Title: Hello
Implementation-Version: 0.1
Implementation-Vendor: Setarcos
SDK-Specification-Version: 1.0
SDK-Extension-Name: com.amazon.kindle.kindlet
Toolbar-Mode: persistent
Font-Size-Mode: point

使用 jar 命令打包(Main.class 放到 test 目录,因为包名称是 test):

$ jar cvmf MANIFEST.MF hello.jar test

最后用 jarsigner 打包:

$ jarsigner -sigalg SHA1withDSA -keystore developer.keystore -storepass \
password hello.jar dktest
$ jarsigner -sigalg SHA1withDSA -keystore developer.keystore -storepass \
password hello.jar ditest
$ jarsigner -sigalg SHA1withDSA -keystore developer.keystore -storepass \
password hello.jar dntest

hello.jar 改名为 hello.azw2 拷贝到 documents 目录就可以了。

遇到的坑

遇到的大部分问题在网上都能找到答案,但很多时候是不知道自己犯了什么错误, 因此花了一整天才把一切搞定。

  1. java 编译的时候要指定版本
  2. MANIFEST 的内容,最后根据 KUAL 里面的修改
  3. jar 打包的格式原来也不熟悉,目录结构需要按照包的层级保存
  4. 签名的部分花了最久的时间,-sigalg 参数的问题没有在网上看到过

关于签名

签名可以通过 keytool 生成新的签名信息,然后把和系统中的签名信息融合在 一起。但其实最方便的还是用 test 用户来签名,将来把程序拷贝给别人也可以用。 签名文件保存在系统的如下目录:

/var/local/java/keystore/developer.keystore

如果要融合签名信息,也可以使用 keytool 命令:

$ keytool -importkeystore -srckeystore developer-to-import.keystore\
-destkeystore developer.keystore

系统签名文件的密码是 password,三个签名的别名前缀 dkdidn 分别代表 kindleinteracitvenetwork 三个权限,一般用三个签名 都签一遍就好了。

开始的时候我的签名总不好使,对比了 KUAL 签名后的 MANIFEST 之后发现它是 用 SHA1 算法,因此加上 -sigalg 再签名就 OK 了。

Hacking Kindle 3

手里的 Kindle 闲置很久了,忽然想起拿它做点什么。

版本

入手 Kindle 大概是在 2011 年,用的不多,也没有 jailbreak,但由于原生 系统对中文的支持不太好,后来装了“多看”。硬件上是第三代包含 3g 和 wifi 的版本,在 mobileread 论坛上被简称为 k3b,序列号开头四位是 B006。

最近有个想法是用电子墨水屏做一个时钟,这样又省电又有很好的可视角度。 于是就想到了闲置的 Kindle,也许可以让它客串一下时钟。

重装上线

在确定了可以 jailbreak 后,首先对 Kindle 进行了系统升级,直接官网下载 升级包,放到文档目录然后系统菜单里面Upgrade your kindle 就可以了。

然后下载了最新的 0.13.N 版本的越狱包,也是和升级相同的操作就搞定。

之后下载了 UsbNetwork 的升级包,同样是升级成功,不过要设置能使用 usb 网络还是需要一些周折。需要在主屏上按 DEL 键进入搜索模式,再 输入如下三个命令:

;debugOn
~usbNetwork
;debugOff

此时接入 USB 线的时候就会识别为网卡,设置网卡地址为 192.168.2.1 就可以用 ssh 访问地址为 192.168.2.2 的 kindle 了。

接下来安装了屏保的补丁,希望可以改变 kindle 的待机显示。结果确没有 得逞,原因是我的 Kindle 是带有 Special Order 的,待机的时候只能显示 广告,只好卸载了事。

再接下来就安装了 KUAL,是个启动器,可以用来启动 kindle 插件。结果 还必须先安装个所谓的 mkk 才可以正常运行。有了 KUAL 后,启动 usb 网卡 的功能就不用输入命令了,直接有个菜单可以操作。

总结

至此,一个已经越狱的 kindle 就算完工了,之后就想试试给 kindle 编程序, 还是另外开一篇文章吧。

try to install freedos on floppy

对在实验室使用 FreeDOS 的一些问题的解决方案

简介

FreeDOS 终于推出了 2.1 的版本,我也多次在我的电脑和虚拟机里面试用。既遇到了一些问题也找了一些解决方法。

主要问题及解决方法

JWasm 无故死机

这个问题是李老师发现的。我在 Linux 下面使用 JWasm 的时候从来没有遇到过问题。经过仔细排查,发现是版本的问题,FreeDOS 2.1 带的 JWasm 不是最新版,有一些奇怪的 Bug,更新以后自然解决。

edit 无法编辑大文件

受限于 DOS 段的大小,edit 无法编辑大于 64k 的文本文件。感觉这是一个很严重的问题,使我对 FreeDOS 有了负面的看法。缺省安装的编辑软件太弱了。当然可以选择安装 MSDOS 里面的 edit,但它并不是开源的。多亏后来找到了 FED 软件,是一个比较出色的编辑器,暂时还没有出什么问题。

FDAPM 的问题

FDAPM 的问题在我第一篇 FreeDOS 的文章中提过,调用参数改成 ADV:REG 搞定

操作系统的保护

在公共机房安装 FreeDOS 还必须考虑操作系统的安全性。原来是通过硬盘保护卡来保证系统文件不被破坏,现在准备采用软件的解决方案。比较简单的就是将 DOS 系统作成一个映像文件,通过 Grub2 启动管理器来启动 DOS 系统。这样用户就无法很容易的破坏 DOS 系统文件了。

比较简单的是做一个软盘镜像

$ dd if=/dev/zero of=btdos.img bs=512 count=2880
$ /sbin/mkfs.msdos -F 12 -n "FREEDOS" btdos.img

然后启动 qemu 的 FreeDOS 把需要的文件拷贝进去。

如果要通过 Grub2 启动,还必须在 grub.cfg 中加入

menuentry "DOS" {
    linux16 /boot/memdisk
    initrd16 /boot/btdos.img
}

其中的 memdisk 是 syslinux 软件中所带,也要拷贝到 boot 目录下。

这样做的缺点是软盘的空间有限,不能放进去太多的程序,一个解决办法就是做一个启动光盘映像。制作光盘映像也要用到启动软盘,还要用 isolinux 的工具生成最终的可启动光盘。在设定 Grub2 启动项的时候,需要在 memdisk 后面加入 iso 参数,否则无法启动。

在 qemu 中测试通过的 iso 映像在实际硬件上竟然无法识别虚拟的光驱,最后通过 syslinux 中自带的驱动正常识别,顺便加上了光盘的 CACHE。AUTOEXEC 中的增加的代码如下:

DEVLOAD /H /Q %dosdir%\BIN\ELTORITO.SYS /D:CDROM001
DEVLOAD /H /Q %dosdir%\BIN\CDRCACHE.SYS CDROM001 CDRCACH$ 1024
SHSUCDX /Q /D:CDRCACH$

Install Gentoo

主机好久没有更新系统了,一直是 Debian 7,今天换个样。

Debian

本来想装 Debian 8 的,但前两天在 Hasee 机器上装的 Debian 8 有点不太满意

  • grub2 启动 Windows 10 有时候会失败,切换回文本模式好像稳定性好一些。不过实际原因不确定
  • 如果没插网线,启动过程超慢
  • 对 systemd 有一点抵触
  • 实验室其它机器已经装了 Debian,换个样

安装

Gentoo 也不是新朋友了,使用 Debian 之前的主力发行版,两年前在机器上也又装了一次, 但现在 emerge --sync 后无法升级,问题多多,只好重新安装。 一切按照 Handbook 安装,从 stage3 开始,没有出多少问题,之后配置其它软件的时候有一些状况。 简单记录一下:

  • git-daemon 好像不需要安装,这个只是只读访问的一个服务
  • git 用户安装的时候 git-shell 路径写错了,结果一直不能登陆,花了一些时间
  • jfs 的一个旧文件系统不能挂载,一点提示消息都没有,结果最后 jfs.fsck 了一下就好了
  • gentoo 的 L10NLINGUAS 环境变量让我花了一些时间学习
  • HP 打印机需要安装 hplip,结果它还依赖 gnugp,这个需要手动安装,然后才可以安装二进制插件

代码如下:

$ hp-plugin
$ sudo hp-setup
  • vsftpd 安装后也不好用,最后增加了一个 seccomp_sandbox=NO 选项搞定。
  • pip 直接安装的 hyde 也不能用,必须用 python2 版本的

可以使用 python2 指定用的 python 版本

# python2 -m pip install hyde
  • Qt5 的程序无法输入中文。这个问题以前我没有注意过,估计是发行版自己给修复了。

具体需要安装输入法模块的 Qt5 包,然后设置环境变量

# emerge --ask fcitx-qt5
$ export QT_IM_MODULE=fcitx

收获

  • 发现 lxterminal 比较好用,依赖又不多,估计以后是我的主力 term
  • 发现 mupdf 是个不错的阅读器(实际是在安装 gentoo 之前发现的)
  • hackrf-tools、gqrx 和 gnuradio 等都通过 emerge 就可以安装,还是比较方便的
  • pcmanfm 一个轻量级的文件管理器,通过配置文件关联,用 feh 查看图片非常方便
  • feh 的快捷键 v 切换全屏,e 切换 exif 信息

存在问题

  • fcitx 输入法在 LibreOffice 中经常会漏掉几个按键:部分拼音片段成为了英文。
  • lxterminal ctrl+shift+v 粘贴的时候会粘贴两次

HackRF handon

买了一对儿 HackRF,学习使用软件无线电

安装

拿到 HackRF 立刻准备安装相应软件进行测试。我使用的环境是 Debian 7.6,版本有点老,所以后面好多工具版本都不够, 也许我真的该升级一下系统了。

首先下载最新的 hackrf 代码

$ git clone http://github.com/mossmann/hackrf.git
$ cd hackrf/host
$ mkdir build
$ cd build
$ cmake ../ -DINSTALL_UDEV_RULES=ON
$ make ; sudo make install
$ hackrf_info

看起来一切正常,而且好像可以两个 hackrf 一起在一个机器上用。

然后是安装 GrOsmoSdr,应该是个必须的中间件,具体用途还需要以后研究

$ git clone git://git.osmocom.org/gr-osmosdr
$ cd gr-osmosdr
$ mkdir build

后面的 build 过程省略,由于 boost 版本不够,还通过源代码安装的方法更新了 boost。 更新了 boost 后,原来安装的 gnuradio 又不好使了,重新编译 gnuradio。

另外安装了gqrx,此软件功能不明,是用 QT 写的,好像是个频谱分析仪之类,安装的时候 采用了源码安装,结果说 cmake 版本不够,同样对 cmake 进行了更新。结果编译 gqrx 的时候 又说 PulseAuduio 有什么问题,后来没有使用 cmake,而是用 qmake 编译通过

$ git clone https://github.com/csete/gqrx.git
$ cd gqrx ; make build
$ qmake ../ ; make ; sudo make install

HackRF 店家提供的手册上说更新固件需要 dfu-util,于是对它进行了安装

$ git clone git://git.code.sf.net/p/dfu-util/dfu-util
$ ./autogen.sh ; ./configure; make; sudo make install

不过最后没有用到这个软件。因为从 hackrf github 的 wiki 里面看到好像不一定必须使用 这个工具,而是直接使用 hackrf_spiflash 烧写固件。

$ git submodule init  # 在 hackrf 目录中
$ git submodule update
$ cd firmware/libopencm3/
$ make -j 4
$ cd ../hackrf_usb/
$ mkdir build; cd build; cmake ../ ; make -j 2
$ hackrf_spiflash -w hackrf_usb.bin

之后用 hackrf_info 看结果如下(不升级不安心)

hackrf_info version: git-9bbbbbf
libhackrf version: git-9bbbbbf (0.5)
Found HackRF
Index: 0
Serial number: 0000000000000000xxxxxxxxxxxxxxx
Board ID Number: 2 (HackRF One)
Firmware Version: git-9bbbbbf (API:1.02)
Part ID Number: 0x******* 0x*******

使用 HackRF

经过与卖家沟通,可以通过 gqrx 实现 FM 的功能。原来 gqrx 就是一个软件的调制解调器, 可以设定频率,然后选择解调方式(FM),然后通过耳机放出来。具体的说明见这个链接

Fan control to reduce noise

控制电脑风扇,抑制不良噪音

电脑的噪音是我一直要解决的问题,最近有空准备解决一下。首先从硬件角度,我本来想找一款无风扇 CPU,但这样的 CPU 的性能实在是一个瓶颈,还不到可以当作日常工作电脑的要求,于是只能想办法抑制风扇的速度。电源风扇是可以通过硬件解决的:我买了一款无风扇电源,虽然贵点,但的确安静了好多。

然后从软件角度,需要装两个软件包,一个是 lm-sensors,另外一个是 fancontrol。通过 sensors-detect 可以对系统进行检测,看看是否可以判断出所使用的传感器芯片。经过一系列检测之后幸运的识别了芯片型号:IT8728F,只要加载 it87 这个模块就好了。

接下来用 pwmconfig 可以检测当前 PWM 通道和风扇速度的对应关系,并且通过问答的方式将 fancontrol 的配置文件写好。比如要设定最低和最高的 PWM 值,最低和最高的检测温度等。当询问具体用哪个温度值为参考温度时,我选择了 temp_type 为 4 的一个temp_input,应该就是其中的一个核心温度。

最后启动 fancontrol deamon,终于这个世界安静了。稳定后核心温度在 46 度左右,而风扇的速度为 570 左右,基本听不到声音。

Hands on Launchpad(part two) with ARM CM4

一年前拿到的 Launchpad,今天再次拿出来玩,发现好玩不少…

示例代码

原来没有玩转“口袋实验室”的原因是觉得硬件复杂,不愿意多花时间。可这次网上找到了示例代码,马上下载尝试一番。

首先示例代码都是为 CCS 写的,因此必然要做一些移植,主要有如下几个方面:

  1. 头文件修改成 msp430.h 就好了,gcc 通过编译参数可以使用正确的设备头文件
  2. _enable_interrupts 没有定义,需要使用 __eint,当然对应的还有__dint
  3. _nop 要换成 __nop
  4. _bis_SR_register 要换成 _BIS_SR,同样还有 _BIC_SR,如果用在中断中,还要加上 _IRQ

很快,128 段 LCD 就搞定了,但这个板接上口袋实验室就不能再扩展了,有点可惜,扩展和 LCD 暂时不能兼得阿。

Launchpad with TM4C123G

另外一款基于 ARM CM4 的 Launchpad 也是去年拿到的,当时也没有找到合适的工具。今天也花了一些时间在网上寻找,就当快要放弃的时候找到了 KernelHacks 上的一篇文章,前面遇到的问题都迎刃而解。

首先,编程工具可以使用 Github 上的一个项目:LM4Tools,当然 Blog 里面也提到了可以直接用 OpenOCD 编程,这个以后再尝试。有 LM4Tools 一般就够了。

另外,从 TI 网站下载了 SW-EK-TM4C123GXL-2.1.1.71.exe,直接用 unzip 解压(以前我还傻乎乎的用 wine 解压)——必须先建个目录再解压,否则你懂的——进入到目录中后有 Makefile,于是 make,竟然马上就可以编译了,整个过程也没有出错。后来看了一下 PATH 变量,发现 arm-none-eabi-gcc 是在路径中的,真是万幸。

玩了几个示例后发现非常顺利,代码通通不用修改,示例中的 Makefile 完美的支持 gcc,LM4Tools 也很给力……

Recovery from git repo corruption

git clone 的时候发生 error: corrupt loose object 错误,费了一番功夫终于恢复了出来。

问题描述

一个很长时间没有维护的代码树忽然不能克隆了,某个对象出现了错误。具体错误信息的关键字是 corrupt loose object。这个问题我从前遇到过,估计是某次内核文件系统的BUG引入的,不知道我的硬盘上还有多少文件隐藏着问题。处理方法也不难,只要找到对应的文件,并用备份的文件进行替换就好了。可是这次替换回去发现还是不行,竟然连备份也是坏的。接着开始在各个电脑上找备份,而最终以失败告终。

问题解决

最后还是在网上找到了一篇文章,指引我参考了 git 自带的文档:recover-corrupted-blob-object.txt,具体的操作过程和文档不太相同,记录如下:

首先把有问题的 object file 删掉,然后执行 git-fsck --full,按照文档,这里应该会提示一个 broken link from … 的信息,这样就找到了链接到丢失文件的目标,然后通过 git ls-tree 找到坏掉文件所对应的源码。可我这里没有 broken link from 的信息,所以我通过另外的命令:

$ git log --raw --all

从输出信息中找到对应丢失的目标文件,也就可以知道对应的源文件是什么了。我的情况比较简单,对应的源文件正好是最新的版本——也许这也是没有 broken link 消息的原因——之后就通过下面的命令恢复了丢失的目标文件

$ git hash-object -w my-magic-file

后记

这次经历让我对 git 的内部文件组织有了更深入的了解,并且也提示了我备份的重要。重要的东西至少应该备份到不同的电脑上,而且还要保证及时的同步更新。比如我可以保存到 VPS 上,但这也要求 VPS 的稳定和安全。另外,git 的可恢复性还是不错的,重要的数据即使不是源代码也可以通过 git 来保存,这样也可以简化同步的过程。

Install Linux(Arch) to Thinkpad Helix

新买了个 Helix,当然要装 Linux

Debian

Helix 只能使用 UEFI 方式启动,没有 Legacy 模式,Debian 的安装盘都无法启动,实在没有办法了,只好下载了个 Arch,顺利启动安装。实际上后来证明 Debian 8.0 的安装盘是可以 UEFI 启动的,但为什么当时没有在 Helix 上启动成功就不知道了。

Arch

Arch 的安装过程按照官网上的步骤也没有问题,但有几个地方还是让我花了一些功夫。

  1. 安装的 fluxbox 无法设定缩放壁纸,必须安装 feh
  2. gnome-terminal 启动失败,显示 Error constructing proxy for org.gnome.Terminal,原来还必须设置 locale.conf 用:localectl set-locale LANG="en_US.UTF-8"
  3. 很多软件不是缺省安装,费了周折的同时也学了很多八百年用不到的命令
  4. 电磁触摸屏 Wacom digitizer 好不容易配置可以使用了,但定位却不太准,在 .xprofile 里面加上 xsetwacom 的参数设置触摸屏的区域搞定

硬件支持

Linux 对 Helix 的硬件支持一直是我的痛,但经过了几个月的折腾,也算是差强人意了。电容屏直接就支持,电磁屏最开始必须要给内核打一个补丁才可以,到了 4.2 的内核,终于补丁被接受,打补丁的日子也就结束了。

显卡的支持原来也不太好,总会有屏幕闪烁的情况出现,但随着更新内核和 xf86-video-intel 的更新,问题也不知不觉的消失了。

声卡的支持是足足花了四个多月才最终搞定,一直都是内核不支持,只有 hdmi 的输出。后来在升级内核的时候忽然发现多了个声卡设备 broadwell-rt286,但配置了好久也是无法发生。今天(2015-09-30)决定和它死磕,通过 aplay 命令选择第二个声卡来播放,然后不断的用 alsamixer 设置不同的通道开关组合,结果终于听到了声音。然后就是找到 PulseAudio 设置缺省声卡的方法,在 /etc/pulse/default.pa 里增加了 set-default-sink 1 搞定。只是音量略低,不过好像 Windows 下也是如此就没有多理了。差点忘记一点,dmesg 命令曾经提示缺少一个固件,最后从 Windows 版的驱动里面拷贝了 IntcPP01.bin 过去搞定。选择声卡的方法也试了半天,最后用的是:

$ aplay Ring05.wav -D sysdefault:CARD=broadwellrt286

Use bluetooth under debian

一直有个蓝牙键盘闲置,今天在 Debian 系统中尝试使用……

网上找到的资料都比较老,用起来经常达不到必要的效果。首先是要确定主机的蓝牙模块正常。

$ hcitool dev
Devices:

如果 Devices 下面的列表是空的,就表明无法识别主机设备,说明内核驱动没有正确加载。编译内核的时候花了好长时间找 bluetooth 相关选项,很意外发现竟然在 Networking 条目下,对应的驱动模块是 btusb。

加载了驱动之后,使用 bluetooth-wizard 可以连接到键盘,并能正常使用。不过重启之后还需要重新连接,这非常不方便。网上存在一些脚本可以自动连接键盘,但最后都被证明并不是必须的。

至少以下几个说法在我的情况下都不是必须的:

  1. 增加 /etc/bluetooth/hcid.conf
  2. 修改 /etc/default/bluetooth 设置 HID2HCI_ENABLED=0

需要做的只是:

bluez-simple-agent hci0 xx:xx:xx:xx:xx:xx
bluez-test-device trusted xx:xx:xx:xx:xx:xx yes
bluez-test-input connect xx:xx:xx:xx:xx:xx

如果第一步出错:org.bluez.Error.AlreadyExists: Already Exists 只要在第一条命令后面加上 remove 然后重新执行就可以了。这样设置好之后,重启依然有效,键盘可以自动连接。