前段时间,由于家中无人,水管突然爆裂,导致水漫金山,以致于把我珍藏多年的高配 TP-Link 给活生生的淹死了。想当年克俭克勤,好不容易买来准备把玩 Openwrt 的(_后来忘了这茬_),看来梦想终是破灭了。
于是,在家人好言相劝并不断督促的前提下,我怒下重金在京东买了小米路由3。一个炎热而又百般无聊的下午,京东快递小哥暧昧的给我递上一个包裹,小米路由安静而美丽的躺在里面,久违的清风吹过,家人乐了,而老司机我这次却坐不住了。
这一次,一定要抽空把玩下这货,以免人生再留下遗憾啊!
开启 SSH
一转眼几周过去了,老司机觉得时机已经成熟,可以对它动手了。而这首当其冲的,是需要我们去剥开它的外衣,直入主题。开启 SSH 后,才可以让我们对它一览无遗,而要开启小米路由3的 SSH,首先我们要升级它的 ROM,稳定版是不能开启的。
升级为开发版 ROM
升级很简单,我们进入这个网址:
http://www1.miwifi.com/miwifi_download.html
选择 ROM 标签,然后下载小米路由3的开发版 ROM,注意不要选错路由器哦。我目前下载到的版本是2.13.33
,然后进入小米路由器管理界面:http://192.168.31.1 ,进入 [常用设置] -> **[系统状态]**,点击 [手动升级] ,然后选择你下载的 ROM,一段时间的等待后,再进入系统状态查看就已经是你升级的开发版啦。
官方工具开启 SSH
有了开发版这个前提,老司机可以带你用官方工具来开启 SSH 了,进入官方的这个地址:
http://www1.miwifi.com/miwifi_open.html
滚动到 开启SSH工具 这里:
点击进入,这里会显示你 root 的密码,赶快用个小本子记下来吧:
点击下载工具包,然后按照官方的步骤如下:
- 请将下载的工具包bin文件复制到U盘(FAT/FAT32格式)的根目录下,保证文件名为miwifi_ssh.bin;
- 断开小米路由器的电源,将U盘插入 USB 接口;
- 按住 reset 按钮之后重新接入电源,指示灯变为黄色闪烁状态即可松开 reset 键;
- 等待3-5秒后安装完成之后,小米路由器会自动重启,之后您就可以尽情折腾啦 :)
不过这里老司机要提醒下,如果你的路由没有固定,那么想一个人完成这整个动作有点困难,对于老司机我,当然就轻车熟路了。
初尝 SSH 连接
一切完毕后,等这一刻是不是已经很久了,那么赶快进入主题吧:
ssh root@192.168.31.1
输入你刚刚记在小本子上的密码,进入后可以看到震撼的欢迎界面:
顿时雷总被鬼畜后那魔性的声音在我脑海中旋转起来,老司机欣然的笑了笑,这工程师文化,牛逼!来不及多想,试验了几个命令,发现opkg
都没有了,看来小米对 openwrt 做了些阉割。扫了扫几个 bin 目录,发现工具还是挺多的,包括一个简化版的 vi。然后再扫了扫 lib 目录,发现里面集成的库还是很多的,值得注意的是 C 标准库用的是uClibc
。
这时候,如果你想在 /root 目录下建立文件,肯定会报只读的错误,没关系,我们重新挂载下 /root,按下面命令执行:
# cd /data
# mkdir -p diy/root
# mount diy/root/ /root
这时候再进入 /root 目录下,就可以进行读写操作了,从现在开始,我们可以做一些更有趣的事情,比如写一个小程序玩玩。
交叉编译环境搭建
小米路由官方提供了插件开发文档,但这种受限且无趣的扩展,老司机是一点都提不起精神,甚至连试都懒得去试。我们需要一些更加激进的玩法,需要更大的掌控权利,所以开发完全原生的应用是个不错的选择。
开发原生应用,那就不得不搭建一个交叉编译环境了,在这之前首先我们要清楚小米路由的 CPU 是什么架构的:
uname -m
输出了mips
,呃,mips
还有大端mipsbe
和小端mipsel
区分,这个在没有法写程序的情况下,还真不好区分。没关系,我们先去官方找找看,有没有现成的交叉环境。
进入刚刚下载开启 SSH 工具的地址:http://www1.miwifi.com/miwifi_open.html
选择 小米路由器插件开发文档,下载下来是一个 sdk_package.zip 文件,解压后看到了 toolchain 目录:
什么鬼?怎么这些 toolchain 都是 arm 架构的,完全不符合情理,老司机都不镇定了。用file
看了下,这些都是 linux 下的二进制文件,作为有追求的 mac 党,果断删、删、删。
于是,抱着好奇的态度,点了旁边 小米路由Mini插件开发文档,下载下来是一个 sdk_package_r1c.zip 文件,解压后看到了 toolchain 目录:
这下 CPU 架构对了,看来是小端mipsel
无疑了,但是老司机怒了,原来这小米路由3就是小米路由mini的升级版啊!没有追求的人可以直接开 linux 虚拟机用这 toolchain 去玩耍了,但老司机是绝对不会做这事。既然官方没有提供 mac 下的 toolchain,老司机决定自己去编译一个。
环境准备
要在 mac 上编译 openwrt,需要有些准备工作,首先用brew
安装一些依赖库,逐条执行:
brew tap homebrew/dupes
brew install coreutils findutils gawk gnu-getopt gnu-tar grep wget quilt xz
brew ln gnu-getopt --force
依赖库安装完后,我们需要导一下环境变量:
export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"
其次,mac 的文件系统默认是大小写不明感的(_Case-insensitive_),而 openwrt 必须在大小写敏感的(_Case-sensitive_)文件系统上编译,这点也不难,我们创建一个即可:
hdiutil create -size 10g -type SPARSE -fs "Case-sensitive HFS+" -volname OpenWrt OpenWrt.sparseimage
hdiutil attach OpenWrt.sparseimage
创建完毕并附加成功后,我们切入到这个盘中:
cd /Volumes/OpenWrt
接下来就是下载源码了,进入 openwrt 的官方 git 仓库:http://git.openwrt.org ,我们发现最新的稳定版是15.05
,那我们就选择这个版本。
git clone git://git.openwrt.org/15.05/openwrt.git
等待克隆完毕,老司机就可以带你编译了!
开始编译
克隆完毕后,我们需要更新和安装下 openwrt 的包列表,执行下面命令:
scripts/feeds update -a
scripts/feeds install -a
等待执行完毕后,开始我们的定制化编译配置了,openwrt 这块做得还是非常人性化的,执行make menuconfig
之后,我们看见一个命令行下的图形化配置界面:
这个界面有点酷啊,注意图中老司机的红色箭头标注,这里选择了系统架构和要构建 toolchain,按两次 ESC,保存后,我们就可以开始编译了。
make toolchain/install
这个要耗蛮久的时间,老司机转身就出门抽烟去了,大概 20 多分钟后它才编译完成,这时候新鲜出炉的 toolchain 就在 staging_dir 目录下了:
久违的 Hello World
这一刻我们已经等得太久了,mac 下的 toolchain 在老司机的轻车熟路下很快就构建了出来,那么我们试试写一个经典的Hello World
吧!
1 |
|
编译前,我们需要指定STAGING_DIR
到 openwrt 编译好的 staging_dir,依次执行如下:
export STAGING_DIR=/Volumes/OpenWrt/openwrt/staging_dir
export CXX=/Volumes/OpenWrt/openwrt/staging_dir/toolchain-mipsel_mips32_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mipsel-openwrt-linux-g++
$CXX helloworld.cpp -o helloworld
正确的生成了 helloworld 文件,我们用file
命令看一下:
helloworld: ELF 32-bit LSB executable, MIPS, MIPS32 version 1, dynamically linked (uses shared libs), with unknown capability 0xf41 = 0x756e6700, with unknown capability 0x70100 = 0x3040000, not stripped
现在放到小米路由上试试吧:
scp helloworld root@192.168.31.1:/root/
结果如下图:
这个Hello World
可真是久违了,那么再来一个更加现代化的Hello World
:
1 |
|
使用如下命令编译:
$CXX -std=c++11 helloworld.cpp -o helloworld2
拷贝、执行,完全没问题!你以为这样的 Hello World 就算结束了么?真正的大招现在才开始呢!
放大招,上 Node
Node JS 可以说在跨平台这一块算是做得非常出色的,而在 openwrt 平台上编译 Node JS 也并非难事,最新的非稳定吧 openwrt 中已经包含了 Node 包了,但遗憾的是,最新的 openwrt 使用的是musl-libc
实现,这个 C 标准库与uClibc
二进制不兼容,所以编译的二进制文件小米路由3是无法使用的。
老司机灵机一动,想到一个最简单的编译方式,把最新版 openwrt 的 Node 包拷贝到15.05
中,用15.05
来编译,如此一来少了很多麻烦的参数配置。于是乎:
cd /Volumes/OpenWrt
# 克隆最新版到 openwrt_dev
git clone git://git.openwrt.org/openwrt.git openwrt_dev
# 拷贝最新版的 feeds 包
cd /Volumes/OpenWrt/openwrt/package
cp -rf ../../openwrt_dev/package/feeds .
这些都执行完毕后,我们再回到 openwrt 根目录make menuconfig
:
注意上图中的层次,保存好后,我们直接make -j2
,漫长的等待之后,在下面的目录中产生了编译好的 Node:
/Volumes/OpenWrt/openwrt/build_dir/target-mipsel_mips32_uClibc-0.9.33.2/node-v4.4.5/out/Release
我们拷贝到路由上,再次写一个Hello World
:
1 | var http = require('http'); |
路由器上跑起来,完全没问题:
本地访问起来,也完全没问题:
还能怎么玩
折腾下来,发现 openwrt 的可定制程度还是相当高的,小米路由3嘛,就是一个弱鸡!老司机觉得,接下来可以折腾、折腾小米硬件相关的 API 使用了(_libroutermain\libxmrouter_)。
当然,永远相信,美好的事情即将发生!