auto import from //depot/cupcake/@136594
diff --git a/CHANGES.TXT b/CHANGES.TXT
index 0f362b7..9e5bb50 100644
--- a/CHANGES.TXT
+++ b/CHANGES.TXT
@@ -116,6 +116,9 @@
   toggle will not switch the display resolution anymore (which resulted
   in distorted images).
 
+- Using '-no-audio' no longer disables sound hardware emulation. It simply
+  mutes the emulator program on the host.
+
 ==============================================================================
 Changes between 1.6 and 1.7
 
diff --git a/android-configure.sh b/android-configure.sh
index c5e60ef..7542e9b 100755
--- a/android-configure.sh
+++ b/android-configure.sh
@@ -365,6 +365,22 @@
 fi
 log "LD         : linker check ok ($LD)"
 
+# We may need to add -fno-stack-protector but this is not
+# supported by older versions of GCC
+#
+cat > $TMPC <<EOF
+int main(void) {}
+EOF
+OLD_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -fno-stack-protector"
+compile
+if [ $? != 0 ] ; then
+    log "CFLAGS     : C compiler doesn't support -fno-stack-protector"
+    CFLAGS="$OLD_CFLAGS"
+else
+    log "CFLAGS     : Adding -fno-stack-protector to CFLAGS"
+fi
+
 ###
 ###  SDL Probe
 ###
diff --git a/android/avd/info.c b/android/avd/info.c
index 230ddaa..afff342 100644
--- a/android/avd/info.c
+++ b/android/avd/info.c
@@ -23,14 +23,6 @@
 #include <stdio.h>
 #include <errno.h>
 
-/* define this to 1 to support obsolete platform/add-on
- * specific parsing and path searching as was used temporarily
- * in post-1.1 / pre-cupcake SDKs.
- *
- * the corresponding code should be removed soon.
- */
-#define  SUPPORT_PLATFORM_OR_ADDON  1
-
 /* global variables - see android/globals.h */
 AvdInfoParams   android_avdParams[1];
 AvdInfo*        android_avdInfo;
@@ -70,184 +62,6 @@
  * with one of the usual options.
  */
 
