feat: Android 8 (API 26) support — NDK retarget, devtmpfs fix, LF normalization, mount hardening#42
Merged
Conversation
Retarget NDK toolchain from android28 to android26 throughout Dockerfile, add hand-rolled iconv shim for API-26 glib build, lower minSdk to 26. Fixes: ExTV#28 Co-authored-by: Copilot <[email protected]>
…cripts Windows git core.autocrlf=true was silently converting LF→CRLF in all shell scripts on checkout. When Docker COPY'd init-podroid into the initramfs the shebang became #!/bin/sh\r, causing the kernel to fail init with ENOENT (error -2) and fall back to mounting /dev/vda directly. This booted the old overlay-upper content (with stale inittab having tty1-6 gettys) instead of the current squashfs, so boot-stage markers were never emitted and the VM appeared stuck. Changes: - Add .gitattributes: force eol=lf for *.sh, Dockerfile, init-podroid, all build-rootfs/files/** scripts and configs; mark binary assets - Normalize all affected working-copy files from CRLF to LF Both the initramfs /init and the squashfs init.d scripts now carry correct LF endings, fixing VM boot on all platforms. Co-authored-by: Copilot <[email protected]>
…and Android 8 docs - init-podroid: move mount -o flags before device/mountpoint (util-linux stops getopt at first non-option arg when POSIXLY_CORRECT is set; options after the mountpoint were silently dropped, causing EPERM -> 'must be superuser to use mount' even for root) - init-podroid: add '|| true' to devtmpfs mount and remove 'size=2M' (CONFIG_DEVTMPFS_MOUNT=y pre-mounts /dev before /init runs; a second mount returns EBUSY, and size= is invalid for ramfs-backed devtmpfs causing EINVAL; either failure exits util-linux with MNT_EX_FAIL=32, propagated by set -e as exit(32) = kernel exitcode=0x00002000 'Attempted to kill init!') - init-podroid: add mkdir -p /proc /sys /dev /run guard and [podroid-init] diagnostic echo markers throughout the boot sequence - Dockerfile: replace 'RUN cat > file << EOF ... [binaries]' heredoc with 'COPY build-tools/cross-android-aarch64.ini' to fix Docker BuildKit parse error (BuildKit treats [section] lines in heredocs as unknown instructions) - build-tools/cross-android-aarch64.ini: new file containing the Meson cross-compilation config for aarch64-android26, extracted from the heredoc - README.md, CONTRIBUTING.md, CLAUDE.md: update Android min version 9+ -> 8+, add build-tools/ to project layout, document devtmpfs and Dockerfile quirks Co-authored-by: Copilot <[email protected]>
Contributor
Author
Additional test resultsAsus Zenfone 4 (ASUS_Z01KD) — Android 8.0 (API 26), arm64
Samsung Galaxy S24 Ultra — Android 16, arm64
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Summary
Extends minimum supported Android version from API 28 to API 26 (Android 8.0) by fixing four independent root causes that together prevented QEMU + the VM guest from working on API 26 devices.
Fixes: #28
Commits
1.
feat: add Android 8 (API 26) support with iconv shimRetargets the NDK toolchain from
android28toandroid26throughout the Dockerfile and adds a hand-rollediconvshim required for theglibbuild at API 26 (whereiconvis not in the NDK sysroot). LowersminSdkto 26 in the Android project.2.
fix(build): add .gitattributes to enforce LF line endings for Linux scriptsWindows
git core.autocrlf=truesilently converted LF→CRLF on checkout. When DockerCOPY'dinit-podroidinto the initramfs the shebang became#!/bin/sh\r, causing the kernel to fail init withENOENTand fall back to mounting/dev/vdadirectly — booting stale overlay content with oldinittabgettys instead of the current squashfs, so boot-stage markers were never emitted and the VM appeared stuck indefinitely..gitattributes:eol=lffor all*.sh,Dockerfile,init-podroid, andbuild-rootfs/files/**; binary assets marked accordingly3.
feat(init): enhance virtual filesystem mounting logic in init scriptIntermediate step hardening the early-boot mount sequence before the root-cause fix below.
4.
fix(build): fix devtmpfs boot panic, Dockerfile heredoc parse error, and Android 8 docsThe definitive boot-panic fix, addressing three separate issues found during API 26 testing:
devtmpfs mount panic (
exitcode=0x00002000/Attempted to kill init!)util-linux mountstops option parsing at the first non-option argument whenPOSIXLY_CORRECTis set;-oflags placed after the mountpoint were silently dropped, causingEPERM→"must be superuser to use mount"even for rootCONFIG_DEVTMPFS_MOUNT=ypre-mounts/devbefore/initruns; a secondmountcall returnsEBUSY. Additionally,size=2Mis invalid for ramfs-backed devtmpfs →EINVAL. Either failure exits withMNT_EX_FAIL=32, whichset -epropagated as PID 1 exit → kernel panic-oflags before device/mountpoint; add|| trueto devtmpfs mount; removesize=2M; addmkdir -pguards; add[podroid-init]echo markers throughoutDockerfile heredoc parse error (Docker BuildKit)
RUN cat > file << EOF ... [section]heredocs were broken by BuildKit treating[section]lines as unknown build instructionsCOPY build-tools/cross-android-aarch64.ini; extract the Meson cross-compilation config tobuild-tools/cross-android-aarch64.iniDocumentation
README.md,CONTRIBUTING.md,CLAUDE.md: update Android min version9+→8+, addbuild-tools/to project layout, document the devtmpfs and Dockerfile quirks for future contributorsTesting
Ready!detected byBootStageDetectorin ~55 s, no timeout fallback triggeredThe guest-side fixes (
init-podroid,.gitattributes) are host-OS agnostic and require no API-level guards in the Android app.Checklist
README.mdupdated (user-facing: new minimum Android version)CLAUDE.mdupdated (architecture change: NDK target, build-tools layout, devtmpfs behaviour)CONTRIBUTING.mdupdated (min version, newbuild-tools/directory)