SlideShare ist ein Scribd-Unternehmen logo
1 von 84
Downloaden Sie, um offline zu lesen
STUDY ON ANDROID EMULATOR
Samael Wang
PURPOSE
• To understand important details of emulator.
• To get familiar with recent upstream changes and possibly ongoing plans.
• To evaluate upstream contribution process (for potential back porting).
• For fun, of course.
BUILD & RUN
GET THE EMULATOR SOURCE
$ mkdir emu-master-dev && cd emu-master-dev
$ repo init -u https://android.googlesource.com/platform/manifest -b emu-master-dev
$ repo sync
emu-master-dev (~12GB) master (~36GB)
external
frameworks
prebuilts
sdk
tools
abi
art
bionic
bootable
build
cts
dalvik
developers
development
device
docs
external
frameworks
hardware
libcore
libnativehelper
Makefile
ndk
packages
pdk
prebuilts
sdk
system
toolchain
tools
BUILD THE EMULATOR
classic
- Use QEMU 0.10.5 since ~2009
- Android Cupcake ~ Lollipop
- Goldfish virtual platform
- @external/qemu
qemu2
- Use QEMU 2.2.0 since ~2015
- Android M ~
- Ranchu virtual platform
- @external/qemu-android
The classic and qemu2 emulator
$ cd external/qemu
$ ./android-rebuild.sh --build-qemu-android
Build both
the output is under objs directory
BUILD EMULATOR WITH QT
• Android Emulator is moving to Qt.
• In development. Unstable.
• Providing Tool Window.
• Default option remains SDL2.
$ cd external/qemu
$ ./android/scripts/download-sources.sh
$ ./android/scripts/build-qt.sh
$ ./android/scripts/build-libxml2.sh
$ ./android-rebuild.sh --ui=qt
APPARENTLY…
… android emulator should have a floating toolbox ?
Xamarin Android Player (VirtualBox) Visual Studio Emulator for Android (Hyper V)
EMULATOR BINARIES
- emulator: front-end used to find proper emulation engine and setup environment
variables (mainly LD_LIBRARY_PATH).
- green nodes: classic emulation engines.
- blue nodes: qemu2 emulation engines.
- orange nodes: GLES / EGL emulation libraries.
3 WAYS TO LAUNCH EMULATOR
• Setup an Android Virtual Device, or
• Setup corresponding environment variables (in build-root), or
• Skip front-end and pass all arguments manually to emulation engine.
ANDROID VIRTUAL DEVICE
$ cat emulator-x86-l.avd/config.ini
avd.ini.encoding=UTF-8
abi.type=x86
disk.dataPartition.size=200M
hw.accelerometer=yes
hw.audioInput=yes
hw.battery=yes
hw.camera.back=none
hw.camera.front=none
hw.cpu.arch=x86
hw.dPad=no
hw.device.hash2=MD5:37a2ff6e511626ba3ceddec8264474be
hw.device.manufacturer=Google
hw.device.name=Nexus S
hw.gps=yes
…
SETUP ENVIRONMENT VARIABLES
$ export ANDROID_BUILD_TOP=$PWD
$ export ANDROID_PRODUCT_OUT=$PWD/out/target/product/generic_x86
$ ./out/host/darwin-x86/bin/emulator -gpu on
- Load kernel from ${ANDROID_BUILD_TOP}/prebuilts/qemu-­‐kernel/
- Load skin from ${ANDROID_BUILD_TOP}/development/tools/emulator/skins/
- Load the images from ${ANDROID_PRODUCT_OUT}

system.img (or system-­‐qemu.img)

userdata.img

ramdisk.img

cache.img (optional)

sdcard.img (optional)
PASS EVERYTHING MANUALLY
/Volumes/Development/b2g/emulator-x86-kk/out/host/darwin-x86/bin/emulator-x86
-kernel /Volumes/Development/b2g/emulator-x86-kk/prebuilts/qemu-kernel/x86/kernel-qemu
-sysdir /Volumes/Development/b2g/emulator-x86-kk/out/target/product/generic_x86/
-data /Volumes/Development/b2g/emulator-x86-kk/out/target/product/generic_x86/userdata.img
-sdcard /Volumes/Development/b2g/emulator-x86-kk/out/target/product/generic_x86/sdcard.img
-memory 512
-partition-size 512
-skindir /Volumes/Development/b2g/emulator-x86-kk/development/tools/emulator/skins
-skin HVGA
-verbose
-gpu on
-camera-back webcam0
WRITABLE SYSTEM IMAGE
• system.img and userdata.img are read-only initial images.
• usedata-­‐qemu.img is generated automatically on first launch.
• Temporarily writable system image is generated on each launch under /tmp.
• To make system image writable by default, move system.img to system-­‐qemu.img.
• See emulator	
  -­‐help-­‐disk-­‐images for more information
$ ls -lh /tmp/android-freesamael/
-rw------- 1 freesamael wheel 750M Sep 15 17:46 emulator-w1MQmT
EMULATOR INITIALIZATION
MAIN FUNCTIONS (1/2)
android/
main-emulator.c:main
android/
main.c:main vl-android.c:main
MAIN FUNCTIONS (2/2)
Emulator Front-end
Emulation Engine
android/main-emulator.c:main
- setups environment variables
- finds correct emulation engine

(32/64, arm/x86/…)
android/main.c:main
- setups UI skin window (SDL2/Qt)
- generates final hardware config 