-#if SUPPORT_PLATFORM_OR_ADDON
-/*
- * BELOW IS THE DOCUMENTATION FOR AN OBSOLETE SCHEME THAT USED TO BE MORE
- * COMPLEX TO IMPLEMENT, AND EXPOSED TOO MUCH SDK INTERNALS WITHIN THE
- * EMULATOR SOURCE CODE.
- *
- * THE CORRESPONDING CODE IS STILL THERE FOR LEGACY SUPPORT REASON BUT WILL
- * SOON BE REMOVED FOR SIMPLIFICATION REASONS.
- *
- * we assume the following SDK layout:
- *
- *  SDK/
- *    tools/
- *      emulator[.exe]
- *      libs/
- *        hardware-properties.ini
- *        ...
- *
- *    platforms/
- *      <platform1>/
- *        build.prop
- *        images/
- *          <default kernel/disk images>
- *        skins/
- *          default/    --> default skin
- *            layout
- *            <skin bitmaps>
- *          <skin2>/    --> another skin
- *            layout
- *            <skin bitmaps>
- *          <skin3>/    --> skin alias to <skin2>
- *            alias-<skin2>
- *
- *      <platform2>/
- *        build.prop
- *        images/
- *          <other default kernel/disk images>
- *
- *    add-ons/
- *      <partner1>/
- *        manifest.ini
- *        images/
- *          <replacement disk images>
- *
- *      <partner2>/
- *        manifest.ini
- *        <replacement disk images>
- *        hardware.ini
- *        skins/
- *           default/
- *              layout
- *              <skin bitmaps>
- *           <skin2>/
- *              layout
- *              <skin bitmaps>
- *
- *
- * we define a 'platform' as a directory that provides a complete
- * set of disk/kernel images, some skins, as well as a build.prop
- * file.
- *
- * we define an 'addon' as a directory that provides additionnal
- * or replacement files related to a given existing platform.
- * each add-on provides at the minimum a 'manifest.ini' file
- * that describes it (see below).
- *
- * important notes:
- *
- * - the build.prop file of a given platform directory contains
- *   a line that reads 'ro.build.version.sdk=<version>' where
- *   <version> is an integer corresponding to the corresponding
- *   official API version number as defined by Android.
- *
- *   each platform provided with the SDK must have a unique
- *   version number.
- *
- * - the manifest.ini of a given addon must contain lines
- *   that include:
- *
- *      name=<addOnName>
- *      vendor=<vendorName>
- *      api=<version>
- *
- *   where <version> is used to identify the platform the add-on
- *   refers to. Note that the platform's directory name is
- *   irrelevant to the matching algorithm.
- *
- *   each addon available must have a unique
- *   <vendor>:<name>:<sdk> triplet
- *
- * - an add-on can provide a hardware.ini file. If present, this
- *   is used to force the hardware setting of any virtual device
- *   built from the add-on.
- *
- * - the file in SDK/tools/lib/hardware-properties.ini declares which
- *   hardware properties are supported by the emulator binary.
- *   these can appear in the config.ini file of a given virtual
- *   device, or the hardware.ini of a given add-on.
- *
- * normally, a virtual device corresponds to:
- *
- *  - a root configuration file, placed in ~/.android/avd/<foo>.ini
- *    where <foo> is the name of the virtual device.
- *
- *  - a "content" directory, which contains disk images for the
- *    virtual device (e.g. at a minimum, the userdata.img file)
- *    plus some configuration information.
- *
- *  - the root config file must have at least two lines like:
- *
- *      path=<pathToContentDirectory>
- *      target=<targetAddonOrPlatform>
- *
- *    the 'path' value must point to the location of
- *    the virtual device's content directory. By default, this
- *    should be ~/.android/avd/<foo>/, though the user should be
- *    able to choose an alternative path at creation time.
- *
- *    the 'target' value can be one of:
- *
- *        android-<version>
- *        <vendor>:<name>:<version>
- *
- *    the first form is used to refer to a given platform.
- *    the second form is used to refer to a unique add-on.
- *    in both forms, <version> must be an integer that
- *    matches one of the available platforms.
- *
- *    <vendor>:<name>:<version> must match the triplet of one
- *    of the available add-ons
- *
- *    if the target value is incorrect, or if the content path
- *    is invalid, the emulator will abort with an error.
- *
- * - the content directory shall contain a 'config.ini' that
- *   contains hardware properties for the virtual device
- *   (as defined by SDK/tools/lib/hardware-properties.ini), as
- *   well as additional lines like:
- *
- *      sdcard=<pathToDefaultSDCard>
- *      skin=<defaultSkinName>
- *      options=<additionalEmulatorStartupOptions>
- *
- *
- *  Finally, to find the skin to be used with a given virtual
- *  device, the following logic is used:
- *
- *  - if no skin name has been manually specified on
- *    the command line, or in the config.ini file,
- *    look in $CONTENT/skin/layout and use it if available.
- *
- *  - otherwise, set SKINNAME to 'default' if not manually
- *    specified, and look for $ADDON/skins/$SKINNAME/layout
- *    and use it if available
- *
- *  - otherwise, look for $PLATFORM/skins/$SKINNAME/layout
- *    and use it if available.
- *
- *  - otherwise, look for $PLATFORM/skins/$SKINNAME/alias-<other>.
- *    if a file exist by that name, look at $PLATFORM/skins/<other>/layout
- *    and use it if available. Aliases are not recursives :-)
- */
-
-/*  now, things get a little bit more complicated when working
- *  within the Android build system. In this mode, which can be
- *  detected by looking at the definition of the ANDROID_PRODUCT_OUT
- *  environment variable, we're going to simply pick the image files
- *  from the out directory, or from $BUILDROOT/prebuilt
- */
-
-/* the name of the $SDKROOT subdirectory that contains all platforms */
-#  define  PLATFORMS_SUBDIR  "platforms"
-
-/* the name of the $SDKROOT subdirectory that contains add-ons */
-#  define  ADDONS_SUBDIR     "add-ons"
-
-#endif /* SUPPORT_PLATFORM_OR_ADDON */
-
 /* this is the subdirectory of $HOME/.android where all
  * root configuration files (and default content directories)
  * are located.
@@ -257,7 +71,7 @@
 /* the prefix of config.ini keys that will be used for search directories
  * of system images.
  */
