为了不影响孩子的学习,家里的电视基本上只有逢年过节才打开看看,偶尔老婆想追个剧啥的,就只能躲着孩子在电脑上看,可毕竟坐在电脑前追剧不如躺在沙发上看电视,正好元旦假期在家休息,一时心血来潮,捣鼓着在电视上看奈飞,研究了小半天,发现乐视上还真玩不转,于是,只能另寻他法——弄个电视盒子。

N1 盒子

于是,在某宝上逛了一圈,发现 N1 盒子是 Android 系统,还可以自己刷机玩,于是花了 150 左右淘了一个没有刷过的盒子(带遥控器),最初这盒子都是白送的,后来这家公司黄了,反而物以稀为贵,从几十块一路涨到了 150。

连接 Wifi

快递很快就收到了,卖家还送了一根双公头 USB 刷机线和 HDMI 线,插上电源试着接上电视,发现 Launcher 是定制过的,只显示了设备信息和网络信息,接上鼠标,配置好 Wifi 后,便能看到设备的 IP 地址,如下图所示:

N1 Screenshot

打开 adb

点击 固件版本 4 次,正常情况下,会弹出 Toast 「打开 adb」,这时,便可以在电脑上通过 adb 远程连接到盒子了:

1
adb connect 192.168.1.78

连接成功后,会看到 adb 输出:

1
connected to 192.168.1.78:5555

连上设备后,就可以通过 adb 来安装各种应用了,而对于电视来说,Kodi 是值得一玩儿的。

Kodi

对于开发过 Android TV 应用的程序员来说,不知道 Kodi 都不好意思说自己是 Android 程序员,其实,Kodi 这个名字是后来改的,以前叫 XBMC,它是一个跨平台的家庭多媒体中心,支持 Windows , Linuxmac OSAndroidiOS ,算是相当强大的一款应用了,它的跨平台技术完全是基于 C++ 做了一套 GUI 系统,为界面布局单独定义了一套 XML 规范,而在 Android 平台上,只有少量的 Java 代码,连 MainActivity 都是继承自 NativeActivity,同时,它还支持 PythonSambaUPnP 等等。

泡泡云

大概是 2010 年左右,那时候云计算炒得火热,云盘如雨后春笋,有一天,老板在全员大会上给我们演示了一把在他的 iPhone 上使用 DropBox ,我们正在感叹其功能之强大,突然话风一转 —— 我们要做私有云!当时大家都惊呆了,一脸懵逼的看着老板。

相对于公有云而言,私有云的存储设备是放在家里的,所有端到端的的数据访问都要通过 HTTP Relay Server 来进行通信,这样的好处是设备不需要绑定域名就能从外网访问设备上挂载的硬盘里的照片、视频或者其它文件了,而且还能穿透防火墙。

不知道是谁想出来的「泡泡云」这个名字,还是挺接地气的,还上了百度百科。整个盒子是基于 AMLogic 的方案,为了降低功耗,就把 Android 的整个 Framework 都去掉了,只保留了 Kernel 和根文件系统,还改了 init.rc ,记得当时定制 init.rc 的时候掉到了坑里,service 总是启不起来,后来,对着源码一行行的看,才发现原来 service 的名字不能超过 16 个字符 😂

为了更好的支持挂载 SATA 硬盘,把 Volume Daemon 也改了。作为私有云服务器,必须得有一个 app server ,调研下来,最终选择了 Python ,所以把 Python 2.7 移植到了 Android 平台上。

为了支持局域网文件共享,又移植了 Samba ,一想到 Samba 就头疼,移植起来是相当的费劲,因为 AndroidC 库是 Bionic C,而 Samba 使用的是 GNU C ,很多 APINDK 里都没有,如果要移植到 Android 平台上,就得自己实现这些 API ,也是在那个时候,我才知道原来还有 netlink 这个东西,对于毕业 3 年的我来说,那段经历让我成长了不少。

切换到 root 用户

一般情况下,我们切换到 root 用户是通过 su (switch user) 命令,但在 N1 上执行 su 会提示:

1
Please enter password!

各种尝试都不行,卖家也不知道,网上也没搜到,后来根据网上的刷机脚本,找到了切 root 的办法,原来 N1 是通过系统属性来控制的:

1
2
adb shell setprop service.phiadb.root 1
adb shell setprop service.adb.root 1

然后再重启一下 adb 服务,重连一下设备:

1
2
adb kill-server
adb connect 192.168.1.78

然后再执行 adb shell,便进入了 shell

1
p230:/ #

看到这里的 # 就知道,现在已经是 root 了(普通用户的命令行提示符是 $),如果不相信,可以通过 whoami 来查看当前用户:

1
2
3
p230:/ # whoami
root
p230:/ #

有了 root 权限,就可以随便折腾了。

刷机 Armbian