“hardware-qemu.ini”
vl-android.c:main (qemu_main)
- init machine / virtual hardware
- init emulator adb / console
- start main loop
MAIN LOOP
• The core of QEMU is event driven - by using an
event loop.
• Waits for file descriptors (files, sockets, pipes,…)
to become readable or writable.
• Polls charpipe (android-specific).
• Runs expired timers.
• Runs bottom-halves (BHs) scheduled by above
handlers.
SKIN & UI HANDLING
SKIN (1/2)
emulator-window (SDL2/Qt)
window (abstraction)
events texture / bitmap
SkinSurface
SkinSurface
rendered
texture / bitmap
skin_window_redraw
SKIN (2/2) parts {
device {
display {
width 320
height 480
x 0
y 0
}
}
basic_controls {
background {
image basic.png
width 159
height 55
}
buttons {
volume-down {
image button.png
x 1
y 9
}
…
}
}
…
}
struct SkinSurface {
int refcount;
int w;
int h;
SDL_Surface* surface;
SDL_Texture* texture;
};
struct SkinSurface {
int refcount;
int id;
QImage *bitmap;
int w, h, original_w, original_h;
EmulatorQtWindow *window;
};
Layout Snippet
SDL2 SkinSurface
Qt SkinSurface
SKIN UI REFRESH
• Emulator skin refreshes at 60Hz by registered a timer to the main loop.
• gui_update() / nographic_update()
• Processes input events or passes them to the emulated system (multiple
events might be passed at the same time).
• Refresh the emulated framebuffer, if OpenGL emulation is not in use.
THE GOLDFISH VIRTUAL PLATFORM
GOLDFISH DEVICE REGISTRATION
int goldfish_device_add(struct goldfish_device *dev,
CPUReadMemoryFunc **mem_read,
CPUWriteMemoryFunc **mem_write,
void *opaque);
- Platform devices
- MMIO
GOLDFISH DEVICE REGISTRATION
int goldfish_device_add(struct goldfish_device *dev,
CPUReadMemoryFunc **mem_read,
CPUWriteMemoryFunc **mem_write,
void *opaque);
struct goldfish_device {
struct goldfish_device *next;
struct goldfish_device *prev;
uint32_t reported_state;
void *cookie;
const char *name;
uint32_t id;
uint32_t base; // filled in by goldfish_device_add if 0
uint32_t size;
uint32_t irq; // filled in by goldfish_device_add if 0
uint32_t irq_count;
};
int goldfish_device_add(struct goldfish_device *dev,
CPUReadMemoryFunc **mem_read,
CPUWriteMemoryFunc **mem_write,
void *opaque);
- Platform devices
- MMIO
GOLDFISH DEVICE REGISTRATION
int goldfish_device_add(struct goldfish_device *dev,
CPUReadMemoryFunc **mem_read,
CPUWriteMemoryFunc **mem_write,
void *opaque);
typedef uint32_t CPUReadMemoryFunc(void *opaque, hwaddr addr);
static CPUReadMemoryFunc *goldfish_bus_readfn[] = {
goldfish_bus_read, // byte
goldfish_bus_read, // word
goldfish_bus_read // dword
};
int goldfish_device_add(struct goldfish_device *dev,
CPUReadMemoryFunc **mem_read,
CPUWriteMemoryFunc **mem_write,
void *opaque);
- Platform devices
- MMIO
GOLDFISH DEVICE REGISTRATION
int goldfish_device_add(struct goldfish_device *dev,
CPUReadMemoryFunc **mem_read,
CPUWriteMemoryFunc **mem_write,
void *opaque);
typedef void CPUWriteMemoryFunc(void *opaque, hwaddr addr, uint32_t value);
static CPUWriteMemoryFunc *goldfish_bus_writefn[] = {
goldfish_bus_write, // byte
goldfish_bus_write, // word
goldfish_bus_write // dword
};
int goldfish_device_add(struct goldfish_device *dev,
CPUReadMemoryFunc **mem_read,
CPUWriteMemoryFunc **mem_write,
void *opaque);
- Platform devices
- MMIO
GOLDFISH DEVICE REGISTRATION
int goldfish_device_add(struct goldfish_device *dev,
CPUReadMemoryFunc **mem_read,
CPUWriteMemoryFunc **mem_write,
void *opaque);
typedef void CPUWriteMemoryFunc(void *opaque, hwaddr addr, uint32_t value);
static CPUWriteMemoryFunc *goldfish_bus_writefn[] = {
goldfish_bus_write, // byte
goldfish_bus_write, // word
goldfish_bus_write // dword
};
- Platform devices
- MMIO
int goldfish_device_add(struct goldfish_device *dev,
CPUReadMemoryFunc **mem_read,
CPUWriteMemoryFunc **mem_write,
void *opaque);
typedef void CPUWriteMemoryFunc(void *opaque, hwaddr addr, uint32_t value);
static CPUWriteMemoryFunc *goldfish_bus_writefn[] = {
goldfish_bus_write, // byte
goldfish_bus_write, // word
goldfish_bus_write // dword
};
Goldfish Platform Bus
DESIGN
• Discoverability: which memory address and interrupt a device uses?
• Platform bus: a special platform device to enumerate other devices.
• Goldfish platform bus design
• MMIO address region 0xff001000 to 0xff801000.
• 0xff001000 - 0xff001fff are reserved by goldfish_device_bus as a set of
32bit I/O registers for bus operations.
• The bus itself uses IRQ 1 on ARM, IRQ 4 on x86.
I/O REGISTERS
Device properties:
Name: goldfish_device_bus
Id: -1
IrqCount: 1
32-bit I/O registers (offset, name, abstract)
0x00 BUS_OP R: Iterate to next device in enumeration.
W: Start device enumeration.
0x04 GET_NAME W: Copy device name to kernel memory.
0x08 NAME_LEN R: Read length of current device's name.
0x0c ID R: Read id of current device.
0x10 IO_BASE R: Read I/O base address of current device.
0x14 IO_SIZE R: Read I/O base size of current device.
0x18 IRQ_BASE R: Read base IRQ of current device.
0x1c IRQ_COUNT R: Read IRQ count of current device.
KERNEL DRIVER IMPL
KERNEL DRIVER IMPL
0000-001f : dma1
0020-0021 : pic1
0040-0043 : timer0
0050-0053 : timer1
0060-0060 : keyboard
0064-0064 : keyboard
0070-0071 : rtc_cmos
0070-0071 : rtc0
0080-008f : dma page reg
00a0-00a1 : pic2
00c0-00df : dma2
00f0-00ff : fpu
03c0-03df : vga+
0cf8-0cff : PCI conf1
1000-10ff : goldfish_pdev_bus
c000-c0ff : 0000:00:02.0
c000-c01f : ne2k-pci
/proc/ioports
KERNEL DRIVER IMPL
00000000-0000ffff : reserved
00010000-0009efff : System RAM
0009f000-0009ffff : reserved
000a0000-000bffff : Video RAM area
000c0000-000c8bff : Video ROM
000c9000-000c91ff : Adapter ROM
000e8000-000fffff : reserved
000f0000-000fffff : System ROM
00100000-1ffeffff : System RAM
00200000-0067f9ec : Kernel code
0067f9ed-008906ff : Kernel data
008dd000-00a3dfff : Kernel bss
1fff0000-1fffffff : ACPI Tables
ff001000-ff001fff : goldfish_device_bus
ff004000-ff004fff : goldfish_audio.0
ff005000-ff005fff : goldfish_mmc.0
ff010000-ff010fff : goldfish-battery.0
ff011000-ff011fff : goldfish_nand.0
ff012000-ff013fff : qemu_pipe
ff014000-ff014fff : goldfish_tty.0
ff015000-ff015fff : goldfish_tty.1
ff016000-ff016fff : goldfish_fb.0
ff017000-ff017fff : goldfish_events.0
fffc0000-ffffffff : reserved
/proc/iomem
EMULATOR IMPL (X86)
Goldfish Platform Bus
Goldfish Kernel Goldfish Platform Bus
GoldfishAudio
GoldfishMMC
GoldfishBattery
GoldfishNAND
GoldfishTTY
GoldfishFB
QEMUPipe
GoldfishEvents
Goldfish Platform Bus
Goldfish Kernel Goldfish Platform Bus
GoldfishAudio
GoldfishMMC
GoldfishBattery
GoldfishNAND
GoldfishTTY
GoldfishFB
QEMUPipe
GoldfishEvents
QEMUPipe
Goldfish Platform Bus
Goldfish Kernel Goldfish Platform Bus
QEMU Pipe / Goldfish Pipe
DESIGN
• Fast communication channel between guest and emulator.
• /dev/qemu_pipe or /dev/goldfish_pipe (since kernel 3.10).
• Kernel driver: drivers/misc/qemupipe/qemu_pipe.c	
  
• No extra drivers necessary for QEMU Pipe Services.
• 4 pipe services implemented.
QEMU Pipe Services
Goldfish Platform Bus
GoldfishAudio
GoldfishMMC
GoldfishBattery
GoldfishNAND
GoldfishTTY
GoldfishFB
QEMUPipe
GoldfishEvents
Goldfish Kernel
QEMU Pipe Services
Goldfish Platform Bus
GoldfishAudio
GoldfishMMC
GoldfishBattery
GoldfishNAND
GoldfishTTY
GoldfishFB
QEMUPipe
GoldfishEvents
QEMUD
TCP
Unix
OpenGLES
Goldfish Kernel
SERVICE REGISTRATION
typedef struct {
void* (*init)( void* hwpipe, void* pipeOpaque, const char* args );
void (*close)( void* pipe );
int (*sendBuffers)( void* pipe, const GoldfishPipeBuffer* buffers, int numBuffers );
int (*recvBuffers)( void* pipe, GoldfishPipeBuffer* buffers, int numBuffers );
unsigned (*poll)( void* pipe );
void (*wakeOn)( void* opaque, int flags );
void (*save)( void* pipe, QEMUFile* file );
void* (*load)( void* hwpipe, void* pipeOpaque, const char* args, QEMUFile* file);
} GoldfishPipeFuncs;
void
goldfish_pipe_add_type(const char* pipeName,
void* pipeOpaque,
const GoldfishPipeFuncs* pipeFuncs );
WORKFLOW (1/3)
• Kernel side:
• Sends the command PIPE_CMD_OPEN with a channel id.
• Emulator side:
• Generates a pipe connection with the given channel id.
• Generates a pipe connector, which has the interface as a pipe service,
on the pipe channel.
fd = open("/dev/qemu_pipe", O_RDWR);
const char* pipeName = "<pipename>";
ret = write(fd, pipeName, strlen(pipeName)+1);
if (ret < 0) {
// error
}
... ready to go
WORKFLOW (2/3)
+------+ +----------------+
| fd |<------pipe channel------>| pipe connector |
+------+ +----------------+
WORKFLOW (3/3)
+------+ +----------------+
| fd |<------pipe channel------>| pipe service |
+------+ +----------------+
WORKFLOW (3/3)
+------+ +----------------+
| fd |<------pipe channel------>| pipe service |
+------+ +----------------+
/* Do the evil switch now */
pipe->opaque = peer;
pipe->service = svc;
pipe->funcs = &svc->funcs;
pipe->args = ASTRDUP(pipeArgs);
AFREE(pcon);
R/W WAITING
• When a service not able to consume more writes, or provide anything to
read temporarily: PIPE_ERROR_AGAIN.
• Kernel driver sends PIPE_CMD_WAKE_ON_READ/WRITE to wait.
• When service is available, emulator triggers an IRQ.
• Kernel reads 

