今天看到有人用Root的Android+Golang搭建Http服务器,这使我想起了变砖的那个机顶盒。

现状

虽说变砖了,但是linux内核能够正常启动,开机看了一下meminfo,如下:

MemTotal:        1009780 kB    总内存
MemFree:          506464 kB    空闲
MemAvailable:     510624 kB    可用

看了一下进程,似乎只启动了com.amlogic.inputmethod.remote这一个安卓进程。

内存有半个G给我发挥,足够了。

配置Wifi

我记得之前是能自连接上Wifi的,但是不知道为啥,似乎现在不连了,就算Android坏了,Linux上面也是可以连Wifi的吧。

理论上可以通过wpa_cli命令设置Wifi,但是执行这个命令会出错,猜测是服务没有启动,我修改文件测试了一下,似乎服务没问题。

linux的wpa_supplicant配置似乎都在/etc/wpa_supplicant.conf,而我的在/etc/wifi/wpa_supplicant.conf,保险起见,编辑完再往/etc/wpa_supplicant.conf复制一份。

ctrl_interface=wlan0
update_config=1
ap_scan=1
network={
	ssid="wifissid"
	psk="password"
	priority=0
}

wifi名没填对的一次,重启设备,和之前一样。

wifi名填对的一次,重启设备,真的成砖了。

新砖

刚刚启动完成就显示SysRq : Emergency Remount R/O,然后会重启,进入一个莫名其妙的模式,连个/bin目录都没有的模式。各种linux命令都不能用,cd能用、cat能用,但是没啥用。

ls不能用,连目录里有什么都看不到,还好,tab键能用,补全一下就知道有什么文件了。

我把/etc/wifi/wpa_supplicant.conf改回去就好了吧!

但事实是,/etc下面根本没有这个文件。

cat了一下meminfo,如下

MemTotal:        1009780 kB
MemFree:          897876 kB
MemAvailable:     901440 kB

对比前后两次的linux内核版本:

Linux version 3.14.29-gd469121-dirty (cusdl2_lan@Amlogic) (gcc version 4.9.2 20140904 (prerelease) (crosstool-NG linaro-1.13.1-4.9-2014.09 - Linaro GCC 4.9-2014.09) ) #1 SMP PREEMPT Mon Jul 6 17:00:59 CST 2020
Linux version 3.14.29-ga1fb381-dirty (cusdl2_lan@Amlogic) (gcc version 4.9.2 20140904 (prerelease) (crosstool-NG linaro-1.13.1-4.9-2014.09 - Linaro GCC 4.9-2014.09) ) #1 SMP PREEMPT Wed Mar 6 15:34:38 CST 2019

最后的编译时间居然不同!猜测两次启动的并不是同一个操作系统。

再往上找启动日志,在U-boot那里,两次启动的启动参数不相同,首次启动rebootmode=cold_boot,再次启动是rebootmode=factory_reset

cold_boot时,会去找SD卡,U盘之类的去启动,最后在flash上启动,factory_reset会直接在flash上启动。

但是!最终的结果不都是启动flash上的系统嘛,为什么版本不同?

看最后,在解压完成内核时,内核的首地址相同,结束地址不同,也就是内核的长度不同,也就是不同内核,接下来,从U-boot全局变量找线索。

看起来是,在factory_reset启动时会多一些启动参数,多了一些aml_dt=${aml_dt} recovery_part={recovery_part} recovery_offset={recovery_offset};if imgread kernel ${recovery_part} ${loadaddr} ${recovery_offset}之类的东西,全是和recovery有关的,我赶紧搜了一下这个眼熟的英文单词,这是安卓的Recovery模式,这个模式在我刷过破解系统之后就莫名其妙进不去了,进去了!

我赶紧插上显示器,果然,Android的Recovery出现在我眼前!

对我的技术来言,现在最好的做法就是重新安装系统吧。早就想给它重新烧录系统了,奈何找不到短接点,又不会拆屏蔽罩,今天就借助Recovery,恢复吧!

翻了一下百度网盘,找到了之前系统包,很不错的满速下载。

找了个U盘,直接复制进去,插给机顶盒安装。

