You are absolutely correct. On Windows/macOS, we run as a "Guest Application" inside a Window (minifb). But on Android (specifically as an OS replacement or High-Privilege Service), AetherOS operates differently.
Instead of running on top of a desktop compositor, AetherOS on Android runs in one of two modes:
- Role: AetherOS replaces the Android Runtime (ART/Zygote).
- Graphics: It takes control of the Hardware Composer (HWC) or
DRM/KMSdirectly. - Input: Reads directly from
/dev/input/event*.
- Role: AetherOS is the Kernel (using the Linux backend as a Type-1 Hypervisor shim).
In kernel/src/main.rs, we already gated minifb out for Android. The next step is replacing the "Sleep Loop" with a Direct Rendering Backend.
pub struct AndroidBackend {
// Direct access to GPU/Display hardware
drm_device: std::fs::File,
framebuffer_map: *mut u8,
}
impl Backend for AndroidBackend {
fn new() -> Self {
// 1. Open /dev/dri/card0 (Direct Rendering Manager)
// 2. Perform IOCTLs to set video mode (KMS)
// 3. Map the "Dumb Buffer" (Video RAM) to host memory
// 4. Return this pointer as the "Framebuffer"
}
unsafe fn get_framebuffer(&self) -> &[u32] {
// Return pointer to ACTUAL Video RAM, not a heap buffer
}
}In the Desktop version, we copy Guest RAM -> Host RAM -> Window Texture. In the Android Native version:
- We configure the Display Controller (CRTC) to scan out directly from the Guest's Physical RAM address (if using IOMMU/SMMU).
- Or simpler: The Guest writes to a memory region that IS the mapped Video Output.
- Result: 0% CPU usage for display. Pure hardware scan-out.
- Desktop:
minifbevents. - Android: Parse
/dev/input/event0(Touchscreen) raw byte streams directly in the Kernel thread, converting them to ABI events for the Guest.
You raised a critical point: Vendor drivers (GPU, WiFi) are compiled against bionic (Android libc) and often present as proprietary HAL modules.
Since AetherOS compiles to aarch64-linux-android, it native links against Bionic!
- We don't strictly need
libhybrisif we stay within the Android Linker namespace. - Challenge: Vendor drivers speak HIDL/AIDL. We would need to implement a "Rust HwBinder" to talk to the GPU HAL.
If we want to run AetherOS on a standard Linux kernel (bypassing Android Init entirely), we need libhybris to load the Android-specific .so blobs (e.g., libGLESv2_adreno.so) inside a glibc/musl environment.
- Precedent: SailfishOS and Ubuntu Touch use this.
- Recommendation: For the "Android Replacement" goal, we should stick to Strategy A: run as an Android executable (using Bionic), but replace the upper Java Framework (SurfaceFlinger/Zygote).
You asked about permissions. Android is notorious for locking down Native processes.
- SELinux: Even as
root, you cannot just open/dev/kvmor/dev/driif the Security Policy (sepolicy) forbids your domain from doing so. - Seccomp: The Kernel filters "dangerous" syscalls.
- AVB (Verified Boot): If we modify
boot.imgto spawn AetherOS, the phone will refuse to boot unless the bootloader is unlocked.
- Device must be Unlock Bootloader.
- We use
suto launch AetherOS. - We perform
setenforce 0(Permissive Mode) to bypass SELinux temporarily.
- We modify
init.rcto startservice aether /system/bin/aether-kernel. - We compile a custom SEPolicy (
.tefile) grantingallow aether kvm_device:chr_file rw_file_perms;. - This is how OEMs add their own services. We play by the same rules.
The current minifb implementation is a "Simulator" for development.
The Android target will evolve into a "Driver" that talks to silicon, potentially using libhybris or native HIDL to bridge proprietary vendor blobs.