PIPE_REG_CHANNEL register to find the channel id, and 

PIPE_REG_WAKES to find out what the event is (read / write / close).
QEMUD
QEMUD over QEMU Pipe
Goldfish Platform Bus
GoldfishAudio
GoldfishMMC
GoldfishBattery
GoldfishNAND
GoldfishTTY
GoldfishFB
QEMUPipe
GoldfishEvents
QEMUD
TCP
Unix
OpenGLES
Goldfish Kernel
LEGACY IMPLEMENTATION
• The legacy communication channel between guest and emulator.
• Multiplexing daemon qemud runs in the guest OS.
• Guest client apps operate on socket /dev/socket/qemud.
emulator <==serial==> qemud <---> /dev/socket/qemud <-+--> client1
|
+--> client2
emulator: Kernel parameters: qemu.gles=1 qemu=1 console=ttyS0 android.qemud=ttyS1
androidboot.hardware=goldfish clocksource=pit android.checkjni=1 ndns=2
Ever noticed the boot parameters?
ADAPTATION TO QEMU PIPE
QEMUD Services
Goldfish Platform Bus
GoldfishAudio
GoldfishMMC
GoldfishBattery
GoldfishNAND
GoldfishTTY
GoldfishFB
QEMUPipe
GoldfishEvents
QEMUD
TCP
Unix
OpenGLES
Goldfish Kernel
QEMUD Services
Goldfish Platform Bus
GoldfishAudio
GoldfishMMC
GoldfishBattery
GoldfishNAND
GoldfishTTY
GoldfishFB
QEMUPipe
GoldfishEvents
QEMUD
TCP
Unix
OpenGLES
Goldfish Kernel
hw-control
boot-properties
gsm
gps
camera
sensors
fingerprintlisten
adb
adb-debug
SERVICE REGISTRATION
/* A function that will be called each time a new client in the emulated
* system tries to connect to a given qemud service. This should typically
* call qemud_client_new() to register a new client.
*/
typedef QemudClient* (*QemudServiceConnect)( void* opaque,
QemudService* service,
int channel,
const char* client_param );
QemudService*
qemud_service_register( const char* service_name,
int max_clients,
void* serv_opaque,
QemudServiceConnect serv_connect,
QemudServiceSave serv_save,
QemudServiceLoad serv_load );
ACCEPTING A CLIENT
/* A function that will be called when the client sends a message to the
* service through qemud.
*/
typedef void
(*QemudClientRecv) ( void* opaque, uint8_t* msg, int msglen, QemudClient* client );
extern QemudClient* qemud_client_new( QemudService* service,
int channel_id,
const char* client_param,
void* clie_opaque,
QemudClientRecv clie_recv,
QemudClientClose clie_close,
QemudClientSave clie_save,
QemudClientLoad clie_load );
CALLBACKS MAPPING
QEMU Pipe Callback QEMUD Callback Purpose
GoldfishPipeFuncs.init QemudServiceConnect accepting incoming client
GoldfishPipeFuncs.sendBuffers QemudClientRecv client is sendings messages
GoldfishPipeFuncs.recvBuffers - client is reading messages
GoldfishPipeFuncs.close QemudClientClose client closed connection
QEMUD services send messages to clients proactively through
qemud_client_send() or qemud_service_broadcast().
INIT
WRITING TO SERVICE
READING FROM SERVICE
charpipe
charpipeQEMUD
NOT DONE YET…
hw-control
boot-properties
gsm
gps
camera
sensors
fingerprintlisten
adb
adb-debug
charpipe
charpipeQEMUD
NOT DONE YET…
hw-control
boot-properties
gsm
gps
camera
sensors
fingerprintlisten
adb
adb-debug
(wrapper)
(wrapper)
CharDriverState
CHAR DRIVER STATE
• CharDriver is an object to operate on a specific type of char devices.
• TCPCharDriver with tcp_chr_ functions for TCP net console.
• CharDriverState forms an unified interface between a char driver and a
user operating on the char driver (often shorted as cs in code).
• CharDriver plays the backend of CharDriverState.
• Char devices are usually polled in the main loop (qemu_iohandler_poll).
EXAMPLE
+--------+ +---------------+ +-----+
| User 1 |---+ +---| TcpCharDriver |-----| tcp |
+--------+ | | +---------------+ +-----+
| |
+--------+ | +-----------------+ | +---------------+ +-----+
| User 2 |---+---| CharDriverState |---+---| FDCharDriver |-----| fd |
+--------+ | +-----------------+ | +---------------+ +-----+
| |
+--------+ | | +---------------+ +-----+
| User 3 |---+ +---| PtyCharDriver |-----| pty |
+--------+ +---------------+ +-----+
INIT
use the function defined in the backend_table
WRITING
- success is not guaranteed
- returns the number of bytes really written
- similar to non-blocking BSD socket
READING
- not directly, but by callbacks
- controlled by main loop
CHAR BUFFER
• CharDriverState doesn’t tell how many bytes it can accept, nor notify
when it’s ready again.
• CharBuffer: a wrapper on top of CS with internal buffer to keep writing on
each polling until buffer empties.
• Simplify the implementation of a CharDriverState user.
+-------+ +-------------+ +--------------+
| QEMUD |------>| GSM Service |--CharBuffer-->| Radio Device |
+-------+ +-------------+ +--------------+
CHAR PIPE
• CharBuffer creates a write buffer on a CharDriverState; 