选择文件,点了确定之后就啥选项都没了,终端也什么都没输出。Linux哲学,没有信息就是最好的信息,结果等了一会又回到了Recovery首页,大概是完成了,结果是,没有结果,和之前一样,重试还是一样。

我给它清了一下用户数据,然后重启,好了···

我去看我修改过的wifi配置文件,这些文件还是我改完的样子,离谱了!变砖的原因不是配置Wifi!

继续配置Wifi

不长教训,接着想办法连Wifi。

根据测试,网线是可以连接的,但是我希望不用网线。值得注意的是,ipv6似乎没有启用。

看了下,在/etc/wifi下面还有几个疑似wifi配置文件的可疑文件,我不想一个一个试,我写的格式还不一定对。

所以,从/init.amlogic.wifi.rc找线索:

service rtl_supplicant /system/bin/wpa_supplicant \
    -ip2p0 -Dnl80211 -c /data/misc/wifi/p2p_supplicant.conf \
    -I/system/etc/wifi/p2p_supplicant_overlay.conf \
    -O/data/misc/wifi/sockets \
    -e/data/misc/wifi/entropy.bin -g@android:wpa_wlan0 \
    -N -puse_p2p_group_interface=1 \
    -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf
#   we will start as root and wpa_supplicant will switch to user wifi
#   after setting up the capabilities required for WEXT
#   user wifi
#   group wifi inet keystore
    class main
    socket wpa_wlan0 dgram 660 wifi wifi
    disabled
    oneshot

service bcm_supplicant /system/bin/wpa_supplicant \
    -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \
    -I/system/etc/wifi/bcm_supplicant_overlay.conf \
    -O/data/misc/wifi/sockets \
    -g@android:wpa_wlan0    \
    -puse_p2p_group_interface=1p2p_device=1 -e/data/misc/wifi/entropy.bin
#   we will start as root and wpa_supplicant will switch to user wifi
#   after setting up the capabilities required for WEXT
#   user wifi
#   group wifi inet keystore
    class main
    socket wpa_wlan0 dgram 660 wifi wifi
    disabled
    oneshot
~

可以搭配wpa_supplicant命令的说明研究提到的文件到底是干什么的。

options:
  -b = optional bridge interface name
  -B = run daemon in the background
  -c = Configuration file
  -C = ctrl_interface parameter (only used if -c is not)
  -i = interface name
  -I = additional configuration file
  -d = increase debugging verbosity (-dd even more)
  -D = driver name (can be multiple drivers: nl80211,wext)
  -e = entropy file
  -g = global ctrl_interface
  -G = global ctrl_interface group
  -K = include keys (passwords, etc.) in debug output
  -t = include timestamp in debug messages
  -h = show this help text
  -L = show license (BSD)
  -o = override driver parameter for new interfaces
  -O = override ctrl_interface parameter for new interfaces
  -p = driver parameters
  -P = PID file
  -q = decrease debugging verbosity (-qq even less)
  -v = show version
  -W = wait for a control interface monitor before starting
  -N = start describing new interface

但是我比较懒,感觉上,/data/misc/wifi/wpa_supplicant.conf 实锤了,原因嘛:

  • 百度搜的wifi密码存在/data/misc下面
  • 清理数据理应清理掉wifi密码,也就是我写的wpa_supplicant.conf文件,但却没有,说明这个不对。

/data/misc/wifi/这个目录我之前就来找过,里面并没有wpa_supplicant.conf,但命令都说这么清楚了,我不能创建一个嘛。

保险起见,我把/etc/wifi下的复制过来。

重启之后,没有连接WIfi,考虑到可能是服务没启动,我试了一下start rtl_supplicantstart bcm_supplicant最终都没连Wifi,甚至都没有Wlan0这个网络接口。

有没有可能Wifi服务坏了呢?

算了算了,网线就网线吧。

ssh服务

这个百度有教程,需要编译文件。

这个板子网线接口有些不牢固,防止把网线接口晃掉这种尴尬情况发生,我把板子装回外壳,用Adb工具操作终端。