-#define  SEARCH_PREFIX   "images.sysdir."
+#define  SEARCH_PREFIX   "image.sysdir."
 
 /* the maximum number of search path keys we're going to read from the
  * config.ini file
@@ -266,12 +80,8 @@
 
 /* the config.ini key that will be used to indicate the full relative
  * path to the skin directory (including the skin name).
- *
- * If SUPPORT_PLATFORM_OR_ADDON is defined, then this can also be
- * the name of a skin, without any path, and platform/add-on directories
- * will be searched for it.
  */
-#define  SKIN_PATH       "skin"
+#define  SKIN_PATH       "skin.path"
 
 /* default skin name */
 #define  SKIN_DEFAULT    "HVGA"
@@ -314,12 +124,6 @@
     char      sdkRootPathFromEnv;
     char*     searchPaths[ MAX_SEARCH_PATHS ];
     int       numSearchPaths;
-#if SUPPORT_PLATFORM_OR_ADDON
-    int       platformVersion;
-    char*     platformPath;
-    char*     addonTarget;
-    char*     addonPath;
-#endif
     char*     contentPath;
     IniFile*  rootIni;      /* root <foo>.ini file */
     IniFile*  configIni;    /* virtual device's config.ini */
@@ -367,12 +171,6 @@
         if (i->inAndroidBuild) {
             AFREE(i->androidOut);
             AFREE(i->androidBuildRoot);
-        } else {
-#if SUPPORT_PLATFORM_OR_ADDON
-            AFREE(i->platformPath);
-            AFREE(i->addonTarget);
-            AFREE(i->addonPath);
-#endif
         }
 
         AFREE(i->deviceName);
@@ -462,195 +260,15 @@
     }
 
     i->numSearchPaths = count;
-    if (count == 0)
-        DD("no search paths found in this AVD's config.ini");
+    if (count == 0) {
+        derror("no search paths found in this AVD's configuration.\n"
+               "Weird, the AVD's config.ini file is malformed. Try re-creating it.\n");
+        exit(2);
+    }
     else
         DD("found a total of %d search paths for this AVD", count);
 }
 
