相对于一般的 GNU/Linux 来说,根据前面的文章仅仅启动一个 labwc 是完全没办法正常使用的。比如在我的平板上面,只要"adb stop"后,过不了几秒整个安卓就会被奇怪的程序拉起,占用RAM不说,他还会和 labwc 共用同一个输入,这导致在操作 labwc 时经常会误触安卓的锁屏界面。
labwc(左下) 与 安卓(右上,使用scrcpy) 同时运行
同时,没有 systemd,系统缺少对硬件动态处理的能力。比如手动启动 systemd-networkd dbus-daemon NetworkManager 等服务后,即使连上网络
nmtui (欸..之前还能用来着)
由于缺少对内核的设置(gateway, ip rule 等),总是ping不通。
$ ping 8.8.8.8
connect: Network is unreachable
$
缺少 udevd,使得插入的 otg 等设备没有任何反应。(似乎可以手动运行他? /usr/lib/systemd/systemd-udevd)
为了解决这些问题,打算引入 systemd,但他只能以pid 1 运行
root@localhost:~# /usr/lib/systemd/systemd --system
Can't run system mode unless PID 1.
root@localhost:~#
所以就只能尝试替换安卓的 init 进程来运行 systemd 了
注: 以下内容只在某闭源骁龙870平板上进行测试
Ramdisk 中的 init
Ramdisk 一般存放于 boot.img 内,可以使用 magiskboot 进行修改,于是向里面添加了 busybox-static 和一个用 shell 写的简单的 init
$ # ramdisk文件结构如下
$ tree -a
.
└── ramdisk
├── avb
│ ├── q-gsi.avbpubkey
│ ├── r-gsi.avbpubkey
│ └── s-gsi.avbpubkey
├── .backup
│ ├── init
│ ├── .magisk
│ └── .rmlist
├── bin
│ └── busybox (bin文件夹下的文件似乎无法访问)
├── busybox (所以用这个啦)
├── debug_ramdisk
├── dev
├── fstab.qcom
├── init
├── mnt
├── overlay.d
│ └── sbin
│ ├── magisk32.xz
│ ├── magisk64.xz
│ └── stub.xz
├── proc
├── sh (busybox的sh组件)
├── sys
└── system
└── bin
└── e2fsck
14 directories, 15 files
一个简单的 /init, 使用 /sh 当作解释器
打包 boot.img, 刷入并启动手机然后就能看见输出了吧...并不能
缺少 framebuffer console / virtual terminal,屏幕上不会显示任何文本,只有第一屏的 logo
使用 magiskboot 解包 boot.img
$ ./libmagiskboot.so unpack boot.img Parsing boot image: [boot.img]
HEADER_VER [2]
KERNEL_SZ [44187664]
RAMDISK_SZ [1638119]
SECOND_SZ [0]
RECOV_DTBO_SZ [0]
DTB_SZ [1617030]
OS_VERSION [11.0.0]
OS_PATCH_LEVEL [2021-10]
PAGESIZE [4096]
NAME []
CMDLINE [console=ttyMSM0,115200n8 earlycon=msm_geni_serial,0xa90000 androidboot.hardware=qcom androidboot.console=ttyMSM0 androidboot.memcg=1 lpm_levels.sleep_disabled=1 video=vfb:640x400,bpp=32,memsize=3072000 msm_rtb.filter=0x237 service_locator.enable=1 androidboot.usbcontroller=a600000.dwc3 swiotlb=2048 loop.max_part=7 cgroup.memory=nokmem,nosocket reboot=panic_warm buildvariant=user systemd.log_level=debug selinux=0 enforcing=0]
CHECKSUM [1e81e0583771617c63cad091dca1e602f65038fa000000000000000000000000]
KERNEL_FMT [raw]
RAMDISK_FMT [gzip]
unexpected ASN.1 DER tag: expected SEQUENCE, got APPLICATION [1] (primitive)
VBMETA
可以看到 cmdline 中指定了 console=ttyMSM0,115200n8, 搜索后了解到这个是 ucrt 的输出,需要在主板上外接线才能用。
好在这个高通平板魔改的不是很多,init 进程崩溃后会重启到 900e 模式 (ID: 05c6:900e) (一加还会显示"QUALCOMM CrashDump Mode", 而我这个平板只会黑屏)
$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 002: ID 048d:6006 Integrated Technology Express, Inc. ITE Device(8291)
Bus 003 Device 003: ID 04f2:b71a Chicony Electronics Co., Ltd Integrated IR Camera
Bus 003 Device 004: ID 8087:0026 Intel Corp. AX201 Bluetooth
Bus 003 Device 011: ID 05c6:900e Qualcomm, Inc. QUSB_BULK_SN:34AB1B59 # 900E 模式下的手机
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
此时可以使用 edl 把 LASTKMSG.BIN dump 出来,里面便是 珍贵 的内核日志
[ 1.669238] ALSA device list:
[ 1.669247] No soundcards found.
[ 1.670808] Freeing unused kernel memory: 6144K
[ 1.670906] Run /init as init process
[ 1.672942] INIT: before mkdirs
[ 1.674525] INIT: after mkdirs
[ 1.678339] request_module fs-devtmpfs succeeded, but still no fs?
[ 1.678724] INIT: mount /proc /sys /tmp /dev
[ 1.679394] Filesystem Size Used Available Use% Mounted on
[ 1.679394] proc 0 0 0 0% /proc
[ 1.679394] sysfs 0 0 0 0% /sys
[ 1.679394] tmpfs 3.7G 0 3.7G 0% /tmp
[ 1.682495] INIT: mount /dev/pts
[ 1.685940] INIT: redirect stdout stderr to /kmsg
[ 1.686011] Starting init process...
[ 1.686487] BusyBox v1.36.1 (Debian 1:1.36.1-7)
[ 1.686490] multi-call binary.
[ 1.686510] BusyBox is copyrighted by many authors between 1998-2015.
[ 1.686510] Licensed under GPLv2. See source distribution for detailed
[ 1.686510] copyright notices.
[ 1.686510]
[ 1.686510] Usage: busybox [function [arguments]...]
[ 1.686510] or: busybox --list[-full]
[ 1.686510] or: busybox --install [-s] [DIR]
[ 1.686510] or: function [arguments]...
[ 1.686510]
[ 1.686510] BusyBox is a multi-call binary that combines many common Unix
[ 1.686510] utilities into a single executable. The shell in this build
....
[ 1.687631] Thu Jan 1 00:00:33 UTC 1970 # 此处对应着 /busybox date
....
[ 6.720912] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000
研究了一下 magisk 的 init,幻想着他重写了第一阶段的 init 程序....
获取 patch ramdisk 前的 init 程序
替换为原始的 init
但是他并没有
....
既然这样还是看看 init 的源码吧...
$ git clone https://mirrors.ustc.edu.cn/aosp/platform/system/core.git --depth=1
....
可以看见 init 在第一阶段(First Stage),也就是 ramdisk 内, 从 super 分区读取了元数据并创建基于 dm(Device Mapper) 的逻辑分区,最后运行 /system/init。这样的话,可以替换一下 system 分区内的 init,也方便用dsu测试。
core/init/first_stage_mount.cpp
system 内的 init
用c语言写了个小的 init,并把 stderr 和 stdout 重定向到 kmsg
创建kmsg节点并重定向
使用busybox的sh执行/bin/init.sh
使用 dsu 启动后,成功运行 init.sh, 并执行了 df -h 等命令
[ 1.797713] init: [libfs_mgr]__mount(source=/dev/block/dm-11,target=/odm,type=ext4)=0: Success
[ 1.798148] init: Skipped setting INIT_AVB_VERSION (not in recovery mode)
[ 1.877445] mount: mounting proc on /proc failed: Device or resource busy
[ 1.878251] mount: mounting sysfs on /sys failed: Device or resource busy
[ 1.879599] INIT: mount /proc /sys /tmp /dev
[ 1.880246] Filesystem Size Used Available Use% Mounted on
[ 1.880246] tmpfs 3.7G 0 3.7G 0% /dev
[ 1.880255] df: /dev/pts: No such file or directory
[ 1.880395] proc 0 0 0 0% /proc
[ 1.880395] sysfs 0 0 0 0% /sys
[ 1.880395] selinuxfs 0 0 0 0% /sys/fs/selinux
[ 1.880395] tmpfs 3.7G 0 3.7G 0% /mnt
[ 1.880395] tmpfs 3.7G 0 3.7G 0% /debug_ramdisk
[ 1.880395] /dev/block/by-name/metadata
[ 1.880395] 11.5M 280.0K 10.7M 2% /metadata
[ 1.880395] /dev/block/dm-7 108.0M 5.3M 98.9M 5% /
[ 1.880395] /dev/block/dm-8 360.4M 359.3M 0 100% /system/system_ext
[ 1.880395] /dev/block/dm-9 457.8M 456.4M 0 100% /system/product
[ 1.880395] /dev/block/dm-10 643.4M 641.5M 0 100% /vendor
[ 1.880395] /dev/block/dm-11 908.0K 904.0K 0 100% /odm
[ 1.880414] df: /dev/ufxpfdlbchnpfaj: No such file or directory
[ 1.880492] magisk 3.7G 1.1M 3.7G 0% /sys/fs/selinux/load
[ 1.880492] magisk 3.7G 1.1M 3.7G 0% /sys/fs/selinux/enforce
[ 1.880492] magisk 3.7G 1.1M 3.7G 0% /init.rc
[ 1.880492] tmpfs 3.7G 0 3.7G 0% /tmp
[ 1.880492] tmpfs 3.7G 0 3.7G 0% /dev
...
[ 6.942006] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000
[ 6.942006]
[ 6.942018] CPU: 1 PID: 1 Comm: busybox Tainted: G S W 4.19.157-perf+ #1
[ 6.942023] Hardware name: Qualcomm Technologies, Inc. kona standalone MTP (DT)
照着 debian 的 init 脚本抄下来的时候,刷入测试后发现这个内核不支持 devtmpfs。
[ 1.678339] request_module fs-devtmpfs succeeded, but still no fs?
在我另一部较新的手机上,也不支持 devtmpfs
# cat /proc/filesystems | grep tmp
nodev tmpfs
#
所以只能想办法帮忙处理 devtmpfs 的事情了
创建设备节点
根据文档以及 这个回答 可以了解到 devtmpfs 会自动创建设备节点,但这个内核没打开这个功能。这里可以用 busybox mdev -s 来创建设备节点
# busybox mdev
BusyBox v1.36.1 (Debian 1:1.36.1-9+b1) multi-call binary.
Usage: mdev [-vS] { [-s] | [-df] }
-v Verbose
-S Log to syslog too
-s Scan /sys and populate /dev
-d Daemon, listen on netlink
-f Run in foreground
...
创建完设备节点,也有 system 分区存储基本文件,但这些都是只读的。"你也不想跑起来的 GNU/linux 是挂载到只读文件系统上的吧?"
那么就需要打包 GNU/Linux 到 tgz 文件中,然后解压到读写的 /data 分区上
挂载 data 分区
观察 fstab 可以看到 /data 挂载到了某个物理分区上,但实际上他挂载到了 /dev/dm-10 上
olivine:/ # cat /vendor/etc/fstab.qcom
#<src> <mnt_point> <type> <mnt_flags and options> <fs_mgr_flags>
/dev/block/bootdevice/by-name/userdata /data f2fs noatime,nosuid,nodev,discard,... latemount,wait,check,formattable,fileencryption=aes-256-xts:aes-256-cts:v2+inlinecrypt_optimized+wrappedkey_v0,metadata_encryption=aes-256-xts:wrappedkey_v0,keydirectory=/metadata/vold/metadata_encryption,quota,resize,reservedsize=128M,sysfs_path=/sys/devices/platform/soc/1d84000.ufshc,checkpoint=fs
....
olivine:/ # cat /proc/mounts | grep /data
/dev/block/dm-10 /data f2fs rw,lazytime,seclabel,nosuid,nodev,noatime,background_gc=on,discard,no_heap,user_xattr,inline_xattr,acl,inline_data,inline_dentry,flush_merge,extent_cache,mode=adaptive,active_logs=6,reserve_root=32768,resuid=0,resgid=1065,inlinecrypt,alloc_mode=default,fsync_mode=nobarrier 0 0
tmpfs /data_mirror tmpfs rw,seclabel,nosuid,nodev,noexec,relatime,size=3911952k,nr_inodes=977988,mode=700,gid=1000 0 0
....
查看源码可以了解到
fs_mgr/fs_mgr.cpp
为了实现动态分区,/data 可能会在第一阶段已经挂载上去,这时只能用 dm-linear device-mapper 当做临时的 /data 分区使用。对于 dsu, 必定会使用 /dev/dm-?。
但在 init.sh, 如何知道从哪个节点挂载呢?
因此照着 init 的源码,简单写了个获取dm编号的程序
这个程序包含几个不同的组件, GetDmDevicePathByName 用来根据名称获取节点名称
按照 init 里的逻辑, 新创建的分区是空白的,挂载前需要格式化,所以又写了个自动格式化的程序
如果是空白分区则调用 /system/bin/mkfs.f2fs 执行格式化
然后使用 busybox 的 mount 正常挂载提供的节点,并解压打包好的 rootfs
探测输入设备
按照之前的文章,只需要 udevadm test /dev/input/event? 就可以把这些设备写入到 systemd 的数据库内,但 systemd 更新到某个版本后(>255.4),这个方法就失效了
所以现在只能先运行 udevd 再发送 trigger 了
# /usr/lib/systemd/systemd-udevd
# udevadm trigger /dev/input/event?
加载固件
使用编写的 sh 脚本启动 labwc 后,提示缺少固件
[ 9.846046] INIT: /bin/busybox chroot /data/root /bin/bash /wra/run.sh finished with return code: 139
[ 9.846127] exec /bin/busybox chroot /data/root /sbin/init --log-level=debug --log-target=kmsg --default-standard-output=kmsg --default-standard-error=kmsg
[ 9.862034] magiskinit: Fail to load policy from .magisk/selinux/load
....
[ 12.007066] subsys-restart: __subsystem_get(): Changing subsys fw_name to venus
[ 12.007112] subsys-pil-tz aab0000.qcom,venus: Falling back to syfs fallback for: venus.mdt
[ 12.007644] subsys-pil-tz aab0000.qcom,venus: venus: Failed to locate venus.mdt(rc:-11)
[ 12.007654] msm_vidc: err : ffffffff: .....: Failed to download firmware
[ 12.009064] msm_vidc: err : ffffffff: .....: DBLP Set: status 0
[ 12.010508] msm_vidc_v4l2 aa00000.qcom,vidc: Dropping the link to regulator.78
[ 12.010521] msm_vidc_v4l2 aa00000.qcom,vidc: Dropping the link to regulator.79
[ 12.010529] msm_vidc: err : ffffffff: .....: Failed to load Venus FW
[ 12.010534] msm_vidc: err : ffffffff: .....: Core init failed
[ 12.010539] msm_vidc: err : 00000002: ....e: Failed to init core, id = 0
[ 12.010544] msm_vidc: err : 00000002: ....e: Failed to move from state: 1 to 3
[ 12.010550] msm_vidc: err : 00000002: ....e: msm_comm_kill_session: no session to kill for inst 00000000433fbabc
[ 12.010555] msm_vidc: err : 00000002: ....e: Failed to move video instance to init state
[ 12.010592] msm_vidc: err : ffffffff: .....: Failed to create instance, core: 0, type = 0
观察 ueventd 的源码(注释)可以了解到,他不仅创建了 /dev 目录下的设备节点
init/ueventd.cpp
还可以从接收到的 uevent 事件加载对应的固件
init/firmware_handler.cpp
而这个功能(Userspace Firmware Loading) systemd 并没有提供
所以静态编译了一份精简版的 ueventd,放到了 /system/bin 里面,也顺便替换掉了之前使用的mdev 程序。
为了防止 systemd-udevd 提前发送"找不到"的消息,顺便把 这个systemd rules 也禁用了。
# stub for immediately telling the kernel that userspace firmware loading
# failed; necessary to avoid long timeouts with CONFIG_FW_LOADER_USER_HELPER=y
- SUBSYSTEM=="firmware", ACTION=="add", ATTR{loading}="-1"
+# SUBSYSTEM=="firmware", ACTION=="add", ATTR{loading}="-1"
捉摸不透的显示
加载固件成功后,理论上可以正常显示输出了。也确实如此,但是有极大的概率花屏..
花屏时的样子
好苦恼啊..不会触发 kernel panic (因为 /sbin/init 进程跑起来了), 也不会进入 900E。
简单写了 panic trigger 来解决这个问题
可以保证60秒内如果 /data/root/wra/.trigger 没有变成空的话,就手动触发 sysrq-trigger
测试后..日志里也看不到有用的信息...
为了测试是否为 drm 的问题,找了个简单的入门程序,打开 drm 设备并随机写入一个颜色,等待5秒后关闭并退出。
drm-test 正在运行,此时屏幕被写入为淡蓝色
静态编译成 drm-test,每次启动前都先运行他。然后 labwc 很奇妙的就不再花屏了...
插上鼠标简单测试了一下
启动 systemd 和 cmst(一个简易的网络管理器) 后,没有wifi。
缺少 Type 为 wifi 的设备...
载入内核模块
查看安卓 init 进程的日志可以看到,启动时会加载 /vendor/lib/modules 内的内核模块,此处的“qca6390/qca6490”便是网络内核模块。
[ 3.493304] init: Command 'symlink /vendor/bt_firmware /bt_firmware' action=early-init (/vendor/etc/init/hw/init.qcom.rc:42) took 0ms and failed: symlink() failed: Read-only file system
[ 3.493586] init: Command 'symlink /vendor/dsp /dsp' action=early-init (/vendor/etc/init/hw/init.qcom.rc:43) took 0ms and failed: symlink() failed: Read-only file system
[ 3.499056] init: starting service 'exec 2 (/vendor/bin/modprobe -a -d /vendor/lib/modules msm_11ad_proxy)'...
[ 3.501498] init: SVC_EXEC service 'exec 2 (/vendor/bin/modprobe -a -d /vendor/lib/modules msm_11ad_proxy)' pid 616 (uid 0 gid 0+0 context u:r:vendor_modprobe:s0) started; waiting...
....
[ 3.531967] init: Service 'exec 2 (/vendor/bin/modprobe -a -d /vendor/lib/modules msm_11ad_proxy)' (pid 616) exited with status 0 waiting took 0.031000 seconds
[ 3.531993] init: Sending signal 9 to service 'exec 2 (/vendor/bin/modprobe -a -d /vendor/lib/modules msm_11ad_proxy)' (pid 616) process group...
[ 3.532159] libprocessgroup: Successfully killed process cgroup uid 0 pid 616 in 0ms
[ 3.532447] init: processing action (early-init) from (/vendor/etc/init/hw/init.target.rc:31)
[ 3.532786] init: starting service 'exec 3 (/vendor/bin/modprobe -a -d /vendor/lib/modules audio_q6_pdr audio_q6_notifier audio_snd_event audio_apr audio_adsp_loader audio_q6 audio_native audio_usf audio_pinctrl_wcd audio_pinctrl_lpi audio_swr audio_platform audio_hdmi audio_stub audio_wcd_core audio_wsa881x audio_bolero_cdc audio_wsa_macro audio_va_macro audio_rx_macro audio_tx_macro audio_wcd938x audio_wcd938x_slave audio_machine_kona)'...
[ 3.535184] init: SVC_EXEC service 'exec 3 (/vendor/bin/modprobe -a -d /vendor/lib/modules audio_q6_pdr audio_q6_notifier audio_snd_event audio_apr audio_adsp_loader audio_q6 audio_native audio_usf audio_pinctrl_wcd audio_pinctrl_lpi audio_swr audio_platform audio_hdmi audio_stub audio_wcd_core audio_wsa881x audio_bolero_cdc audio_wsa_macro audio_va_macro audio_rx_macro audio_tx_macro audio_wcd938x audio_wcd938x_slave audio_machine_kona)' pid 617 (uid 0 gid 0+0 context u:r:vendor_modprobe:s0) started; waiting...
....
[ 12.465931] init: Service 'exec 23 (/vendor/bin/modprobe -a -d /vendor/lib/modules/ qca_cld3_qca6390 qca_cld3_qca6490)' (pid 1228) exited with status 0 oneshot service took 5.991000 seconds in background
[ 12.465939] init: Sending signal 9 to service 'exec 23 (/vendor/bin/modprobe -a -d /vendor/lib/modules/ qca_cld3_qca6390 qca_cld3_qca6490)' (pid 1228) process group...
[ 12.466033] libprocessgroup: Successfully killed process cgroup uid 0 pid 1228 in 0ms
....
在这里来说最"通用"的方法是按照 /vendor/lib/modules/modules.load 里的顺序全部加载,刚好 init 里也有这个函数
libmodprobe/libmodprobe.cpp
写个小组件调用即可
basePaths 为 module 所在的目录。useBlocklist 是否禁用 modules.blocklist 里的模块。strictMode 任何一个模块加载失败就退出
CNSS
想要高通的 cnss 网络子系统正常启动,需要 /vendor/bin/cnss-daemon 与 /vendor/bin/qrtr-ns 同时运行
前者提供了 cnss 子系统的固件 载入 校正 功能,是闭源的。
后者提供了 cnss 子系统的 qmi 网络功能,有社区开源实现。
需要对 /dev/ipa 写入 1 才能启动子系统。
需要对 /sys/kernel/cnss/fs_ready 写入 1 才能通知内核准备执行校正
总之很麻烦,也很 dirty。网上也没多少资料。
如果 cnss 没有正确初始化而载入了 wlan 网络模块的话,便会 kernel panic
[ 33.649082] pm8150b_charger: smblib_run_aicl: re-running AICL
[ 33.649318] FCC_MAIN: effective vote is now 3599978 voted by FCC_STEPPER_VOTER,1
[ 33.649323] pm8150b_charger: is_cp_topo_vbatt: true
[ 33.649340] pm8150b_charger: smblib_set_charge_param: fast charge current = 3599978 (0x47)
[ 33.760053] cnss: fatal: Timeout waiting for FW ready indication
[ 33.760115] subsys-restart: subsystem_restart_dev(): Restart sequence requested for wlan, restart_level = SYSTEM.
[ 33.864080] Kernel panic - not syncing: subsys-restart: Resetting the SoC - wlan crashed.
[ 33.864089] CPU: 0 PID: 663 Comm: kworker/0:4 Tainted: G S W O 4.19.157-perf+ #1
[ 33.864094] Hardware name: Qualcomm Technologies, Inc. kona standalone MTP (DT)
[ 33.864111] Workqueue: events device_restart_work_hdlr
[ 33.864117] Call trace:
[ 33.864126] dump_backtrace+0x0/0x248
[ 33.864133] show_stack+0x14/0x20
[ 33.864141] dump_stack+0xb8/0xf4
[ 33.864149] panic+0x158/0x2d8
[ 33.864154] device_restart_work_hdlr+0x44/0x48
[ 33.864162] process_one_work+0x278/0x440
[ 33.864167] worker_thread+0x260/0x4a8
[ 33.864174] kthread+0x140/0x150
[ 33.864180] ret_from_fork+0x10/0x18
[ 33.864191] SMP: stopping secondary CPUs
....
为了能运行这两个二进制文件,只能提取 Android GSI 里的 /system/lib64/* 以及 /system/bin/linker64 来创建基本的运行环境。
cnss 加载成功后,启动 cmst 连接网络,试着 ping一下,但是..
明明都 sudo 了为什么还会 Permission denied 呢
奇怪的网络
根据这个回答可以了解到安卓内核有个特别的Patch,只允许属于某些硬编码GID的用户访问网络。而且 postmarketos 也不要打开这个内核配置(CONFIG_ANDROID_PARANOID_NETWORK)
解决方法就是把使用网络的用户添加到 gid 为 3001 及以上的组里面
# groupadd -g 3001 aid_bt
# groupadd -g 3002 aid_bt_net
# groupadd -g 3003 aid_inet
# groupadd -g 3004 aid_net_raw
# groupadd -g 3005 aid_admin
# usermod -a -G aid_bt,aid_bt_net,aid_inet,aid_net_raw,aid_admin [someuser]
这里的用户不是有很多吗,后面可能也会创建不同的用户。
怎么打开屏幕键盘,修改后的软件更新怎么办?
触摸输入这些命令是不是太不方便了?
Control Panel
那就只能写一个软件来补充了,现在暂时是这个样子。
可以很方便的设置 labwc 的触摸输入旋转
FAQ
Q: 为什么只弄到网络?
A: 有了网络就方便装包,也可以电脑远程debug。
Q: 有项目地址吗?
A: github.com/SnowNF/wra.… 有帮助的话记得点个星星 作者会高兴好几天的..
Q: 有简单的展示吗?
A:
Since Thu 1970, 这个平板已经运行 54 年了 hahaha
连接的是 busybox 的 telnetd,所以 Terminal 是 busybox
Q: GSI的镜像“格式”
A: 使用了 system-as-root 所以是 system-arm64-ab.img
Q: 兼容性怎么样?
A: WORKS ON MY MACHINE, 我也不清楚呀..试试就知道啦。不过我的 8+gen1 的手机启动不了,没有日志,暂时不清楚什么原因。(可能是缺少/system/bin/snapuserd)
Q: 未来的计划?
A: 有空的话修修声音吧...如果有其他备用机的话也会试试,尝试提升一下兼容性。
Q: 性能怎么样?
A: 和上一篇文章一样,不过少了安卓服务所以RAM占用更少。