装上壳子,直接插网线,登录路由器看IP,adb连接25555端口。

Dropbear是一个轻量的SSH服务器。

但是这个似乎用在安卓上面需要一点改动,所以,dropbear-android是帮助修改代码的脚本。

避免更多麻烦,我用linux编译。

搭建Linux交叉编译环境

本来我还在到处找交叉编译,但是交叉编译似乎是个基本操作,直接

sudo apt-get install gcc-9-arm-linux-gnueabihf

就完了吗?

我看了一下脚本,用到了一个叫arm-linux-androideabi-gcc的东西。我的交叉编译器不对。

为了得到arm-linux-androideabi-gcc

先去下载NDK

wget https://dl.google.com/android/repository/android-ndk-r25b-linux.zip
unzip android-ndk-r25b-linux.zip

阴差阳错在android-ndk-r25b/toolchains/llvm/prebuilt/linux-x86_64/找到了交叉编译器。

arm-linux-androideabi-gcc的名字有点不像,armv7a-linux-androideabi19-clang这样子。

改一下脚本就好了啊。不,缺文件。

怎么办,要止步于此吗?

我下载了低版本的NDK-r11c,发现它五脏俱全,好了,版本的问题。

下载这个我用了VPN+多线程下载器。


根据Readme的提示,设置环境变量:

export DISABLE_PIE=1
export TOOLCHAIN=/home/ffeng/dropbear-android/android-ndk-r11c/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/

然后直接开始执行,脚本莫名其妙停止。

经过排除,死在这句话上:

./configure --host=$HOST --disable-utmp --disable-wtmp --disable-utmpx --disable-zlib --disable-syslog > /dev/null 2>&1

为了能够看到错误,改成这样:

./configure --host=$HOST --disable-utmp --disable-wtmp --disable-utmpx --disable-zlib --disable-syslog

得到了这样的错误:

checking whether the C compiler works... no
configure: error: in `/home/ffeng/dropbear-android/dropbear-2018.76':
configure: error: C compiler cannot create executables
See `config.log' for more details

猜测是版本问题,再换NDK版本。

NDK-r17c,不行,还是那样。

NDK-r21e,不行,缺文件。

去去去,我不用SSH了!

假砖

在我等下载的时候,往机顶盒里安装了个apk,我发现,这可不是变砖了,这是因为没有APP可以在开机后运行!Wifi问题解决了。

里面是这样写的:

ctrl_interface=/data/misc/wifi/sockets
driver_param=use_p2p_group_interface=1
update_config=1
device_name=S-010W-AV2A
manufacturer=NSB
model_name=S-010W-AV2A
model_number=S-010W-AV2A
serial_number=000004370020A32000EF6CEFC6B2A062
device_type=10-0050F204-5
config_methods=physical_display virtual_push_button
p2p_go_intent=13
wowlan_triggers=any

network={
	ssid="XXXX"
	psk="XXXX"
	key_mgmt=WPA-PSK
	priority=1
}

IPV6

我需要IPV6地址。

使用ifconfig查询,不管是eth(网线)还是wlan0(Wifi)都不支持IPV6,实际测试,IPV6域名可以解析,但是ping6不可达。

搜索不到相关的东西,gogodroid似乎也不能用,干脆自己研究吧。

adb pull / 本地目录

把根目录下载下来放在本地方便看。

下载倒是没问题,但是研究?我的实力不允许

期待我处理这个问题游刃有余的那一天。

go交叉编译

ipv6弄不好,这个也没大用。

首先写一个hello world,,然后交叉编译:

export CGO_ENABLED=0 GOOS=linux GOARCH=arm
go build .

cgo这个东西是golang调用clang函数用的,CGO_ENABLED=0关闭这个功能,这样才能交叉编译。

安卓有一些目录是不允许执行的,最开始我放在/sdcard里面,无论如何都给不上权限,挪到/data/data下,成功!

总结

从早忙到晚,我做了什么?

好像处了实践证明了Android可以运行Golang程序就没了。

学习,永无止境啊。

我写到这里了,adb的pull依旧没完成。

我能想到的,最大的成功就是无愧于自己的心。