qemu internals

277 views
Skip to first unread message

Lehel Kovach

unread,
Dec 21, 2008, 7:28:26 PM12/21/08
to android-...@googlegroups.com
can someone give me a crash course on the structure of qemu, mainly how it emulates hardware? what exactly are the "goldfish" files and, using sound as an example, which file contains the code for the emulation of android's sound drivers.

David Turner

unread,
Dec 21, 2008, 10:50:33 PM12/21/08
to android-...@googlegroups.com
I can't make this much longer, but:

CPU emulation:
QEMU isolates code fragments (i.e. series of ARM instructions ending in a branch (i.e. jumps, conditional jumps, function calls, returns, etc...) and converts them into a "translated block" (a.k.a. TB) of native host (x86) code. All TB fragments are put in a cache and each time the instruction pointer changes, a hash table lookup is performed to find the next TB to execute. If none exists, a new one is generated.

CPU state is kept in a single static structure which the generated code can access directly.

MMU emulation:
QEMU emulates the ARM MMU in software, since it is so different from the host's one.
Essentially, a single ARM load instruction is translated into a small sequence of native instructions that will perform the virtual to physical address conversion as follows:

first look in a static 256-entries cache for the current page and see if a corresponding value is already stored there. If so, use it. (the cache is called the "tbl" in the sources).

otherwise, call a helper function that will perform all necessary computations to translate the virtual address into a physical one. this will eventually update the tbl for the next access within the same page.

when initializing the MMU emulation, one can define several zones of the address space, with different access rights / type. This is how memory-mapped i/o is implemented: the virtual->physical conversion function detects that you're trying to read/write from an i/o memory region, and will then call a callback function associated to it.

note that there is really two distinct TBL caches used in the sources: one for the kernel address space, and another one for user-space (the latter is flushed each time on each process context switch). they implement different policies but most of this difference is handled at code generation time (i.e. a memory load in the kernel will not be translated into the same sequence than a memory load in user-space memory).

Hardware emulation:
most hardware initializes by registering its own region of i/o memory, as well as providing read/write callbacks for it. Then actions will be based on which offset of the i/o memory is read from/written to and eventually with which value.

the code in target-arm/translate.c is used to dynamically translate ARM instructions into native code for the host machine. This works by isolating code fragments (i.e. series of ARM instructions ending in a branch, conditional or not), then generating a "translated block" for each one of them, which is supposed to 

Goldfish:
this is simply the name of the configuration (virtual platform) used to build the Android kernel for the emulator.Any goldfish device is thus strictly speaking only used for the emulator and should not reflect any real hardware.

the exact details depend on the kernel sources, so you can't just guess what's need to be done. there must be a convention between the kernel driver and the corresponding emulated hardware as to how to do things.

the initialization of all goldfish devices is done in hw/android_arm.c at the time.

hw/goldfish_audio.c contains the emulated audio hardware support, which relies on the capabilities of the audio/ subsystem;which itself is a bit sophisticated. For a simpler example, have a look at hw/goldfish_tty.c used for serial ports.
Reply all
Reply to author
Forward
0 new messages