-#if SUPPORT_PLATFORM_OR_ADDON
-/* returns the full path of the platform subdirectory
- * corresponding to a given API version
- */
-static char*
-_findPlatformByVersion( const char*  sdkRoot, int  version )
-{
-    char         temp[PATH_MAX], *p=temp, *end=p+sizeof temp;
-    char*        subdir = NULL;
-    DirScanner*  scanner;
-
-    DD("> %s(%s,%d)", __FUNCTION__, sdkRoot, version);
-    p = bufprint(temp, end, "%s/%s", sdkRoot, PLATFORMS_SUBDIR);
-    if (p >= end) {
-        DD("! path too long");
-        return NULL;
-    }
-
-    scanner = dirScanner_new(temp);
-    if (scanner == NULL) {
-        DD("! cannot scan path %s: %s", temp, strerror(errno));
-        return NULL;
-    }
-
-    for (;;) {
-        IniFile*  ini;
-        int       apiVersion;
-
-        subdir = (char*) dirScanner_nextFull(scanner);
-        if (subdir == NULL)
-            break;
-
-        /* look for a file named "build.prop */
-        p = bufprint(temp, end, "%s/build.prop", subdir);
-        if (p >= end)
-            continue;
-
-        if (!path_exists(temp)) {
-            DD("! no file at %s", temp);
-            continue;
-        }
-
-        ini = iniFile_newFromFile(temp);
-        if (ini == NULL)
-            continue;
-
-        apiVersion = iniFile_getInteger(ini, "ro.build.version.sdk", -1);
-        iniFile_free(ini);
-
-        DD("! found %s (version %d)", temp, apiVersion);
-
-        if (apiVersion == version) {
-            /* Bingo */
-            subdir = ASTRDUP(subdir);
-            break;
-        }
-    }
-
-    if (!subdir) {
-        DD("< didn't found anything");
-    }
-
-    dirScanner_free(scanner);
-    return subdir;
-}
-
-/* returns the full path of the addon corresponding to a given target,
- * or NULL if not found. on success, *pversion will contain the SDK
- * version number
- */
-static char*
-_findAddonByTarget( const char*  sdkRoot, const char*  target, int  *pversion )
-{
-    char*  targetCopy    = ASTRDUP(target);
-    char*  targetVendor  = NULL;
-    char*  targetName    = NULL;
-    int    targetVersion = -1;
-
-    char         temp[PATH_MAX];
-    char*        p;
-    char*        end;
-    DirScanner*  scanner;
-    char*        subdir;
-
-    DD("> %s(%s,%s)", __FUNCTION__, sdkRoot, target);
-
-    /* extract triplet from target string */
-    targetVendor = targetCopy;
-
-    p = strchr(targetVendor, ':');
-    if (p == NULL) {
-        DD("< missing first column separator");
-        goto FAIL;
-    }
-    *p         = 0;
-    targetName = p + 1;
-    p          = strchr(targetName, ':');
-    if (p == NULL) {
-        DD("< missing second column separator");
-        goto FAIL;
-    }
-    *p++ = 0;
-
-    targetVersion = atoi(p);
-
-    if (targetVersion == 0) {
-        DD("< invalid version number");
-        goto FAIL;
-    }
-    /* now scan addons directory */
-    p   = temp;
-    end = p + sizeof temp;
-
-    p = bufprint(p, end, "%s/%s", sdkRoot, ADDONS_SUBDIR);
-    if (p >= end) {
-        DD("< add-on path too long");
-        goto FAIL;
-    }
-    scanner = dirScanner_new(temp);
-    if (scanner == NULL) {
-        DD("< cannot scan add-on path %s: %s", temp, strerror(errno));
-        goto FAIL;
-    }
-    for (;;) {
-        IniFile*     ini;
-        const char*  vendor;
-        const char*  name;
-        int          version;
-        int          matches;
-
-        subdir = (char*) dirScanner_nextFull(scanner);
-        if (subdir == NULL)
-            break;
-
-        /* try to open the manifest.ini file */
-        p = bufprint(temp, end, "%s/manifest.ini", subdir);
-        if (p >= end)
-            continue;
-
-        ini = iniFile_newFromFile(temp);
-        if (ini == NULL)
-            continue;
-
-        DD("! scanning manifest.ini in %s", temp);
-
-        /* find the vendor, name and version */
-        vendor  = iniFile_getValue(ini,  "vendor");
-        name    = iniFile_getValue(ini,  "name");
-        version = iniFile_getInteger(ini, "api", -1);
-
-        matches = 0;
-
-        matches += (version == targetVersion);
-        matches += (vendor && !strcmp(vendor, targetVendor));
-        matches += (name   && !strcmp(name, targetName));
-
-        DD("! matches=%d vendor=[%s] name=[%s] version=%d",
-           matches,
-           vendor ? vendor : "<NULL>",
-           name ? name : "<NULL>",
-           version);
-
-        iniFile_free(ini);
-
-        if (matches == 3) {
-            /* bingo */
-            *pversion = version;
-            subdir    = ASTRDUP(subdir);
-            break;
-        }
-    }
-
-    dirScanner_free(scanner);
-
-    DD("< returning %s", subdir ? subdir : "<NULL>");
-    return subdir;
-
-FAIL:
-    AFREE(targetCopy);
-    return NULL;
-}
-#endif /* SUPPORT_PLATFORM_OR_ADDON */
-
 static int
 _checkAvdName( const char*  name )
 {
@@ -703,64 +321,6 @@
     return 0;
 }
 
