我想不明真相的吃瓜群众的小脑袋里一定有大大的疑惑。 **安卓能变成Linux?** 能!为什么不能?安卓本就和Linux同源,如果你愿意,甚至可以通过BL的方式引导Linux,更有大佬搞定了EFI引导,达到引导Windows启动的目的。当然我们一般不这么做,我们是菜鸟。 **好吧,没想到安卓那么强,但是手机的性能运行Linux能用?** 其实你的旧手机没有你想象的那么弱,只要不是古董机。 还记得安卓刚刚兴起那会,内存大都只有256M,512M,不少极客开始给手机获取ROOT权限,刷入定制系统,玩得不亦乐乎。 而到了今天,安卓手机的配置在一定程度上来说不亚于一台小型电脑。就拿我这台吃灰很久的“旧手机”,一台2017年发布的三星S8+来说,看下具体参数。 - 晓龙835 8核心CPU(4\*1.9GH小核 + 4\*2.45GH大核) - 4GB RAM - 64GB ROM 尽管很老的机型,但是这个配置拿来跑Linux真的是绰绰有余了,实测跑起项目来比我干活的机器也不遑多让。 **活久见!我还是疑惑能运行Linux有啥用,又不是没有电脑!** 这你就错了,手机相比于电脑,有点大大的有。目前我能想到的优点: - 超低功耗,最普通的电脑待机也要10-20W功率,而手机可能1W都不到。 - 自带“UPS”,具体时长目前还没有测试,但是绝对比常规家用UPS坚挺。 - 自带SIM模块,停电依然能够正常联网,配合上述UPS。 - 摄像头可以做监控、可以远程录音、提供短信服务……可以整好多活啊。 - Linux能干的事情基本都能干,部署Web应用,安装开发工具MySQL等等。 - 通过OTG外接硬盘做NAS、下载器。 **哦~~~大佬不愧是大佬,给跪了,快教教我怎么弄!** 这就来! ### 一、安卓运行Linux的几种方式 有ROOT通过Linux Deploy,体验会更好,无ROOT通过Termux,我没有试过,但是可以预见,体验不如前者。就不浪费时间了。 ### 二、Linux Deploy 方式安装 首先推荐取Google Play上下载最新版本的Linux Deploy,当然啦,我知道大家可能不知道如何出墙,所以贴心的准备了另一种方式。 Linux Deploy项目源码:[Github](https://github.com/meefik/linuxdeploy) Linux Deploy应用下载:[Releases](https://github.com/meefik/linuxdeploy/releases/tag/2.6.0) ##### 1、配置Linux Deploy **配置文件** 点击左上角菜单按钮,选择配置文件。 默认带有一个linux,可以添加、删除和重命名配置文件。 我们添加一个新的配置文件,命名为:debian。 **设置** - 屏幕常亮:ON - 锁定WiFi:ON - CPU唤醒:ON 以上几个选项保证手机待机时不会自动断网和休眠,仍然能够访问到Linux容器,但是会增加电量消耗。 ##### 2、查看当前手机状态信息 点击右上角的菜单键,选择状态,随后命令行会输出一些文本。 ``` [14:50:52] >>> status [14:50:52] Device: SM-G9550 [14:50:52] Android: 9 [14:50:52] Architecture: aarch64 [14:50:52] Kernal: 4.4.153-Stock-AuroraKernal-Pie-V5.0 [14:50:52] Memery: 182/3349MB [14:50:52] Swap: 363/2047MB [14:50:52] SELinux: inactive [14:50:52] Loop devices: yes [14:50:52] Support binfmt_misc: no [14:50:52] Supprted FS: ext2 ext3 ext4 f2fs fuseblk msdos ntfs sdfat vfat [14:50:52] Installed system: unknown [14:50:52] Status of components: [14:50:52] :: extra/ssh ... stopped [14:50:52] Mounted parts: [14:50:52] <<< status ``` 我们需要关注**Architecture**这一项,代表了稍后安装Linux选择的架构。aarch64和arm64其实是一回事,等会安装的时候不要因为找不到aarch64而疑惑,直接选择arm64即可。 ##### 3、配置当前配置文件 点击右下角的配置按钮,打开配置页面,下面是配置项的一些解释,根据实际情况配置。 **引导设置** > 一些基本的设置,此项中的配置用于初始化系统安装,安装完成后更改无效。如果想更改这些参数,只能重新安装系统。 - 发行版GNU/Linux:Debian - 架构:arm64 - 发行版GNU/Linux版本:stable - 源地址:http://mirrors.tuna.tsinghua.edu.cn/debian - 默认源国内速度不佳,可以换成清华源。 - 似乎Linux Deploy无法访问*HTTPS*站点,所以改为*HTTP*。 - 安装类型:镜像文件 - 推荐使用镜像方式,缺点是如果想使用SD卡,需要注意分区格式问题。 - 目录类型的性能会比镜像文件类型更好,但是我的手机上无法通过目录类型安装。 - 安装路径:${EXTERNAL_STORAGE}/debian.img - 安装路径`${EXTERNAL_STORAGE}`默认指向外部存储地址,本意是指向SD卡。但是在我的手机上,默认的外部存储设置为了手机内置的EMMC存储,所以仍然会存放到机身内部的存储中。但是我觉得这没有问题,相比SD卡,EMMC在速度上有优势。如果机身空间足够,推荐优先使用内置存储。 - 为了避免路径因默认存储位置的设置而变动,可以在此处使用绝对路径。例如:`/storage/emulated/0/debian.img`。 - 镜像大小:8192 - 根据情况,默认的自动是2G,大部分情况下够用了,反正我空间足够,就设置的大一点。 - 文件系统:ext4 - 用户名:simaek - 密码:xueye.io - 特权用户:simaek:aid_inet simaek:aid_sdcard_rw simaek:aid_graphics - 使用默认生成的。 - 本地化:zh_CN.UTF-8 - 保证中文显示正常,也可以进入系统后安装语言包。 - DNS:114.114.114.114 - 可以使用自动,我这里手动设置一下。 - Network trigger: - 不用设置。 - Power trigger: - 不用设置。 **初始化** > 初始化可以完成服务的自动运行。 - 启用:ON - 初始化系统:sysv - 初始化设置:默认 **挂载** > 将外置SD卡`/storage/0462-01A9`挂载到Linux容器的`/data`目录,SD卡的路径根据实际情况来定。如果不需要,就不设置。需要挂载几个目录就添加几条。目的地址需要在容器中提前创建。 - 启用:ON - 挂载点列表:/storage/0462-01A9 - /data **SSH** > 因为不打算配置图形界面,所以如果没有SSH服务,将无法访问到Linux容器。如果有多个容器,需要在SSH设置里更改端口号,负责端口冲突将导致容器启动异常。 - 启用:ON - SSH设置:默认 **声音服务** - 启用:OFF 我不需要,所以不设置。 **图形界面** - 启用:OFF 我不需要,所以不设置。 ##### 4、开始安装 以上都配置完成后,回到主页面,点击右上角的菜单键,选择安装。依据网络情况,大概10-15分钟即可安装完成。 如果出错,多半是网络原因,重试或者换个网络环境。 ##### 5、启动容器 安装完成后,最后会显示`<<< deploy`字样,此时就可以点击最外面的启动按钮,启动容器了。 启动完成后显示`>>> start`。 之后就和正常使用Linux系统一样,使用SSH远程操作即可。本机的IP地址就是配置文件后面括号里的地址。 ### 三、常用服务的安装 上一步说到可以通过SSH连接到Linux容器进行操作,可以使用本机的工具,也可以使用外部工具。 安卓上的终端可是使用体验较好的**JuiceSSH**,在本机连接,IP地址需使用环回地址(127.0.0.1)。 ##### 1、常用工具包安装 初始化安装的镜像非常精简,很多常用的工具包都没有,需要自己安装,下面是几个常用的例子。 ``` sudo apt-get update sudo apt-get install vim lrzsz net-tools curl wget git python3 openjdk-11-jdk maven nodejs ``` ##### 2、MySQL/MariaDB数据库 安装最新版的MariaDB。 ``` sudo apt-get update sudo apt-get install mariadb-server ``` 由于Linux容器通过chroot运行,无法使用systemctl命令,但是可以通过service命令管理服务。实际上执行的是`/etc/init.d`目录下的脚本,了解Linux的话应该知道这个目录,现在的Linux大都使用systemd引导。 ``` root@localhost:~# service mariadb Usage: /etc/init.d/mariadb start|stop|restart|reload|force-reload|status ``` 不出意外启动是会报错的,类似于: Failed to create a socket for IPv4 '127.0.0.1': errno: 13. 这是因为Android内核已使用`CONFIG_ANDROID_PARANOID_NETWORK`进行了编译。可以通过将mysql用户添加到aid_inet和aid_net_raw组来修复它。 ``` usermod -a -G aid_inet,aid_net_raw mysql ``` 再次启动即可。 > MariaDB默认绑定127.0.0.1环回地址,只能在本机访问,如果想在外部进行访问,需要修改配置文件`/etc/mysql/mariadb.conf.d/50-server.cnf`,将bind_address更改为0.0.0.0。 ##### 3、NFS(未完待续,脑袋发懵,到此暂停) 还记得我挂载了一张SD卡么,为了方便共享文件,安装NFS服务,将SD卡共享出去。 ``` sudo apt-get install nfs-kernel-server portmap ``` **使用vim编辑`/etc/exports`,添加一条记录:** ``` # /etc/exports: the access control list for filesystems which may be exported # to NFS clients. See exports(5). # # Example for NFSv2 and NFSv3: # /srv/homes hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check) # # Example for NFSv4: # /srv/nfs4 gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check) # /srv/nfs4/homes gss/krb5i(rw,sync,no_subtree_check) # /data 0.0.0.0/0(rw,sync,no_subtree_check) ``` 我这里允许所有的主机进行读写,更多的设置参数可以参考:[https://linuxconfig.org/how-to-set-up-a-nfs-server-on-debian-10-buster](https://linuxconfig.org/how-to-set-up-a-nfs-server-on-debian-10-buster)。 **最后启动NFS服务:** ``` service nfs-kernal-server start ``` **遇到第一个问题:** Not starting NFS kernel daemon: no support in current kernel. ... (warning). 原因是如果没有将*NFS*服务器作为模块运行,它就退出。这个判断在启动脚本中,解决方法是将这个判断注释掉。 ``` # See if our running kernel supports the NFS kernel server #if ! grep -E -qs "[[:space:]]nfsd\$" /proc/filesystems; then # log_warning_msg "Not starting $DESC: no support in current kernel." # exit 0 #fi ``` **遇到第二个问题:** Not starting: portmapper is not running ... (warning). 原因是依赖的portmapper服务没有启动,但是在安装的时候,portmap已被rpcbind替代,所以这里需要启动rpcbind服务。 然后又报错! /run/rpcbind not owned by root 仍然打开启动脚本`/etc/init.d/rpcbind`: ``` if [ `ls -dl "$STATEDIR" | grep -cE '^drwxr-xr-x [0-9]+ _rpc root '` -lt 1 ] ; then log_begin_msg "$STATEDIR not owned by root" log_end_msg 1 exit 1 fi ``` 判断启动目录下是否有运行目录,可以把判断语句拷贝到命令行中执行,发现确实不存在。原因是表达式和文件系统不一致。注意表达式`^drwxr-xr-x [0-9]+ _rpc root `,通过`ls -dl "/run/rpcbind"`命令执行返回的结果如下。 ``` drwxr-xr-x. 2 _rpc root 4096 1月 25 16:31 /run/rpcbind ``` 在权限后多了一个点,在脚本中加上那个点。 我以为,就这?也不难嘛,然后还有报错! 1、Starting RPC port mapper daemon: rpcbindln: failed to create symbolic link '/run/sendsigs.omit.d/rpcbind' 2、Starting NFS kernel daemon: nfsdrpc.nfsd: Unable to access /proc/fs/nfsd errno 2 (No such file or directory). 到这里,我放弃了。真的太烦了,以后再说。或者有大佬来帮我填坑,我需要静静。 ### 四、小技巧GET 如果应用配置锁屏保持CPU运行无效,可以试试进入本机终端,输入`su`获取管理员权限,使用下面的命令禁用锁屏之后的睡眠模式。 ``` dumpsys deviceidle disable ``` Loading... 我想不明真相的吃瓜群众的小脑袋里一定有大大的疑惑。 **安卓能变成Linux?** 能!为什么不能?安卓本就和Linux同源,如果你愿意,甚至可以通过BL的方式引导Linux,更有大佬搞定了EFI引导,达到引导Windows启动的目的。当然我们一般不这么做,我们是菜鸟。 **好吧,没想到安卓那么强,但是手机的性能运行Linux能用?** 其实你的旧手机没有你想象的那么弱,只要不是古董机。 还记得安卓刚刚兴起那会,内存大都只有256M,512M,不少极客开始给手机获取ROOT权限,刷入定制系统,玩得不亦乐乎。 而到了今天,安卓手机的配置在一定程度上来说不亚于一台小型电脑。就拿我这台吃灰很久的“旧手机”,一台2017年发布的三星S8+来说,看下具体参数。 - 晓龙835 8核心CPU(4\*1.9GH小核 + 4\*2.45GH大核) - 4GB RAM - 64GB ROM 尽管很老的机型,但是这个配置拿来跑Linux真的是绰绰有余了,实测跑起项目来比我干活的机器也不遑多让。 **活久见!我还是疑惑能运行Linux有啥用,又不是没有电脑!** 这你就错了,手机相比于电脑,有点大大的有。目前我能想到的优点: - 超低功耗,最普通的电脑待机也要10-20W功率,而手机可能1W都不到。 - 自带“UPS”,具体时长目前还没有测试,但是绝对比常规家用UPS坚挺。 - 自带SIM模块,停电依然能够正常联网,配合上述UPS。 - 摄像头可以做监控、可以远程录音、提供短信服务……可以整好多活啊。 - Linux能干的事情基本都能干,部署Web应用,安装开发工具MySQL等等。 - 通过OTG外接硬盘做NAS、下载器。 **哦~~~大佬不愧是大佬,给跪了,快教教我怎么弄!** 这就来! ### 一、安卓运行Linux的几种方式 有ROOT通过Linux Deploy,体验会更好,无ROOT通过Termux,我没有试过,但是可以预见,体验不如前者。就不浪费时间了。 ### 二、Linux Deploy 方式安装 首先推荐取Google Play上下载最新版本的Linux Deploy,当然啦,我知道大家可能不知道如何出墙,所以贴心的准备了另一种方式。 Linux Deploy项目源码:[Github](https://github.com/meefik/linuxdeploy) Linux Deploy应用下载:[Releases](https://github.com/meefik/linuxdeploy/releases/tag/2.6.0) ##### 1、配置Linux Deploy **配置文件** 点击左上角菜单按钮,选择配置文件。 默认带有一个linux,可以添加、删除和重命名配置文件。 我们添加一个新的配置文件,命名为:debian。 **设置** - 屏幕常亮:ON - 锁定WiFi:ON - CPU唤醒:ON 以上几个选项保证手机待机时不会自动断网和休眠,仍然能够访问到Linux容器,但是会增加电量消耗。 ##### 2、查看当前手机状态信息 点击右上角的菜单键,选择状态,随后命令行会输出一些文本。 ``` [14:50:52] >>> status [14:50:52] Device: SM-G9550 [14:50:52] Android: 9 [14:50:52] Architecture: aarch64 [14:50:52] Kernal: 4.4.153-Stock-AuroraKernal-Pie-V5.0 [14:50:52] Memery: 182/3349MB [14:50:52] Swap: 363/2047MB [14:50:52] SELinux: inactive [14:50:52] Loop devices: yes [14:50:52] Support binfmt_misc: no [14:50:52] Supprted FS: ext2 ext3 ext4 f2fs fuseblk msdos ntfs sdfat vfat [14:50:52] Installed system: unknown [14:50:52] Status of components: [14:50:52] :: extra/ssh ... stopped [14:50:52] Mounted parts: [14:50:52] <<< status ``` 我们需要关注**Architecture**这一项,代表了稍后安装Linux选择的架构。aarch64和arm64其实是一回事,等会安装的时候不要因为找不到aarch64而疑惑,直接选择arm64即可。 ##### 3、配置当前配置文件 点击右下角的配置按钮,打开配置页面,下面是配置项的一些解释,根据实际情况配置。 **引导设置** > 一些基本的设置,此项中的配置用于初始化系统安装,安装完成后更改无效。如果想更改这些参数,只能重新安装系统。 - 发行版GNU/Linux:Debian - 架构:arm64 - 发行版GNU/Linux版本:stable - 源地址:http://mirrors.tuna.tsinghua.edu.cn/debian - 默认源国内速度不佳,可以换成清华源。 - 似乎Linux Deploy无法访问*HTTPS*站点,所以改为*HTTP*。 - 安装类型:镜像文件 - 推荐使用镜像方式,缺点是如果想使用SD卡,需要注意分区格式问题。 - 目录类型的性能会比镜像文件类型更好,但是我的手机上无法通过目录类型安装。 - 安装路径:${EXTERNAL_STORAGE}/debian.img - 安装路径`${EXTERNAL_STORAGE}`默认指向外部存储地址,本意是指向SD卡。但是在我的手机上,默认的外部存储设置为了手机内置的EMMC存储,所以仍然会存放到机身内部的存储中。但是我觉得这没有问题,相比SD卡,EMMC在速度上有优势。如果机身空间足够,推荐优先使用内置存储。 - 为了避免路径因默认存储位置的设置而变动,可以在此处使用绝对路径。例如:`/storage/emulated/0/debian.img`。 - 镜像大小:8192 - 根据情况,默认的自动是2G,大部分情况下够用了,反正我空间足够,就设置的大一点。 - 文件系统:ext4 - 用户名:simaek - 密码:xueye.io - 特权用户:simaek:aid_inet simaek:aid_sdcard_rw simaek:aid_graphics - 使用默认生成的。 - 本地化:zh_CN.UTF-8 - 保证中文显示正常,也可以进入系统后安装语言包。 - DNS:114.114.114.114 - 可以使用自动,我这里手动设置一下。 - Network trigger: - 不用设置。 - Power trigger: - 不用设置。 **初始化** > 初始化可以完成服务的自动运行。 - 启用:ON - 初始化系统:sysv - 初始化设置:默认 **挂载** > 将外置SD卡`/storage/0462-01A9`挂载到Linux容器的`/data`目录,SD卡的路径根据实际情况来定。如果不需要,就不设置。需要挂载几个目录就添加几条。目的地址需要在容器中提前创建。 - 启用:ON - 挂载点列表:/storage/0462-01A9 - /data **SSH** > 因为不打算配置图形界面,所以如果没有SSH服务,将无法访问到Linux容器。如果有多个容器,需要在SSH设置里更改端口号,负责端口冲突将导致容器启动异常。 - 启用:ON - SSH设置:默认 **声音服务** - 启用:OFF 我不需要,所以不设置。 **图形界面** - 启用:OFF 我不需要,所以不设置。 ##### 4、开始安装 以上都配置完成后,回到主页面,点击右上角的菜单键,选择安装。依据网络情况,大概10-15分钟即可安装完成。 如果出错,多半是网络原因,重试或者换个网络环境。 ##### 5、启动容器 安装完成后,最后会显示`<<< deploy`字样,此时就可以点击最外面的启动按钮,启动容器了。 启动完成后显示`>>> start`。 之后就和正常使用Linux系统一样,使用SSH远程操作即可。本机的IP地址就是配置文件后面括号里的地址。 ### 三、常用服务的安装 上一步说到可以通过SSH连接到Linux容器进行操作,可以使用本机的工具,也可以使用外部工具。 安卓上的终端可是使用体验较好的**JuiceSSH**,在本机连接,IP地址需使用环回地址(127.0.0.1)。 ##### 1、常用工具包安装 初始化安装的镜像非常精简,很多常用的工具包都没有,需要自己安装,下面是几个常用的例子。 ``` sudo apt-get update sudo apt-get install vim lrzsz net-tools curl wget git python3 openjdk-11-jdk maven nodejs ``` ##### 2、MySQL/MariaDB数据库 安装最新版的MariaDB。 ``` sudo apt-get update sudo apt-get install mariadb-server ``` 由于Linux容器通过chroot运行,无法使用systemctl命令,但是可以通过service命令管理服务。实际上执行的是`/etc/init.d`目录下的脚本,了解Linux的话应该知道这个目录,现在的Linux大都使用systemd引导。 ``` root@localhost:~# service mariadb Usage: /etc/init.d/mariadb start|stop|restart|reload|force-reload|status ``` 不出意外启动是会报错的,类似于: Failed to create a socket for IPv4 '127.0.0.1': errno: 13. 这是因为Android内核已使用`CONFIG_ANDROID_PARANOID_NETWORK`进行了编译。可以通过将mysql用户添加到aid_inet和aid_net_raw组来修复它。 ``` usermod -a -G aid_inet,aid_net_raw mysql ``` 再次启动即可。 > MariaDB默认绑定127.0.0.1环回地址,只能在本机访问,如果想在外部进行访问,需要修改配置文件`/etc/mysql/mariadb.conf.d/50-server.cnf`,将bind_address更改为0.0.0.0。 ##### 3、NFS(未完待续,脑袋发懵,到此暂停) 还记得我挂载了一张SD卡么,为了方便共享文件,安装NFS服务,将SD卡共享出去。 ``` sudo apt-get install nfs-kernel-server portmap ``` **使用vim编辑`/etc/exports`,添加一条记录:** ``` # /etc/exports: the access control list for filesystems which may be exported # to NFS clients. See exports(5). # # Example for NFSv2 and NFSv3: # /srv/homes hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check) # # Example for NFSv4: # /srv/nfs4 gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check) # /srv/nfs4/homes gss/krb5i(rw,sync,no_subtree_check) # /data 0.0.0.0/0(rw,sync,no_subtree_check) ``` 我这里允许所有的主机进行读写,更多的设置参数可以参考:[https://linuxconfig.org/how-to-set-up-a-nfs-server-on-debian-10-buster](https://linuxconfig.org/how-to-set-up-a-nfs-server-on-debian-10-buster)。 **最后启动NFS服务:** ``` service nfs-kernal-server start ``` **遇到第一个问题:** Not starting NFS kernel daemon: no support in current kernel. ... (warning). 原因是如果没有将*NFS*服务器作为模块运行,它就退出。这个判断在启动脚本中,解决方法是将这个判断注释掉。 ``` # See if our running kernel supports the NFS kernel server #if ! grep -E -qs "[[:space:]]nfsd\$" /proc/filesystems; then # log_warning_msg "Not starting $DESC: no support in current kernel." # exit 0 #fi ``` **遇到第二个问题:** Not starting: portmapper is not running ... (warning). 原因是依赖的portmapper服务没有启动,但是在安装的时候,portmap已被rpcbind替代,所以这里需要启动rpcbind服务。 然后又报错! /run/rpcbind not owned by root 仍然打开启动脚本`/etc/init.d/rpcbind`: ``` if [ `ls -dl "$STATEDIR" | grep -cE '^drwxr-xr-x [0-9]+ _rpc root '` -lt 1 ] ; then log_begin_msg "$STATEDIR not owned by root" log_end_msg 1 exit 1 fi ``` 判断启动目录下是否有运行目录,可以把判断语句拷贝到命令行中执行,发现确实不存在。原因是表达式和文件系统不一致。注意表达式`^drwxr-xr-x [0-9]+ _rpc root `,通过`ls -dl "/run/rpcbind"`命令执行返回的结果如下。 ``` drwxr-xr-x. 2 _rpc root 4096 1月 25 16:31 /run/rpcbind ``` 在权限后多了一个点,在脚本中加上那个点。 我以为,就这?也不难嘛,然后还有报错! 1、Starting RPC port mapper daemon: rpcbindln: failed to create symbolic link '/run/sendsigs.omit.d/rpcbind' 2、Starting NFS kernel daemon: nfsdrpc.nfsd: Unable to access /proc/fs/nfsd errno 2 (No such file or directory). 到这里,我放弃了。真的太烦了,以后再说。或者有大佬来帮我填坑,我需要静静。 ### 四、小技巧GET 如果应用配置锁屏保持CPU运行无效,可以试试进入本机终端,输入`su`获取管理员权限,使用下面的命令禁用锁屏之后的睡眠模式。 ``` dumpsys deviceidle disable ``` 最后修改:2022 年 01 月 26 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 2 如果觉得我的文章对你有用,请随意赞赏