作者:admin 日期:2023-09-12 瀏覽: 次
編程開發,用個安卓手機當linux服務器就行
舊的安卓手機不要扔,可以拿來做一個微型的linux服務器,編程開發,跑服務都不在話下!本文就以6年前發布的小米2s為例,親自帶大家一起體驗一下這種手機服務器并簡單分析其中的一些原理。
像小米2s這樣已經發布6年多的手機,配置已經不夠用了。但是我們知道,谷歌每年發布的新安卓系統版本都有性能的優化,所以舊手機如果能升級系統,自然也能改善性能。工欲善其事必先利其器,我們先把舊手機升級一把再說。
魔趣ROM介紹
這是一個國內團隊維護ROM,開源并且支持多款安卓設備。最主要的是他跟隨谷歌的腳步,當有新的安卓版本發行后,魔趣ROM很快就能為多款安卓設備適配。
魔趣ROM下載地址:https://download.mokeedev.com/,需要的朋友可根據自己的手機型號選擇下載并刷機使用。
例如我的小米2s手機,選品牌和型號
選安卓的版本,我選的是8.1版本:
怎么刷機不是我們關注的重點,需要的請到魔趣論壇或百度搜索。刷機后,我那6年前的破手機用上了androd 8.1:
魔趣ROM的是開源的,這意味著:只要我們愿意,隨時可以下載代碼下來定制自己的ROM,這非常符合開發人員的胃口!
理解linux與安卓的關系
首先,安卓操作系統的內核是基于linux的,谷歌為安卓系統做了特殊的定制,如增加了binder驅動,適合手機的電源管理驅動,Low Memory Killer驅動等等。
其次,安卓系統和普通的linux的libc庫不一樣,可執行程序需要專門的android編譯器(arm-linux-androideabi-gcc/g++)編譯,用專門的鏈接器(arm-linux-androideabi-ld)鏈接專用于安卓的libc.so才能運行。
為什么我們只關注C/C++,不是有那么多語言編寫的程序嗎?
因為c/c++是基礎,離開它們基本沒什么能跑的了。java虛擬機是c++編寫的,python的解析器是c寫的,js的解析執行引擎也是c/c++寫的。。。
本文的主角---termux簡介
termux 是一個安卓平臺下的app, 它能夠在安卓上實現一個微型的linux,具有命令行界面,可以以apt方式簡單的安裝各種軟件。
termux的安裝與使用
軟件下載地址
https://f-droid.org/packages/com.termux/
軟件界面
軟件安裝后,在手機上展現的界面如下所示,與我們平時操作的linux終端長得一樣:
安裝openssh,并從PC端訪問
終端界面在手機上操作不方便,所以我們安裝一個ssh服務,然后用PC來操作它。
更新軟件源
1apt update
安裝openssh-server
1pkg install openssh
給termux對應的用戶設置一個密碼
1$passwd
2
3#根據提示設置一個密碼
4New password:
安裝后,需要手動啟動sshd
1sshd &
注意:termux的ssh服務默認端口為8022
測試連接
在PC端,我在windows上用secure crt連接手機的sshd,設置端口為8022,連接似成功的。連接成功后,你就真正擁有一個微型的linux服務器,可以將手機息屏,為所欲為啦。
termux的簡單分析
termux在android系統中運行,與普通的app沒有什么兩樣,在apk安裝時,系統為其分配一個用戶,例如我的分配的用戶為u0_a79。我在手機上點擊termux這個app后,其實termux會以u0_a79這個用戶身份創建一個新的bash進程,然后所有的命令都在這個bash進程里解析執行。
在termux的界面輸入export命令,結果如下:
1$ export
2declare -x ANDROID_DATA="/data"
3declare -x ANDROID_ROOT="/system"
4declare -x EXTERNAL_STORAGE="/sdcard"
5declare -x HOME="/data/data/com.termux/files/home"
鹽城數據恢復 6declare -x LANG="en_US.UTF-8"
7declare -x LD_LIBRARY_PATH="/data/data/com.termux/files/usr/lib"
8declare -x LD_PRELOAD="/data/data/com.termux/files/usr/lib/libtermux-exec.so"
9declare -x LOGNAME="u0_a79"
10declare -x OLDPWD
11declare -x PATH="/data/data/com.termux/files/usr/bin:/data/data/com.termux/files/usr/bin/applets"
12declare -x PREFIX="/data/data/com.termux/files/usr"
13declare -x PWD="/data/data/com.termux/files/home"
14declare -x SHELL="/data/data/com.termux/files/usr/bin/bash"
15declare -x SHLVL="1"
16declare -x TERM="vt100"
17declare -x USER="u0_a79"
我們就可以看到如下端倪:
當前shell其實為
/data/data/com.termux/files/usr/bin/bash
當前用戶為u0_a79,與安卓系統給termux 分配的的uid一致。
LD_LIBRARY_PATH為
/data/data/com.termux/files/usr/lib,當前shell執行的程序鏈接的是termux自己的庫文件,與安卓系統/system/lib下的無關。
LD_PRELOAD加入了一個libtermux-exec.so,說明應該termux hook了一些系統API接口。
PATH環境變量不包含/system/bin目錄,所有命令都與android系統自帶的命令了無關,termux的shell是一個獨立的shell環境。
termux shell里也有am等android命令,但是它自帶的,與用/system/bin下的am無關。
HOME目錄為
/data/data/com.termux/files/home
通過ps命令,我們就可以更清楚的知道,它其實是termux 創建的一個子進程:
1```shell
2$ ps
3PID USER TIME COMMAND
429893 u0_a79 0:00 /data/data/com.termux/files/usr/bin/bash -l
5```
因此我們可以確定:
termux的shell是與/system/bin/下的程序一樣,用的都是android的libc,編譯器應該是arm-linux-androideabi-gcc/g++。
打造個人編程環境
我們已經擁有一個微型linux服務器了,現在我們嘗試在里邊編程開發。
安裝c/c++編譯器:
1apt install clang
測試
1$ gcc -v
2clang version 8.0.0 (tags/RELEASE_800/final)
3Target: arm-unknown-linux-android
4Thread model: posix
5InstalledDir: /data/data/com.termux/files/usr/bin
可以看到打印的arm-unknown-linux-android,的確就是android的編譯器。經過測試,用這個編譯器編譯的程序是可以直接放到android shell中執行的。
經過測試,c、c++、python、node.js等語言在這個微型服務器里都正常運行;搭建tomcat之類的服務也沒問題。
如何打造java編程環境?
從前面的分析我們知道,termux shell和android shell一樣,執行java字節碼的是ART虛擬機,而不是普通的java虛擬機,所以javac編譯的.class是無法運行的。
如果一定要執行java字節碼,需要通過dx工具將字節碼轉換成dex文件,然后art虛擬機才能執行。
1#termux下不能用openjdk,可以用ecj
2apt install ecj
3#adroid的.class轉.dex工具
4apt install dx
5
6apt install termux-tools
7
8#編譯
9ecj HelloWorld.java
10dx --dex --output=HelloWorld.dex HelloWorld.class
11
12#執行
13#參照/system/bin/pm 的內容執行即可
很多人肯定會說,這個java環境不爽。那么想打造一個像普通服務器那樣的java環境怎么做呢,可以“安裝”一個操作系統,后邊會介紹。
如何在PC與termux之間傳輸文件?
我們在服務器內寫代碼,都在/data/data/com.termux/files/home這個目錄里,手機沒有root的話,我們是無法訪問這個目錄的。 我本來想安裝一個samba服務器,發現沒有這個軟件包,所以只能借助網絡傳輸文件:
通過scp工具(windows下用winscp)傳輸文件,雖然沒有直接用samba那么方便但起碼可用。
在termux中“安裝”ubuntu
termux的linux環境對很多人來說基本是夠用的,但是依然是一種android定制版linux,與普通嵌入式linux系統還是有差異的,例如沒有普通的java虛擬機。
下面介紹如何在termux shell里搭建一個ubuntu系統環境:
安裝wget
用于下載文件
1pkg install wget
安裝proot
在linux中,chroot是一個需要root權限的操作,它允許將當前根文件系統切換到另外一個目錄。
例如手機中的進程對應的根目錄為/, 我們弄一個/data/local/tmp/xxxx文件夾, 里邊有ubuntu的根文件系統,我們chroot到這個文件夾后,在shell界面里看到的/則切換到/data/local/tmp/xxxx了。
我們說的安裝ubuntu其實只是chroot到一個ubuntu的根文件系統文件夾里而已。
proot是一個無需root權限就能執行chroot操作的工具。用于在ubuntu里模擬需要sudo的權限(否則沒法安裝軟件)。
1pkg install proot
下載atilo腳本
1wget https://raw.githubusercontent.com/YadominJinta/atilo/master/atilo
下載ubuntu根文件系統并chroot
1chmod +x https://mp.weixin.qq.com/atilo
2https://mp.weixin.qq.com/atilo install ubuntu
3
4#這個命令會執行proot,chroot到所下載的ubuntu根文件系統
5startubuntu
執行startubuntu后,根目變到 --> data/data/com.termux/files/home/.atilo/ubuntu去了, 我們就感覺進入了ubuntu系統了。
我們再來對比一下這個ubuntu shell與termux shell不一樣的地方:
termux shell里,根目錄與android的是一樣的,你還可以訪問/system, /sdcard目錄等原始android系統目錄
startubuntu后,就像執行了chroot操作一樣,根目錄都變了,已經看不到/system 這種分區了(除非mount --bind過來)。
簡單分析和測試我們“安裝”的這個ubuntu系統
這個系統用的是通用的libc,android系統下的可執行程序無法在這個系統中運行。
我們可以通過查看gcc的版本:
1root@localhost:~/workspace# gcc -v
2Using built-in specs.
3COLLECT_GCC=gcc
4COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabihf/8/lto-wrapper
5Target: arm-linux-gnueabihf
可見用的是arm-linux-gnueabihf,而不是arm-linux-androideabi了。
我們并沒有以root身份運行
通過shell界面我們看到,我們似乎在以root權限運行,但是其實是模擬出來的,所以你別想寫個內核模塊安裝到真正的內核里邊去。
在ubuntu中,運行sshd, samba都失敗了
sshd進程一運行就沒了,通過gdb運行我們發現它其實段錯誤了:
同樣,smbd進程也奔潰了,報了一個無權限bind socket的錯誤。
似乎這種chroot后的系統沒有直接用termux穩定。對于已經root的系統,可能不需要proot,也許兼容性會更好,感興趣的可以自行進行嘗試。
samba服務沒法用讓我很失望,但其日志中報的socket bind權限問題是怎么回事?
1[2019/05/23 01:00:34.679242, 0] /source3/lib/util_sock.c:357(open_socket_in)
2 open_socket_in(): setsockopt: SO_REUSEPORT = true on port 139 failed with error = Protocol not available
3[2019/05/23 01:00:34.680860, 0] /source3/lib/util_sock.c:396(open_socket_in)
4 bind failed on port 139 socket_addr = 0.0.0.0.
5 Error = Permission denied
經過驗證,自己寫一個tcp server運行是沒有問題的,只是不支持SO_REUSEPORT這個套接字選項。但是ubuntu系統中綁定的端口號與實際在android中的端口是不一樣的,具體的端口號需要到外部termux的shell才能看出來。
例如:我在ubuntu shell中寫了一個服務,監聽的是9999端口,而你外部要訪問這個服務時,確要連接3456端口。
通過親自體驗,在小米2s上使用termux基本能滿足對一個微型linux服務器的需求,我甚至想在我的新手機上也弄一個。對于需要用ndk編譯android native可執行程序的人來說,直接在android中編譯程序并立馬可以執行,而不需要每次adb push到機器里,也是非常不錯的體驗。
termux擁有比較完備的軟件源,開發環境支持得很完善,可玩性非常高。隨著arm芯片的性能的不斷提升,運行內存都趕超PC了,完全可以把你的手機當成一個隨身linux服務器,推薦喜愛技術的朋友去嘗試一下。
歡迎關注我們的公眾號