|
| 1 | +#!/sbin/busybox sh |
| 2 | +# /sbin/init wrapper: execs Android /init with androidboot.* args. |
| 3 | +# |
| 4 | +# Why this exists: |
| 5 | +# - initramfs-tools switch_root defaults to /sbin/init (or kernel init= param) |
| 6 | +# - Android rootfs only has /init (no /sbin/init) |
| 7 | +# - androidboot.* params must be in /init's argv (/proc/self/cmdline) |
| 8 | +# because redroid's init reads them from there |
| 9 | +# |
| 10 | +# Key params: |
| 11 | +# - use_memfd=1: use memfd when ashmem is unavailable on modern kernels |
| 12 | +# - selinux=permissive: required for redroid in VM mode |
| 13 | +# - redroid_gpu_mode=guest: force software-render path in VM direct-boot mode |
| 14 | +# - use_redroid_c2/use_dmabufheaps: prefer Codec2 path in ashmem-less kernels |
| 15 | +# - use_redroid_omx=0: avoid unstable OMX path when gralloc.redroid requires ashmem |
| 16 | +# |
| 17 | +# Uses busybox (static) as interpreter — no dependency on Android's |
| 18 | +# /system/bin/sh or linker64 at this early boot stage. |
| 19 | + |
| 20 | +# Relocate product/system_ext apps to /system/{app,priv-app}/ (system namespace). |
| 21 | +# |
| 22 | +# In bare VM, everything is on a single overlayfs — Android's libnativeloader |
| 23 | +# can't detect partition boundaries (same st_dev), so sandboxed processes get |
| 24 | +# "product-clns-N" classloader namespaces with restricted permitted_paths, |
| 25 | +# blocking dlopen of native libs (e.g. WebView's libwebviewchromium.so). |
| 26 | +# Docker doesn't hit this because its overlay layers create distinct mount points. |
| 27 | +# |
| 28 | +# Moving apps to /system/app/ puts them in the "system" namespace which has |
| 29 | +# full lib access. Runs before Android init scans packages; COW layer absorbs writes. |
| 30 | +# Can't do this in Dockerfile RUN — Android rootfs has no standard Linux linker. |
| 31 | +BB=/sbin/busybox |
| 32 | +for d in /system/product/app/*/; do |
| 33 | + [ -d "$d" ] || continue |
| 34 | + name=$($BB basename "$d") |
| 35 | + [ -e "/system/app/$name" ] || $BB mv "$d" /system/app/ |
| 36 | +done |
| 37 | +for d in /system/product/priv-app/*/; do |
| 38 | + [ -d "$d" ] || continue |
| 39 | + name=$($BB basename "$d") |
| 40 | + [ -e "/system/priv-app/$name" ] || $BB mv "$d" /system/priv-app/ |
| 41 | +done |
| 42 | +for d in /system/system_ext/app/*/; do |
| 43 | + [ -d "$d" ] || continue |
| 44 | + name=$($BB basename "$d") |
| 45 | + [ -e "/system/app/$name" ] || $BB mv "$d" /system/app/ |
| 46 | +done |
| 47 | +for d in /system/system_ext/priv-app/*/; do |
| 48 | + [ -d "$d" ] || continue |
| 49 | + name=$($BB basename "$d") |
| 50 | + [ -e "/system/priv-app/$name" ] || $BB mv "$d" /system/priv-app/ |
| 51 | +done |
| 52 | + |
| 53 | +# Fix native lib symlinks pointing to product/system_ext paths. |
| 54 | +# After moving apps to /system/app/, their lib/ dirs may contain symlinks |
| 55 | +# like libjni_latinime.so -> /system/product/lib64/libjni_latinime.so. |
| 56 | +# The system namespace can't dlopen from product paths, so replace symlinks |
| 57 | +# with copies of the actual files. |
| 58 | +for link in $($BB find /system/app /system/priv-app -type l -name '*.so' 2>/dev/null); do |
| 59 | + target=$($BB readlink "$link") |
| 60 | + case "$target" in |
| 61 | + /system/product/*|/system/system_ext/*) |
| 62 | + [ -f "$target" ] && $BB cp "$target" "${link}.tmp" && $BB mv "${link}.tmp" "$link" |
| 63 | + ;; |
| 64 | + esac |
| 65 | +done |
| 66 | + |
| 67 | +# Disable simulated Bluetooth — no real BT hardware in VM. |
| 68 | +# Four layers disabled to fully prevent the crash loop: |
| 69 | +# 1. APEX: rename com.android.btservices apex so apexd won't activate it, |
| 70 | +# preventing com.android.bluetooth process from ever starting |
| 71 | +# 2. HAL binary: prevents "Invalid address" abort from vendor HAL |
| 72 | +# 3. VINTF manifest: prevents system_server from discovering BT HAL via HIDL |
| 73 | +# 4. config.disable_bluetooth (in cocoon-disable-bt.rc): framework-level disable |
| 74 | +for f in $($BB find /system/apex -name '*btservices*' -o -name '*bluetooth*' 2>/dev/null); do |
| 75 | + $BB mv "$f" "${f}.disabled" 2>/dev/null |
| 76 | +done |
| 77 | +$BB mv /vendor/bin/hw/android.hardware.bluetooth@1.1-service.sim \ |
| 78 | + /vendor/bin/hw/android.hardware.bluetooth@1.1-service.sim.disabled 2>/dev/null |
| 79 | +for f in $($BB find /vendor/etc/vintf -name '*bluetooth*' 2>/dev/null); do |
| 80 | + $BB mv "$f" "${f}.disabled" 2>/dev/null |
| 81 | +done |
| 82 | + |
| 83 | +exec /init \ |
| 84 | + qemu=1 \ |
| 85 | + androidboot.hardware=redroid \ |
| 86 | + androidboot.use_memfd=1 \ |
| 87 | + androidboot.use_redroid_c2=1 \ |
| 88 | + androidboot.use_dmabufheaps=1 \ |
| 89 | + androidboot.use_redroid_omx=0 \ |
| 90 | + androidboot.selinux=permissive \ |
| 91 | + androidboot.redroid_gpu_mode=guest \ |
| 92 | + androidboot.redroid_width=720 \ |
| 93 | + androidboot.redroid_height=1280 \ |
| 94 | + androidboot.redroid_dpi=240 |
0 commit comments