18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copyright (C) 2006-2008 The Android Open Source Project
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This software is licensed under the terms of the GNU General Public
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** License version 2, as published by the Free Software Foundation, and
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** may be copied, distributed, and modified under those terms.
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This program is distributed in the hope that it will be useful,
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** but WITHOUT ANY WARRANTY; without even the implied warranty of
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** GNU General Public License for more details.
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <signal.h>
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <unistd.h>
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <string.h>
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <sys/time.h>
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <process.h>
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
207fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "sockets.h"
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/android.h"
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "qemu-common.h"
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "sysemu.h"
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "console.h"
2734f2974ce7ec7c71beb47b5daf9089d5c8c40c79David 'Digit' Turner#include "user-events.h"
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <SDL.h>
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <SDL_syswm.h>
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "math.h"
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/charmap.h"
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/debug.h"
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/config.h"
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/config/config.h"
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/user-config.h"
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/bufprint.h"
4126d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner#include "android/utils/filelock.h"
420a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner#include "android/utils/lineinput.h"
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/path.h"
44622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner#include "android/utils/tempfile.h"
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
46f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner#include "android/main-common.h"
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/help.h"
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "hw/goldfish_nand.h"
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/globals.h"
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
52fc8ed80ba1362d2ce500003625e1c9c39f765661Xavier Ducrohet#include "android/qemulator.h"
53055ae42d36d9d78a7920f66ee2df485d81d24264David 'Digit' Turner#include "android/display.h"
540119362f0d74ca74f3ea743f6e0e527a9edcc474Vladimir Chtchetkine
55ae835acc2d1a8b4aaeb599add9cfc02ea5789eafOt ten Thije#include "android/snapshot.h"
56ae835acc2d1a8b4aaeb599add9cfc02ea5789eafOt ten Thije
57e3fdd075ed97085b4201cb0c79609633b19bddccDavid 'Digit' Turner#include "android/framebuffer.h"
589a33e8554225c82cd900208f88e8965bb085ab87Vladimir Chtchetkine#include "iolooper.h"
59055ae42d36d9d78a7920f66ee2df485d81d24264David 'Digit' Turner
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectAndroidRotation  android_framebuffer_rotation;
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  STRINGIFY(x)   _STRINGIFY(x)
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  _STRINGIFY(x)  #x
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
65a383d02cb57dd7dadd382654175e51354073a139David 'Digit' Turner#ifdef ANDROID_SDK_TOOLS_REVISION
66a383d02cb57dd7dadd382654175e51354073a139David 'Digit' Turner#  define  VERSION_STRING  STRINGIFY(ANDROID_SDK_TOOLS_REVISION)".0"
67a383d02cb57dd7dadd382654175e51354073a139David 'Digit' Turner#else
68a383d02cb57dd7dadd382654175e51354073a139David 'Digit' Turner#  define  VERSION_STRING  "standalone"
69a383d02cb57dd7dadd382654175e51354073a139David 'Digit' Turner#endif
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  D(...)  do {  if (VERBOSE_CHECK(init)) dprint(__VA_ARGS__); } while (0)
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern int  control_console_start( int  port );  /* in control.c */
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern int qemu_milli_needed;
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* the default device DPI if none is specified by the skin
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  DEFAULT_DEVICE_DPI  165
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_TRACE
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void  start_tracing(void);
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void  stop_tracing(void);
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectunsigned long   android_verbose;
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint qemu_main(int argc, char **argv);
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* this function dumps the QEMU help */
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void  help( void );
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void  emulator_help( void );
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  VERBOSE_OPT(str,var)   { str, &var }
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  _VERBOSE_TAG(x,y)   { #x, VERBOSE_##x, y },
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const struct { const char*  name; int  flag; const char*  text; }
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectverbose_options[] = {
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    VERBOSE_TAG_LIST
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { 0, 0, 0 }
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid emulator_help( void )
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    STRALLOC_DEFINE(out);
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    android_help_main(out);
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf( "%.*s", out->n, out->s );
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    stralloc_reset(out);
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    exit(1);
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner/* TODO: Put in shared source file */
11340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turnerstatic char*
11440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner_getFullFilePath( const char* rootPath, const char* fileName )
11540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner{
11640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    if (path_is_absolute(fileName)) {
11740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        return ASTRDUP(fileName);
11840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    } else {
11940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
12040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
12140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        p = bufprint(temp, end, "%s/%s", rootPath, fileName);
12240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        if (p >= end) {
12340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            return NULL;
12440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        }
12540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        return ASTRDUP(temp);
12640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    }
12740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner}
12840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
12940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turnerstatic uint64_t
13040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner_adjustPartitionSize( const char*  description,
13140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                      uint64_t     imageBytes,
13240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                      uint64_t     defaultBytes,
13340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                      int          inAndroidBuild )
13440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner{
13540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    char      temp[64];
13640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    unsigned  imageMB;
13740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    unsigned  defaultMB;
13840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
13940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    if (imageBytes <= defaultBytes)
14040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        return defaultBytes;
14140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
14240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    imageMB   = convertBytesToMB(imageBytes);
14340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    defaultMB = convertBytesToMB(defaultBytes);
14440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
14540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    if (imageMB > defaultMB) {
14640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        snprintf(temp, sizeof temp, "(%d MB > %d MB)", imageMB, defaultMB);
14740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    } else {
148c7389bd69e570a2c8432b37399aff1976b021f0fAndrew Hsieh        snprintf(temp, sizeof temp, "(%" PRIu64 "  bytes > %" PRIu64 " bytes)", imageBytes, defaultBytes);
14940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    }
15040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
15140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    if (inAndroidBuild) {
15240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        dwarning("%s partition size adjusted to match image file %s\n", description, temp);
15340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    }
15440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
15540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    return convertMBToBytes(imageMB);
15640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner}
15740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint main(int argc, char **argv)
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char   tmp[MAX_PATH];
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*  tmpend = tmp + sizeof(tmp);
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*  args[128];
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int    n;
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*  opt;
1655e736937d49affc9131944d7c879246fbcba3b70David 'Digit' Turner    /* The emulator always uses the first serial port for kernel messages
1665e736937d49affc9131944d7c879246fbcba3b70David 'Digit' Turner     * and the second one for qemud. So start at the third if we need one
1675e736937d49affc9131944d7c879246fbcba3b70David 'Digit' Turner     * for logcat or 'shell'
1685e736937d49affc9131944d7c879246fbcba3b70David 'Digit' Turner     */
1695e736937d49affc9131944d7c879246fbcba3b70David 'Digit' Turner    int    serial = 2;
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int    shell_serial = 0;
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1722ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    int    forceArmv7 = 0;
1732ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    AndroidHwConfig*  hw;
175cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner    AvdInfo*          avd;
17674d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner    AConfig*          skinConfig;
17774d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner    char*             skinPath;
17883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    int               inAndroidBuild;
17988078b8875dab47abf9fe80488503f60d9835eafVladimir Chtchetkine    uint64_t          defaultPartitionSize = convertMBToBytes(200);
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    AndroidOptions  opts[1];
182b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    /* net.shared_net_ip boot property value. */
183b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    char boot_prop_ip[64];
184b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    boot_prop_ip[0] = '\0';
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    args[0] = argv[0];
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( android_parse_options( &argc, &argv, opts ) < 0 ) {
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        exit(1);
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
192bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner#ifdef _WIN32
193bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner    socket_init();
194bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner#endif
195bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner
196bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner    handle_ui_options(opts);
197bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (argc-- > 1) {
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        opt = (++argv)[0];
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if(!strcmp(opt, "-qemu")) {
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            argc--;
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            argv++;
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!strcmp(opt, "-help")) {
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            emulator_help();
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!strncmp(opt, "-help-",6)) {
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            STRALLOC_DEFINE(out);
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            opt += 6;
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!strcmp(opt, "all")) {
2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                android_help_all(out);
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else if (android_help_for_option(opt, out) == 0) {
2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* ok */
2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else if (android_help_for_topic(opt, out) == 0) {
2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* ok */
2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (out->n > 0) {
2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                printf("\n%.*s", out->n, out->s);
2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                exit(0);
2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(stderr, "unknown option: -help-%s\n", opt);
2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(stderr, "please use -help for a list of valid topics\n");
2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            exit(1);
2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (opt[0] == '-') {
2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(stderr, "unknown option: %s\n", opt);
2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(stderr, "please use -help for a list of valid options\n");
2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            exit(1);
2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(stderr, "invalid command-line parameter: %s.\n", opt);
2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(stderr, "Hint: use '@foo' to launch a virtual device named 'foo'.\n");
2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(stderr, "please use -help for more information\n");
2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        exit(1);
2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (opts->version) {
2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf("Android emulator version %s\n"
2485f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner               "Copyright (C) 2006-2011 The Android Open Source Project and many others.\n"
2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               "This program is a derivative of the QEMU CPU emulator (www.qemu.org).\n\n",
2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined ANDROID_BUILD_ID
2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               VERSION_STRING " (build_id " STRINGIFY(ANDROID_BUILD_ID) ")" );
2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               VERSION_STRING);
2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf("  This software is licensed under the terms of the GNU General Public\n"
2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               "  License version 2, as published by the Free Software Foundation, and\n"
2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               "  may be copied, distributed, and modified under those terms.\n\n"
2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               "  This program is distributed in the hope that it will be useful,\n"
2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               "  but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               "  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               "  GNU General Public License for more details.\n\n");
2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        exit(0);
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2665f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    if (opts->snapshot_list) {
267d80a7861fe5e21e3dcb80480a77b033e6b307dd5David 'Digit' Turner        if (opts->snapstorage == NULL) {
268d80a7861fe5e21e3dcb80480a77b033e6b307dd5David 'Digit' Turner            /* Need to find the default snapstorage */
269d80a7861fe5e21e3dcb80480a77b033e6b307dd5David 'Digit' Turner            avd = createAVD(opts, &inAndroidBuild);
270d80a7861fe5e21e3dcb80480a77b033e6b307dd5David 'Digit' Turner            opts->snapstorage = avdInfo_getSnapStoragePath(avd);
271d80a7861fe5e21e3dcb80480a77b033e6b307dd5David 'Digit' Turner            if (opts->snapstorage != NULL) {
272d80a7861fe5e21e3dcb80480a77b033e6b307dd5David 'Digit' Turner                D("autoconfig: -snapstorage %s", opts->snapstorage);
273d80a7861fe5e21e3dcb80480a77b033e6b307dd5David 'Digit' Turner            } else {
274d80a7861fe5e21e3dcb80480a77b033e6b307dd5David 'Digit' Turner                if (inAndroidBuild) {
275d80a7861fe5e21e3dcb80480a77b033e6b307dd5David 'Digit' Turner                    derror("You must use the -snapstorage <file> option to specify a snapshot storage file!\n");
276d80a7861fe5e21e3dcb80480a77b033e6b307dd5David 'Digit' Turner                } else {
277d80a7861fe5e21e3dcb80480a77b033e6b307dd5David 'Digit' Turner                    derror("This AVD doesn't have snapshotting enabled!\n");
278d80a7861fe5e21e3dcb80480a77b033e6b307dd5David 'Digit' Turner                }
279d80a7861fe5e21e3dcb80480a77b033e6b307dd5David 'Digit' Turner                exit(1);
280d80a7861fe5e21e3dcb80480a77b033e6b307dd5David 'Digit' Turner            }
281d80a7861fe5e21e3dcb80480a77b033e6b307dd5David 'Digit' Turner        }
2825f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        snapshot_print_and_exit(opts->snapstorage);
2835f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    }
2845f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
28525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    sanitizeOptions(opts);
28625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
287bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner    /* Initialization of UI started with -attach-core should work differently
288bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner     * than initialization of UI that starts the core. In particular....
289bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner     */
290bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner
291bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner    /* -charmap is incompatible with -attach-core, because particular
292bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner     * charmap gets set up in the running core. */
29374d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner    if (android_charmap_setup(opts->charmap)) {
29474d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner        exit(1);
2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    /* Parses options and builds an appropriate AVD. */
298462564f31bbdc9939bf1d2376e2782defa7ef655David 'Digit' Turner    avd = android_avdInfo = createAVD(opts, &inAndroidBuild);
299cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner
3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* get the skin from the virtual device configuration */
30125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    if (opts->skindir != NULL) {
30225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        if (opts->skin == NULL) {
30325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            /* NOTE: Normally handled by sanitizeOptions(), just be safe */
30425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            derror("The -skindir <path> option requires a -skin <name> option");
30525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            exit(2);
30625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        }
30725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    } else {
30825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        char* skinName;
30925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        char* skinDir;
3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        avdInfo_getSkinInfo(avd, &skinName, &skinDir);
31225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
31325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        if (opts->skin == NULL) {
31425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            opts->skin = skinName;
31525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            D("autoconfig: -skin %s", opts->skin);
31625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        } else {
31725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            AFREE(skinName);
31825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        }
31925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
32025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        opts->skindir = skinDir;
3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        D("autoconfig: -skindir %s", opts->skindir);
322689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet
323689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet        /* update the avd hw config from this new skin */
324689d1147b1994be1d8e33ee4d1a8ec76742bb4a6Xavier Ducrohet        avdInfo_getSkinHardwareIni(avd, opts->skin, opts->skindir);
3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Read hardware configuration */
3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    hw = android_hw;
329b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner    if (avdInfo_initHwConfig(avd, hw) < 0) {
3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        derror("could not read hardware configuration ?");
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        exit(1);
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (opts->keyset) {
3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        parse_keyset(opts->keyset, opts);
3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!android_keyset) {
3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(stderr,
3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    "emulator: WARNING: could not find keyset file named '%s',"
3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    " using defaults instead\n",
3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    opts->keyset);
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!android_keyset) {
3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        parse_keyset("default", opts);
3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!android_keyset) {
3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            android_keyset = skin_keyset_new_from_text( skin_keyset_get_default() );
3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!android_keyset) {
3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fprintf(stderr, "PANIC: default keyset file is corrupted !!\n" );
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fprintf(stderr, "PANIC: please update the code in android/skin/keyset.c\n" );
3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                exit(1);
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!opts->keyset)
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                write_default_keyset();
3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
35740beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie    if (opts->shared_net_id) {
35840beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        char*  end;
35940beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        long   shared_net_id = strtol(opts->shared_net_id, &end, 0);
36040beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        if (end == NULL || *end || shared_net_id < 1 || shared_net_id > 255) {
36140beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie            fprintf(stderr, "option -shared-net-id must be an integer between 1 and 255\n");
36240beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie            exit(1);
36340beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        }
364b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        snprintf(boot_prop_ip, sizeof(boot_prop_ip),
365b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine                 "net.shared_net_ip=10.1.2.%ld", shared_net_id);
36640beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie    }
36740beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie
36840beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie
369755811e67c266333807571f798b62b6916611f87David 'Digit' Turner    user_config_init();
3702507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner    parse_skin_files(opts->skindir, opts->skin, opts, hw,
37174d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner                     &skinConfig, &skinPath);
3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
373092361e19ecc2992965729538984354099eea8cbDavid 'Digit' Turner    if (!opts->netspeed && skin_network_speed) {
374092361e19ecc2992965729538984354099eea8cbDavid 'Digit' Turner        D("skin network speed: '%s'", skin_network_speed);
375092361e19ecc2992965729538984354099eea8cbDavid 'Digit' Turner        if (strcmp(skin_network_speed, NETWORK_SPEED_DEFAULT) != 0) {
376092361e19ecc2992965729538984354099eea8cbDavid 'Digit' Turner            opts->netspeed = (char*)skin_network_speed;
377092361e19ecc2992965729538984354099eea8cbDavid 'Digit' Turner        }
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
379092361e19ecc2992965729538984354099eea8cbDavid 'Digit' Turner    if (!opts->netdelay && skin_network_delay) {
380092361e19ecc2992965729538984354099eea8cbDavid 'Digit' Turner        D("skin network delay: '%s'", skin_network_delay);
381092361e19ecc2992965729538984354099eea8cbDavid 'Digit' Turner        if (strcmp(skin_network_delay, NETWORK_DELAY_DEFAULT) != 0) {
382092361e19ecc2992965729538984354099eea8cbDavid 'Digit' Turner            opts->netdelay = (char*)skin_network_delay;
383092361e19ecc2992965729538984354099eea8cbDavid 'Digit' Turner        }
3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (opts->trace) {
387cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner        char*   tracePath = avdInfo_getTracePath(avd, opts->trace);
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int     ret;
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (tracePath == NULL) {
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            derror( "bad -trace parameter" );
3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            exit(1);
3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ret = path_mkdir_if_needed( tracePath, 0755 );
3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ret < 0) {
3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(stderr, "could not create directory '%s'\n", tmp);
3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            exit(2);
3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        opts->trace = tracePath;
4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40233f89d05b375f18596fa5892acaaae356fbb0c0eVladimir Chtchetkine    /* Update CPU architecture for HW configs created from build dir. */
40333f89d05b375f18596fa5892acaaae356fbb0c0eVladimir Chtchetkine    if (inAndroidBuild) {
40433f89d05b375f18596fa5892acaaae356fbb0c0eVladimir Chtchetkine#if defined(TARGET_ARM)
40533f89d05b375f18596fa5892acaaae356fbb0c0eVladimir Chtchetkine        free(android_hw->hw_cpu_arch);
40633f89d05b375f18596fa5892acaaae356fbb0c0eVladimir Chtchetkine        android_hw->hw_cpu_arch = ASTRDUP("arm");
40733f89d05b375f18596fa5892acaaae356fbb0c0eVladimir Chtchetkine#elif defined(TARGET_I386)
40833f89d05b375f18596fa5892acaaae356fbb0c0eVladimir Chtchetkine        free(android_hw->hw_cpu_arch);
40933f89d05b375f18596fa5892acaaae356fbb0c0eVladimir Chtchetkine        android_hw->hw_cpu_arch = ASTRDUP("x86");
41033f89d05b375f18596fa5892acaaae356fbb0c0eVladimir Chtchetkine#endif
41133f89d05b375f18596fa5892acaaae356fbb0c0eVladimir Chtchetkine    }
41233f89d05b375f18596fa5892acaaae356fbb0c0eVladimir Chtchetkine
4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    n = 1;
4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* generate arguments for the underlying qemu main() */
415238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner    {
4160b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        char*  kernelFile    = opts->kernel;
4170b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        int    kernelFileLen;
4180b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner
4190b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        if (kernelFile == NULL) {
4200b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner            kernelFile = avdInfo_getKernelPath(avd);
4210b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner            if (kernelFile == NULL) {
4220b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner                derror( "This AVD's configuration is missing a kernel file!!" );
4230b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner                exit(2);
4240b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner            }
4250b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner            D("autoconfig: -kernel %s", kernelFile);
4260b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        }
4270b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        if (!path_exists(kernelFile)) {
4280b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner            derror( "Invalid or missing kernel image file: %s", kernelFile );
4290b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner            exit(2);
4300b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        }
431238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner
4320b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        hw->kernel_path = kernelFile;
433238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner
434238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner        /* If the kernel image name ends in "-armv7", then change the cpu
435238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * type automatically. This is a poor man's approach to configuration
436238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * management, but should allow us to get past building ARMv7
437238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * system images with dex preopt pass without introducing too many
438238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * changes to the emulator sources.
439238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         *
440238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * XXX:
441238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * A 'proper' change would require adding some sort of hardware-property
442238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * to each AVD config file, then automatically determine its value for
443238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * full Android builds (depending on some environment variable), plus
444238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * some build system changes. I prefer not to do that for now for reasons
445238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * of simplicity.
446238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         */
4470b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner         kernelFileLen = strlen(kernelFile);
448238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         if (kernelFileLen > 6 && !memcmp(kernelFile + kernelFileLen - 6, "-armv7", 6)) {
4492ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner             forceArmv7 = 1;
450238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         }
451238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner    }
4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
453b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    if (boot_prop_ip[0]) {
454b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        args[n++] = "-boot-property";
455b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        args[n++] = boot_prop_ip;
456b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    }
457b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine
458318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine    if (opts->tcpdump) {
459318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine        args[n++] = "-tcpdump";
460318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine        args[n++] = opts->tcpdump;
461318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine    }
462318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine
463e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine#ifdef CONFIG_NAND_LIMITS
464e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    if (opts->nand_limits) {
465e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        args[n++] = "-nand-limits";
466e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        args[n++] = opts->nand_limits;
467e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    }
468e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine#endif
469e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
47074d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner    if (opts->timezone) {
47174d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner        args[n++] = "-timezone";
47274d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner        args[n++] = opts->timezone;
47374d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner    }
47474d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner
475e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    if (opts->netspeed) {
476e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        args[n++] = "-netspeed";
477e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        args[n++] = opts->netspeed;
478e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    }
479e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    if (opts->netdelay) {
480e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        args[n++] = "-netdelay";
481e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        args[n++] = opts->netdelay;
482e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    }
483e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    if (opts->netfast) {
484e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        args[n++] = "-netfast";
485e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    }
486e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
487b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    if (opts->audio) {
488b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        args[n++] = "-audio";
489b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        args[n++] = opts->audio;
490b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    }
491b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
492b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    if (opts->cpu_delay) {
493b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        args[n++] = "-cpu-delay";
494b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        args[n++] = opts->cpu_delay;
495b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    }
496b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
4977fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    if (opts->dns_server) {
4987fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        args[n++] = "-dns-server";
4997fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        args[n++] = opts->dns_server;
5007fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    }
5017fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
5029ff69721d24f81317183ddb2e9e352bb34650752David 'Digit' Turner    /* opts->ramdisk is never NULL (see createAVD) here */
5039ff69721d24f81317183ddb2e9e352bb34650752David 'Digit' Turner    if (opts->ramdisk) {
5049ff69721d24f81317183ddb2e9e352bb34650752David 'Digit' Turner        AFREE(hw->disk_ramdisk_path);
5059ff69721d24f81317183ddb2e9e352bb34650752David 'Digit' Turner        hw->disk_ramdisk_path = ASTRDUP(opts->ramdisk);
5069ff69721d24f81317183ddb2e9e352bb34650752David 'Digit' Turner    }
5079ff69721d24f81317183ddb2e9e352bb34650752David 'Digit' Turner    else if (!hw->disk_ramdisk_path[0]) {
5089ff69721d24f81317183ddb2e9e352bb34650752David 'Digit' Turner        hw->disk_ramdisk_path = avdInfo_getRamdiskPath(avd);
5099ff69721d24f81317183ddb2e9e352bb34650752David 'Digit' Turner        D("autoconfig: -ramdisk %s", hw->disk_ramdisk_path);
5109ff69721d24f81317183ddb2e9e352bb34650752David 'Digit' Turner    }
5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
51240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    /* -partition-size is used to specify the max size of both the system
51340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner     * and data partition sizes.
51440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner     */
51540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    if (opts->partition_size) {
51640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        char*  end;
51740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        long   sizeMB = strtol(opts->partition_size, &end, 0);
51840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        long   minSizeMB = 10;
51940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        long   maxSizeMB = LONG_MAX / ONE_MB;
52040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
52140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        if (sizeMB < 0 || *end != 0) {
52240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            derror( "-partition-size must be followed by a positive integer" );
52340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            exit(1);
52440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        }
52540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        if (sizeMB < minSizeMB || sizeMB > maxSizeMB) {
52640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            derror( "partition-size (%d) must be between %dMB and %dMB",
52740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                    sizeMB, minSizeMB, maxSizeMB );
52840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            exit(1);
52940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        }
53040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        defaultPartitionSize = (uint64_t) sizeMB * ONE_MB;
53140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    }
53240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
53340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
53440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    /** SYSTEM PARTITION **/
53540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
53640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    if (opts->sysdir == NULL) {
53740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        if (avdInfo_inAndroidBuild(avd)) {
53840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            opts->sysdir = ASTRDUP(avdInfo_getContentPath(avd));
53940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            D("autoconfig: -sysdir %s", opts->sysdir);
54040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        }
54140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    }
54240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
54340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    if (opts->sysdir != NULL) {
54440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        if (!path_exists(opts->sysdir)) {
54540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            derror("Directory does not exist: %s", opts->sysdir);
54640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            exit(1);
54740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        }
54840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    }
54940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
55140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        char*  rwImage   = NULL;
55240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        char*  initImage = NULL;
55340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
55440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        do {
55540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            if (opts->system == NULL) {
55640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                /* If -system is not used, try to find a runtime system image
55740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                * (i.e. system-qemu.img) in the content directory.
55840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                */
55940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                rwImage = avdInfo_getSystemImagePath(avd);
56040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                if (rwImage != NULL) {
56140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                    break;
56240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                }
56340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                /* Otherwise, try to find the initial system image */
56440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                initImage = avdInfo_getSystemInitImagePath(avd);
56540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                if (initImage == NULL) {
56640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                    derror("No initial system image for this configuration!");
56740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                    exit(1);
56840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                }
56940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                break;
57040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            }
5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
57240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            /* If -system <name> is used, use it to find the initial image */
573ea2837728272b04bd236a74cd1ea547ec6f63c20David 'Digit' Turner            if (opts->sysdir != NULL && !path_exists(opts->system)) {
57440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                initImage = _getFullFilePath(opts->sysdir, opts->system);
57540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            } else {
57640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                initImage = ASTRDUP(opts->system);
57740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            }
57840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            if (!path_exists(initImage)) {
57940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                derror("System image file doesn't exist: %s", initImage);
58040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                exit(1);
58140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            }
5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
58340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        } while (0);
58440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
58540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        if (rwImage != NULL) {
58640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            /* Use the read/write image file directly */
58740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            hw->disk_systemPartition_path     = rwImage;
58840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            hw->disk_systemPartition_initPath = NULL;
58940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            D("Using direct system image: %s", rwImage);
59040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        } else if (initImage != NULL) {
59140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            hw->disk_systemPartition_path = NULL;
59240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            hw->disk_systemPartition_initPath = initImage;
59340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            D("Using initial system image: %s", initImage);
59440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        }
5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
59640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        /* Check the size of the system partition image.
59740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        * If we have an AVD, it must be smaller than
59840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        * the disk.systemPartition.size hardware property.
59940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        *
60040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        * Otherwise, we need to adjust the systemPartitionSize
60140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        * automatically, and print a warning.
60240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        *
60340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        */
60440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        const char* systemImage = hw->disk_systemPartition_path;
60540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        uint64_t    systemBytes;
60640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
60740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        if (systemImage == NULL)
60840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            systemImage = hw->disk_systemPartition_initPath;
60940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
61040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        if (path_get_size(systemImage, &systemBytes) < 0) {
61140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            derror("Missing system image: %s", systemImage);
61240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            exit(1);
61340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        }
61440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
61540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        hw->disk_systemPartition_size =
61640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            _adjustPartitionSize("system", systemBytes, defaultPartitionSize,
61740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                                 avdInfo_inAndroidBuild(avd));
6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
62040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    /** DATA PARTITION **/
62140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
622fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner    if (opts->datadir) {
623fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        if (!path_exists(opts->datadir)) {
624fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            derror("Invalid -datadir directory: %s", opts->datadir);
625fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        }
626fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner    }
627fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
628fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner    {
629fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        char*  dataImage = NULL;
630fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        char*  initImage = NULL;
631fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
632fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        do {
633fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            if (!opts->data) {
634fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                dataImage = avdInfo_getDataImagePath(avd);
635fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                if (dataImage != NULL) {
636fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                    D("autoconfig: -data %s", dataImage);
637fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                    break;
638fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                }
639fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                dataImage = avdInfo_getDefaultDataImagePath(avd);
640fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                if (dataImage == NULL) {
641fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                    derror("No data image path for this configuration!");
642fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                    exit (1);
643fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                }
644fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                opts->wipe_data = 1;
645fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                break;
646fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            }
6478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
648fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            if (opts->datadir) {
649fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                dataImage = _getFullFilePath(opts->datadir, opts->data);
650fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            } else {
651fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                dataImage = ASTRDUP(opts->data);
652fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            }
653fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        } while (0);
654fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
655fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        if (opts->initdata != NULL) {
656fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            initImage = ASTRDUP(opts->initdata);
657fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            if (!path_exists(initImage)) {
658fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                derror("Invalid initial data image path: %s", initImage);
659fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                exit(1);
660fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            }
661fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        } else {
662fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            initImage = avdInfo_getDataInitImagePath(avd);
663fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            D("autoconfig: -initdata %s", initImage);
664fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        }
665fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
666fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        hw->disk_dataPartition_path = dataImage;
667fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        if (opts->wipe_data) {
668fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            hw->disk_dataPartition_initPath = initImage;
669fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        } else {
670fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            hw->disk_dataPartition_initPath = NULL;
671fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        }
672fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
673f758411e012389b1d9699e10cae6f1ac98cca419Maciek Molerus        uint64_t     defaultBytes =
674f758411e012389b1d9699e10cae6f1ac98cca419Maciek Molerus                hw->disk_dataPartition_size == 0 ?
675f758411e012389b1d9699e10cae6f1ac98cca419Maciek Molerus                defaultPartitionSize :
676d4f5a3ae87a7246613188940c1667bf2880da402Vladimir Chtchetkine                hw->disk_dataPartition_size;
677fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        uint64_t     dataBytes;
678fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        const char*  dataPath = hw->disk_dataPartition_initPath;
679fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
680fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        if (dataPath == NULL)
681fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            dataPath = hw->disk_dataPartition_path;
682fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
683fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        path_get_size(dataPath, &dataBytes);
684fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
685fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        hw->disk_dataPartition_size =
686fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            _adjustPartitionSize("data", dataBytes, defaultBytes,
687fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                                 avdInfo_inAndroidBuild(avd));
688fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner    }
6898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
690c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner    /** CACHE PARTITION **/
691c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner
692c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner    if (opts->no_cache) {
693c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        /* No cache partition at all */
694c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        hw->disk_cachePartition = 0;
6958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
696c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner    else if (!hw->disk_cachePartition) {
697c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        if (opts->cache) {
698c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner            dwarning( "Emulated hardware doesn't support a cache partition. -cache option ignored!" );
699c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner            opts->cache = NULL;
700c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        }
7018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
702c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner    else
703c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner    {
704c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        if (!opts->cache) {
705c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner            /* Find the current cache partition file */
706c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner            opts->cache = avdInfo_getCachePath(avd);
707c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner            if (opts->cache == NULL) {
708c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner                /* The file does not exists, we will force its creation
709c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner                 * if we are not in the Android build system. Otherwise,
710c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner                 * a temporary file will be used.
711c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner                 */
712c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner                if (!avdInfo_inAndroidBuild(avd)) {
713c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner                    opts->cache = avdInfo_getDefaultCachePath(avd);
714c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner                }
715c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner            }
71648a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            if (opts->cache) {
71748a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                D("autoconfig: -cache %s", opts->cache);
71848a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            }
719c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        }
7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
721c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        if (opts->cache) {
722c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner            hw->disk_cachePartition_path = ASTRDUP(opts->cache);
723c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        }
7248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
726c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner    /** SD CARD PARTITION */
727c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner
72848a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner    if (!hw->hw_sdCard) {
72948a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner        /* No SD Card emulation, so -sdcard will be ignored */
73048a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner        if (opts->sdcard) {
73148a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            dwarning( "Emulated hardware doesn't support SD Cards. -sdcard option ignored." );
73248a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            opts->sdcard = NULL;
73348a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner        }
73448a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner    } else {
73548a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner        /* Auto-configure -sdcard if it is not available */
73648a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner        if (!opts->sdcard) {
73748a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            do {
73848a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                /* If -datadir <path> is used, look for a sdcard.img file here */
73948a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                if (opts->datadir) {
74048a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                    bufprint(tmp, tmpend, "%s/%s", opts->datadir, "system.img");
74148a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                    if (path_exists(tmp)) {
74248a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                        opts->sdcard = strdup(tmp);
74348a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                        break;
74448a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                    }
74548a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                }
74648a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner
74748a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                /* Otherwise, look at the AVD's content */
74848a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                opts->sdcard = avdInfo_getSdCardPath(avd);
74948a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                if (opts->sdcard != NULL) {
75048a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                    break;
75148a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                }
75248a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner
75348a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                /* Nothing */
75448a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            } while (0);
75548a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner
75648a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            if (opts->sdcard) {
75748a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                D("autoconfig: -sdcard %s", opts->sdcard);
75848a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            }
75948a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner        }
7608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if(opts->sdcard) {
7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint64_t  size;
7648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (path_get_size(opts->sdcard, &size) == 0) {
7658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* see if we have an sdcard image.  get its size if it exists */
7668b657e5deaa03b989b0b36791fcf2aa6b2882656David 'Digit' Turner            /* due to what looks like limitations of the MMC protocol, one has
7678b657e5deaa03b989b0b36791fcf2aa6b2882656David 'Digit' Turner             * to use an SD Card image that is equal or larger than 9 MB
7688b657e5deaa03b989b0b36791fcf2aa6b2882656David 'Digit' Turner             */
7698b657e5deaa03b989b0b36791fcf2aa6b2882656David 'Digit' Turner            if (size < 9*1024*1024ULL) {
7708b657e5deaa03b989b0b36791fcf2aa6b2882656David 'Digit' Turner                fprintf(stderr, "### WARNING: SD Card files must be at least 9MB, ignoring '%s'\n", opts->sdcard);
7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
77248a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                hw->hw_sdCard_path = ASTRDUP(opts->sdcard);
7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
7748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
77548a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            dwarning("no SD Card image at '%s'", opts->sdcard);
7768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
77948a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner
78048a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner    /** SNAPSHOT STORAGE HANDLING */
78148a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner
7825f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    /* Determine snapstorage path. -no-snapstorage disables all snapshotting
7835f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner     * support. This means you can't resume a snapshot at load, save it at
7845f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner     * exit, or even load/save them dynamically at runtime with the console.
7855f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner     */
7865f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    if (opts->no_snapstorage) {
7875f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
7885f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        if (opts->snapshot) {
7895f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            dwarning("ignoring -snapshot option due to the use of -no-snapstorage");
7905f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            opts->snapshot = NULL;
7915f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        }
7925f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
7935f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        if (opts->snapstorage) {
7945f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            dwarning("ignoring -snapstorage option due to the use of -no-snapstorage");
7955f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            opts->snapstorage = NULL;
7965f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        }
7975f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    }
7985f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    else
7995f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    {
800873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine        if (!opts->snapstorage && avdInfo_getSnapshotPresent(avd)) {
8015f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            opts->snapstorage = avdInfo_getSnapStoragePath(avd);
8025f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            if (opts->snapstorage != NULL) {
8035f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner                D("autoconfig: -snapstorage %s", opts->snapstorage);
804353b3b1135563e2bcaf7797acfa35a2fe2d3a818Ot ten Thije            }
805353b3b1135563e2bcaf7797acfa35a2fe2d3a818Ot ten Thije        }
806353b3b1135563e2bcaf7797acfa35a2fe2d3a818Ot ten Thije
8075f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        if (opts->snapstorage && !path_exists(opts->snapstorage)) {
8085f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            D("no image at '%s', state snapshots disabled", opts->snapstorage);
8095f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            opts->snapstorage = NULL;
8105f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        }
8115f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    }
8125f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
8135f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    /* If we have a valid snapshot storage path */
8145f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
8155f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    if (opts->snapstorage) {
8165f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
8175f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        hw->disk_snapStorage_path = ASTRDUP(opts->snapstorage);
8185f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
8195f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        /* -no-snapshot is equivalent to using both -no-snapshot-load
8205f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        * and -no-snapshot-save. You can still load/save snapshots dynamically
8215f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        * from the console though.
8225f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        */
8235f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        if (opts->no_snapshot) {
8245f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
8255f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            opts->no_snapshot_load = 1;
8265f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            opts->no_snapshot_save = 1;
8275f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
8285f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            if (opts->snapshot) {
8295f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner                dwarning("ignoring -snapshot option due to the use of -no-snapshot.");
83053d8a5c0c8fc087d16316a4399f5a773339c4956Tim Baverstock            }
8315f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        }
8325f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
8335f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        if (!opts->no_snapshot_load || !opts->no_snapshot_save) {
8345f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            if (opts->snapshot == NULL) {
8355f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner                opts->snapshot = "default-boot";
8365f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner                D("autoconfig: -snapshot %s", opts->snapshot);
837353b3b1135563e2bcaf7797acfa35a2fe2d3a818Ot ten Thije            }
838353b3b1135563e2bcaf7797acfa35a2fe2d3a818Ot ten Thije        }
8395f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
8405f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        /* We still use QEMU command-line options for the following since
8415f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        * they can change from one invokation to the next and don't really
8425f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        * correspond to the hardware configuration itself.
8435f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        */
8445f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        if (!opts->no_snapshot_load) {
8455f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            args[n++] = "-loadvm";
8465f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            args[n++] = ASTRDUP(opts->snapshot);
8475f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        }
8485f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
8495f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        if (!opts->no_snapshot_save) {
8505f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            args[n++] = "-savevm-on-exit";
8515f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            args[n++] = ASTRDUP(opts->snapshot);
8525f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        }
8535f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
854622b8f4c760b8c4479d28430f978bad8bb9ea32cTim Baverstock        if (opts->no_snapshot_update_time) {
855bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner            args[n++] = "-snapshot-no-time-update";
856622b8f4c760b8c4479d28430f978bad8bb9ea32cTim Baverstock        }
857ae835acc2d1a8b4aaeb599add9cfc02ea5789eafOt ten Thije    }
858353b3b1135563e2bcaf7797acfa35a2fe2d3a818Ot ten Thije
8598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!opts->logcat || opts->logcat[0] == 0) {
8608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        opts->logcat = getenv("ANDROID_LOG_TAGS");
8618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (opts->logcat && opts->logcat[0] == 0)
8628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            opts->logcat = NULL;
8638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* we always send the kernel messages from ttyS0 to android_kmsg */
866062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    if (opts->show_kernel) {
867062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        args[n++] = "-show-kernel";
8688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXXX: TODO: implement -shell and -logcat through qemud instead */
8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!opts->shell_serial) {
8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        opts->shell_serial = "con:";
8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        opts->shell_serial = "stdio";
8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else
8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        opts->shell = 1;
8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (opts->shell || opts->logcat) {
8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args[n++] = "-serial";
8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args[n++] = opts->shell_serial;
8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shell_serial = serial++;
8858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
887062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    if (opts->radio) {
888062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        args[n++] = "-radio";
889062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        args[n++] = opts->radio;
8908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
892062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    if (opts->gps) {
893062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        args[n++] = "-gps";
894062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        args[n++] = opts->gps;
8958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (opts->memory) {
8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char*  end;
8998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        long   ramSize = strtol(opts->memory, &end, 0);
9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ramSize < 0 || *end != 0) {
9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            derror( "-memory must be followed by a positive integer" );
9028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            exit(1);
9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
9048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ramSize < 32 || ramSize > 4096) {
9058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            derror( "physical memory size must be between 32 and 4096 MB" );
9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            exit(1);
9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
9085377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        hw->hw_ramSize = ramSize;
9098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!opts->memory) {
9113bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner        int ramSize = hw->hw_ramSize;
9123bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner        if (ramSize <= 0) {
9133bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner            /* Compute the default RAM size based on the size of screen.
9143bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             * This is only used when the skin doesn't provide the ram
9153bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             * size through its hardware.ini (i.e. legacy ones) or when
9163bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             * in the full Android build system.
9173bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             */
9185377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner            int64_t pixels  = hw->hw_lcd_width * hw->hw_lcd_height;
9193bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner            /* The following thresholds are a bit liberal, but we
9203bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             * essentially want to ensure the following mappings:
9213bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             *
9223bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             *   320x480 -> 96
9233bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             *   800x600 -> 128
9243bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             *  1024x768 -> 256
9253bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             *
9263bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             * These are just simple heuristics, they could change in
9273bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             * the future.
9283bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             */
9293bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner            if (pixels <= 250000)
9303bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner                ramSize = 96;
9313bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner            else if (pixels <= 500000)
9323bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner                ramSize = 128;
9333bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner            else
9343bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner                ramSize = 256;
9353bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner        }
9365377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        hw->hw_ramSize = ramSize;
9375377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner    }
9385377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner
9395377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner    D("Physical RAM size: %dMB\n", hw->hw_ramSize);
9405377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner
9415377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner    if (hw->vm_heapSize == 0) {
9425377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        /* Compute the default heap size based on the RAM size.
9435377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner         * Essentially, we want to ensure the following liberal mappings:
9445377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner         *
9455377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner         *   96MB RAM -> 16MB heap
9465377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner         *  128MB RAM -> 24MB heap
9475377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner         *  256MB RAM -> 48MB heap
9485377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner         */
9495377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        int  ramSize = hw->hw_ramSize;
9505377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        int  heapSize;
9515377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner
9525377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        if (ramSize < 100)
9535377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner            heapSize = 16;
9545377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        else if (ramSize < 192)
9555377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner            heapSize = 24;
9565377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        else
9575377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner            heapSize = 48;
9585377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner
9595377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        hw->vm_heapSize = heapSize;
9608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (opts->trace) {
9638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args[n++] = "-trace";
9648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args[n++] = opts->trace;
9658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args[n++] = "-tracing";
9668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args[n++] = "off";
9678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
969b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    /* Pass boot properties to the core. */
970b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    if (opts->prop != NULL) {
971b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        ParamList*  pl = opts->prop;
972b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        for ( ; pl != NULL; pl = pl->next ) {
973b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine            args[n++] = "-boot-property";
974b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine            args[n++] = pl->param;
975b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        }
976b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    }
977b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine
978318e4f294c181df33cf2541763904565b29bcccbDavid 'Digit' Turner    /* Setup the kernel init options
979318e4f294c181df33cf2541763904565b29bcccbDavid 'Digit' Turner     */
9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        static char  params[1024];
9828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char        *p = params, *end = p + sizeof(params);
9838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
984062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        /* Don't worry about having a leading space here, this is handled
985062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner         * by the core later. */
986062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner
987334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima#ifdef TARGET_I386
988334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima        p = bufprint(p, end, " androidboot.hardware=goldfish");
989bac9add881e0b7cfa2da2b86242347c096329a4cJun Nakajima        p = bufprint(p, end, " clocksource=pit");
990334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima#endif
9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (opts->shell || opts->logcat) {
9938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = bufprint(p, end, " androidboot.console=ttyS%d", shell_serial );
9948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (opts->trace) {
9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = bufprint(p, end, " android.tracing=1");
9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!opts->no_jni) {
10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = bufprint(p, end, " android.checkjni=1");
10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (opts->no_boot_anim) {
10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = bufprint( p, end, " android.bootanim=0" );
10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (opts->logcat) {
10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            char*  q = bufprint(p, end, " androidboot.logcat=%s", opts->logcat);
10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (q < end) {
10128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* replace any space by a comma ! */
10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                {
10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  nn;
10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    for (nn = 1; p[nn] != 0; nn++)
10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if (p[nn] == ' ' || p[nn] == '\t')
10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            p[nn] = ',';
10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    p += nn;
10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
10208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = q;
10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (opts->bootchart) {
10258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = bufprint(p, end, " androidboot.bootchart=%s", opts->bootchart);
10268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (p >= end) {
10298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(stderr, "### ERROR: kernel parameters too long\n");
10308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            exit(1);
10318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10330b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        hw->kernel_parameters = strdup(params);
10348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1036d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    if (opts->ports) {
1037d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        args[n++] = "-android-ports";
1038d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        args[n++] = opts->ports;
1039d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    }
1040d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
1041d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    if (opts->port) {
1042d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        args[n++] = "-android-port";
1043d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        args[n++] = opts->port;
1044d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    }
1045d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
1046d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    if (opts->report_console) {
1047d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        args[n++] = "-android-report-console";
1048d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        args[n++] = opts->report_console;
1049d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    }
1050d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
1051d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    if (opts->http_proxy) {
1052d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        args[n++] = "-http-proxy";
1053d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        args[n++] = opts->http_proxy;
1054d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    }
1055d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
105672d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet    if (!opts->charmap) {
105772d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        /* Try to find a valid charmap name */
105872d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        char* charmap = avdInfo_getCharmapFile(avd, hw->hw_keyboard_charmap);
105972d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        if (charmap != NULL) {
106072d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet            D("autoconfig: -charmap %s", charmap);
106172d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet            opts->charmap = charmap;
106272d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        }
106372d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet    }
106472d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet
106543552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine    if (opts->charmap) {
106672d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        char charmap_name[AKEYCHARMAP_NAME_SIZE];
106772d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet
106872d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        if (!path_exists(opts->charmap)) {
106972d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet            derror("Charmap file does not exist: %s", opts->charmap);
107072d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet            exit(1);
107172d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        }
107272d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        /* We need to store the charmap name in the hardware configuration.
107372d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet         * However, the charmap file itself is only used by the UI component
107472d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet         * and doesn't need to be set to the emulation engine.
107572d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet         */
107672d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        kcm_extract_charmap_name(opts->charmap, charmap_name,
107772d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet                                 sizeof(charmap_name));
107872d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        AFREE(hw->hw_keyboard_charmap);
107972d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        hw->hw_keyboard_charmap = ASTRDUP(charmap_name);
108043552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine    }
108143552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine
1082b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine    if (opts->memcheck) {
1083b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine        args[n++] = "-android-memcheck";
1084b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine        args[n++] = opts->memcheck;
1085b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine    }
1086b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine
10879da935dd0c616cfd9072d11080a622320497dc9eDavid Turner    if (opts->gpu) {
10889da935dd0c616cfd9072d11080a622320497dc9eDavid Turner        const char* gpu = opts->gpu;
1089ae0d8136ce0d3c39ca80c64763e633b86b0c5453Vladimir Chtchetkine        if (!strcmp(gpu,"on") || !strcmp(gpu,"enable")) {
10909da935dd0c616cfd9072d11080a622320497dc9eDavid Turner            hw->hw_gpu_enabled = 1;
1091ae0d8136ce0d3c39ca80c64763e633b86b0c5453Vladimir Chtchetkine        } else if (!strcmp(gpu,"off") || !strcmp(gpu,"disable")) {
10929da935dd0c616cfd9072d11080a622320497dc9eDavid Turner            hw->hw_gpu_enabled = 0;
10939da935dd0c616cfd9072d11080a622320497dc9eDavid Turner        } else if (!strcmp(gpu,"auto")) {
10949da935dd0c616cfd9072d11080a622320497dc9eDavid Turner            /* Nothing to do */
10959da935dd0c616cfd9072d11080a622320497dc9eDavid Turner        } else {
10969da935dd0c616cfd9072d11080a622320497dc9eDavid Turner            derror("Invalid value for -gpu <mode> parameter: %s\n", gpu);
10979da935dd0c616cfd9072d11080a622320497dc9eDavid Turner            derror("Valid values are: on, off or auto\n");
10989da935dd0c616cfd9072d11080a622320497dc9eDavid Turner            exit(1);
10999da935dd0c616cfd9072d11080a622320497dc9eDavid Turner        }
11009da935dd0c616cfd9072d11080a622320497dc9eDavid Turner    }
11019da935dd0c616cfd9072d11080a622320497dc9eDavid Turner
11029242b33d3545e6632d21c1f416794a9f5d385c45Vladimir Chtchetkine    /* Quit emulator on condition that both, gpu and snapstorage are on. This is
11039242b33d3545e6632d21c1f416794a9f5d385c45Vladimir Chtchetkine     * a temporary solution preventing the emulator from crashing until GPU state
11049242b33d3545e6632d21c1f416794a9f5d385c45Vladimir Chtchetkine     * can be properly saved / resored in snapshot file. */
11059242b33d3545e6632d21c1f416794a9f5d385c45Vladimir Chtchetkine    if (hw->hw_gpu_enabled && opts->snapstorage && (!opts->no_snapshot_load ||
11069242b33d3545e6632d21c1f416794a9f5d385c45Vladimir Chtchetkine                                                    !opts->no_snapshot_save)) {
11079242b33d3545e6632d21c1f416794a9f5d385c45Vladimir Chtchetkine        derror("Snapshots and gpu are mutually exclusive at this point. Please turn one of them off, and restart the emulator.");
11089242b33d3545e6632d21c1f416794a9f5d385c45Vladimir Chtchetkine        exit(1);
11099242b33d3545e6632d21c1f416794a9f5d385c45Vladimir Chtchetkine    }
11109242b33d3545e6632d21c1f416794a9f5d385c45Vladimir Chtchetkine
11117485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine    /* Deal with camera emulation */
11127485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine    if (opts->webcam_list) {
11137485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine        /* List connected webcameras */
11147485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine        args[n++] = "-list-webcam";
11157485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine    }
11167485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine
11177485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine    if (opts->camera_back) {
11187485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine        /* Validate parameter. */
11197485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine        if (memcmp(opts->camera_back, "webcam", 6) &&
11207485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine            strcmp(opts->camera_back, "emulated") &&
11217485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine            strcmp(opts->camera_back, "none")) {
11227485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine            derror("Invalid value for -camera-back <mode> parameter: %s\n"
11237485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine                   "Valid values are: 'emulated', 'webcam<N>', or 'none'\n",
11247485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine                   opts->camera_back);
1125ae0d8136ce0d3c39ca80c64763e633b86b0c5453Vladimir Chtchetkine            exit(1);
1126ae0d8136ce0d3c39ca80c64763e633b86b0c5453Vladimir Chtchetkine        }
11277485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine        hw->hw_camera_back = ASTRDUP(opts->camera_back);
1128ae0d8136ce0d3c39ca80c64763e633b86b0c5453Vladimir Chtchetkine    }
1129ae0d8136ce0d3c39ca80c64763e633b86b0c5453Vladimir Chtchetkine
11307485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine    if (opts->camera_front) {
11317485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine        /* Validate parameter. */
11327485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine        if (memcmp(opts->camera_front, "webcam", 6) &&
11337485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine            strcmp(opts->camera_front, "emulated") &&
11347485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine            strcmp(opts->camera_front, "none")) {
11357485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine            derror("Invalid value for -camera-front <mode> parameter: %s\n"
11367485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine                   "Valid values are: 'emulated', 'webcam<N>', or 'none'\n",
11377485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine                   opts->camera_front);
11387485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine            exit(1);
1139f8675c20db7625adc69800ca4ac54e72846ac9a8Vladimir Chtchetkine        }
11407485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine        hw->hw_camera_front = ASTRDUP(opts->camera_front);
1141f8675c20db7625adc69800ca4ac54e72846ac9a8Vladimir Chtchetkine    }
1142f8675c20db7625adc69800ca4ac54e72846ac9a8Vladimir Chtchetkine
11435377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner    /* physical memory is now in hw->hw_ramSize */
11448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
114553eb66db4eba72d2e4fc951456be725e14243f25David 'Digit' Turner    hw->avd_name = ASTRDUP(avdInfo_getName(avd));
11466b8555cac04862908bf6c64565061f2c8e871ad7David 'Digit' Turner
114740beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie    /* Set up the interfaces for inter-emulator networking */
114840beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie    if (opts->shared_net_id) {
114940beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        unsigned int shared_net_id = atoi(opts->shared_net_id);
115040beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        char nic[37];
115140beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie
115240beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        args[n++] = "-net";
115340beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        args[n++] = "nic,vlan=0";
115440beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        args[n++] = "-net";
115540beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        args[n++] = "user,vlan=0";
1156111d6f8ed6dea6e651ab450e1ea11310ff0b2857Dries Harnie
1157111d6f8ed6dea6e651ab450e1ea11310ff0b2857Dries Harnie        args[n++] = "-net";
1158111d6f8ed6dea6e651ab450e1ea11310ff0b2857Dries Harnie        snprintf(nic, sizeof nic, "nic,vlan=1,macaddr=52:54:00:12:34:%02x", shared_net_id);
1159111d6f8ed6dea6e651ab450e1ea11310ff0b2857Dries Harnie        args[n++] = strdup(nic);
1160111d6f8ed6dea6e651ab450e1ea11310ff0b2857Dries Harnie        args[n++] = "-net";
1161111d6f8ed6dea6e651ab450e1ea11310ff0b2857Dries Harnie        args[n++] = "socket,vlan=1,mcast=230.0.0.10:1234";
116240beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie    }
116340beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie
11648dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine    /* Setup screen emulation */
11658dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine    if (opts->screen) {
1166863d1010d9c8fa4342b1b0ea860bcfb096806accVladimir Chtchetkine        if (strcmp(opts->screen, "touch") &&
1167863d1010d9c8fa4342b1b0ea860bcfb096806accVladimir Chtchetkine            strcmp(opts->screen, "multi-touch") &&
1168863d1010d9c8fa4342b1b0ea860bcfb096806accVladimir Chtchetkine            strcmp(opts->screen, "no-touch")) {
1169863d1010d9c8fa4342b1b0ea860bcfb096806accVladimir Chtchetkine
1170863d1010d9c8fa4342b1b0ea860bcfb096806accVladimir Chtchetkine            derror("Invalid value for -screen <mode> parameter: %s\n"
1171863d1010d9c8fa4342b1b0ea860bcfb096806accVladimir Chtchetkine                   "Valid values are: touch, multi-touch, or no-touch\n",
1172863d1010d9c8fa4342b1b0ea860bcfb096806accVladimir Chtchetkine                   opts->screen);
11738dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine            exit(1);
11748dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine        }
1175863d1010d9c8fa4342b1b0ea860bcfb096806accVladimir Chtchetkine        hw->hw_screen = ASTRDUP(opts->screen);
11768dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine    }
11778dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine
11788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while(argc-- > 0) {
11798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args[n++] = *argv++;
11808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    args[n] = 0;
11828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11832ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    /* If the target ABI is armeabi-v7a, we can auto-detect the cpu model
11842ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner     * as a cortex-a8, instead of the default (arm926) which only emulates
11852ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner     * an ARMv5TE CPU.
11862ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner     */
11872ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    if (!forceArmv7 && hw->hw_cpu_model[0] == '\0')
11882ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    {
11892ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner        char* abi = avdInfo_getTargetAbi(avd);
11902ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner        if (abi != NULL) {
11912ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner            if (!strcmp(abi, "armeabi-v7a")) {
11922ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner                forceArmv7 = 1;
11932ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner            }
11942ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner            AFREE(abi);
11952ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner        }
11962ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    }
11972ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner
11982ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    if (forceArmv7 != 0) {
11992ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner        AFREE(hw->hw_cpu_model);
12002ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner        hw->hw_cpu_model = ASTRDUP("cortex-a8");
12012ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner        D("Auto-config: -qemu -cpu %s", hw->hw_cpu_model);
12022ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    }
12032ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner
120426d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner    /* Generate a hardware-qemu.ini for this AVD. The real hardware
1205622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner     * configuration is ususally stored in several files, e.g. the AVD's
1206622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner     * config.ini plus the skin-specific hardware.ini.
1207622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner     *
120826d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner     * The new file will group all definitions and will be used to
1209622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner     * launch the core with the -android-hw <file> option.
1210622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner     */
1211622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    {
121242074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner        const char* coreHwIniPath = avdInfo_getCoreHwIniPath(avd);
121342074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner        IniFile*    hwIni         = iniFile_newFromMemory("", NULL);
1214622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner        androidHwConfig_write(hw, hwIni);
121526d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner
121626d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner        if (filelock_create(coreHwIniPath) == NULL) {
121726d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner            /* The AVD is already in use, we still support this as an
121826d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner             * experimental feature. Use a temporary hardware-qemu.ini
121926d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner             * file though to avoid overwriting the existing one. */
122026d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner             TempFile*  tempIni = tempfile_create();
122126d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner             coreHwIniPath = tempfile_path(tempIni);
122226d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner        }
122326d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner
1224db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine        /* While saving HW config, ignore valueless entries. This will not break
1225db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine         * anything, but will significantly simplify comparing the current HW
1226db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine         * config with the one that has been associated with a snapshot (in case
1227db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine         * VM starts from a snapshot for this instance of emulator). */
1228db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine        if (iniFile_saveToFileClean(hwIni, coreHwIniPath) < 0) {
122942074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner            derror("Could not write hardware.ini to %s: %s", coreHwIniPath, strerror(errno));
1230622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner            exit(2);
1231622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner        }
1232622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner        args[n++] = "-android-hw";
123342074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner        args[n++] = strdup(coreHwIniPath);
12340a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner
12350a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner        /* In verbose mode, dump the file's content */
12360a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner        if (VERBOSE_CHECK(init)) {
12370a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner            FILE* file = fopen(coreHwIniPath, "rt");
12380a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner            if (file == NULL) {
12390a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                derror("Could not open hardware configuration file: %s\n",
12400a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                       coreHwIniPath);
12410a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner            } else {
12420a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                LineInput* input = lineInput_newFromStdFile(file);
12430a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                const char* line;
12440a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                printf("Content of hardware configuration file:\n");
12450a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                while ((line = lineInput_getLine(input)) !=  NULL) {
12460a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                    printf("  %s\n", line);
12470a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                }
12480a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                printf(".\n");
12490a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                lineInput_free(input);
12500a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                fclose(file);
12510a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner            }
12520a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner        }
1253622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    }
1254622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner
12558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if(VERBOSE_CHECK(init)) {
12568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int i;
12573336176fc898915b7b5544f3a7c60ec2794507c3David 'Digit' Turner        printf("QEMU options list:\n");
12588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for(i = 0; i < n; i++) {
12593336176fc898915b7b5544f3a7c60ec2794507c3David 'Digit' Turner            printf("emulator: argv[%02d] = \"%s\"\n", i, args[i]);
12608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
12613336176fc898915b7b5544f3a7c60ec2794507c3David 'Digit' Turner        /* Dump final command-line option to make debugging the core easier */
12623336176fc898915b7b5544f3a7c60ec2794507c3David 'Digit' Turner        printf("Concatenated QEMU options:\n");
12633336176fc898915b7b5544f3a7c60ec2794507c3David 'Digit' Turner        for (i = 0; i < n; i++) {
126426722dde31c3467cd31a078662810927eec05de5David 'Digit' Turner            /* To make it easier to copy-paste the output to a command-line,
126526722dde31c3467cd31a078662810927eec05de5David 'Digit' Turner             * quote anything that contains spaces.
126626722dde31c3467cd31a078662810927eec05de5David 'Digit' Turner             */
126726722dde31c3467cd31a078662810927eec05de5David 'Digit' Turner            if (strchr(args[i], ' ') != NULL) {
126826722dde31c3467cd31a078662810927eec05de5David 'Digit' Turner                printf(" '%s'", args[i]);
126926722dde31c3467cd31a078662810927eec05de5David 'Digit' Turner            } else {
127026722dde31c3467cd31a078662810927eec05de5David 'Digit' Turner                printf(" %s", args[i]);
127126722dde31c3467cd31a078662810927eec05de5David 'Digit' Turner            }
12723336176fc898915b7b5544f3a7c60ec2794507c3David 'Digit' Turner        }
12733336176fc898915b7b5544f3a7c60ec2794507c3David 'Digit' Turner        printf("\n");
12748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
127574d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner
127674d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner    /* Setup SDL UI just before calling the code */
127774d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner    init_sdl_ui(skinConfig, skinPath, opts);
127874d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner
1279bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner    if (attach_ui_to_core(opts) < 0) {
1280bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner        derror("Can't attach to core!");
1281bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner        exit(1);
1282bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner    }
1283bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner
12848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return qemu_main(n, args);
12858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1286