diff options
Diffstat (limited to 'docs/ANDROID-QEMUD.TXT')
-rw-r--r-- | docs/ANDROID-QEMUD.TXT | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/docs/ANDROID-QEMUD.TXT b/docs/ANDROID-QEMUD.TXT new file mode 100644 index 0000000..6415a47 --- /dev/null +++ b/docs/ANDROID-QEMUD.TXT @@ -0,0 +1,241 @@ + THE ANDROID "QEMUD" MULTIPLEXING DAEMON + +I. Overview: +------------ + +The Android system image includes a small daemon program named "qemud" +which is started at boot time. Its purpose is to provide a multiplexing +communication channel between the emulated system and the emulator program +itself. + +Its goal is to allow certain parts of the system to talk directly to the +emulator without requiring special kernel support; this simplifies a lot of +things since it does *not* require: + +- writing/configuring a specific kernel driver +- writing the corresponding hardware emulation code in hw/goldfish_xxxx.c +- dealing with device allocation and permission issues in the emulated system + +The emulator provides 'services' to various parts of the emulated system. +Each service is identified by a name and serves a specific purpose. For +example: + + "gsm" Used to communicate with the emulated GSM modem with + AT commands. + + "gps" Used to receive NMEA sentences broadcasted from the + emulated GPS device. + + "sensors" Used to list the number of emulated sensors, as well as + enable/disable reception of specific sensor events. + + "control" Used to control misc. simple emulated hardware devices + (e.g. vibrator, leds, LCD backlight, etc...) + + +II. Implementation: +------------------- + +Since the "cupcake" platform, this works as follows: + +- A 'qemud client' is any part of the emulated system that wants to talk + to the emulator. It does so by: + + - connecting to the /dev/socket/qemud Unix domain socket + - sending the service name through the socket + - receives two bytes of data, which will be "OK" in case of + success, or "KO" in case of failure. + + After an OK, the same connection can be used to talk directly to the + corresponding service. + + +- The /dev/socket/qemud Unix socket is created by init and owned by the + 'qemud' daemon started at boot by /system/etc/init.goldfish.rc + + The daemon also opens an emulated serial port (e.g. /dev/ttyS1) and + will pass all messages between clients and emulator services. Thus, + everything looks like the following: + + + emulator <==serial==> qemud <---> /dev/socket/qemud <-+--> client1 + | + +--> client2 + + A very simple multiplexing protocol is used on the serial connection: + + offset size description + + 0 2 2-char hex string giving the destination or + source channel + + 2 4 4-char hex string giving the payload size + + 6 n the message payload + + Where each client gets a 'channel' number allocated by the daemon + at connection time. + + Note that packets larger than 65535 bytes cannot be sent directly + through the qemud channel. This is intentional; for large data + communication, the client and service should use a fragmentation + convention that deals with this. + + Zero-sized packets are silently discard by qemud and the emulator and + should normally not appear on the serial port. + + Channel 0 is reserved for control messages between the daemon and the + emulator. These are the following: + + - When a client connects to /dev/socket/qemud and sends a service + name to the daemon, the later sends to the emulator: + + connect:<service>:<id> + + where <service> is the service name, and <id> is a 4-hexchar string + giving the allocated channel index for the client. + + + - The emulator can respond in case of success with: + + ok:connect:<id> + + or, in case of failure, with: + + ok:connect:<id>:<reason> + + where <reason> is a liberal string giving the reason for failure. + It is never sent to clients (which will only receive a "KO") and + is used strictly for debugging purposes. + + - After a succesful connect, all messages between the client and + the corresponding emulator service will be passed through the + corresponding numbered channel. + + But if the client disconnects from the socket, the daemon will + send through channel 0 this message to the emulator: + + disconnect:<id> + + - If an emulator service decides, for some reason, to disconnect + a client, the emulator will send to the daemon (on channel 0): + + disconnect:<id> + + The daemon deals with this gracefully (e.g. it will wait that the + client has read all buffered data in the daemon before closing the + socket, to avoid packet loss). + + - Any other command sent from the daemon to the emulator will result + in the following answer: + + ko:bad command + +- Which exact serial port to open is determined by the emulator at startup + and is passed to the system as a kernel parameter, e.g.: + + android.qemud=ttyS1 + + +- The code to support services and their clients in the emulator is located + in android/hw-qemud.c. This code is heavily commented. + + The daemon's source is in $ROOT/development/emulator/qemud/qemud.c + + The header in $ROOT/hardware/libhardware/include/hardware/qemud.h + can be used by clients to ease connecting and talking to QEMUD-based + services. + + This is used by $ROOT/developement/emulator/sensors/sensors_qemu.c which + implements emulator-specific sensor support in the system by talking to + the "sensors" service provided by the emulator (if available). + + Code in $ROOT/hardware/libhardware_legacy also uses QEMUD-based services. + + +- Certain services also implement a simple framing protocol when exchanging + messages with their clients. The framing happens *after* serial port + multiplexing and looks like: + + offset size description + + 0 4 4-char hex string giving the payload size + + 4 n the message payload + + This is needed because the framing protocol used on the serial port is + not preserved when talking to clients through /dev/socket/qemud. + + Certain services do not need it at all (GSM, GPS) so it is optional and + must be used depending on which service you talk to by clients. + + +III. Legacy 'qemud': +-------------------- + +The system images provided by the 1.0 and 1.1 releases of the Android SDK +implement an older variant of the qemud daemon that uses a slightly +different protocol to communicate with the emulator. + +This is documented here since this explains some subtleties in the +implementation code of android/hw-qemud.c + +The old scheme also used a serial port to allow the daemon and the emulator +to communicate. Besides, the same multiplexing protocol was used to pass +messages through multiple channels. However, several other differences +exist, best illustrated by the following graphics: + + emulator <==serial==> qemud <-+--> /dev/socket/qemud_gsm <--> GSM client + | + +--> /dev/socket/qemud_gps <--> GPS client + | + +--> /dev/socket/qemud_control <--> client(s) + +Now, for the details: + + - instead of a single /dev/socket/qemud, init created several Unix domain + sockets, one per service: + + /dev/socket/qemud_gsm + /dev/socket/qemud_gps + /dev/socket/qemud_control + + note that there is no "sensors" socket in 1.0 and 1.1 + + - the daemon created a de-facto numbered channel for each one of these + services, even if no client did connect to it (only one client could + connect to a given service at a time). + + - at startup, the emulator does query the channel numbers of all services + it implements, e.g. it would send *to* the daemon on channel 0: + + connect:<service> + + where <service> can be one of "gsm", "gps" or "control" + + (Note that on the current implementation, the daemon is sending connection + messages to the emulator instead). + + - the daemon would respond with either: + + ok:connect:<service>:<hxid> + + where <service> would be the service name, and <hxid> a 4-hexchar channel + number (NOTE: 4 chars, not 2). Or with: + + ko:connect:bad name + + +This old scheme was simpler to implement in both the daemon and the emulator +but lacked a lot of flexibility: + + - adding a new service required to modify /system/etc/init.goldfish.rc + as well as the daemon source file (which contained a hard-coded list + of sockets to listen to for client connections). + + - only one client could be connected to a given service at a time, + except for the GPS special case which was a unidirectionnal broadcast + by convention. + +The current implementation moves any service-specific code to the emulator, +only uses a single socket and allows concurrent clients for a all services. |