Thoughts and questions about Android compatibility layers


Haraldur

Very Active Member
Joined
Mar 12, 2015
Messages
300
What-ho, chums! I have spent too much time musing about Android compatibility layers since I posted the following over a fortnight ago:

A compatibility layer for Android may provide better performance, though. It should be easier to do than WINE (hey, does anyone know of an explanation of how WINE works, at a low level? I am particularly interested in how it does system call or library call redirection), as there are some open source components that (seem to) already exist: the Hybris library (https://en.wikipedia.org/wiki/Hybris_(software)) that is a compatibility layer just for the Bionic C library on GLIBC; plus the FOSS components of Android itself. Given that Android uses a variant of the Linux kernel, the wineserver equivalent (I think that is the part involved with system call redirection) would only need to cover the Android kernel's additions, like Binder, with other syscalls getting passed along, unchanged (someone please correct any misconceptions).

As you may surmise, I know very little about Android and, unfortunately, I failed to spark a discussion with that post. I try again now.

I know very little about Microsoft Windows internals as well, so my assumption that WINE does system call redirection may be wrong; I have learned, since, that direct/naked syscall use on Windows is highly discouraged, as syscalls and syscall ID numbers can (and do) change from release to release (and from hotfix to hotfix -- there is absolutely no stable kernel ABI, unlike with Linux). Instead, Windows application programmers are expected to use the Windows API, which, I suppose, fills the same niche as glibc; the Windows API itself is over the Native API, which is not supposed to be used outside Microsoft. WINE re-implements these APIs (ABIs?), so I suppose any syscall redirection (if it exists) is of minor importance for WINE. It does use the ptrace syscall (see below), though, for what, I know not.

My reading suggests that the only way to intercept syscalls is with the kernel's help, using the ptrace syscall. So a compatibility layer might try to use ptrace to intercept all syscalls from Android/Dalvik, resending those that "exist" in the mainline Linux kernel while diverting syscalls with ID numbers that do not "exist" (such as any involved with Binder) to the compatibility layer's own code. While researching this, I came across User Mode Linux, which seems to do something very similar: it is a copy of the Linux Kernel as a normal ELF executable that runs on top of the host Linux system, with all programs launched by this guest kernel having their syscalls intercepted with ptrace and forwarded when appropriate. It seems to be intended for testing development versions of the Linux kernel on top of a stable system -- and the Android kernel can be considered to be simply a development kernel with extra features. Three problems exist that I can think of: first, User Mode Linux lacks an ARM version so far (there exist x86 -- not sure about x86_64 -- and PowerPC versions) so that would have to be created; second, User Mode Linux does not seem to be a hugely active project at the moment (I could be wrong); third, User Mode Linux may be nearer to virtualization than WINE, so it may be too "heavy" -- that is, why not just use a full virtual machine with, presumably, less effort? Not to mention that it may be that Android programs very rarely use Linux syscalls directly (does Dalvik's dynamic recompiler, or Android's newer AOT compiler, generate syscall instructions?), like with Windows (after all, if the Android kernel's features were mainlined, would the new syscalls keep their current ID numbers? Also, I am not sure that the Android developers have the same attitude to binary code compatibility that Linus Torvalds professes to have regarding to the Linux ABI and its syscalls).

Aside from the kernel, there are Dalvik/ART(Android Runtime), Bionic libc and the windowing system (SurfaceFlinger?). I mentioned libhybris in my quoted post, though if using User Mode Linux I suppose it may make more sense to use Bionic directly, with Dalvik/ART on top of that. If not using User Mode Linux, libhybris may be used for Dalvik/ART. For the windowing system, there would need to be either a Xephyr equivalent or direct use of a Linux framebuffer (or virtual console, whatever it is called, it is switched with CTRL+ALT+F(X) where X is from 1 to 7 or 8, usually -- by the way I have not been able to do this on a Pandora, any idea why?). I assume that the latter would be simpler.

Any comments? Do I grossly misunderstand any of this? Can kernel differences be ignored due to ABI instability leading to Android programs not using syscalls directly? How does using User Mode Linux compare with using a more general purpose virtualization program?
[doublepost=1451524979,1451505788][/doublepost]Oh, incidentally, would there be any substantial downside to using the Android kernel by default in Pyra OS? As far as I know, the Android kernel includes only additions compared with the mainline kernel it is based on, so there would be extra work (how much, I know not) importing features to/from the latest mainline kernel. However, unless I misunderstand something, it would allow the use of a chroot plus some way of choosing to use Bionic within the chroot (is that not automatic?) plus Dalvik/ART plus SurfaceFlinger (or whatever it is) on a separate framebuffer/virtual console with relatively little work.
 
I guess any kernel that Android supports might not be as up to date as the one Debian ships with, although then again, Debian tends to rely on backports to older stable kernel versions in the main, so maybe that's less of a problem.

I still tend to think a dual-boot solution where the system boots a completely different android kernel and kicks off the android init rather than the systemd one is the simpler way to get android up and running at least to begin with though. An android shim could later be coded up, if people are interested, to allow android apps to be ported, and to run enough core android services to look like an android device if people want, but that seems like a stretch goal to me. Or perhaps you could qemu emulate an ARM core running android within debian if you wanted to, which may or may not be fast enough for general use.

There's more that one way to skin this cat.
 
I seem to recall that Gingerbread on the Pandora just used the Pandora Kernel, because all the kernel code needed by Android had already been mainlined. That being the case would it really be necessary to use separate kernels for Android and Debian on the Pyra? If Android can be used with our default Pyra kernel, why would you need to intercept syscalls at all?
Or am I missing something?

-Neelix
 
I seem to recall that Gingerbread on the Pandora just used the Pandora Kernel, because all the kernel code needed by Android had already been mainlined. That being the case would it really be necessary to use separate kernels for Android and Debian on the Pyra? If Android can be used with our default Pyra kernel, why would you need to intercept syscalls at all?
Or am I missing something?

-Neelix

This is very interesting, if true, as it seems to contradict what I have read (or construed, at least) elsewhere -- it may be that Android's extra kernel features are never used directly by application software and can be "faked".

If the Pandora/Pyra kernel was Android compatible, or if the Pyra used an Android kernel, then there be no need for syscall interception. There would need to be some way of running Dalvik on top of GNU (for which there are few search results), likely needing either the Bionic libc or the libhybris compatibility layer, with a faked/virtual filesystem (perhaps a chroot) and some way of displaying graphics (either in a window, like with Xephyr, or by providing a replacement library to produce X protocol commands -- or whatever -- or by using a separate virtual/framebuffer console).

Thus far, I have not had the patience to read through all the details of the Android stack, nor the GNU/Linux stack. I have also not found any convenient guides for lazy people like me.

One problem I have had with researching this stuff is that I get so many irrelevant results: instructions for running a GNU system on top of Android (i.e. the wrong way around), instructions for running Android x86 in VirtualBox and so on. It is almost as if there is no interest in running Android programs on top of GNU, unlike with WINE. I find this perplexing.
 
Back
Top