当时,泡泡云市场价大概是在 500 RMB 左右,硬件的成本价大概是 200 RMB,相比现在的 N1 ,发现 N1 是真香,一个要用来看电视,不够玩儿,于是又淘了一个,为了玩 Docker ,于是选择了刷个 Armbian (Debian Linux for ARM) 玩玩儿,刷机之前,得先准备以下材料:

  1. 电脑,首选 Windows 系统
    一般都是用的 AMLogic 提供的 USB Burning Tools 软件直接连着设备刷机(俗称线刷),但 USB Burning Tools 只有 WindowsLinux 版本,mac OS 只能通过 USB 启动盘来刷机
  2. 双公头 USB 线(线刷才需要),最好多备几根
  3. Armbian 镜像文件,网上一搜一大把,如果懒得找,可以用这个:云盘链接
  4. 8GB U 盘至少一个,有些 U 盘兼容性不好,可能启动不了,需要多换几个试试,反正我用的第一个 U 盘就不行,捣鼓了很久,都开始怀疑人生了,结果换了一个立马就好使了)
  5. 启动盘制作工具 - balena Etcher (线刷可忽略)
  6. USB 键盘一个
  7. HDMI 线一根
  8. HDMI 接口的显示器/电视一台
  9. 网线一根

mac OS 刷机其实也很简单:

  1. balena Etcher 做好启动 U
  2. N1 断电
  3. 插上网线
  4. 插上 HDMI 显示器
  5. 再插上 U
  6. 接上 USB 键盘
  7. N1 上电

如果能看到 Linux 的启动日志,说明从 U 盘启动成功了,否则,换个 U 盘试试。启动完成后,会提示登录,输入:

  • 用户名:root
  • 密码:1234

登录成功后,会显示 AML S9XXXlogo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    _    __  __ _       ____  ___
/ \ | \/ | | / ___|/ _ \__ ____ ____ __
/ _ \ | |\/| | | \___ \ (_) \ \/ /\ \/ /\ \/ /
/ ___ \| | | | |___ ___) \__, |> < > < > <
/_/ \_\_| |_|_____| |____/ /_//_/\_\/_/\_\/_/\_\

Welcome to Debian GNU/Linux 10 (buster) with Linux 5.9.16-flippy-51+

No end-user support: built from trunk

System load: 2% Up time: 13 days 12:11
Memory usage: 17% of 1.70G Zram usage: 7% of 0.85G IP: 172.30.0.1 192.168.1.81
CPU temp: 42°C Usage of /: 33% of 7.0G storage/: 53% of 192M

[email protected]:~#

到目前为止,还没有真正的刷机,只是从 U 盘启动而已,如果要想脱离 U 盘启动 Armbian ,需要把 U 盘里的内容写进 eMMC 存储器,系统根目录里已经有内置的脚本:

1
2
3
4
[email protected]:~# ls -l
-rwxr-xr-x 1 root root 82 Dec 30 22:46 install-docker.sh
-rwxr-xr-x 1 root root 8626 Dec 30 22:46 install-to-emmc.sh
-rwxr-xr-x 1 root root 221 Dec 30 22:46 install-zerotier.sh

只需要执行 install-to-emmc.sh 即可,如果想把 dockerzerotier 也一起刷进去,在执行 install-to-emmc.sh 之前,先安装 dockerzerotier

1
./install-docker.sh && ./install-zerotier.sh && ./install-to-emmc.sh

如果对 Docker 命令行不熟,可以安装一个 Web 版本 Docker 客户端 portainer

1
2
3
4
5
6
7
docker volume create portainer_data && docker run -d \
-p 9000:9000 \
--name=portainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer

安心看奈飞

之前用 N1 当电视盒子看奈飞时,用的 Igniter ,但是很不稳定,经常看着看着网络就断了,为了能好好的看完一部电影,只好弄个 Proxy Server 了,这里选择了用 trojan 来作 SOCK5 代理服务器,那么问题来了,很多设备并不支持 SOCK5 协议,只能走 HTTP(S) 协议,为了解决这个问题,于是选择了 privoxy,将 HTTP(S) 的请求封装成 SOCK5 的协议转发给 trojan ,详见:https://github.com/johnsonlee/proxify ,已经完全 Docker 化了,在 N1 上部署的话,直接用 docker-compose 启动就行了:

1
2
3
4
5
git clone https://github.com/johnsonlee/proxify
cd proxify && docker-compose up -d \
-e TROJAN_SERVER_HOST=xxx \
-e TROJAN_SERVER_PORT=xxx \
-e TROJAN_PASSWORD=xxx

默认 SOCK5 的端口为 1080HTTP(S) 的端口为 1081

软路由

当然,也可以刷个 openwrt 来玩玩儿,但 proxify 基本能满足日常需求了,所以懒得折腾了。