-#if SUPPORT_PLATFORM_OR_ADDON
-#   define  ROOT_TARGET_KEY  "target"
-
-/* retrieve the content path and target from the root .ini file */
-static int
-_getTarget( AvdInfo*  i )
-{
-    i->addonTarget = iniFile_getString(i->rootIni, ROOT_TARGET_KEY);
-
-    if (i->addonTarget == NULL) {
-        derror("bad config: %s",
-               "virtual device file lacks a "ROOT_TARGET_KEY" entry");
-        return -1;
-    }
-
-    D("virtual device target is %s", i->addonTarget);
-
-    if (!strncmp(i->addonTarget, "android-", 8)) {  /* target is platform */
-        char*        end;
-        const char*  versionString = i->addonTarget+8;
-        int          version = (int) strtol(versionString, &end, 10);
-        if (*end != 0 || version <= 0) {
-            derror("bad config: invalid platform version: '%s'", versionString);
-            return -1;
-        }
-        i->platformVersion = version;
-        i->platformPath    = _findPlatformByVersion(i->sdkRootPath, 
-                                                    version);
-        if (i->platformPath == NULL) {
-            derror("bad config: unknown platform version: '%d'", version);
-            return -1;
-        }
-    }
-    else  /* target is add-on */
-    {
-        i->addonPath = _findAddonByTarget(i->sdkRootPath, i->addonTarget,
-                                          &i->platformVersion);
-        if (i->addonPath == NULL) {
-            derror("bad config: %s",
-                   "unknown add-on target: '%s'", i->addonTarget);
-            return -1;
-        }
-
-        i->platformPath = _findPlatformByVersion(i->sdkRootPath, 
-                                                 i->platformVersion);
-        if (i->platformPath == NULL) {
-            derror("bad config: %s",
-                   "unknown add-on platform version: '%d'", i->platformVersion);
-            return -1;
-        }
-        D("virtual device add-on path: %s", i->addonPath);
-    }
-    D("virtual device platform path: %s",   i->platformPath);
-    D("virtual device platform version %d", i->platformVersion);
-    return 0;
-}
-#endif /* SUPPORT_PLATFORM_OR_ADDON */
-
 /* find and parse the config.ini file from the content directory */
 static int
 _getConfigIni(AvdInfo*  i)
@@ -891,26 +451,6 @@
             DD("    no %s in search dir: %s", image, searchDir);
         }
 
-#if SUPPORT_PLATFORM_OR_ADDON
-        /* try the add-on directory, if any */
-        if (i->addonPath != NULL) {
-            p = bufprint(temp, end, "%s/images/%s", i->addonPath, image);
-            if (p < end && path_exists(temp)) {
-                DD("found %s in add-on dir:", image, i->addonPath);
-                break;
-            }
-            DD("    no %s in add-on dir: ", image, i->addonPath);
-        }
-
-        /* or try the platform directory */
-        p = bufprint(temp, end, "%s/images/%s",
-                     i->platformPath, image);
-        if (p < end && path_exists(temp)) {
-            DD("found %s in platform dir:", image, i->platformPath);
-            break;
-        }
-        DD("    no %s in platform dir: ", image, i->platformPath);
-#endif
         return NULL;
 
     } while (0);
@@ -1179,13 +719,15 @@
         /* find SDK source file */
         const char*  srcPath;
 
-        if (imageLoader_lookupSdk(l)) {
+        imageLoader_set( l, AVD_IMAGE_INITDATA );
+        if (imageLoader_lookupSdk(l) == NULL) {
             derror("can't locate initial %s image in SDK",
                 l->imageText);
             exit(2);
         }
         srcPath = imageLoader_extractPath(l);
 
+        imageLoader_set( l, AVD_IMAGE_USERDATA );
         imageLoader_copyFrom( l, srcPath );
         AFREE((char*) srcPath);
     }
@@ -1458,16 +1000,6 @@
                 break;
         }
 
-#if SUPPORT_PLATFORM_OR_ADDON
-        /* look in the add-on directory, if any */
-        if (i->addonPath && 
-            _checkSkinDir(temp, end, i->addonPath, skinName))
-            break;
-
-        /* look in the platforms directory */
-        if (_checkSkinDir(temp, end, i->platformPath, skinName))
-            break;
-#endif
         /* didn't find it */
         if (explicitSkin) {
             derror("could not find directory for skin '%s',"
@@ -1527,14 +1059,6 @@
      */
     _getSearchPaths(i);
 
-    if (i->numSearchPaths == 0) {
-#if SUPPORT_PLATFORM_OR_ADDON
-        /* no search paths, look for platform/add-on */
-        if (_getTarget(i) < 0)
-            goto FAIL;
-#endif
-    }
-
     /* don't need this anymore */
     iniFile_free(i->rootIni);
     i->rootIni = NULL;
@@ -1571,8 +1095,7 @@
  *****      prebuilt
  *****
  *****    - there is no root .ini file, or any config.ini in
- *****      the content directory, no SDK platform version
- *****      and no add-on to consider.
+ *****      the content directory, no SDK images search path.
  *****/
 
 /* used to fake a config.ini located in the content directory */
diff --git a/android/main.c b/android/main.c
index c366a9e..f0029f4 100644
--- a/android/main.c
+++ b/android/main.c
@@ -2085,6 +2085,11 @@
         }
     }
 
