在 Kindle 电子书上部署 Node.js 运行环境

如你所见,流行的脚本语言如 Python, Lua 都被各路大神移植到了 Kindle 上, 为什么 JavaScript/Node.js 不可以呢?经过一番搜索后我发现,这方面的研究鲜有人进行过,只找到了寥寥几篇老外写的文章,而且年代都十分久远,几乎没有参考价值. Node.js 主页虽然提供了 ARM 架构的预编译二进制包下载,但都只适用于支持硬浮点的设备,不能用于 Kindle. 好吧,那就自己动手,丰衣足食.

我的设备是 Kindle 8 (中亚 558 那款).本文提到的方法应该也适用于其他型号.

首先你应该将你的 Kindle 越狱,并安装 KUAL 和 kterm, 后者是 Kindle 上的虚拟终端.这部分内容本文不作介绍.

接下来是交叉编译.如果你嫌麻烦,可以下载我提供的编译好的二进制包: https://mega.nz/#!VggDTbAI!YSG4-Bwo0tMUmT4txCfxyNZOoqxgvjuoUH7KfigDkTA. 阉割了一些特性(后文会提到).不过我还是推荐你自己编译.

安装好评如潮的 CodeSourcery 交叉编译工具链.去官网下太麻烦,这里有一份百度网盘的链接, GCC 版本为 4.8.3. 下载后解压,假定你把它放在了 /opt/mentor/arm-2014.05 目录中.

然后从 Node.js 主页下载源代码,推荐 7.0 以上版本,因为可以在编译时显式指定为交叉编译.我用的是 v7.9.0. 解压备用.

此时我建议你新建一个 screen 会话.然后需要设置大量的环境变量,将以下内容保存为 Shell 脚本并执行:

#!/bin/sh -e

#Define our target device
export TARGET_ARCH="-march=armv7-a"
export TARGET_TUNE="-mtune=cortex-a9 -mfpu=neon -mfloat-abi=softfp -mthumb-interwork"

#Define the cross compilators on your system
export AR_target="arm-none-linux-gnueabi-ar"
export CC_target="arm-none-linux-gnueabi-gcc"
export CXX_target="arm-none-linux-gnueabi-g++"
export LINK_target="arm-none-linux-gnueabi-g++"
export CPP="arm-none-linux-gnueabi-gcc -E"
export LD="arm-none-linux-gnueabi-ld"
export AS="arm-none-linux-gnueabi-as"
export CCLD="arm-none-linux-gnueabi-gcc ${TARGET_ARCH} ${TARGET_TUNE}"
export NM="arm-none-linux-gnueabi-nm"
export STRIP="arm-none-linux-gnueabi-strip"
export OBJCOPY="arm-none-linux-gnueabi-objcopy"
export RANLIB="arm-none-linux-gnueabi-ranlib"
export F77="arm-none-linux-gnueabi-g77 ${TARGET_ARCH} ${TARGET_TUNE}"
unset LIBC

#Define flags
export CXXFLAGS="-march=armv7-a"
export LDFLAGS="-L${CSTOOLS_LIB} -Wl,-rpath-link,${CSTOOLS_LIB} -Wl,-O1 -Wl,--hash-style=gnu"
export CFLAGS="-isystem${CSTOOLS_INC} -fexpensive-optimizations -frename-registers -fomit-frame-pointer -O2 -ggdb3"
export CPPFLAGS="-isystem${CSTOOLS_INC}"
export CCFLAGS="-march=armv7-a"

#Tools
export CSTOOLS=/opt/mentor/arm-2014.05
export CSTOOLS_INC=${CSTOOLS}/include
export CSTOOLS_LIB=${CSTOOLS}/lib
export ARM_TARGET_LIB=$CSTOOLS_LIB
export GYP_DEFINES="armv7=1"

#Define other things, those are not 'must' to have defined but we added
export SHELL="/bin/bash"
export TERM="screen"
export LANG="en_US.UTF-8"
export MAKE="make"

#Export the path for your system
export HOME="/root" #Change this one with the name of your user directory
export PATH="${CSTOOLS}/bin:/opt/mentor/arm-2014.05:${HOME}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"

bash --norc

(某些路径请根据你的实际情况修改)

顺便一提. Kindle 8 使用的 CPU(SoC) 是 Freescale i.MX6 SoloLite. 这颗处理器使用 ARMv7 指令集, Cortex-A9 架构,不支持硬浮点.可以在 Kindle 上执行 cat /proc/cpuinfo 查看它的详细信息.

上述 Shell 脚本执行后会进入一个新的 Bash 会话中.把工作目录切换到 Node.js 源代码所在目录,准备编译.

执行:

./configure --without-snapshot --without-inspector --without-intl --dest-cpu=arm --dest-os=linux  --cross-compiling --with-arm-float-abi=soft --with-arm-fpu=neon

(推荐加上 --prefix 选项.我当时没加,结果编译好的可执行文件跟其他文件杂糅在一起,得手动去删,幸好我的 /usr/local 还算干净.另外,如果不想复制一大堆东西,也可以加上 --fully-static 选项)

以上命令会使得编译好后的 Node.js 没有 Snapshot, Inspector 和 Intl 三个特性,因为这三个特性会造成编译失败.给强迫症的特别提示:这三个特性用得并不多.

然后执行:

make

好了,没你的事了,慢慢等吧. 使用 make -j2 ,在我的 VPS 上花了十多分钟.编译出来的可执行文件是这个样子:

然后 make install ,去你指定的目录把生成的那堆东西复制出来,传到 Kindle 里.假定你把它放到了 /mnt/us/node 下.将 /mnt/us/node/bin 添加到 $PATH 中(或者,你也可以把 node 和 npm 两个可执行文件链接到 /usr/local/bin 目录下),然后执行:

node

看到 Node.js 的提示符没? That's fucking cool!

另外,NPM 有点小问题,勉强能用.

说下 Kindle 怎么改 $PATH .方法比较蛋疼(因为 kterm 终端不会自动载入一些 Bash 配置文件).安装 USBNetwork 越狱插件并 SSH 连接到 Kindle,然后执行 mntroot rw 挂载读写.修改 /etc/profile ,把第 5 行改为

export PATH=/usr/local/bin:/bin:/usr/bin:/usr/sbin:/sbin:/mnt/us/node/bin

以后,每次在 Kindle 上运行 Node.js 前,先执行 source /etc/profile ,再执行 node .

就是这样,奇妙的玩具语言 JavaScript 又攻占了一种设备.毕竟,

JavaScript is the new C.


实话实说,这是我第一次成功的交叉编译,实在是太不容易了.昨晚熬到很晚,今天又几乎花了整整一天时间,超级累.这里面的坑实在是不计其数.关于 ARM 平台上的 Node.js 的文章倒不少,但基本上都是关于 RPi 和 Android 两大平台的,很多时候只能参考为 Android 编译 Node.js 的资料,很蛋疼.所以,希望这篇文章能够帮到你(不过,应该没人像我一样在非主流的 Kindle 上玩 Node 吧)

对了,我为什么要如此蛋疼地把 Node.js 移植到 Kindle 上呢?一是因为我最近正在 Kindle 上读一些 Node.js 方面的书,如果能够直接在 Kindle 上写代码当然是最棒的;至于二呢,我最近准备搞个大新闻,敬请期待哦~

以上.

 

Update:

这就是我搞的大新闻: Kindle 竟也可以播放 Bad Apple?!

One thought on “在 Kindle 电子书上部署 Node.js 运行环境

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注