main.c revision 88078b8875dab47abf9fe80488503f60d9835eaf
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);
3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Read hardware configuration */
3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    hw = android_hw;
326b64325d15d9e767c652491414c95f4fc148b0211David 'Digit' Turner    if (avdInfo_initHwConfig(avd, hw) < 0) {
3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        derror("could not read hardware configuration ?");
3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        exit(1);
3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (opts->keyset) {
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        parse_keyset(opts->keyset, opts);
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!android_keyset) {
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(stderr,
3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    "emulator: WARNING: could not find keyset file named '%s',"
3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    " using defaults instead\n",
3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    opts->keyset);
3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!android_keyset) {
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        parse_keyset("default", opts);
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!android_keyset) {
3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            android_keyset = skin_keyset_new_from_text( skin_keyset_get_default() );
3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!android_keyset) {
3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fprintf(stderr, "PANIC: default keyset file is corrupted !!\n" );
3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fprintf(stderr, "PANIC: please update the code in android/skin/keyset.c\n" );
3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                exit(1);
3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!opts->keyset)
3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                write_default_keyset();
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
35440beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie    if (opts->shared_net_id) {
35540beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        char*  end;
35640beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        long   shared_net_id = strtol(opts->shared_net_id, &end, 0);
35740beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        if (end == NULL || *end || shared_net_id < 1 || shared_net_id > 255) {
35840beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie            fprintf(stderr, "option -shared-net-id must be an integer between 1 and 255\n");
35940beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie            exit(1);
36040beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        }
361b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        snprintf(boot_prop_ip, sizeof(boot_prop_ip),
362b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine                 "net.shared_net_ip=10.1.2.%ld", shared_net_id);
36340beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie    }
36440beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie
36540beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie
366755811e67c266333807571f798b62b6916611f87David 'Digit' Turner    user_config_init();
3672507cab8a78fb609461a2b9cc4708bab60fc53a4David 'Digit' Turner    parse_skin_files(opts->skindir, opts->skin, opts, hw,
36874d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner                     &skinConfig, &skinPath);
3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
370092361e19ecc2992965729538984354099eea8cbDavid 'Digit' Turner    if (!opts->netspeed && skin_network_speed) {
371092361e19ecc2992965729538984354099eea8cbDavid 'Digit' Turner        D("skin network speed: '%s'", skin_network_speed);
372092361e19ecc2992965729538984354099eea8cbDavid 'Digit' Turner        if (strcmp(skin_network_speed, NETWORK_SPEED_DEFAULT) != 0) {
373092361e19ecc2992965729538984354099eea8cbDavid 'Digit' Turner            opts->netspeed = (char*)skin_network_speed;
374092361e19ecc2992965729538984354099eea8cbDavid 'Digit' Turner        }
3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
376092361e19ecc2992965729538984354099eea8cbDavid 'Digit' Turner    if (!opts->netdelay && skin_network_delay) {
377092361e19ecc2992965729538984354099eea8cbDavid 'Digit' Turner        D("skin network delay: '%s'", skin_network_delay);
378092361e19ecc2992965729538984354099eea8cbDavid 'Digit' Turner        if (strcmp(skin_network_delay, NETWORK_DELAY_DEFAULT) != 0) {
379092361e19ecc2992965729538984354099eea8cbDavid 'Digit' Turner            opts->netdelay = (char*)skin_network_delay;
380092361e19ecc2992965729538984354099eea8cbDavid 'Digit' Turner        }
3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (opts->trace) {
384cd059b15f2c7df69f4a087bd66900eb172e41d1cDavid 'Digit' Turner        char*   tracePath = avdInfo_getTracePath(avd, opts->trace);
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int     ret;
3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (tracePath == NULL) {
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            derror( "bad -trace parameter" );
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            exit(1);
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ret = path_mkdir_if_needed( tracePath, 0755 );
3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ret < 0) {
3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(stderr, "could not create directory '%s'\n", tmp);
3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            exit(2);
3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        opts->trace = tracePath;
3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
39933f89d05b375f18596fa5892acaaae356fbb0c0eVladimir Chtchetkine    /* Update CPU architecture for HW configs created from build dir. */
40033f89d05b375f18596fa5892acaaae356fbb0c0eVladimir Chtchetkine    if (inAndroidBuild) {
40133f89d05b375f18596fa5892acaaae356fbb0c0eVladimir Chtchetkine#if defined(TARGET_ARM)
40233f89d05b375f18596fa5892acaaae356fbb0c0eVladimir Chtchetkine        free(android_hw->hw_cpu_arch);
40333f89d05b375f18596fa5892acaaae356fbb0c0eVladimir Chtchetkine        android_hw->hw_cpu_arch = ASTRDUP("arm");
40433f89d05b375f18596fa5892acaaae356fbb0c0eVladimir Chtchetkine#elif defined(TARGET_I386)
40533f89d05b375f18596fa5892acaaae356fbb0c0eVladimir Chtchetkine        free(android_hw->hw_cpu_arch);
40633f89d05b375f18596fa5892acaaae356fbb0c0eVladimir Chtchetkine        android_hw->hw_cpu_arch = ASTRDUP("x86");
40733f89d05b375f18596fa5892acaaae356fbb0c0eVladimir Chtchetkine#endif
40833f89d05b375f18596fa5892acaaae356fbb0c0eVladimir Chtchetkine    }
40933f89d05b375f18596fa5892acaaae356fbb0c0eVladimir Chtchetkine
4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    n = 1;
4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* generate arguments for the underlying qemu main() */
412238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner    {
4130b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        char*  kernelFile    = opts->kernel;
4140b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        int    kernelFileLen;
4150b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner
4160b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        if (kernelFile == NULL) {
4170b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner            kernelFile = avdInfo_getKernelPath(avd);
4180b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner            if (kernelFile == NULL) {
4190b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner                derror( "This AVD's configuration is missing a kernel file!!" );
4200b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner                exit(2);
4210b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner            }
4220b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner            D("autoconfig: -kernel %s", kernelFile);
4230b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        }
4240b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        if (!path_exists(kernelFile)) {
4250b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner            derror( "Invalid or missing kernel image file: %s", kernelFile );
4260b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner            exit(2);
4270b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        }
428238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner
4290b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        hw->kernel_path = kernelFile;
430238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner
431238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner        /* If the kernel image name ends in "-armv7", then change the cpu
432238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * type automatically. This is a poor man's approach to configuration
433238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * management, but should allow us to get past building ARMv7
434238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * system images with dex preopt pass without introducing too many
435238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * changes to the emulator sources.
436238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         *
437238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * XXX:
438238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * A 'proper' change would require adding some sort of hardware-property
439238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * to each AVD config file, then automatically determine its value for
440238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * full Android builds (depending on some environment variable), plus
441238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * some build system changes. I prefer not to do that for now for reasons
442238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * of simplicity.
443238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         */
4440b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner         kernelFileLen = strlen(kernelFile);
445238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         if (kernelFileLen > 6 && !memcmp(kernelFile + kernelFileLen - 6, "-armv7", 6)) {
4462ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner             forceArmv7 = 1;
447238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         }
448238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner    }
4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
450b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    if (boot_prop_ip[0]) {
451b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        args[n++] = "-boot-property";
452b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        args[n++] = boot_prop_ip;
453b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    }
454b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine
455318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine    if (opts->tcpdump) {
456318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine        args[n++] = "-tcpdump";
457318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine        args[n++] = opts->tcpdump;
458318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine    }
459318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine
460e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine#ifdef CONFIG_NAND_LIMITS
461e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    if (opts->nand_limits) {
462e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        args[n++] = "-nand-limits";
463e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        args[n++] = opts->nand_limits;
464e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    }
465e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine#endif
466e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
46774d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner    if (opts->timezone) {
46874d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner        args[n++] = "-timezone";
46974d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner        args[n++] = opts->timezone;
47074d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner    }
47174d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner
472e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    if (opts->netspeed) {
473e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        args[n++] = "-netspeed";
474e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        args[n++] = opts->netspeed;
475e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    }
476e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    if (opts->netdelay) {
477e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        args[n++] = "-netdelay";
478e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        args[n++] = opts->netdelay;
479e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    }
480e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    if (opts->netfast) {
481e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        args[n++] = "-netfast";
482e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    }
483e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
484b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    if (opts->audio) {
485b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        args[n++] = "-audio";
486b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        args[n++] = opts->audio;
487b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    }
488b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
489b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    if (opts->cpu_delay) {
490b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        args[n++] = "-cpu-delay";
491b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        args[n++] = opts->cpu_delay;
492b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    }
493b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
4947fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    if (opts->dns_server) {
4957fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        args[n++] = "-dns-server";
4967fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        args[n++] = opts->dns_server;
4977fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    }
4987fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
4999ff69721d24f81317183ddb2e9e352bb34650752David 'Digit' Turner    /* opts->ramdisk is never NULL (see createAVD) here */
5009ff69721d24f81317183ddb2e9e352bb34650752David 'Digit' Turner    if (opts->ramdisk) {
5019ff69721d24f81317183ddb2e9e352bb34650752David 'Digit' Turner        AFREE(hw->disk_ramdisk_path);
5029ff69721d24f81317183ddb2e9e352bb34650752David 'Digit' Turner        hw->disk_ramdisk_path = ASTRDUP(opts->ramdisk);
5039ff69721d24f81317183ddb2e9e352bb34650752David 'Digit' Turner    }
5049ff69721d24f81317183ddb2e9e352bb34650752David 'Digit' Turner    else if (!hw->disk_ramdisk_path[0]) {
5059ff69721d24f81317183ddb2e9e352bb34650752David 'Digit' Turner        hw->disk_ramdisk_path = avdInfo_getRamdiskPath(avd);
5069ff69721d24f81317183ddb2e9e352bb34650752David 'Digit' Turner        D("autoconfig: -ramdisk %s", hw->disk_ramdisk_path);
5079ff69721d24f81317183ddb2e9e352bb34650752David 'Digit' Turner    }
5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
50940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    /* -partition-size is used to specify the max size of both the system
51040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner     * and data partition sizes.
51140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner     */
51240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    if (opts->partition_size) {
51340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        char*  end;
51440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        long   sizeMB = strtol(opts->partition_size, &end, 0);
51540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        long   minSizeMB = 10;
51640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        long   maxSizeMB = LONG_MAX / ONE_MB;
51740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
51840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        if (sizeMB < 0 || *end != 0) {
51940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            derror( "-partition-size must be followed by a positive integer" );
52040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            exit(1);
52140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        }
52240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        if (sizeMB < minSizeMB || sizeMB > maxSizeMB) {
52340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            derror( "partition-size (%d) must be between %dMB and %dMB",
52440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                    sizeMB, minSizeMB, maxSizeMB );
52540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            exit(1);
52640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        }
52740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        defaultPartitionSize = (uint64_t) sizeMB * ONE_MB;
52840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    }
52940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
53040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
53140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    /** SYSTEM PARTITION **/
53240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
53340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    if (opts->sysdir == NULL) {
53440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        if (avdInfo_inAndroidBuild(avd)) {
53540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            opts->sysdir = ASTRDUP(avdInfo_getContentPath(avd));
53640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            D("autoconfig: -sysdir %s", opts->sysdir);
53740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        }
53840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    }
53940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
54040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    if (opts->sysdir != NULL) {
54140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        if (!path_exists(opts->sysdir)) {
54240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            derror("Directory does not exist: %s", opts->sysdir);
54340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            exit(1);
54440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        }
54540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    }
54640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
54840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        char*  rwImage   = NULL;
54940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        char*  initImage = NULL;
55040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
55140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        do {
55240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            if (opts->system == NULL) {
55340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                /* If -system is not used, try to find a runtime system image
55440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                * (i.e. system-qemu.img) in the content directory.
55540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                */
55640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                rwImage = avdInfo_getSystemImagePath(avd);
55740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                if (rwImage != NULL) {
55840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                    break;
55940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                }
56040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                /* Otherwise, try to find the initial system image */
56140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                initImage = avdInfo_getSystemInitImagePath(avd);
56240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                if (initImage == NULL) {
56340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                    derror("No initial system image for this configuration!");
56440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                    exit(1);
56540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                }
56640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                break;
56740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            }
5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
56940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            /* If -system <name> is used, use it to find the initial image */
570ea2837728272b04bd236a74cd1ea547ec6f63c20David 'Digit' Turner            if (opts->sysdir != NULL && !path_exists(opts->system)) {
57140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                initImage = _getFullFilePath(opts->sysdir, opts->system);
57240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            } else {
57340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                initImage = ASTRDUP(opts->system);
57440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            }
57540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            if (!path_exists(initImage)) {
57640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                derror("System image file doesn't exist: %s", initImage);
57740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                exit(1);
57840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            }
5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
58040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        } while (0);
58140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
58240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        if (rwImage != NULL) {
58340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            /* Use the read/write image file directly */
58440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            hw->disk_systemPartition_path     = rwImage;
58540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            hw->disk_systemPartition_initPath = NULL;
58640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            D("Using direct system image: %s", rwImage);
58740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        } else if (initImage != NULL) {
58840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            hw->disk_systemPartition_path = NULL;
58940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            hw->disk_systemPartition_initPath = initImage;
59040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            D("Using initial system image: %s", initImage);
59140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        }
5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
59340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        /* Check the size of the system partition image.
59440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        * If we have an AVD, it must be smaller than
59540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        * the disk.systemPartition.size hardware property.
59640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        *
59740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        * Otherwise, we need to adjust the systemPartitionSize
59840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        * automatically, and print a warning.
59940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        *
60040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        */
60140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        const char* systemImage = hw->disk_systemPartition_path;
60240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        uint64_t    systemBytes;
60340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
60440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        if (systemImage == NULL)
60540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            systemImage = hw->disk_systemPartition_initPath;
60640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
60740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        if (path_get_size(systemImage, &systemBytes) < 0) {
60840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            derror("Missing system image: %s", systemImage);
60940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            exit(1);
61040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        }
61140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
61240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        hw->disk_systemPartition_size =
61340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            _adjustPartitionSize("system", systemBytes, defaultPartitionSize,
61440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                                 avdInfo_inAndroidBuild(avd));
6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
61740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    /** DATA PARTITION **/
61840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
619fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner    if (opts->datadir) {
620fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        if (!path_exists(opts->datadir)) {
621fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            derror("Invalid -datadir directory: %s", opts->datadir);
622fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        }
623fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner    }
624fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
625fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner    {
626fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        char*  dataImage = NULL;
627fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        char*  initImage = NULL;
628fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
629fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        do {
630fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            if (!opts->data) {
631fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                dataImage = avdInfo_getDataImagePath(avd);
632fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                if (dataImage != NULL) {
633fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                    D("autoconfig: -data %s", dataImage);
634fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                    break;
635fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                }
636fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                dataImage = avdInfo_getDefaultDataImagePath(avd);
637fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                if (dataImage == NULL) {
638fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                    derror("No data image path for this configuration!");
639fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                    exit (1);
640fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                }
641fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                opts->wipe_data = 1;
642fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                break;
643fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            }
6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
645fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            if (opts->datadir) {
646fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                dataImage = _getFullFilePath(opts->datadir, opts->data);
647fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            } else {
648fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                dataImage = ASTRDUP(opts->data);
649fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            }
650fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        } while (0);
651fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
652fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        if (opts->initdata != NULL) {
653fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            initImage = ASTRDUP(opts->initdata);
654fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            if (!path_exists(initImage)) {
655fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                derror("Invalid initial data image path: %s", initImage);
656fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                exit(1);
657fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            }
658fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        } else {
659fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            initImage = avdInfo_getDataInitImagePath(avd);
660fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            D("autoconfig: -initdata %s", initImage);
661fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        }
662fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
663fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        hw->disk_dataPartition_path = dataImage;
664fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        if (opts->wipe_data) {
665fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            hw->disk_dataPartition_initPath = initImage;
666fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        } else {
667fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            hw->disk_dataPartition_initPath = NULL;
668fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        }
669fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
670f758411e012389b1d9699e10cae6f1ac98cca419Maciek Molerus        uint64_t     defaultBytes =
671f758411e012389b1d9699e10cae6f1ac98cca419Maciek Molerus                hw->disk_dataPartition_size == 0 ?
672f758411e012389b1d9699e10cae6f1ac98cca419Maciek Molerus                defaultPartitionSize :
673d4f5a3ae87a7246613188940c1667bf2880da402Vladimir Chtchetkine                hw->disk_dataPartition_size;
674fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        uint64_t     dataBytes;
675fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        const char*  dataPath = hw->disk_dataPartition_initPath;
676fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
677fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        if (dataPath == NULL)
678fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            dataPath = hw->disk_dataPartition_path;
679fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
680fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        path_get_size(dataPath, &dataBytes);
681fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
682fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        hw->disk_dataPartition_size =
683fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            _adjustPartitionSize("data", dataBytes, defaultBytes,
684fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                                 avdInfo_inAndroidBuild(avd));
685fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner    }
6868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
687c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner    /** CACHE PARTITION **/
688c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner
689c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner    if (opts->no_cache) {
690c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        /* No cache partition at all */
691c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        hw->disk_cachePartition = 0;
6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
693c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner    else if (!hw->disk_cachePartition) {
694c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        if (opts->cache) {
695c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner            dwarning( "Emulated hardware doesn't support a cache partition. -cache option ignored!" );
696c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner            opts->cache = NULL;
697c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        }
6988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
699c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner    else
700c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner    {
701c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        if (!opts->cache) {
702c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner            /* Find the current cache partition file */
703c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner            opts->cache = avdInfo_getCachePath(avd);
704c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner            if (opts->cache == NULL) {
705c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner                /* The file does not exists, we will force its creation
706c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner                 * if we are not in the Android build system. Otherwise,
707c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner                 * a temporary file will be used.
708c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner                 */
709c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner                if (!avdInfo_inAndroidBuild(avd)) {
710c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner                    opts->cache = avdInfo_getDefaultCachePath(avd);
711c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner                }
712c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner            }
71348a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            if (opts->cache) {
71448a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                D("autoconfig: -cache %s", opts->cache);
71548a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            }
716c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        }
7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
718c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        if (opts->cache) {
719c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner            hw->disk_cachePartition_path = ASTRDUP(opts->cache);
720c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        }
7218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
723c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner    /** SD CARD PARTITION */
724c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner
72548a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner    if (!hw->hw_sdCard) {
72648a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner        /* No SD Card emulation, so -sdcard will be ignored */
72748a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner        if (opts->sdcard) {
72848a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            dwarning( "Emulated hardware doesn't support SD Cards. -sdcard option ignored." );
72948a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            opts->sdcard = NULL;
73048a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner        }
73148a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner    } else {
73248a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner        /* Auto-configure -sdcard if it is not available */
73348a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner        if (!opts->sdcard) {
73448a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            do {
73548a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                /* If -datadir <path> is used, look for a sdcard.img file here */
73648a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                if (opts->datadir) {
73748a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                    bufprint(tmp, tmpend, "%s/%s", opts->datadir, "system.img");
73848a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                    if (path_exists(tmp)) {
73948a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                        opts->sdcard = strdup(tmp);
74048a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                        break;
74148a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                    }
74248a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                }
74348a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner
74448a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                /* Otherwise, look at the AVD's content */
74548a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                opts->sdcard = avdInfo_getSdCardPath(avd);
74648a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                if (opts->sdcard != NULL) {
74748a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                    break;
74848a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                }
74948a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner
75048a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                /* Nothing */
75148a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            } while (0);
75248a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner
75348a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            if (opts->sdcard) {
75448a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                D("autoconfig: -sdcard %s", opts->sdcard);
75548a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            }
75648a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner        }
7578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if(opts->sdcard) {
7608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint64_t  size;
7618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (path_get_size(opts->sdcard, &size) == 0) {
7628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* see if we have an sdcard image.  get its size if it exists */
7638b657e5deaa03b989b0b36791fcf2aa6b2882656David 'Digit' Turner            /* due to what looks like limitations of the MMC protocol, one has
7648b657e5deaa03b989b0b36791fcf2aa6b2882656David 'Digit' Turner             * to use an SD Card image that is equal or larger than 9 MB
7658b657e5deaa03b989b0b36791fcf2aa6b2882656David 'Digit' Turner             */
7668b657e5deaa03b989b0b36791fcf2aa6b2882656David 'Digit' Turner            if (size < 9*1024*1024ULL) {
7678b657e5deaa03b989b0b36791fcf2aa6b2882656David 'Digit' Turner                fprintf(stderr, "### WARNING: SD Card files must be at least 9MB, ignoring '%s'\n", opts->sdcard);
7688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
76948a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                hw->hw_sdCard_path = ASTRDUP(opts->sdcard);
7708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
77248a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            dwarning("no SD Card image at '%s'", opts->sdcard);
7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
77648a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner
77748a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner    /** SNAPSHOT STORAGE HANDLING */
77848a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner
7795f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    /* Determine snapstorage path. -no-snapstorage disables all snapshotting
7805f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner     * support. This means you can't resume a snapshot at load, save it at
7815f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner     * exit, or even load/save them dynamically at runtime with the console.
7825f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner     */
7835f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    if (opts->no_snapstorage) {
7845f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
7855f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        if (opts->snapshot) {
7865f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            dwarning("ignoring -snapshot option due to the use of -no-snapstorage");
7875f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            opts->snapshot = NULL;
7885f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        }
7895f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
7905f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        if (opts->snapstorage) {
7915f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            dwarning("ignoring -snapstorage option due to the use of -no-snapstorage");
7925f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            opts->snapstorage = NULL;
7935f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        }
7945f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    }
7955f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    else
7965f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    {
797873c3cb5688092d2822837511cfb2b330d265801Vladimir Chtchetkine        if (!opts->snapstorage && avdInfo_getSnapshotPresent(avd)) {
7985f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            opts->snapstorage = avdInfo_getSnapStoragePath(avd);
7995f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            if (opts->snapstorage != NULL) {
8005f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner                D("autoconfig: -snapstorage %s", opts->snapstorage);
801353b3b1135563e2bcaf7797acfa35a2fe2d3a818Ot ten Thije            }
802353b3b1135563e2bcaf7797acfa35a2fe2d3a818Ot ten Thije        }
803353b3b1135563e2bcaf7797acfa35a2fe2d3a818Ot ten Thije
8045f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        if (opts->snapstorage && !path_exists(opts->snapstorage)) {
8055f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            D("no image at '%s', state snapshots disabled", opts->snapstorage);
8065f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            opts->snapstorage = NULL;
8075f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        }
8085f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    }
8095f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
8105f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    /* If we have a valid snapshot storage path */
8115f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
8125f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    if (opts->snapstorage) {
8135f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
8145f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        hw->disk_snapStorage_path = ASTRDUP(opts->snapstorage);
8155f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
8165f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        /* -no-snapshot is equivalent to using both -no-snapshot-load
8175f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        * and -no-snapshot-save. You can still load/save snapshots dynamically
8185f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        * from the console though.
8195f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        */
8205f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        if (opts->no_snapshot) {
8215f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
8225f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            opts->no_snapshot_load = 1;
8235f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            opts->no_snapshot_save = 1;
8245f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
8255f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            if (opts->snapshot) {
8265f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner                dwarning("ignoring -snapshot option due to the use of -no-snapshot.");
82753d8a5c0c8fc087d16316a4399f5a773339c4956Tim Baverstock            }
8285f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        }
8295f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
8305f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        if (!opts->no_snapshot_load || !opts->no_snapshot_save) {
8315f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            if (opts->snapshot == NULL) {
8325f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner                opts->snapshot = "default-boot";
8335f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner                D("autoconfig: -snapshot %s", opts->snapshot);
834353b3b1135563e2bcaf7797acfa35a2fe2d3a818Ot ten Thije            }
835353b3b1135563e2bcaf7797acfa35a2fe2d3a818Ot ten Thije        }
8365f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
8375f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        /* We still use QEMU command-line options for the following since
8385f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        * they can change from one invokation to the next and don't really
8395f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        * correspond to the hardware configuration itself.
8405f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        */
8415f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        if (!opts->no_snapshot_load) {
8425f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            args[n++] = "-loadvm";
8435f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            args[n++] = ASTRDUP(opts->snapshot);
8445f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        }
8455f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
8465f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        if (!opts->no_snapshot_save) {
8475f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            args[n++] = "-savevm-on-exit";
8485f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            args[n++] = ASTRDUP(opts->snapshot);
8495f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        }
8505f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
851622b8f4c760b8c4479d28430f978bad8bb9ea32cTim Baverstock        if (opts->no_snapshot_update_time) {
852bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner            args[n++] = "-snapshot-no-time-update";
853622b8f4c760b8c4479d28430f978bad8bb9ea32cTim Baverstock        }
854ae835acc2d1a8b4aaeb599add9cfc02ea5789eafOt ten Thije    }
855353b3b1135563e2bcaf7797acfa35a2fe2d3a818Ot ten Thije
8568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!opts->logcat || opts->logcat[0] == 0) {
8578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        opts->logcat = getenv("ANDROID_LOG_TAGS");
8588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (opts->logcat && opts->logcat[0] == 0)
8598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            opts->logcat = NULL;
8608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* we always send the kernel messages from ttyS0 to android_kmsg */
863062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    if (opts->show_kernel) {
864062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        args[n++] = "-show-kernel";
8658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXXX: TODO: implement -shell and -logcat through qemud instead */
8688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!opts->shell_serial) {
8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        opts->shell_serial = "con:";
8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        opts->shell_serial = "stdio";
8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else
8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        opts->shell = 1;
8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (opts->shell || opts->logcat) {
8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args[n++] = "-serial";
8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args[n++] = opts->shell_serial;
8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shell_serial = serial++;
8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
884062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    if (opts->radio) {
885062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        args[n++] = "-radio";
886062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        args[n++] = opts->radio;
8878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
889062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    if (opts->gps) {
890062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        args[n++] = "-gps";
891062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        args[n++] = opts->gps;
8928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (opts->memory) {
8958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char*  end;
8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        long   ramSize = strtol(opts->memory, &end, 0);
8978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ramSize < 0 || *end != 0) {
8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            derror( "-memory must be followed by a positive integer" );
8998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            exit(1);
9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ramSize < 32 || ramSize > 4096) {
9028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            derror( "physical memory size must be between 32 and 4096 MB" );
9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            exit(1);
9048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
9055377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        hw->hw_ramSize = ramSize;
9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!opts->memory) {
9083bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner        int ramSize = hw->hw_ramSize;
9093bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner        if (ramSize <= 0) {
9103bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner            /* Compute the default RAM size based on the size of screen.
9113bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             * This is only used when the skin doesn't provide the ram
9123bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             * size through its hardware.ini (i.e. legacy ones) or when
9133bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             * in the full Android build system.
9143bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             */
9155377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner            int64_t pixels  = hw->hw_lcd_width * hw->hw_lcd_height;
9163bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner            /* The following thresholds are a bit liberal, but we
9173bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             * essentially want to ensure the following mappings:
9183bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             *
9193bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             *   320x480 -> 96
9203bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             *   800x600 -> 128
9213bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             *  1024x768 -> 256
9223bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             *
9233bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             * These are just simple heuristics, they could change in
9243bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             * the future.
9253bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             */
9263bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner            if (pixels <= 250000)
9273bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner                ramSize = 96;
9283bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner            else if (pixels <= 500000)
9293bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner                ramSize = 128;
9303bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner            else
9313bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner                ramSize = 256;
9323bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner        }
9335377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        hw->hw_ramSize = ramSize;
9345377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner    }
9355377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner
9365377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner    D("Physical RAM size: %dMB\n", hw->hw_ramSize);
9375377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner
9385377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner    if (hw->vm_heapSize == 0) {
9395377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        /* Compute the default heap size based on the RAM size.
9405377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner         * Essentially, we want to ensure the following liberal mappings:
9415377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner         *
9425377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner         *   96MB RAM -> 16MB heap
9435377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner         *  128MB RAM -> 24MB heap
9445377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner         *  256MB RAM -> 48MB heap
9455377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner         */
9465377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        int  ramSize = hw->hw_ramSize;
9475377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        int  heapSize;
9485377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner
9495377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        if (ramSize < 100)
9505377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner            heapSize = 16;
9515377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        else if (ramSize < 192)
9525377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner            heapSize = 24;
9535377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        else
9545377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner            heapSize = 48;
9555377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner
9565377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        hw->vm_heapSize = heapSize;
9578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (opts->trace) {
9608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args[n++] = "-trace";
9618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args[n++] = opts->trace;
9628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args[n++] = "-tracing";
9638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args[n++] = "off";
9648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
966b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    /* Pass boot properties to the core. */
967b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    if (opts->prop != NULL) {
968b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        ParamList*  pl = opts->prop;
969b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        for ( ; pl != NULL; pl = pl->next ) {
970b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine            args[n++] = "-boot-property";
971b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine            args[n++] = pl->param;
972b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        }
973b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    }
974b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine
975318e4f294c181df33cf2541763904565b29bcccbDavid 'Digit' Turner    /* Setup the kernel init options
976318e4f294c181df33cf2541763904565b29bcccbDavid 'Digit' Turner     */
9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        static char  params[1024];
9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char        *p = params, *end = p + sizeof(params);
9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
981062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        /* Don't worry about having a leading space here, this is handled
982062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner         * by the core later. */
983062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner
984334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima#ifdef TARGET_I386
985334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima        p = bufprint(p, end, " androidboot.hardware=goldfish");
986bac9add881e0b7cfa2da2b86242347c096329a4cJun Nakajima        p = bufprint(p, end, " clocksource=pit");
987334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima#endif
9888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (opts->shell || opts->logcat) {
9908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = bufprint(p, end, " androidboot.console=ttyS%d", shell_serial );
9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (opts->trace) {
9948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = bufprint(p, end, " android.tracing=1");
9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!opts->no_jni) {
9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = bufprint(p, end, " android.checkjni=1");
9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (opts->no_boot_anim) {
10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = bufprint( p, end, " android.bootanim=0" );
10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (opts->logcat) {
10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            char*  q = bufprint(p, end, " androidboot.logcat=%s", opts->logcat);
10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (q < end) {
10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* replace any space by a comma ! */
10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                {
10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  nn;
10128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    for (nn = 1; p[nn] != 0; nn++)
10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if (p[nn] == ' ' || p[nn] == '\t')
10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            p[nn] = ',';
10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    p += nn;
10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = q;
10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (opts->bootchart) {
10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = bufprint(p, end, " androidboot.bootchart=%s", opts->bootchart);
10238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (p >= end) {
10268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(stderr, "### ERROR: kernel parameters too long\n");
10278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            exit(1);
10288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10300b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        hw->kernel_parameters = strdup(params);
10318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1033d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    if (opts->ports) {
1034d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        args[n++] = "-android-ports";
1035d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        args[n++] = opts->ports;
1036d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    }
1037d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
1038d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    if (opts->port) {
1039d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        args[n++] = "-android-port";
1040d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        args[n++] = opts->port;
1041d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    }
1042d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
1043d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    if (opts->report_console) {
1044d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        args[n++] = "-android-report-console";
1045d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        args[n++] = opts->report_console;
1046d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    }
1047d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
1048d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    if (opts->http_proxy) {
1049d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        args[n++] = "-http-proxy";
1050d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        args[n++] = opts->http_proxy;
1051d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    }
1052d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
105372d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet    if (!opts->charmap) {
105472d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        /* Try to find a valid charmap name */
105572d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        char* charmap = avdInfo_getCharmapFile(avd, hw->hw_keyboard_charmap);
105672d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        if (charmap != NULL) {
105772d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet            D("autoconfig: -charmap %s", charmap);
105872d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet            opts->charmap = charmap;
105972d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        }
106072d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet    }
106172d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet
106243552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine    if (opts->charmap) {
106372d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        char charmap_name[AKEYCHARMAP_NAME_SIZE];
106472d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet
106572d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        if (!path_exists(opts->charmap)) {
106672d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet            derror("Charmap file does not exist: %s", opts->charmap);
106772d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet            exit(1);
106872d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        }
106972d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        /* We need to store the charmap name in the hardware configuration.
107072d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet         * However, the charmap file itself is only used by the UI component
107172d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet         * and doesn't need to be set to the emulation engine.
107272d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet         */
107372d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        kcm_extract_charmap_name(opts->charmap, charmap_name,
107472d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet                                 sizeof(charmap_name));
107572d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        AFREE(hw->hw_keyboard_charmap);
107672d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet        hw->hw_keyboard_charmap = ASTRDUP(charmap_name);
107743552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine    }
107843552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine
1079b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine    if (opts->memcheck) {
1080b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine        args[n++] = "-android-memcheck";
1081b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine        args[n++] = opts->memcheck;
1082b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine    }
1083b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine
10849da935dd0c616cfd9072d11080a622320497dc9eDavid Turner    if (opts->gpu) {
10859da935dd0c616cfd9072d11080a622320497dc9eDavid Turner        const char* gpu = opts->gpu;
1086ae0d8136ce0d3c39ca80c64763e633b86b0c5453Vladimir Chtchetkine        if (!strcmp(gpu,"on") || !strcmp(gpu,"enable")) {
10879da935dd0c616cfd9072d11080a622320497dc9eDavid Turner            hw->hw_gpu_enabled = 1;
1088ae0d8136ce0d3c39ca80c64763e633b86b0c5453Vladimir Chtchetkine        } else if (!strcmp(gpu,"off") || !strcmp(gpu,"disable")) {
10899da935dd0c616cfd9072d11080a622320497dc9eDavid Turner            hw->hw_gpu_enabled = 0;
10909da935dd0c616cfd9072d11080a622320497dc9eDavid Turner        } else if (!strcmp(gpu,"auto")) {
10919da935dd0c616cfd9072d11080a622320497dc9eDavid Turner            /* Nothing to do */
10929da935dd0c616cfd9072d11080a622320497dc9eDavid Turner        } else {
10939da935dd0c616cfd9072d11080a622320497dc9eDavid Turner            derror("Invalid value for -gpu <mode> parameter: %s\n", gpu);
10949da935dd0c616cfd9072d11080a622320497dc9eDavid Turner            derror("Valid values are: on, off or auto\n");
10959da935dd0c616cfd9072d11080a622320497dc9eDavid Turner            exit(1);
10969da935dd0c616cfd9072d11080a622320497dc9eDavid Turner        }
10979da935dd0c616cfd9072d11080a622320497dc9eDavid Turner    }
10989da935dd0c616cfd9072d11080a622320497dc9eDavid Turner
10999242b33d3545e6632d21c1f416794a9f5d385c45Vladimir Chtchetkine    /* Quit emulator on condition that both, gpu and snapstorage are on. This is
11009242b33d3545e6632d21c1f416794a9f5d385c45Vladimir Chtchetkine     * a temporary solution preventing the emulator from crashing until GPU state
11019242b33d3545e6632d21c1f416794a9f5d385c45Vladimir Chtchetkine     * can be properly saved / resored in snapshot file. */
11029242b33d3545e6632d21c1f416794a9f5d385c45Vladimir Chtchetkine    if (hw->hw_gpu_enabled && opts->snapstorage && (!opts->no_snapshot_load ||
11039242b33d3545e6632d21c1f416794a9f5d385c45Vladimir Chtchetkine                                                    !opts->no_snapshot_save)) {
11049242b33d3545e6632d21c1f416794a9f5d385c45Vladimir Chtchetkine        derror("Snapshots and gpu are mutually exclusive at this point. Please turn one of them off, and restart the emulator.");
11059242b33d3545e6632d21c1f416794a9f5d385c45Vladimir Chtchetkine        exit(1);
11069242b33d3545e6632d21c1f416794a9f5d385c45Vladimir Chtchetkine    }
11079242b33d3545e6632d21c1f416794a9f5d385c45Vladimir Chtchetkine
11087485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine    /* Deal with camera emulation */
11097485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine    if (opts->webcam_list) {
11107485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine        /* List connected webcameras */
11117485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine        args[n++] = "-list-webcam";
11127485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine    }
11137485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine
11147485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine    if (opts->camera_back) {
11157485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine        /* Validate parameter. */
11167485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine        if (memcmp(opts->camera_back, "webcam", 6) &&
11177485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine            strcmp(opts->camera_back, "emulated") &&
11187485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine            strcmp(opts->camera_back, "none")) {
11197485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine            derror("Invalid value for -camera-back <mode> parameter: %s\n"
11207485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine                   "Valid values are: 'emulated', 'webcam<N>', or 'none'\n",
11217485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine                   opts->camera_back);
1122ae0d8136ce0d3c39ca80c64763e633b86b0c5453Vladimir Chtchetkine            exit(1);
1123ae0d8136ce0d3c39ca80c64763e633b86b0c5453Vladimir Chtchetkine        }
11247485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine        hw->hw_camera_back = ASTRDUP(opts->camera_back);
1125ae0d8136ce0d3c39ca80c64763e633b86b0c5453Vladimir Chtchetkine    }
1126ae0d8136ce0d3c39ca80c64763e633b86b0c5453Vladimir Chtchetkine
11277485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine    if (opts->camera_front) {
11287485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine        /* Validate parameter. */
11297485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine        if (memcmp(opts->camera_front, "webcam", 6) &&
11307485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine            strcmp(opts->camera_front, "emulated") &&
11317485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine            strcmp(opts->camera_front, "none")) {
11327485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine            derror("Invalid value for -camera-front <mode> parameter: %s\n"
11337485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine                   "Valid values are: 'emulated', 'webcam<N>', or 'none'\n",
11347485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine                   opts->camera_front);
11357485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine            exit(1);
1136f8675c20db7625adc69800ca4ac54e72846ac9a8Vladimir Chtchetkine        }
11377485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine        hw->hw_camera_front = ASTRDUP(opts->camera_front);
1138f8675c20db7625adc69800ca4ac54e72846ac9a8Vladimir Chtchetkine    }
1139f8675c20db7625adc69800ca4ac54e72846ac9a8Vladimir Chtchetkine
11405377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner    /* physical memory is now in hw->hw_ramSize */
11418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
114253eb66db4eba72d2e4fc951456be725e14243f25David 'Digit' Turner    hw->avd_name = ASTRDUP(avdInfo_getName(avd));
11436b8555cac04862908bf6c64565061f2c8e871ad7David 'Digit' Turner
114440beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie    /* Set up the interfaces for inter-emulator networking */
114540beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie    if (opts->shared_net_id) {
114640beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        unsigned int shared_net_id = atoi(opts->shared_net_id);
114740beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        char nic[37];
114840beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie
114940beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        args[n++] = "-net";
115040beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        args[n++] = "nic,vlan=0";
115140beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        args[n++] = "-net";
115240beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        args[n++] = "user,vlan=0";
1153111d6f8ed6dea6e651ab450e1ea11310ff0b2857Dries Harnie
1154111d6f8ed6dea6e651ab450e1ea11310ff0b2857Dries Harnie        args[n++] = "-net";
1155111d6f8ed6dea6e651ab450e1ea11310ff0b2857Dries Harnie        snprintf(nic, sizeof nic, "nic,vlan=1,macaddr=52:54:00:12:34:%02x", shared_net_id);
1156111d6f8ed6dea6e651ab450e1ea11310ff0b2857Dries Harnie        args[n++] = strdup(nic);
1157111d6f8ed6dea6e651ab450e1ea11310ff0b2857Dries Harnie        args[n++] = "-net";
1158111d6f8ed6dea6e651ab450e1ea11310ff0b2857Dries Harnie        args[n++] = "socket,vlan=1,mcast=230.0.0.10:1234";
115940beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie    }
116040beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie
11618dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine    /* Setup screen emulation */
11628dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine    if (opts->screen) {
1163863d1010d9c8fa4342b1b0ea860bcfb096806accVladimir Chtchetkine        if (strcmp(opts->screen, "touch") &&
1164863d1010d9c8fa4342b1b0ea860bcfb096806accVladimir Chtchetkine            strcmp(opts->screen, "multi-touch") &&
1165863d1010d9c8fa4342b1b0ea860bcfb096806accVladimir Chtchetkine            strcmp(opts->screen, "no-touch")) {
1166863d1010d9c8fa4342b1b0ea860bcfb096806accVladimir Chtchetkine
1167863d1010d9c8fa4342b1b0ea860bcfb096806accVladimir Chtchetkine            derror("Invalid value for -screen <mode> parameter: %s\n"
1168863d1010d9c8fa4342b1b0ea860bcfb096806accVladimir Chtchetkine                   "Valid values are: touch, multi-touch, or no-touch\n",
1169863d1010d9c8fa4342b1b0ea860bcfb096806accVladimir Chtchetkine                   opts->screen);
11708dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine            exit(1);
11718dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine        }
1172863d1010d9c8fa4342b1b0ea860bcfb096806accVladimir Chtchetkine        hw->hw_screen = ASTRDUP(opts->screen);
11738dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine    }
11748dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine
11758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while(argc-- > 0) {
11768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args[n++] = *argv++;
11778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    args[n] = 0;
11798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11802ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    /* If the target ABI is armeabi-v7a, we can auto-detect the cpu model
11812ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner     * as a cortex-a8, instead of the default (arm926) which only emulates
11822ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner     * an ARMv5TE CPU.
11832ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner     */
11842ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    if (!forceArmv7 && hw->hw_cpu_model[0] == '\0')
11852ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    {
11862ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner        char* abi = avdInfo_getTargetAbi(avd);
11872ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner        if (abi != NULL) {
11882ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner            if (!strcmp(abi, "armeabi-v7a")) {
11892ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner                forceArmv7 = 1;
11902ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner            }
11912ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner            AFREE(abi);
11922ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner        }
11932ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    }
11942ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner
11952ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    if (forceArmv7 != 0) {
11962ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner        AFREE(hw->hw_cpu_model);
11972ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner        hw->hw_cpu_model = ASTRDUP("cortex-a8");
11982ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner        D("Auto-config: -qemu -cpu %s", hw->hw_cpu_model);
11992ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    }
12002ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner
120126d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner    /* Generate a hardware-qemu.ini for this AVD. The real hardware
1202622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner     * configuration is ususally stored in several files, e.g. the AVD's
1203622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner     * config.ini plus the skin-specific hardware.ini.
1204622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner     *
120526d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner     * The new file will group all definitions and will be used to
1206622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner     * launch the core with the -android-hw <file> option.
1207622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner     */
1208622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    {
120942074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner        const char* coreHwIniPath = avdInfo_getCoreHwIniPath(avd);
121042074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner        IniFile*    hwIni         = iniFile_newFromMemory("", NULL);
1211622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner        androidHwConfig_write(hw, hwIni);
121226d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner
121326d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner        if (filelock_create(coreHwIniPath) == NULL) {
121426d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner            /* The AVD is already in use, we still support this as an
121526d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner             * experimental feature. Use a temporary hardware-qemu.ini
121626d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner             * file though to avoid overwriting the existing one. */
121726d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner             TempFile*  tempIni = tempfile_create();
121826d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner             coreHwIniPath = tempfile_path(tempIni);
121926d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner        }
122026d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner
1221db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine        /* While saving HW config, ignore valueless entries. This will not break
1222db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine         * anything, but will significantly simplify comparing the current HW
1223db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine         * config with the one that has been associated with a snapshot (in case
1224db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine         * VM starts from a snapshot for this instance of emulator). */
1225db450d73092add519efddcd6d55c7a0e7541ec70Vladimir Chtchetkine        if (iniFile_saveToFileClean(hwIni, coreHwIniPath) < 0) {
122642074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner            derror("Could not write hardware.ini to %s: %s", coreHwIniPath, strerror(errno));
1227622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner            exit(2);
1228622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner        }
1229622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner        args[n++] = "-android-hw";
123042074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner        args[n++] = strdup(coreHwIniPath);
12310a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner
12320a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner        /* In verbose mode, dump the file's content */
12330a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner        if (VERBOSE_CHECK(init)) {
12340a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner            FILE* file = fopen(coreHwIniPath, "rt");
12350a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner            if (file == NULL) {
12360a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                derror("Could not open hardware configuration file: %s\n",
12370a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                       coreHwIniPath);
12380a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner            } else {
12390a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                LineInput* input = lineInput_newFromStdFile(file);
12400a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                const char* line;
12410a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                printf("Content of hardware configuration file:\n");
12420a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                while ((line = lineInput_getLine(input)) !=  NULL) {
12430a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                    printf("  %s\n", line);
12440a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                }
12450a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                printf(".\n");
12460a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                lineInput_free(input);
12470a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                fclose(file);
12480a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner            }
12490a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner        }
1250622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    }
1251622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner
12528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if(VERBOSE_CHECK(init)) {
12538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int i;
12543336176fc898915b7b5544f3a7c60ec2794507c3David 'Digit' Turner        printf("QEMU options list:\n");
12558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for(i = 0; i < n; i++) {
12563336176fc898915b7b5544f3a7c60ec2794507c3David 'Digit' Turner            printf("emulator: argv[%02d] = \"%s\"\n", i, args[i]);
12578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
12583336176fc898915b7b5544f3a7c60ec2794507c3David 'Digit' Turner        /* Dump final command-line option to make debugging the core easier */
12593336176fc898915b7b5544f3a7c60ec2794507c3David 'Digit' Turner        printf("Concatenated QEMU options:\n");
12603336176fc898915b7b5544f3a7c60ec2794507c3David 'Digit' Turner        for (i = 0; i < n; i++) {
126126722dde31c3467cd31a078662810927eec05de5David 'Digit' Turner            /* To make it easier to copy-paste the output to a command-line,
126226722dde31c3467cd31a078662810927eec05de5David 'Digit' Turner             * quote anything that contains spaces.
126326722dde31c3467cd31a078662810927eec05de5David 'Digit' Turner             */
126426722dde31c3467cd31a078662810927eec05de5David 'Digit' Turner            if (strchr(args[i], ' ') != NULL) {
126526722dde31c3467cd31a078662810927eec05de5David 'Digit' Turner                printf(" '%s'", args[i]);
126626722dde31c3467cd31a078662810927eec05de5David 'Digit' Turner            } else {
126726722dde31c3467cd31a078662810927eec05de5David 'Digit' Turner                printf(" %s", args[i]);
126826722dde31c3467cd31a078662810927eec05de5David 'Digit' Turner            }
12693336176fc898915b7b5544f3a7c60ec2794507c3David 'Digit' Turner        }
12703336176fc898915b7b5544f3a7c60ec2794507c3David 'Digit' Turner        printf("\n");
12718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
127274d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner
127374d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner    /* Setup SDL UI just before calling the code */
127474d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner    init_sdl_ui(skinConfig, skinPath, opts);
127574d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner
1276bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner    if (attach_ui_to_core(opts) < 0) {
1277bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner        derror("Can't attach to core!");
1278bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner        exit(1);
1279bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner    }
1280bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner
12818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return qemu_main(n, args);
12828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1283