Android内嵌web服务器

背景

因项目需求,需要在Android(7.1.2)中内嵌web服务器(lighttpd+PHP环境)
硬件平台: RK3399

方案选择

  1. 通过现成的APK安装:
    https://zhuanlan.zhihu.com/p/34730760
    https://blog.csdn.net/Jye13/article/details/8987620?locationNum=4
    版本低,自由度低,自己不好把控
  2. 自己移植,复杂
    参考:
    android 自己移植编译lighttpd:
    http://blog.chinaunix.net/uid-14735472-id-5213247.html
  3. 内嵌Linux+chroot,通过buildroot构建,方便扩展,之前老项目用过,可行性高
  4. 先通过apk(Linux Deploy)安装Linux发行版,再编译安装Lighttpd + php
    http://www.webhek.com/post/instll-lighttpd-php-sqlite3-on-android-arm-linux.html
    需要手机root

最终选择用方案3, 采用buildroot+chroot自己构建

过程

buildroot构建最小文件系统

具体过程可参考博文:
文件系统中需填加lighttpd和PHP的packet

编译Busybox(可选)

rk3399官方提供的/system/bin/busybox为32位的,路径在:(vendor/rockchip/common/bin/arm64/)
可自己编译64位的busybox,需要用Android的编译链(aarch64-linux-android),编译过程比较麻烦

  1. 初始化编译环境

    1
    2
    3
    4
    5
    6
    7
    #初始化Android编译环境
    source build/envsetup.sh
    lunch rk3399_firefly_aiojd4_box-userdebug
    cd ~/xxx/busybox-1.28.1

    #选择编译脚本
    make android2_defconfig
  2. 主要是修改.config

    1
    2
    3
    4
    5
    6
    7
    8
    9
    CONFIG_CROSS_COMPILER_PREFIX="aarch64-linux-android-"

    CONFIG_SYSROOT="/home/xxx/android7.1/prebuilts/ndk/current/platforms/android-24/arch-arm64"

    #使 busybox 编译产物输出到源码根目录下
    CONFIG_INSTALL_NO_USR=y

    #要求静态编译
    CONFIG_STATIC=y
  3. 最后根据报错屏蔽掉那些报错且不用的包

【参考】:
编译 Android 系统的 arm64 架构版 busybox:
https://www.veryarm.com/116053.html
在android系统命令行中执行arm linux程序,出现/system/bin/sh: .xxx No such file or directory问题:
https://blog.csdn.net/zmc1216/article/details/46777897

配置Chroot

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/system/bin/sh

chroot_dir=/data/chroot_linux

unalias haha
alias haha="/system/bin/busybox"

haha cp -P /system/chroot_linux /data -rf

haha mkdir -p $chroot_dir/mnt/sdcard
haha mkdir -p $chroot_dir/mnt/udisk
haha mkdir -p $chroot_dir/mnt/extsd
haha mkdir -p $chroot_dir/cache

haha mount -o bind /sdcard "$chroot_dir/mnt/sdcard"
#haha mount -o bind /mnt/media_rw/udisk "$chroot_dir/mnt/udisk"
#haha mount -o bind /mnt/media_rw/extsd "$chroot_dir/mnt/extsd"
haha mount -o bind /cache "$chroot_dir/cache"

haha mount -o bind /dev "$chroot_dir/dev"
haha mount -t devpts devpts "$chroot_dir/dev/pts"
haha mount -t proc proc "$chroot_dir/proc"
haha mount -t sysfs sysfs "$chroot_dir/sys"
haha mount -t tmpfs tmpfs "$chroot_dir/tmp"

haha sysctl -n -w net.ipv4.ip_forward=1


haha chroot $chroot_dir /usr/bin/env -i HOME=/root USER=root PATH=/sbin:/bin:/usr/sbin:/usr/bin LD_LIBRARY_PATH=/lib:/usr/lib:/lib64:/usr/lib64 TERM=linux run_linux.sh

Android chroot 报”Permission denied”:
https://stackoverflow.com/questions/14992828/cannot-do-chroot-with-init-shell-script-in-android?r=SearchResults
system/core/libcutils/fs_config.c 添加:

1
{ 00777, AID_ROOT,      AID_ROOT,      0, "system/chroot_linux/*" },

android5.1是在system/core/include/private/android_filesystem_config.h

添加自启动服务

在init文件中添加启动chroot的自启动服务

1
2
3
4
5
6
7
8
9
10
11
#方式一	
#service chroot_linux /system/bin/chroot_linux.sh
# class main
# user root
# group root system
# oneshot

#方式2
on property:sys.boot_completed=1
# start chroot_linux
exec /system/bin/sh /system/bin/chroot_linux.sh