CharPipe works as if 2 CharBuffers are connected to each other.
• Bidirectional communication channel between 2 CS users.
• Plays the backend of CS on both side. Writing on one endpoint triggers
the read handler on the other endpoint directly.
• CharBuffer / CharPipe rely on main loop polling (charpipe_poll).
+-------+ +-------------+ +-------------+
| QEMUD |------>| GSM Service |<---CharPipe--->| ModemDriver |
+-------+ +-------------+ +-------------+
FROM RILD TO MODEM
QEMUPipe
gsmQEMUD
TCP
Unix
OpenGLES
ModemDriver
AModem
rild
Goldfish Kernel
/dev/qemu_pipe
qemu_pipe driver
charpipe
[rild side]
see commit 385a739
[modem side]
1.init gsm service
1.init charpipe
2.set qemud wrapper
2.init modem driver
1.set modem read handler
3.accept connection
1.set qemud read handler
Android Debug Bridge
ADB ON PHONES
ADB Server
(tcp:5037)
ADB Client
Host USB
Phone USB ADBD
Phone USB ADBD
Phone USB ADBD
Phone 1
Phone 2
Phone 3
ADB ON EMULATORS
ADB Server
(tcp:5037)
ADB Client
QEMUD ADBD
QEMUD ADBD
QEMUD ADBD
Emulator 1
ADB Service
ADB Service
ADB Service
Emulator 2
Emulator 3
CASE STUDY
OPENGL EMULATION
Gralloc
GRAPHICS
Framebuffer
GPU Driver
Vendor GL Impl
Graphic BufferHWComposer
OpenGL ES & EGL
FB Driver ION
Gecko Compositor
OPENGL LIBS
/system/lib/egl/libEGL_adreno.so/system/lib/libEGL.so
/system/lib/libGLESv1_CM.so
/system/lib/libGLESv2.so
/system/lib/libGLESv3.so
/system/lib/egl/libGLESv1_CM_adreno.so
/system/lib/egl/libGLESv2_adreno.so
/system/lib/egl/libGLES_android.so
/system/lib/libEGL.so
/system/lib/libGLESv1_CM.so
With vendor GL support
With software GL
Gralloc (gralloc.goldfish.so)
WITH OPENGL EMULATION
Framebuffer Graphic Buffer
QEMU Pipe
libEGL / libGLESv1_CM / libGLESv2
libEGL_emulation
libGLESv1_CM_emulation
libGLESv1_enc
libGLESv2_emulation
libGLESv2_enc
libOpenglRender
libEGL_translator libGLES_CM_translator libGLES_v2_translator
EmuGL Framebuffer
GLX AGL WGL
Gralloc (gralloc.default.so)
WITHOUT OPENGL EMULATION
Framebuffer Graphic Buffer
/dev/graphics/framebuffer
libEGL / libGLESv1_CM
libGLES_android
QFramebuffer
QEMU2 STATUS
QEMU2 EMULATOR STATUS
• Device Trees to replace Platform Bus.
• VirtIO to replace Goldfish NAND / MMC.
• QEMUD is completely abandoned / services porting is in progress.
• x86 support is still in development.
• No skin support yet.
Goldfish Virtual Hardware
Goldfish Platform Bus
GoldfishAudio
GoldfishMMC
GoldfishBattery
GoldfishNAND
GoldfishTTY
GoldfishFB
QEMUPipe
GoldfishEvents
hw-control
boot-properties
gsm
gps
camera
sensors
fingerprintlisten
QEMUD
TCP
Unix
OpenGLES
Goldfish Kernel
(PIC, RTC, Timer not shown)
adb
adb-debug

Weitere ähnliche Inhalte

Was ist angesagt?

Linux SD/MMC device driver
Linux SD/MMC device driverLinux SD/MMC device driver
Linux SD/MMC device driver艾鍗科技
 
Testing real-time Linux. What to test and how
Testing real-time Linux. What to test and how Testing real-time Linux. What to test and how
Testing real-time Linux. What to test and how Chirag Jog
 
Accelerating Virtual Machine Access with the Storage Performance Development ...
Accelerating Virtual Machine Access with the Storage Performance Development ...Accelerating Virtual Machine Access with the Storage Performance Development ...
Accelerating Virtual Machine Access with the Storage Performance Development ...Michelle Holley
 
Linux Initialization Process (1)
Linux Initialization Process (1)Linux Initialization Process (1)
Linux Initialization Process (1)shimosawa
 
Linux SD/MMC Driver Stack
Linux SD/MMC Driver Stack Linux SD/MMC Driver Stack
Linux SD/MMC Driver Stack Champ Yen
 
Slab Allocator in Linux Kernel
Slab Allocator in Linux KernelSlab Allocator in Linux Kernel
Slab Allocator in Linux KernelAdrian Huang
 
Linux Kernel MMC Storage driver Overview
Linux Kernel MMC Storage driver OverviewLinux Kernel MMC Storage driver Overview
Linux Kernel MMC Storage driver OverviewRajKumar Rampelli
 
Page reclaim
Page reclaimPage reclaim
Page reclaimsiburu
 
LCA14: LCA14-306: CPUidle & CPUfreq integration with scheduler
LCA14: LCA14-306: CPUidle & CPUfreq integration with schedulerLCA14: LCA14-306: CPUidle & CPUfreq integration with scheduler
LCA14: LCA14-306: CPUidle & CPUfreq integration with schedulerLinaro
 
OSC2011 Tokyo/Fall 濃いバナ(virtio)
OSC2011 Tokyo/Fall 濃いバナ(virtio)OSC2011 Tokyo/Fall 濃いバナ(virtio)
OSC2011 Tokyo/Fall 濃いバナ(virtio)Takeshi HASEGAWA
 
Project ACRN expose and pass through platform hidden PCIe devices to SOS
Project ACRN expose and pass through platform hidden PCIe devices to SOSProject ACRN expose and pass through platform hidden PCIe devices to SOS
Project ACRN expose and pass through platform hidden PCIe devices to SOSProject ACRN
 
Android Boot Time Optimization
Android Boot Time OptimizationAndroid Boot Time Optimization
Android Boot Time OptimizationKan-Ru Chen
 
Device Tree for Dummies (ELC 2014)
Device Tree for Dummies (ELC 2014)Device Tree for Dummies (ELC 2014)
Device Tree for Dummies (ELC 2014)Thomas Petazzoni
 
Kernel Recipes 2017 - 20 years of Linux Virtual Memory - Andrea Arcangeli
Kernel Recipes 2017 - 20 years of Linux Virtual Memory - Andrea ArcangeliKernel Recipes 2017 - 20 years of Linux Virtual Memory - Andrea Arcangeli
Kernel Recipes 2017 - 20 years of Linux Virtual Memory - Andrea ArcangeliAnne Nicolas
 

Was ist angesagt? (20)

Linux SD/MMC device driver
Linux SD/MMC device driverLinux SD/MMC device driver
Linux SD/MMC device driver
 
Testing real-time Linux. What to test and how
Testing real-time Linux. What to test and how Testing real-time Linux. What to test and how
Testing real-time Linux. What to test and how
 
Accelerating Virtual Machine Access with the Storage Performance Development ...
Accelerating Virtual Machine Access with the Storage Performance Development ...Accelerating Virtual Machine Access with the Storage Performance Development ...
Accelerating Virtual Machine Access with the Storage Performance Development ...
 
Linux Initialization Process (1)
Linux Initialization Process (1)Linux Initialization Process (1)
Linux Initialization Process (1)
 
Linux SD/MMC Driver Stack
Linux SD/MMC Driver Stack Linux SD/MMC Driver Stack
Linux SD/MMC Driver Stack
 
Slab Allocator in Linux Kernel
Slab Allocator in Linux KernelSlab Allocator in Linux Kernel
Slab Allocator in Linux Kernel
 
Embedded Android : System Development - Part II (HAL)
Embedded Android : System Development - Part II (HAL)Embedded Android : System Development - Part II (HAL)
Embedded Android : System Development - Part II (HAL)
 
Audio Drivers
Audio DriversAudio Drivers
Audio Drivers
 
Embedded Hypervisor for ARM
Embedded Hypervisor for ARMEmbedded Hypervisor for ARM
Embedded Hypervisor for ARM
 
Linux Kernel MMC Storage driver Overview
Linux Kernel MMC Storage driver OverviewLinux Kernel MMC Storage driver Overview
Linux Kernel MMC Storage driver Overview
 
Page reclaim
Page reclaimPage reclaim
Page reclaim
 
LCA14: LCA14-306: CPUidle & CPUfreq integration with scheduler
LCA14: LCA14-306: CPUidle & CPUfreq integration with schedulerLCA14: LCA14-306: CPUidle & CPUfreq integration with scheduler
LCA14: LCA14-306: CPUidle & CPUfreq integration with scheduler
 
OSC2011 Tokyo/Fall 濃いバナ(virtio)
OSC2011 Tokyo/Fall 濃いバナ(virtio)OSC2011 Tokyo/Fall 濃いバナ(virtio)
OSC2011 Tokyo/Fall 濃いバナ(virtio)
 
Project ACRN expose and pass through platform hidden PCIe devices to SOS
Project ACRN expose and pass through platform hidden PCIe devices to SOSProject ACRN expose and pass through platform hidden PCIe devices to SOS
Project ACRN expose and pass through platform hidden PCIe devices to SOS
 
Android Boot Time Optimization
Android Boot Time OptimizationAndroid Boot Time Optimization
Android Boot Time Optimization
 
Linux dma engine
Linux dma engineLinux dma engine
Linux dma engine
 
Qemu
QemuQemu
Qemu
 
Android 10
Android 10Android 10
Android 10
 