+    /* the purpose of -no-audio is to disable sound output from the emulator,
+     * not to disable Audio emulation. So simply force the 'none' backends */
+    if (opts->no_audio)
+        opts->audio = "none";
+
     if (opts->audio) {
         if (opts->audio_in || opts->audio_out) {
             derror( "you can't use -audio with -audio-in or -audio-out\n" );
@@ -2430,10 +2435,6 @@
         opts->memory = qemu_strdup(tmp);
     }
 
-    if (opts->no_audio) {
-        args[n++] = "-noaudio";
-    }
-
     if (opts->trace) {
         args[n++] = "-trace";
         args[n++] = opts->trace;
@@ -2815,7 +2816,16 @@
 
             D( "ping command: %s %s", comspec, args );
 #else
-            int  pid = fork();
+            int  pid;
+
+            /* disable SIGALRM for the fork(), the periodic signal seems to
+             * interefere badly with the fork() implementation on Linux running
+             * under VMWare.
+             */
+            BEGIN_NOSIGALRM
+              pid = fork();
+            END_NOSIGALRM
+
             if (pid == 0) {
                 int  fd = open("/dev/null", O_WRONLY);
                 dup2(fd, 1);
diff --git a/android/utils/path.c b/android/utils/path.c
index b15b6de..e7ef2b0 100644
--- a/android/utils/path.c
+++ b/android/utils/path.c
@@ -34,7 +34,8 @@
 #include <signal.h>
 #endif
 
-#define  D(...)  ((void)0)
+#include "android/utils/debug.h"
+#define  D(...)  VERBOSE_PRINT(init,__VA_ARGS__)
 
 #ifndef CHECKED
 #  ifdef _WIN32
@@ -457,6 +458,12 @@
         return -1;
     }
 
+    if ( access(source, R_OK) < 0 ) {
+        D("%s: source file is un-readable: %s\n",
+          __FUNCTION__, source);
+        return -1;
+    }
+
 #ifdef _WIN32
     fd = _open(dest, _O_RDWR | _O_BINARY);
     fs = _open(source, _O_RDONLY |  _O_BINARY);
diff --git a/docs/CPU-EMULATION.TXT b/docs/CPU-EMULATION.TXT
new file mode 100644
index 0000000..303d6c0
--- /dev/null
+++ b/docs/CPU-EMULATION.TXT
@@ -0,0 +1,91 @@
+HOW THE QEMU EXECUTION ENGINE WORKS:
+====================================
+
+Translating ARM to x86 machine code:
+------------------------------------
+
+QEMU starts by isolating code "fragments" from the emulated machine code.
+Each "fragment" corresponds to a seris of ARM instructions ending with a
+branch (e.g. jumps, conditional branches, returns).
+
+Each fragment is translated into a "translated block" (a.k.a. TB) of host
+machine code (e.g. x86). All TBs are put in a cache and each time the
+instruction pointer changes (i.e. at the end of TB execution), a hash
+table lookup is performed to find the next TB to execute.
+
+If none exists, a new one is generated. As a special exception, it is
+sometimes possible to 'link' the end of a given TB to the start of
+another one by tacking an explicit jump instruction.
+
+Note that due to differences in translations of memory-related operations
+(described below in "MMU emulation"), there are actually two TB caches per
+emulated CPU: one for translated kernel code, and one for translated
+user-space code.
+
+When a cache fills up, it is simply totally emptied and translation starts
+again.
+
+CPU state is kept in a single global structure which the generated code
+can access directly (with direct memory addressing).
+
+the file target-arm/translate.c is in charge of translating the ARM or
+Thumb instructions starting at the current instruction pointer position
+into a TB. This is done by decomposing each instruction into a series of
+micro-operations supported by the TCG code generator.
+
+TCG stands for "Tiny Code Generator" and is specific to QEMU. It supports
+several host machine code backends. See source files under tcg/ for details.
+
+
+MMU Emulation:
+--------------
+
+The ARM Memory Management Unit is emulated in software, since it is so
+different from the one on the host. Essentially, a single ARM memory load/store
+instruction is translated into a series of host machine instructions that will
+translate virtual addresses into physical ones by performing the following:
+
+- first lookup in a global 256-entries cache for the current page and see if
+  a corresponding value is already stored there. If this is the case, use it
+  directly.
+
+- otherwise, call a special helper function that will implement the full
+  translation according to the emulated system's state, and modify the
+  cache accordingly.
+
+The page cache is called the "TLB" in the QEMU sources.
+
+Note that there are actually two TLBs: one is used for host machine
+instructions that correspond to kernel code, and the other for instructions
+translated from user-level code.
+
+This means that a memory load in the kernel will not be translated into the
+same instructions than the same load in user space.
+
+Each TLB is also implemented as a global per-CPU hash-table.
+The user-level TLB is flushed on each process context switch. 
+
+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 helper 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.
+
+
+Hardware Emulation:
+-------------------
+
+Most hardware emulation code 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.
+
+You can have a look at hw/goldfish_tty.c that implements an emulated serial
+port for the Goldfish platform.
+
+"Goldfish" is simply the name of the virtual Linux platform used to build
+the Android-emulator-specific kernel image. The corresponding sources are
+located in the origin/android-goldfish-2.6.27 branch of
+git://android.git.kernel.org/kernel/common.git. You can have a look at
+arch/arm/mach-goldfish/ for the corresponding kernel driver sources.
+
diff --git a/hw/android_arm.c b/hw/android_arm.c
index efc8ba1..ae21be8 100644
--- a/hw/android_arm.c
+++ b/hw/android_arm.c
@@ -22,7 +22,6 @@
 
 #define ARM_CPU_SAVE_VERSION  1
 
-int android_audio_enabled;
 char* audio_input_source = NULL;
 
 void goldfish_memlog_init(uint32_t base);
@@ -116,10 +115,8 @@
 
     goldfish_fb_init(ds, 0);
 #ifdef HAS_AUDIO
-    if (android_audio_enabled) {
-        AUD_init();
-        goldfish_audio_init(0xff004000, 0, audio_input_source);
-    }
+    AUD_init();
+    goldfish_audio_init(0xff004000, 0, audio_input_source);
 #endif
     {
         int  idx = drive_get_index( IF_IDE, 0, 0 );
@@ -171,5 +168,7 @@
     "android_arm",
     "ARM Android Emulator",
     android_arm_init,
+    0,
+    0,
     NULL
 };
diff --git a/vl.c b/vl.c
index a9c1940..1fe18d2 100644
--- a/vl.c
+++ b/vl.c
@@ -282,7 +282,6 @@
 
 
 extern int   qemu_cpu_delay;
-extern int   android_audio_enabled;
 extern char* audio_input_source;
 
 extern void  dprint( const char* format, ... );
@@ -8354,7 +8353,6 @@
     QEMU_OPTION_name,
     QEMU_OPTION_prom_env,
     QEMU_OPTION_old_param,
-    QEMU_OPTION_noaudio,
     QEMU_OPTION_mic,
 #ifdef CONFIG_TRACE
     QEMU_OPTION_trace_file,
@@ -8482,7 +8480,6 @@
 #endif
 
     /* android stuff */
-    { "noaudio", 0, QEMU_OPTION_noaudio },
     { "mic", HAS_ARG, QEMU_OPTION_mic },
 #ifdef CONFIG_TRACE
     { "trace", HAS_ARG, QEMU_OPTION_trace_file },
@@ -8808,7 +8805,6 @@
     nb_nics = 0;
 
     tb_size = 0;
-	android_audio_enabled = 1;
 
     optind = 1;
     for(;;) {
@@ -9349,9 +9345,6 @@
                 }
                 break;
 
-            case QEMU_OPTION_noaudio:
-                android_audio_enabled = 0;
-                break;
             case QEMU_OPTION_mic:
                 audio_input_source = (char*)optarg;
                 break;