Device Tree for Dummies (ELC 2014)
Device Tree for Dummies (ELC 2014)Device Tree for Dummies (ELC 2014)
Device Tree for Dummies (ELC 2014)
 
Kernel Recipes 2017 - 20 years of Linux Virtual Memory - Andrea Arcangeli
Kernel Recipes 2017 - 20 years of Linux Virtual Memory - Andrea ArcangeliKernel Recipes 2017 - 20 years of Linux Virtual Memory - Andrea Arcangeli
Kernel Recipes 2017 - 20 years of Linux Virtual Memory - Andrea Arcangeli
 

Ähnlich wie Study on Android Emulator

U-Boot presentation 2013
U-Boot presentation  2013U-Boot presentation  2013
U-Boot presentation 2013Wave Digitech
 
Jagan Teki - U-boot from scratch
Jagan Teki - U-boot from scratchJagan Teki - U-boot from scratch
Jagan Teki - U-boot from scratchlinuxlab_conf
 
U-Boot Porting on New Hardware
U-Boot Porting on New HardwareU-Boot Porting on New Hardware
U-Boot Porting on New HardwareRuggedBoardGroup
 
U Boot or Universal Bootloader
U Boot or Universal BootloaderU Boot or Universal Bootloader
U Boot or Universal BootloaderSatpal Parmar
 
Embedded Android
Embedded AndroidEmbedded Android
Embedded Android晓东 杜
 
Android for Embedded Linux Developers
Android for Embedded Linux DevelopersAndroid for Embedded Linux Developers
Android for Embedded Linux DevelopersOpersys inc.
 
How to Make Android's Bootable Recovery Work For You by Drew Suarez
How to Make Android's Bootable Recovery Work For You by Drew SuarezHow to Make Android's Bootable Recovery Work For You by Drew Suarez
How to Make Android's Bootable Recovery Work For You by Drew SuarezShakacon
 
IoT Getting Started with Intel® IoT Devkit
IoT Getting Started with Intel® IoT DevkitIoT Getting Started with Intel® IoT Devkit
IoT Getting Started with Intel® IoT DevkitVasily Ryzhonkov
 
LCU14 302- How to port OP-TEE to another platform
LCU14 302- How to port OP-TEE to another platformLCU14 302- How to port OP-TEE to another platform
LCU14 302- How to port OP-TEE to another platformLinaro
 
I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits
I/O, You Own: Regaining Control of Your Disk in the Presence of BootkitsI/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits
I/O, You Own: Regaining Control of Your Disk in the Presence of BootkitsCrowdStrike
 
Lab Handson: Power your Creations with Intel Edison!
Lab Handson: Power your Creations with Intel Edison!Lab Handson: Power your Creations with Intel Edison!
Lab Handson: Power your Creations with Intel Edison!Codemotion
 
Getting started with Intel IoT Developer Kit
Getting started with Intel IoT Developer KitGetting started with Intel IoT Developer Kit
Getting started with Intel IoT Developer KitSulamita Garcia
 
Working with the AOSP - Linaro Connect Asia 2013
Working with the AOSP - Linaro Connect Asia 2013Working with the AOSP - Linaro Connect Asia 2013
Working with the AOSP - Linaro Connect Asia 2013Opersys inc.
 
Starting Raspberry Pi
Starting Raspberry PiStarting Raspberry Pi
Starting Raspberry PiLloydMoore
 
Build and Run Android N Source Ccode on NXP SABRESD platform
Build and Run Android N Source Ccode on NXP SABRESD platformBuild and Run Android N Source Ccode on NXP SABRESD platform
Build and Run Android N Source Ccode on NXP SABRESD platformDaniel Chiu
 
A million ways to provision embedded linux devices
A million ways to provision embedded linux devicesA million ways to provision embedded linux devices
A million ways to provision embedded linux devicesMender.io
 

Ähnlich wie Study on Android Emulator (20)

U-Boot presentation 2013
U-Boot presentation  2013U-Boot presentation  2013
U-Boot presentation 2013
 
Jagan Teki - U-boot from scratch
Jagan Teki - U-boot from scratchJagan Teki - U-boot from scratch
Jagan Teki - U-boot from scratch
 
U-Boot Porting on New Hardware
U-Boot Porting on New HardwareU-Boot Porting on New Hardware
U-Boot Porting on New Hardware
 
U Boot or Universal Bootloader
U Boot or Universal BootloaderU Boot or Universal Bootloader
U Boot or Universal Bootloader
 
Embedded Android
Embedded AndroidEmbedded Android
Embedded Android
 
Android for Embedded Linux Developers
Android for Embedded Linux DevelopersAndroid for Embedded Linux Developers
Android for Embedded Linux Developers
 
How to Make Android's Bootable Recovery Work For You by Drew Suarez
How to Make Android's Bootable Recovery Work For You by Drew SuarezHow to Make Android's Bootable Recovery Work For You by Drew Suarez
How to Make Android's Bootable Recovery Work For You by Drew Suarez
 
There is more to C
There is more to CThere is more to C
There is more to C
 
IoT Getting Started with Intel® IoT Devkit
IoT Getting Started with Intel® IoT DevkitIoT Getting Started with Intel® IoT Devkit
IoT Getting Started with Intel® IoT Devkit
 
Начало работы с Intel IoT Dev Kit
Начало работы с Intel IoT Dev KitНачало работы с Intel IoT Dev Kit
Начало работы с Intel IoT Dev Kit
 
LCU14 302- How to port OP-TEE to another platform
LCU14 302- How to port OP-TEE to another platformLCU14 302- How to port OP-TEE to another platform
LCU14 302- How to port OP-TEE to another platform
 
I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits
I/O, You Own: Regaining Control of Your Disk in the Presence of BootkitsI/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits
I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits
 
Lab Handson: Power your Creations with Intel Edison!
Lab Handson: Power your Creations with Intel Edison!Lab Handson: Power your Creations with Intel Edison!
Lab Handson: Power your Creations with Intel Edison!
 
Getting started with Intel IoT Developer Kit
Getting started with Intel IoT Developer KitGetting started with Intel IoT Developer Kit
Getting started with Intel IoT Developer Kit
 
Working with the AOSP - Linaro Connect Asia 2013
Working with the AOSP - Linaro Connect Asia 2013Working with the AOSP - Linaro Connect Asia 2013
Working with the AOSP - Linaro Connect Asia 2013
 
Starting Raspberry Pi
Starting Raspberry PiStarting Raspberry Pi
Starting Raspberry Pi
 
Beagleboard xm-setup
Beagleboard xm-setupBeagleboard xm-setup
Beagleboard xm-setup
 
Build and Run Android N Source Ccode on NXP SABRESD platform
Build and Run Android N Source Ccode on NXP SABRESD platformBuild and Run Android N Source Ccode on NXP SABRESD platform
Build and Run Android N Source Ccode on NXP SABRESD platform
 
Basic Linux kernel
Basic Linux kernelBasic Linux kernel
Basic Linux kernel
 
A million ways to provision embedded linux devices
A million ways to provision embedded linux devicesA million ways to provision embedded linux devices
A million ways to provision embedded linux devices
 

Kürzlich hochgeladen

Android Application Components with Implementation & Examples
Android Application Components with Implementation & ExamplesAndroid Application Components with Implementation & Examples
Android Application Components with Implementation & ExamplesChandrakantDivate1
 
Mobile Application Development-Components and Layouts
Mobile Application Development-Components and LayoutsMobile Application Development-Components and Layouts
Mobile Application Development-Components and LayoutsChandrakantDivate1
 
Mobile Application Development-Android and It’s Tools
Mobile Application Development-Android and It’s ToolsMobile Application Development-Android and It’s Tools
Mobile Application Development-Android and It’s ToolsChandrakantDivate1
 
Mobile App Penetration Testing Bsides312
Mobile App Penetration Testing Bsides312Mobile App Penetration Testing Bsides312
Mobile App Penetration Testing Bsides312wphillips114
 
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...nishasame66
 

Kürzlich hochgeladen (6)

Android Application Components with Implementation & Examples
Android Application Components with Implementation & ExamplesAndroid Application Components with Implementation & Examples
Android Application Components with Implementation & Examples
 
Mobile Application Development-Components and Layouts
Mobile Application Development-Components and LayoutsMobile Application Development-Components and Layouts
Mobile Application Development-Components and Layouts
 
Mobile Application Development-Android and It’s Tools
Mobile Application Development-Android and It’s ToolsMobile Application Development-Android and It’s Tools
Mobile Application Development-Android and It’s Tools
 
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
 
Mobile App Penetration Testing Bsides312
Mobile App Penetration Testing Bsides312Mobile App Penetration Testing Bsides312
Mobile App Penetration Testing Bsides312
 
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
 

Study on Android Emulator

  • 1. STUDY ON ANDROID EMULATOR Samael Wang
  • 2. PURPOSE • To understand important details of emulator. • To get familiar with recent upstream changes and possibly ongoing plans. • To evaluate upstream contribution process (for potential back porting). • For fun, of course.
  • 4. GET THE EMULATOR SOURCE $ mkdir emu-master-dev && cd emu-master-dev $ repo init -u https://android.googlesource.com/platform/manifest -b emu-master-dev $ repo sync emu-master-dev (~12GB) master (~36GB) external frameworks prebuilts sdk tools abi art bionic bootable build cts dalvik developers development device docs external frameworks hardware libcore libnativehelper Makefile ndk packages pdk prebuilts sdk system toolchain tools
  • 5. BUILD THE EMULATOR classic - Use QEMU 0.10.5 since ~2009 - Android Cupcake ~ Lollipop - Goldfish virtual platform - @external/qemu qemu2 - Use QEMU 2.2.0 since ~2015 - Android M ~ - Ranchu virtual platform - @external/qemu-android The classic and qemu2 emulator $ cd external/qemu $ ./android-rebuild.sh --build-qemu-android Build both the output is under objs directory
  • 6. BUILD EMULATOR WITH QT • Android Emulator is moving to Qt. • In development. Unstable. • Providing Tool Window. • Default option remains SDL2. $ cd external/qemu $ ./android/scripts/download-sources.sh $ ./android/scripts/build-qt.sh $ ./android/scripts/build-libxml2.sh $ ./android-rebuild.sh --ui=qt
  • 7. APPARENTLY… … android emulator should have a floating toolbox ? Xamarin Android Player (VirtualBox) Visual Studio Emulator for Android (Hyper V)
  • 8. EMULATOR BINARIES - emulator: front-end used to find proper emulation engine and setup environment variables (mainly LD_LIBRARY_PATH). - green nodes: classic emulation engines. - blue nodes: qemu2 emulation engines. - orange nodes: GLES / EGL emulation libraries.
  • 9. 3 WAYS TO LAUNCH EMULATOR • Setup an Android Virtual Device, or • Setup corresponding environment variables (in build-root), or • Skip front-end and pass all arguments manually to emulation engine.
  • 10. ANDROID VIRTUAL DEVICE $ cat emulator-x86-l.avd/config.ini avd.ini.encoding=UTF-8 abi.type=x86 disk.dataPartition.size=200M hw.accelerometer=yes hw.audioInput=yes hw.battery=yes hw.camera.back=none hw.camera.front=none hw.cpu.arch=x86 hw.dPad=no hw.device.hash2=MD5:37a2ff6e511626ba3ceddec8264474be hw.device.manufacturer=Google hw.device.name=Nexus S hw.gps=yes …
  • 11. SETUP ENVIRONMENT VARIABLES $ export ANDROID_BUILD_TOP=$PWD $ export ANDROID_PRODUCT_OUT=$PWD/out/target/product/generic_x86 $ ./out/host/darwin-x86/bin/emulator -gpu on - Load kernel from ${ANDROID_BUILD_TOP}/prebuilts/qemu-­‐kernel/ - Load skin from ${ANDROID_BUILD_TOP}/development/tools/emulator/skins/ - Load the images from ${ANDROID_PRODUCT_OUT}
 system.img (or system-­‐qemu.img)
 userdata.img
 ramdisk.img
 cache.img (optional)
 sdcard.img (optional)
  • 12. PASS EVERYTHING MANUALLY /Volumes/Development/b2g/emulator-x86-kk/out/host/darwin-x86/bin/emulator-x86 -kernel /Volumes/Development/b2g/emulator-x86-kk/prebuilts/qemu-kernel/x86/kernel-qemu -sysdir /Volumes/Development/b2g/emulator-x86-kk/out/target/product/generic_x86/ -data /Volumes/Development/b2g/emulator-x86-kk/out/target/product/generic_x86/userdata.img -sdcard /Volumes/Development/b2g/emulator-x86-kk/out/target/product/generic_x86/sdcard.img -memory 512 -partition-size 512 -skindir /Volumes/Development/b2g/emulator-x86-kk/development/tools/emulator/skins -skin HVGA -verbose -gpu on -camera-back webcam0
  • 13. WRITABLE SYSTEM IMAGE • system.img and userdata.img are read-only initial images. • usedata-­‐qemu.img is generated automatically on first launch. • Temporarily writable system image is generated on each launch under /tmp. • To make system image writable by default, move system.img to system-­‐qemu.img. • See emulator  -­‐help-­‐disk-­‐images for more information $ ls -lh /tmp/android-freesamael/ -rw------- 1 freesamael wheel 750M Sep 15 17:46 emulator-w1MQmT
  • 16. MAIN FUNCTIONS (2/2) Emulator Front-end Emulation Engine android/main-emulator.c:main - setups environment variables - finds correct emulation engine
 (32/64, arm/x86/…) android/main.c:main - setups UI skin window (SDL2/Qt) - generates final hardware config 
 “hardware-qemu.ini” vl-android.c:main (qemu_main) - init machine / virtual hardware - init emulator adb / console - start main loop
  • 17. MAIN LOOP • The core of QEMU is event driven - by using an event loop. • Waits for file descriptors (files, sockets, pipes,…) to become readable or writable. • Polls charpipe (android-specific). • Runs expired timers. • Runs bottom-halves (BHs) scheduled by above handlers.
  • 18. SKIN & UI HANDLING
  • 19. SKIN (1/2) emulator-window (SDL2/Qt) window (abstraction) events texture / bitmap SkinSurface SkinSurface rendered texture / bitmap skin_window_redraw
  • 20. SKIN (2/2) parts { device { display { width 320 height 480 x 0 y 0 } } basic_controls { background { image basic.png width 159 height 55 } buttons { volume-down { image button.png x 1 y 9 } … } } … } struct SkinSurface { int refcount; int w; int h; SDL_Surface* surface; SDL_Texture* texture; }; struct SkinSurface { int refcount; int id; QImage *bitmap; int w, h, original_w, original_h; EmulatorQtWindow *window; }; Layout Snippet SDL2 SkinSurface Qt SkinSurface
  • 21. SKIN UI REFRESH • Emulator skin refreshes at 60Hz by registered a timer to the main loop. • gui_update() / nographic_update() • Processes input events or passes them to the emulated system (multiple events might be passed at the same time). • Refresh the emulated framebuffer, if OpenGL emulation is not in use.
  • 22.
  • 24. GOLDFISH DEVICE REGISTRATION int goldfish_device_add(struct goldfish_device *dev, CPUReadMemoryFunc **mem_read, CPUWriteMemoryFunc **mem_write, void *opaque); - Platform devices - MMIO
  • 25. GOLDFISH DEVICE REGISTRATION int goldfish_device_add(struct goldfish_device *dev, CPUReadMemoryFunc **mem_read, CPUWriteMemoryFunc **mem_write, void *opaque); struct goldfish_device { struct goldfish_device *next; struct goldfish_device *prev; uint32_t reported_state; void *cookie; const char *name; uint32_t id; uint32_t base; // filled in by goldfish_device_add if 0 uint32_t size; uint32_t irq; // filled in by goldfish_device_add if 0 uint32_t irq_count; }; int goldfish_device_add(struct goldfish_device *dev, CPUReadMemoryFunc **mem_read, CPUWriteMemoryFunc **mem_write, void *opaque); - Platform devices - MMIO
  • 26. GOLDFISH DEVICE REGISTRATION int goldfish_device_add(struct goldfish_device *dev, CPUReadMemoryFunc **mem_read, CPUWriteMemoryFunc **mem_write, void *opaque); typedef uint32_t CPUReadMemoryFunc(void *opaque, hwaddr addr); static CPUReadMemoryFunc *goldfish_bus_readfn[] = { goldfish_bus_read, // byte goldfish_bus_read, // word goldfish_bus_read // dword }; int goldfish_device_add(struct goldfish_device *dev, CPUReadMemoryFunc **mem_read, CPUWriteMemoryFunc **mem_write, void *opaque); - Platform devices - MMIO
  • 27. GOLDFISH DEVICE REGISTRATION int goldfish_device_add(struct goldfish_device *dev, CPUReadMemoryFunc **mem_read, CPUWriteMemoryFunc **mem_write, void *opaque); typedef void CPUWriteMemoryFunc(void *opaque, hwaddr addr, uint32_t value); static CPUWriteMemoryFunc *goldfish_bus_writefn[] = { goldfish_bus_write, // byte goldfish_bus_write, // word goldfish_bus_write // dword }; int goldfish_device_add(struct goldfish_device *dev, CPUReadMemoryFunc **mem_read, CPUWriteMemoryFunc **mem_write, void *opaque); - Platform devices - MMIO
  • 28. GOLDFISH DEVICE REGISTRATION int goldfish_device_add(struct goldfish_device *dev, CPUReadMemoryFunc **mem_read, CPUWriteMemoryFunc **mem_write, void *opaque); typedef void CPUWriteMemoryFunc(void *opaque, hwaddr addr, uint32_t value); static CPUWriteMemoryFunc *goldfish_bus_writefn[] = { goldfish_bus_write, // byte goldfish_bus_write, // word goldfish_bus_write // dword }; - Platform devices - MMIO int goldfish_device_add(struct goldfish_device *dev, CPUReadMemoryFunc **mem_read, CPUWriteMemoryFunc **mem_write, void *opaque); typedef void CPUWriteMemoryFunc(void *opaque, hwaddr addr, uint32_t value); static CPUWriteMemoryFunc *goldfish_bus_writefn[] = { goldfish_bus_write, // byte goldfish_bus_write, // word goldfish_bus_write // dword };
  • 30. DESIGN • Discoverability: which memory address and interrupt a device uses? • Platform bus: a special platform device to enumerate other devices. • Goldfish platform bus design • MMIO address region 0xff001000 to 0xff801000. • 0xff001000 - 0xff001fff are reserved by goldfish_device_bus as a set of 32bit I/O registers for bus operations. • The bus itself uses IRQ 1 on ARM, IRQ 4 on x86.
  • 31. I/O REGISTERS Device properties: Name: goldfish_device_bus Id: -1 IrqCount: 1 32-bit I/O registers (offset, name, abstract) 0x00 BUS_OP R: Iterate to next device in enumeration. W: Start device enumeration. 0x04 GET_NAME W: Copy device name to kernel memory. 0x08 NAME_LEN R: Read length of current device's name. 0x0c ID R: Read id of current device. 0x10 IO_BASE R: Read I/O base address of current device. 0x14 IO_SIZE R: Read I/O base size of current device. 0x18 IRQ_BASE R: Read base IRQ of current device. 0x1c IRQ_COUNT R: Read IRQ count of current device.
  • 33. KERNEL DRIVER IMPL 0000-001f : dma1 0020-0021 : pic1 0040-0043 : timer0 0050-0053 : timer1 0060-0060 : keyboard 0064-0064 : keyboard 0070-0071 : rtc_cmos 0070-0071 : rtc0 0080-008f : dma page reg 00a0-00a1 : pic2 00c0-00df : dma2 00f0-00ff : fpu 03c0-03df : vga+ 0cf8-0cff : PCI conf1 1000-10ff : goldfish_pdev_bus c000-c0ff : 0000:00:02.0 c000-c01f : ne2k-pci /proc/ioports
  • 34. KERNEL DRIVER IMPL 00000000-0000ffff : reserved 00010000-0009efff : System RAM 0009f000-0009ffff : reserved 000a0000-000bffff : Video RAM area 000c0000-000c8bff : Video ROM 000c9000-000c91ff : Adapter ROM 000e8000-000fffff : reserved 000f0000-000fffff : System ROM 00100000-1ffeffff : System RAM 00200000-0067f9ec : Kernel code 0067f9ed-008906ff : Kernel data 008dd000-00a3dfff : Kernel bss 1fff0000-1fffffff : ACPI Tables ff001000-ff001fff : goldfish_device_bus ff004000-ff004fff : goldfish_audio.0 ff005000-ff005fff : goldfish_mmc.0 ff010000-ff010fff : goldfish-battery.0 ff011000-ff011fff : goldfish_nand.0 ff012000-ff013fff : qemu_pipe ff014000-ff014fff : goldfish_tty.0 ff015000-ff015fff : goldfish_tty.1 ff016000-ff016fff : goldfish_fb.0 ff017000-ff017fff : goldfish_events.0 fffc0000-ffffffff : reserved /proc/iomem
  • 36. Goldfish Platform Bus Goldfish Kernel Goldfish Platform Bus
  • 39. QEMU Pipe / Goldfish Pipe
  • 40. DESIGN • Fast communication channel between guest and emulator. • /dev/qemu_pipe or /dev/goldfish_pipe (since kernel 3.10). • Kernel driver: drivers/misc/qemupipe/qemu_pipe.c   • No extra drivers necessary for QEMU Pipe Services. • 4 pipe services implemented.
  • 41. QEMU Pipe Services Goldfish Platform Bus GoldfishAudio GoldfishMMC GoldfishBattery GoldfishNAND GoldfishTTY GoldfishFB QEMUPipe GoldfishEvents Goldfish Kernel
  • 42. QEMU Pipe Services Goldfish Platform Bus GoldfishAudio GoldfishMMC GoldfishBattery GoldfishNAND GoldfishTTY GoldfishFB QEMUPipe GoldfishEvents QEMUD TCP Unix OpenGLES Goldfish Kernel
  • 43. SERVICE REGISTRATION typedef struct { void* (*init)( void* hwpipe, void* pipeOpaque, const char* args ); void (*close)( void* pipe ); int (*sendBuffers)( void* pipe, const GoldfishPipeBuffer* buffers, int numBuffers ); int (*recvBuffers)( void* pipe, GoldfishPipeBuffer* buffers, int numBuffers ); unsigned (*poll)( void* pipe ); void (*wakeOn)( void* opaque, int flags ); void (*save)( void* pipe, QEMUFile* file ); void* (*load)( void* hwpipe, void* pipeOpaque, const char* args, QEMUFile* file); } GoldfishPipeFuncs; void goldfish_pipe_add_type(const char* pipeName, void* pipeOpaque, const GoldfishPipeFuncs* pipeFuncs );
  • 44. WORKFLOW (1/3) • Kernel side: • Sends the command PIPE_CMD_OPEN with a channel id. • Emulator side: • Generates a pipe connection with the given channel id. • Generates a pipe connector, which has the interface as a pipe service, on the pipe channel. fd = open("/dev/qemu_pipe", O_RDWR); const char* pipeName = "<pipename>"; ret = write(fd, pipeName, strlen(pipeName)+1); if (ret < 0) { // error } ... ready to go
  • 45. WORKFLOW (2/3) +------+ +----------------+ | fd |<------pipe channel------>| pipe connector | +------+ +----------------+
  • 46. WORKFLOW (3/3) +------+ +----------------+ | fd |<------pipe channel------>| pipe service | +------+ +----------------+
  • 47. WORKFLOW (3/3) +------+ +----------------+ | fd |<------pipe channel------>| pipe service | +------+ +----------------+ /* Do the evil switch now */ pipe->opaque = peer; pipe->service = svc; pipe->funcs = &svc->funcs; pipe->args = ASTRDUP(pipeArgs); AFREE(pcon);
  • 48. R/W WAITING • When a service not able to consume more writes, or provide anything to read temporarily: PIPE_ERROR_AGAIN. • Kernel driver sends PIPE_CMD_WAKE_ON_READ/WRITE to wait. • When service is available, emulator triggers an IRQ. • Kernel reads 
 PIPE_REG_CHANNEL register to find the channel id, and 
 PIPE_REG_WAKES to find out what the event is (read / write / close).
  • 49. QEMUD
  • 50. QEMUD over QEMU Pipe Goldfish Platform Bus GoldfishAudio GoldfishMMC GoldfishBattery GoldfishNAND GoldfishTTY GoldfishFB QEMUPipe GoldfishEvents QEMUD TCP Unix OpenGLES Goldfish Kernel
  • 51. LEGACY IMPLEMENTATION • The legacy communication channel between guest and emulator. • Multiplexing daemon qemud runs in the guest OS. • Guest client apps operate on socket /dev/socket/qemud. emulator <==serial==> qemud <---> /dev/socket/qemud <-+--> client1 | +--> client2 emulator: Kernel parameters: qemu.gles=1 qemu=1 console=ttyS0 android.qemud=ttyS1 androidboot.hardware=goldfish clocksource=pit android.checkjni=1 ndns=2 Ever noticed the boot parameters?
  • 53. QEMUD Services Goldfish Platform Bus GoldfishAudio GoldfishMMC GoldfishBattery GoldfishNAND GoldfishTTY GoldfishFB QEMUPipe GoldfishEvents QEMUD TCP Unix OpenGLES Goldfish Kernel
  • 54. QEMUD Services Goldfish Platform Bus GoldfishAudio GoldfishMMC GoldfishBattery GoldfishNAND GoldfishTTY GoldfishFB QEMUPipe GoldfishEvents QEMUD TCP Unix OpenGLES Goldfish Kernel hw-control boot-properties gsm gps camera sensors fingerprintlisten adb adb-debug
  • 55. SERVICE REGISTRATION /* A function that will be called each time a new client in the emulated * system tries to connect to a given qemud service. This should typically * call qemud_client_new() to register a new client. */ typedef QemudClient* (*QemudServiceConnect)( void* opaque, QemudService* service, int channel, const char* client_param ); QemudService* qemud_service_register( const char* service_name, int max_clients, void* serv_opaque, QemudServiceConnect serv_connect, QemudServiceSave serv_save, QemudServiceLoad serv_load );
  • 56. ACCEPTING A CLIENT /* A function that will be called when the client sends a message to the * service through qemud. */ typedef void (*QemudClientRecv) ( void* opaque, uint8_t* msg, int msglen, QemudClient* client ); extern QemudClient* qemud_client_new( QemudService* service, int channel_id, const char* client_param, void* clie_opaque, QemudClientRecv clie_recv, QemudClientClose clie_close, QemudClientSave clie_save, QemudClientLoad clie_load );
  • 57. CALLBACKS MAPPING QEMU Pipe Callback QEMUD Callback Purpose GoldfishPipeFuncs.init QemudServiceConnect accepting incoming client GoldfishPipeFuncs.sendBuffers QemudClientRecv client is sendings messages GoldfishPipeFuncs.recvBuffers - client is reading messages GoldfishPipeFuncs.close QemudClientClose client closed connection QEMUD services send messages to clients proactively through qemud_client_send() or qemud_service_broadcast().
  • 58. INIT
  • 64. CHAR DRIVER STATE • CharDriver is an object to operate on a specific type of char devices. • TCPCharDriver with tcp_chr_ functions for TCP net console. • CharDriverState forms an unified interface between a char driver and a user operating on the char driver (often shorted as cs in code). • CharDriver plays the backend of CharDriverState. • Char devices are usually polled in the main loop (qemu_iohandler_poll).
  • 65. EXAMPLE +--------+ +---------------+ +-----+ | User 1 |---+ +---| TcpCharDriver |-----| tcp | +--------+ | | +---------------+ +-----+ | | +--------+ | +-----------------+ | +---------------+ +-----+ | User 2 |---+---| CharDriverState |---+---| FDCharDriver |-----| fd | +--------+ | +-----------------+ | +---------------+ +-----+ | | +--------+ | | +---------------+ +-----+ | User 3 |---+ +---| PtyCharDriver |-----| pty | +--------+ +---------------+ +-----+
  • 66. INIT use the function defined in the backend_table
  • 67. WRITING - success is not guaranteed - returns the number of bytes really written - similar to non-blocking BSD socket
  • 68. READING - not directly, but by callbacks - controlled by main loop
  • 69. CHAR BUFFER • CharDriverState doesn’t tell how many bytes it can accept, nor notify when it’s ready again. • CharBuffer: a wrapper on top of CS with internal buffer to keep writing on each polling until buffer empties. • Simplify the implementation of a CharDriverState user. +-------+ +-------------+ +--------------+ | QEMUD |------>| GSM Service |--CharBuffer-->| Radio Device | +-------+ +-------------+ +--------------+
  • 70. CHAR PIPE • CharBuffer creates a write buffer on a CharDriverState; 
 CharPipe works as if 2 CharBuffers are connected to each other. • Bidirectional communication channel between 2 CS users. • Plays the backend of CS on both side. Writing on one endpoint triggers the read handler on the other endpoint directly. • CharBuffer / CharPipe rely on main loop polling (charpipe_poll). +-------+ +-------------+ +-------------+ | QEMUD |------>| GSM Service |<---CharPipe--->| ModemDriver | +-------+ +-------------+ +-------------+
  • 71. FROM RILD TO MODEM QEMUPipe gsmQEMUD TCP Unix OpenGLES ModemDriver AModem rild Goldfish Kernel /dev/qemu_pipe qemu_pipe driver charpipe [rild side] see commit 385a739 [modem side] 1.init gsm service 1.init charpipe 2.set qemud wrapper 2.init modem driver 1.set modem read handler 3.accept connection 1.set qemud read handler
  • 73. ADB ON PHONES ADB Server (tcp:5037) ADB Client Host USB Phone USB ADBD Phone USB ADBD Phone USB ADBD Phone 1 Phone 2 Phone 3
  • 74. ADB ON EMULATORS ADB Server (tcp:5037) ADB Client QEMUD ADBD QEMUD ADBD QEMUD ADBD Emulator 1 ADB Service ADB Service ADB Service Emulator 2 Emulator 3
  • 77. Gralloc GRAPHICS Framebuffer GPU Driver Vendor GL Impl Graphic BufferHWComposer OpenGL ES & EGL FB Driver ION Gecko Compositor
  • 79. Gralloc (gralloc.goldfish.so) WITH OPENGL EMULATION Framebuffer Graphic Buffer QEMU Pipe libEGL / libGLESv1_CM / libGLESv2 libEGL_emulation libGLESv1_CM_emulation libGLESv1_enc libGLESv2_emulation libGLESv2_enc libOpenglRender libEGL_translator libGLES_CM_translator libGLES_v2_translator EmuGL Framebuffer GLX AGL WGL
  • 80. Gralloc (gralloc.default.so) WITHOUT OPENGL EMULATION Framebuffer Graphic Buffer /dev/graphics/framebuffer libEGL / libGLESv1_CM libGLES_android QFramebuffer
  • 82. QEMU2 EMULATOR STATUS • Device Trees to replace Platform Bus. • VirtIO to replace Goldfish NAND / MMC. • QEMUD is completely abandoned / services porting is in progress. • x86 support is still in development. • No skin support yet.
  • 83.
  • 84. Goldfish Virtual Hardware Goldfish Platform Bus GoldfishAudio GoldfishMMC GoldfishBattery GoldfishNAND GoldfishTTY GoldfishFB QEMUPipe GoldfishEvents hw-control boot-properties gsm gps camera sensors fingerprintlisten QEMUD TCP Unix OpenGLES Goldfish Kernel (PIC, RTC, Timer not shown) adb adb-debug