main.c revision ea2837728272b04bd236a74cd1ea547ec6f63c20
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 {
14840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        snprintf(temp, sizeof temp, "(%lld bytes > %lld 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;
17940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    uint64_t          defaultPartitionSize = convertMBToBytes(66);
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
3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    n = 1;
4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* generate arguments for the underlying qemu main() */
401238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner    {
4020b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        char*  kernelFile    = opts->kernel;
4030b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        int    kernelFileLen;
4040b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner
4050b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        if (kernelFile == NULL) {
4060b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner            kernelFile = avdInfo_getKernelPath(avd);
4070b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner            if (kernelFile == NULL) {
4080b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner                derror( "This AVD's configuration is missing a kernel file!!" );
4090b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner                exit(2);
4100b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner            }
4110b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner            D("autoconfig: -kernel %s", kernelFile);
4120b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        }
4130b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        if (!path_exists(kernelFile)) {
4140b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner            derror( "Invalid or missing kernel image file: %s", kernelFile );
4150b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner            exit(2);
4160b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        }
417238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner
4180b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        hw->kernel_path = kernelFile;
419238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner
420238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner        /* If the kernel image name ends in "-armv7", then change the cpu
421238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * type automatically. This is a poor man's approach to configuration
422238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * management, but should allow us to get past building ARMv7
423238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * system images with dex preopt pass without introducing too many
424238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * changes to the emulator sources.
425238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         *
426238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * XXX:
427238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * A 'proper' change would require adding some sort of hardware-property
428238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * to each AVD config file, then automatically determine its value for
429238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * full Android builds (depending on some environment variable), plus
430238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * some build system changes. I prefer not to do that for now for reasons
431238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         * of simplicity.
432238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         */
4330b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner         kernelFileLen = strlen(kernelFile);
434238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         if (kernelFileLen > 6 && !memcmp(kernelFile + kernelFileLen - 6, "-armv7", 6)) {
4352ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner             forceArmv7 = 1;
436238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner         }
437238b4b0ef1a01afa66ef267dae4a96401ad386dbDavid 'Digit' Turner    }
4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
439b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    if (boot_prop_ip[0]) {
440b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        args[n++] = "-boot-property";
441b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        args[n++] = boot_prop_ip;
442b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    }
443b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine
444318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine    if (opts->tcpdump) {
445318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine        args[n++] = "-tcpdump";
446318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine        args[n++] = opts->tcpdump;
447318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine    }
448318f17a0050e729bce8545463b657c1d62835b5eVladimir Chtchetkine
449e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine#ifdef CONFIG_NAND_LIMITS
450e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    if (opts->nand_limits) {
451e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        args[n++] = "-nand-limits";
452e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        args[n++] = opts->nand_limits;
453e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    }
454e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine#endif
455e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
45674d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner    if (opts->timezone) {
45774d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner        args[n++] = "-timezone";
45874d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner        args[n++] = opts->timezone;
45974d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner    }
46074d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner
461e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    if (opts->netspeed) {
462e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        args[n++] = "-netspeed";
463e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        args[n++] = opts->netspeed;
464e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    }
465e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    if (opts->netdelay) {
466e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        args[n++] = "-netdelay";
467e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        args[n++] = opts->netdelay;
468e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    }
469e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    if (opts->netfast) {
470e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine        args[n++] = "-netfast";
471e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine    }
472e13168648d5947955e0fd4fbf396f891ae53921fVladimir Chtchetkine
473b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    if (opts->audio) {
474b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        args[n++] = "-audio";
475b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        args[n++] = opts->audio;
476b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    }
477b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
478b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    if (opts->cpu_delay) {
479b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        args[n++] = "-cpu-delay";
480b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine        args[n++] = opts->cpu_delay;
481b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine    }
482b2438402d16ee4a0bb4b077d0ad0ef1d82b2a08cVladimir Chtchetkine
4837fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    if (opts->dns_server) {
4847fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        args[n++] = "-dns-server";
4857fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine        args[n++] = opts->dns_server;
4867fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine    }
4877fbf49776a98847a5f95325646f7eb5ff787423fVladimir Chtchetkine
4880b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner    hw->disk_ramdisk_path = avdInfo_getRamdiskPath(avd);
4890b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner    D("autoconfig: -ramdisk %s", hw->disk_ramdisk_path);
4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
49140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    /* -partition-size is used to specify the max size of both the system
49240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner     * and data partition sizes.
49340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner     */
49440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    if (opts->partition_size) {
49540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        char*  end;
49640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        long   sizeMB = strtol(opts->partition_size, &end, 0);
49740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        long   minSizeMB = 10;
49840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        long   maxSizeMB = LONG_MAX / ONE_MB;
49940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
50040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        if (sizeMB < 0 || *end != 0) {
50140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            derror( "-partition-size must be followed by a positive integer" );
50240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            exit(1);
50340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        }
50440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        if (sizeMB < minSizeMB || sizeMB > maxSizeMB) {
50540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            derror( "partition-size (%d) must be between %dMB and %dMB",
50640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                    sizeMB, minSizeMB, maxSizeMB );
50740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            exit(1);
50840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        }
50940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        defaultPartitionSize = (uint64_t) sizeMB * ONE_MB;
51040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    }
51140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
51240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
51340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    /** SYSTEM PARTITION **/
51440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
51540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    if (opts->sysdir == NULL) {
51640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        if (avdInfo_inAndroidBuild(avd)) {
51740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            opts->sysdir = ASTRDUP(avdInfo_getContentPath(avd));
51840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            D("autoconfig: -sysdir %s", opts->sysdir);
51940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        }
52040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    }
52140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
52240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    if (opts->sysdir != NULL) {
52340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        if (!path_exists(opts->sysdir)) {
52440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            derror("Directory does not exist: %s", opts->sysdir);
52540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            exit(1);
52640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        }
52740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    }
52840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
53040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        char*  rwImage   = NULL;
53140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        char*  initImage = NULL;
53240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
53340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        do {
53440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            if (opts->system == NULL) {
53540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                /* If -system is not used, try to find a runtime system image
53640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                * (i.e. system-qemu.img) in the content directory.
53740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                */
53840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                rwImage = avdInfo_getSystemImagePath(avd);
53940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                if (rwImage != NULL) {
54040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                    break;
54140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                }
54240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                /* Otherwise, try to find the initial system image */
54340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                initImage = avdInfo_getSystemInitImagePath(avd);
54440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                if (initImage == NULL) {
54540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                    derror("No initial system image for this configuration!");
54640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                    exit(1);
54740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                }
54840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                break;
54940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            }
5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
55140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            /* If -system <name> is used, use it to find the initial image */
552ea2837728272b04bd236a74cd1ea547ec6f63c20David 'Digit' Turner            if (opts->sysdir != NULL && !path_exists(opts->system)) {
55340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                initImage = _getFullFilePath(opts->sysdir, opts->system);
55440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            } else {
55540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                initImage = ASTRDUP(opts->system);
55640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            }
55740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            if (!path_exists(initImage)) {
55840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                derror("System image file doesn't exist: %s", initImage);
55940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                exit(1);
56040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            }
5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
56240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        } while (0);
56340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
56440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        if (rwImage != NULL) {
56540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            /* Use the read/write image file directly */
56640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            hw->disk_systemPartition_path     = rwImage;
56740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            hw->disk_systemPartition_initPath = NULL;
56840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            D("Using direct system image: %s", rwImage);
56940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        } else if (initImage != NULL) {
57040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            hw->disk_systemPartition_path = NULL;
57140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            hw->disk_systemPartition_initPath = initImage;
57240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            D("Using initial system image: %s", initImage);
57340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        }
5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
57540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        /* Check the size of the system partition image.
57640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        * If we have an AVD, it must be smaller than
57740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        * the disk.systemPartition.size hardware property.
57840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        *
57940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        * Otherwise, we need to adjust the systemPartitionSize
58040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        * automatically, and print a warning.
58140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        *
58240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        */
58340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        const char* systemImage = hw->disk_systemPartition_path;
58440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        uint64_t    systemBytes;
58540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
58640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        if (systemImage == NULL)
58740841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            systemImage = hw->disk_systemPartition_initPath;
58840841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
58940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        if (path_get_size(systemImage, &systemBytes) < 0) {
59040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            derror("Missing system image: %s", systemImage);
59140841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            exit(1);
59240841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        }
59340841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
59440841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner        hw->disk_systemPartition_size =
59540841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner            _adjustPartitionSize("system", systemBytes, defaultPartitionSize,
59640841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner                                 avdInfo_inAndroidBuild(avd));
5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
59940841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner    /** DATA PARTITION **/
60040841b2d221273a08abfe20824e7631211ade31dDavid 'Digit' Turner
601fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner    if (opts->datadir) {
602fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        if (!path_exists(opts->datadir)) {
603fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            derror("Invalid -datadir directory: %s", opts->datadir);
604fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        }
605fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner    }
606fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
607fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner    {
608fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        char*  dataImage = NULL;
609fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        char*  initImage = NULL;
610fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
611fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        do {
612fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            if (!opts->data) {
613fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                dataImage = avdInfo_getDataImagePath(avd);
614fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                if (dataImage != NULL) {
615fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                    D("autoconfig: -data %s", dataImage);
616fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                    break;
617fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                }
618fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                dataImage = avdInfo_getDefaultDataImagePath(avd);
619fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                if (dataImage == NULL) {
620fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                    derror("No data image path for this configuration!");
621fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                    exit (1);
622fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                }
623fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                opts->wipe_data = 1;
624fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                break;
625fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            }
6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
627fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            if (opts->datadir) {
628fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                dataImage = _getFullFilePath(opts->datadir, opts->data);
629fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            } else {
630fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                dataImage = ASTRDUP(opts->data);
631fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            }
632fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        } while (0);
633fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
634fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        if (opts->initdata != NULL) {
635fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            initImage = ASTRDUP(opts->initdata);
636fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            if (!path_exists(initImage)) {
637fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                derror("Invalid initial data image path: %s", initImage);
638fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                exit(1);
639fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            }
640fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        } else {
641fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            initImage = avdInfo_getDataInitImagePath(avd);
642fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            D("autoconfig: -initdata %s", initImage);
643fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        }
644fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
645fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        hw->disk_dataPartition_path = dataImage;
646fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        if (opts->wipe_data) {
647fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            hw->disk_dataPartition_initPath = initImage;
648fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        } else {
649fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            hw->disk_dataPartition_initPath = NULL;
650fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        }
651fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
652f758411e012389b1d9699e10cae6f1ac98cca419Maciek Molerus        uint64_t     defaultBytes =
653f758411e012389b1d9699e10cae6f1ac98cca419Maciek Molerus                hw->disk_dataPartition_size == 0 ?
654f758411e012389b1d9699e10cae6f1ac98cca419Maciek Molerus                defaultPartitionSize :
655f758411e012389b1d9699e10cae6f1ac98cca419Maciek Molerus                convertMBToBytes(hw->disk_dataPartition_size);
656fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        uint64_t     dataBytes;
657fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        const char*  dataPath = hw->disk_dataPartition_initPath;
658fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
659fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        if (dataPath == NULL)
660fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            dataPath = hw->disk_dataPartition_path;
661fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
662fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        path_get_size(dataPath, &dataBytes);
663fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner
664fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner        hw->disk_dataPartition_size =
665fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner            _adjustPartitionSize("data", dataBytes, defaultBytes,
666fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner                                 avdInfo_inAndroidBuild(avd));
667fd59c330bec77e7b9241e478efb1e1c508480d1dDavid 'Digit' Turner    }
6688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
669c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner    /** CACHE PARTITION **/
670c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner
671c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner    if (opts->no_cache) {
672c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        /* No cache partition at all */
673c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        hw->disk_cachePartition = 0;
6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
675c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner    else if (!hw->disk_cachePartition) {
676c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        if (opts->cache) {
677c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner            dwarning( "Emulated hardware doesn't support a cache partition. -cache option ignored!" );
678c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner            opts->cache = NULL;
679c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        }
6808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
681c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner    else
682c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner    {
683c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        if (!opts->cache) {
684c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner            /* Find the current cache partition file */
685c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner            opts->cache = avdInfo_getCachePath(avd);
686c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner            if (opts->cache == NULL) {
687c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner                /* The file does not exists, we will force its creation
688c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner                 * if we are not in the Android build system. Otherwise,
689c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner                 * a temporary file will be used.
690c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner                 */
691c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner                if (!avdInfo_inAndroidBuild(avd)) {
692c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner                    opts->cache = avdInfo_getDefaultCachePath(avd);
693c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner                }
694c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner            }
69548a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            if (opts->cache) {
69648a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                D("autoconfig: -cache %s", opts->cache);
69748a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            }
698c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        }
6998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
700c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        if (opts->cache) {
701c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner            hw->disk_cachePartition_path = ASTRDUP(opts->cache);
702c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner        }
7038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
705c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner    /** SD CARD PARTITION */
706c480cca8d2007f5df62a7431beda310911b963e6David 'Digit' Turner
70748a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner    if (!hw->hw_sdCard) {
70848a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner        /* No SD Card emulation, so -sdcard will be ignored */
70948a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner        if (opts->sdcard) {
71048a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            dwarning( "Emulated hardware doesn't support SD Cards. -sdcard option ignored." );
71148a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            opts->sdcard = NULL;
71248a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner        }
71348a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner    } else {
71448a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner        /* Auto-configure -sdcard if it is not available */
71548a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner        if (!opts->sdcard) {
71648a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            do {
71748a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                /* If -datadir <path> is used, look for a sdcard.img file here */
71848a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                if (opts->datadir) {
71948a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                    bufprint(tmp, tmpend, "%s/%s", opts->datadir, "system.img");
72048a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                    if (path_exists(tmp)) {
72148a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                        opts->sdcard = strdup(tmp);
72248a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                        break;
72348a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                    }
72448a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                }
72548a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner
72648a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                /* Otherwise, look at the AVD's content */
72748a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                opts->sdcard = avdInfo_getSdCardPath(avd);
72848a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                if (opts->sdcard != NULL) {
72948a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                    break;
73048a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                }
73148a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner
73248a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                /* Nothing */
73348a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            } while (0);
73448a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner
73548a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            if (opts->sdcard) {
73648a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                D("autoconfig: -sdcard %s", opts->sdcard);
73748a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            }
73848a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner        }
7398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if(opts->sdcard) {
7428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uint64_t  size;
7438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (path_get_size(opts->sdcard, &size) == 0) {
7448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* see if we have an sdcard image.  get its size if it exists */
7458b657e5deaa03b989b0b36791fcf2aa6b2882656David 'Digit' Turner            /* due to what looks like limitations of the MMC protocol, one has
7468b657e5deaa03b989b0b36791fcf2aa6b2882656David 'Digit' Turner             * to use an SD Card image that is equal or larger than 9 MB
7478b657e5deaa03b989b0b36791fcf2aa6b2882656David 'Digit' Turner             */
7488b657e5deaa03b989b0b36791fcf2aa6b2882656David 'Digit' Turner            if (size < 9*1024*1024ULL) {
7498b657e5deaa03b989b0b36791fcf2aa6b2882656David 'Digit' Turner                fprintf(stderr, "### WARNING: SD Card files must be at least 9MB, ignoring '%s'\n", opts->sdcard);
7508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
75148a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner                hw->hw_sdCard_path = ASTRDUP(opts->sdcard);
7528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
7538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
75448a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner            dwarning("no SD Card image at '%s'", opts->sdcard);
7558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
75848a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner
75948a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner    /** SNAPSHOT STORAGE HANDLING */
76048a3c66361158678f476fc7c2eca2bef025eae62David 'Digit' Turner
7615f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    /* Determine snapstorage path. -no-snapstorage disables all snapshotting
7625f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner     * support. This means you can't resume a snapshot at load, save it at
7635f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner     * exit, or even load/save them dynamically at runtime with the console.
7645f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner     */
7655f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    if (opts->no_snapstorage) {
7665f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
7675f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        if (opts->snapshot) {
7685f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            dwarning("ignoring -snapshot option due to the use of -no-snapstorage");
7695f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            opts->snapshot = NULL;
7705f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        }
7715f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
7725f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        if (opts->snapstorage) {
7735f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            dwarning("ignoring -snapstorage option due to the use of -no-snapstorage");
7745f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            opts->snapstorage = NULL;
7755f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        }
7765f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    }
7775f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    else
7785f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    {
7795f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        if (!opts->snapstorage) {
7805f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            opts->snapstorage = avdInfo_getSnapStoragePath(avd);
7815f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            if (opts->snapstorage != NULL) {
7825f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner                D("autoconfig: -snapstorage %s", opts->snapstorage);
783353b3b1135563e2bcaf7797acfa35a2fe2d3a818Ot ten Thije            }
784353b3b1135563e2bcaf7797acfa35a2fe2d3a818Ot ten Thije        }
785353b3b1135563e2bcaf7797acfa35a2fe2d3a818Ot ten Thije
7865f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        if (opts->snapstorage && !path_exists(opts->snapstorage)) {
7875f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            D("no image at '%s', state snapshots disabled", opts->snapstorage);
7885f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            opts->snapstorage = NULL;
7895f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        }
7905f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    }
7915f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
7925f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    /* If we have a valid snapshot storage path */
7935f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
7945f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner    if (opts->snapstorage) {
7955f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
7965f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        hw->disk_snapStorage_path = ASTRDUP(opts->snapstorage);
7975f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
7985f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        /* -no-snapshot is equivalent to using both -no-snapshot-load
7995f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        * and -no-snapshot-save. You can still load/save snapshots dynamically
8005f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        * from the console though.
8015f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        */
8025f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        if (opts->no_snapshot) {
8035f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
8045f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            opts->no_snapshot_load = 1;
8055f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            opts->no_snapshot_save = 1;
8065f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
8075f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            if (opts->snapshot) {
8085f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner                dwarning("ignoring -snapshot option due to the use of -no-snapshot.");
80953d8a5c0c8fc087d16316a4399f5a773339c4956Tim Baverstock            }
8105f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        }
8115f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
8125f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        if (!opts->no_snapshot_load || !opts->no_snapshot_save) {
8135f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            if (opts->snapshot == NULL) {
8145f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner                opts->snapshot = "default-boot";
8155f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner                D("autoconfig: -snapshot %s", opts->snapshot);
816353b3b1135563e2bcaf7797acfa35a2fe2d3a818Ot ten Thije            }
817353b3b1135563e2bcaf7797acfa35a2fe2d3a818Ot ten Thije        }
8185f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
8195f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        /* We still use QEMU command-line options for the following since
8205f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        * they can change from one invokation to the next and don't really
8215f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        * correspond to the hardware configuration itself.
8225f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        */
8235f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        if (!opts->no_snapshot_load) {
8245f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            args[n++] = "-loadvm";
8255f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            args[n++] = ASTRDUP(opts->snapshot);
8265f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        }
8275f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
8285f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        if (!opts->no_snapshot_save) {
8295f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            args[n++] = "-savevm-on-exit";
8305f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner            args[n++] = ASTRDUP(opts->snapshot);
8315f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner        }
8325f64b873605baa5519211b0d47a53c93df9d4868David 'Digit' Turner
833622b8f4c760b8c4479d28430f978bad8bb9ea32cTim Baverstock        if (opts->no_snapshot_update_time) {
834bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner            args[n++] = "-snapshot-no-time-update";
835622b8f4c760b8c4479d28430f978bad8bb9ea32cTim Baverstock        }
836ae835acc2d1a8b4aaeb599add9cfc02ea5789eafOt ten Thije    }
837353b3b1135563e2bcaf7797acfa35a2fe2d3a818Ot ten Thije
8388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!opts->logcat || opts->logcat[0] == 0) {
8398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        opts->logcat = getenv("ANDROID_LOG_TAGS");
8408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (opts->logcat && opts->logcat[0] == 0)
8418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            opts->logcat = NULL;
8428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* we always send the kernel messages from ttyS0 to android_kmsg */
845062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    if (opts->show_kernel) {
846062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        args[n++] = "-show-kernel";
8478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXXX: TODO: implement -shell and -logcat through qemud instead */
8508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!opts->shell_serial) {
8518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
8528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        opts->shell_serial = "con:";
8538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
8548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        opts->shell_serial = "stdio";
8558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
8568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else
8588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        opts->shell = 1;
8598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (opts->shell || opts->logcat) {
8618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args[n++] = "-serial";
8628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args[n++] = opts->shell_serial;
8638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shell_serial = serial++;
8648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
866062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    if (opts->radio) {
867062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        args[n++] = "-radio";
868062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        args[n++] = opts->radio;
8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
871062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner    if (opts->gps) {
872062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        args[n++] = "-gps";
873062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        args[n++] = opts->gps;
8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (opts->memory) {
8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char*  end;
8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        long   ramSize = strtol(opts->memory, &end, 0);
8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ramSize < 0 || *end != 0) {
8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            derror( "-memory must be followed by a positive integer" );
8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            exit(1);
8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ramSize < 32 || ramSize > 4096) {
8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            derror( "physical memory size must be between 32 and 4096 MB" );
8858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            exit(1);
8868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
8875377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        hw->hw_ramSize = ramSize;
8888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!opts->memory) {
8903bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner        int ramSize = hw->hw_ramSize;
8913bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner        if (ramSize <= 0) {
8923bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner            /* Compute the default RAM size based on the size of screen.
8933bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             * This is only used when the skin doesn't provide the ram
8943bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             * size through its hardware.ini (i.e. legacy ones) or when
8953bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             * in the full Android build system.
8963bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             */
8975377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner            int64_t pixels  = hw->hw_lcd_width * hw->hw_lcd_height;
8983bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner            /* The following thresholds are a bit liberal, but we
8993bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             * essentially want to ensure the following mappings:
9003bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             *
9013bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             *   320x480 -> 96
9023bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             *   800x600 -> 128
9033bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             *  1024x768 -> 256
9043bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             *
9053bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             * These are just simple heuristics, they could change in
9063bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             * the future.
9073bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner             */
9083bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner            if (pixels <= 250000)
9093bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner                ramSize = 96;
9103bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner            else if (pixels <= 500000)
9113bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner                ramSize = 128;
9123bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner            else
9133bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner                ramSize = 256;
9143bbc919b70c78e0be6387d06faa90743deedb4dcDavid 'Digit' Turner        }
9155377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        hw->hw_ramSize = ramSize;
9165377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner    }
9175377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner
9185377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner    D("Physical RAM size: %dMB\n", hw->hw_ramSize);
9195377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner
9205377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner    if (hw->vm_heapSize == 0) {
9215377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        /* Compute the default heap size based on the RAM size.
9225377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner         * Essentially, we want to ensure the following liberal mappings:
9235377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner         *
9245377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner         *   96MB RAM -> 16MB heap
9255377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner         *  128MB RAM -> 24MB heap
9265377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner         *  256MB RAM -> 48MB heap
9275377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner         */
9285377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        int  ramSize = hw->hw_ramSize;
9295377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        int  heapSize;
9305377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner
9315377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        if (ramSize < 100)
9325377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner            heapSize = 16;
9335377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        else if (ramSize < 192)
9345377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner            heapSize = 24;
9355377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        else
9365377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner            heapSize = 48;
9375377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner
9385377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner        hw->vm_heapSize = heapSize;
9398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (opts->trace) {
9428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args[n++] = "-trace";
9438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args[n++] = opts->trace;
9448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args[n++] = "-tracing";
9458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args[n++] = "off";
9468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
948b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    /* Pass boot properties to the core. */
949b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    if (opts->prop != NULL) {
950b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        ParamList*  pl = opts->prop;
951b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        for ( ; pl != NULL; pl = pl->next ) {
952b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine            args[n++] = "-boot-property";
953b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine            args[n++] = pl->param;
954b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine        }
955b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine    }
956b25bf2a7477595aa54181874921086d4c0071c03Vladimir Chtchetkine
957318e4f294c181df33cf2541763904565b29bcccbDavid 'Digit' Turner    /* Setup the kernel init options
958318e4f294c181df33cf2541763904565b29bcccbDavid 'Digit' Turner     */
9598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
9608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        static char  params[1024];
9618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        char        *p = params, *end = p + sizeof(params);
9628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
963062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner        /* Don't worry about having a leading space here, this is handled
964062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner         * by the core later. */
965062dd6a8b90c7c553a6a7257e9c245276b1dd969David 'Digit' Turner
966334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima#ifdef TARGET_I386
967334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima        p = bufprint(p, end, " androidboot.hardware=goldfish");
968bac9add881e0b7cfa2da2b86242347c096329a4cJun Nakajima        p = bufprint(p, end, " clocksource=pit");
969334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima#endif
9708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (opts->shell || opts->logcat) {
9728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = bufprint(p, end, " androidboot.console=ttyS%d", shell_serial );
9738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
9748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (opts->trace) {
9768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = bufprint(p, end, " android.tracing=1");
9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!opts->no_jni) {
9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = bufprint(p, end, " android.checkjni=1");
9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
9828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (opts->no_boot_anim) {
9848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = bufprint( p, end, " android.bootanim=0" );
9858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
9868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (opts->logcat) {
9888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            char*  q = bufprint(p, end, " androidboot.logcat=%s", opts->logcat);
9898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (q < end) {
9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* replace any space by a comma ! */
9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                {
9938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  nn;
9948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    for (nn = 1; p[nn] != 0; nn++)
9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if (p[nn] == ' ' || p[nn] == '\t')
9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            p[nn] = ',';
9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    p += nn;
9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = q;
10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (opts->bootchart) {
10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = bufprint(p, end, " androidboot.bootchart=%s", opts->bootchart);
10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (p >= end) {
10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(stderr, "### ERROR: kernel parameters too long\n");
10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            exit(1);
10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10120b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        hw->kernel_parameters = strdup(params);
10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1015d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    if (opts->ports) {
1016d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        args[n++] = "-android-ports";
1017d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        args[n++] = opts->ports;
1018d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    }
1019d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
1020d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    if (opts->port) {
1021d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        args[n++] = "-android-port";
1022d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        args[n++] = opts->port;
1023d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    }
1024d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
1025d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    if (opts->report_console) {
1026d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        args[n++] = "-android-report-console";
1027d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        args[n++] = opts->report_console;
1028d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    }
1029d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
1030d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    if (opts->http_proxy) {
1031d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        args[n++] = "-http-proxy";
1032d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        args[n++] = opts->http_proxy;
1033d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    }
1034d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
1035c803400d45535925fb35c373e2d610fde522c546David 'Digit' Turner    if (!opts->charmap) {
1036c803400d45535925fb35c373e2d610fde522c546David 'Digit' Turner        /* Try to find a valid charmap name */
1037c803400d45535925fb35c373e2d610fde522c546David 'Digit' Turner        char* charmap = avdInfo_getCharmapFile(avd, hw->hw_keyboard_charmap);
1038c803400d45535925fb35c373e2d610fde522c546David 'Digit' Turner        if (charmap != NULL) {
1039c803400d45535925fb35c373e2d610fde522c546David 'Digit' Turner            D("autoconfig: -charmap %s", charmap);
1040c803400d45535925fb35c373e2d610fde522c546David 'Digit' Turner            opts->charmap = charmap;
1041c803400d45535925fb35c373e2d610fde522c546David 'Digit' Turner        }
1042c803400d45535925fb35c373e2d610fde522c546David 'Digit' Turner    }
1043c803400d45535925fb35c373e2d610fde522c546David 'Digit' Turner
104443552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine    if (opts->charmap) {
1045c803400d45535925fb35c373e2d610fde522c546David 'Digit' Turner        char charmap_name[AKEYCHARMAP_NAME_SIZE];
1046c803400d45535925fb35c373e2d610fde522c546David 'Digit' Turner
1047c803400d45535925fb35c373e2d610fde522c546David 'Digit' Turner        if (!path_exists(opts->charmap)) {
1048c803400d45535925fb35c373e2d610fde522c546David 'Digit' Turner            derror("Charmap file does not exist: %s", opts->charmap);
1049c803400d45535925fb35c373e2d610fde522c546David 'Digit' Turner            exit(1);
1050c803400d45535925fb35c373e2d610fde522c546David 'Digit' Turner        }
1051c803400d45535925fb35c373e2d610fde522c546David 'Digit' Turner        /* We need to store the charmap name in the hardware configuration.
1052c803400d45535925fb35c373e2d610fde522c546David 'Digit' Turner         * However, the charmap file itself is only used by the UI component
1053c803400d45535925fb35c373e2d610fde522c546David 'Digit' Turner         * and doesn't need to be set to the emulation engine.
1054c803400d45535925fb35c373e2d610fde522c546David 'Digit' Turner         */
1055c803400d45535925fb35c373e2d610fde522c546David 'Digit' Turner        kcm_extract_charmap_name(opts->charmap, charmap_name,
1056c803400d45535925fb35c373e2d610fde522c546David 'Digit' Turner                                 sizeof(charmap_name));
1057c803400d45535925fb35c373e2d610fde522c546David 'Digit' Turner        AFREE(hw->hw_keyboard_charmap);
1058c803400d45535925fb35c373e2d610fde522c546David 'Digit' Turner        hw->hw_keyboard_charmap = ASTRDUP(charmap_name);
105943552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine    }
106043552dc4fa64aad0c9fdb8f4c92ae7ac79406596Vladimir Chtchetkine
1061b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine    if (opts->memcheck) {
1062b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine        args[n++] = "-android-memcheck";
1063b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine        args[n++] = opts->memcheck;
1064b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine    }
1065b5365f32d7b1dcc6c3e9be7584ce8d4f68b3e7e1Vladimir Chtchetkine
10665377c5bfde6ba62490417bb0a7d7c1be1151692eDavid 'Digit' Turner    /* physical memory is now in hw->hw_ramSize */
10678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
106853eb66db4eba72d2e4fc951456be725e14243f25David 'Digit' Turner    hw->avd_name = ASTRDUP(avdInfo_getName(avd));
10696b8555cac04862908bf6c64565061f2c8e871ad7David 'Digit' Turner
107040beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie    /* Set up the interfaces for inter-emulator networking */
107140beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie    if (opts->shared_net_id) {
107240beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        unsigned int shared_net_id = atoi(opts->shared_net_id);
107340beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        char nic[37];
107440beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie
107540beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        args[n++] = "-net";
107640beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        args[n++] = "nic,vlan=0";
107740beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        args[n++] = "-net";
107840beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie        args[n++] = "user,vlan=0";
1079111d6f8ed6dea6e651ab450e1ea11310ff0b2857Dries Harnie
1080111d6f8ed6dea6e651ab450e1ea11310ff0b2857Dries Harnie        args[n++] = "-net";
1081111d6f8ed6dea6e651ab450e1ea11310ff0b2857Dries Harnie        snprintf(nic, sizeof nic, "nic,vlan=1,macaddr=52:54:00:12:34:%02x", shared_net_id);
1082111d6f8ed6dea6e651ab450e1ea11310ff0b2857Dries Harnie        args[n++] = strdup(nic);
1083111d6f8ed6dea6e651ab450e1ea11310ff0b2857Dries Harnie        args[n++] = "-net";
1084111d6f8ed6dea6e651ab450e1ea11310ff0b2857Dries Harnie        args[n++] = "socket,vlan=1,mcast=230.0.0.10:1234";
108540beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie    }
108640beab42ecdc4e2a79714b54c401feb0fb33b6d0Dries Harnie
10878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while(argc-- > 0) {
10888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        args[n++] = *argv++;
10898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    args[n] = 0;
10918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10922ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    /* If the target ABI is armeabi-v7a, we can auto-detect the cpu model
10932ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner     * as a cortex-a8, instead of the default (arm926) which only emulates
10942ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner     * an ARMv5TE CPU.
10952ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner     */
10962ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    if (!forceArmv7 && hw->hw_cpu_model[0] == '\0')
10972ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    {
10982ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner        char* abi = avdInfo_getTargetAbi(avd);
10992ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner        if (abi != NULL) {
11002ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner            if (!strcmp(abi, "armeabi-v7a")) {
11012ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner                forceArmv7 = 1;
11022ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner            }
11032ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner            AFREE(abi);
11042ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner        }
11052ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    }
11062ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner
11072ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    if (forceArmv7 != 0) {
11082ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner        AFREE(hw->hw_cpu_model);
11092ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner        hw->hw_cpu_model = ASTRDUP("cortex-a8");
11102ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner        D("Auto-config: -qemu -cpu %s", hw->hw_cpu_model);
11112ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner    }
11122ed457ee5259b236bf39701404897f4c486326e8David 'Digit' Turner
111326d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner    /* Generate a hardware-qemu.ini for this AVD. The real hardware
1114622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner     * configuration is ususally stored in several files, e.g. the AVD's
1115622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner     * config.ini plus the skin-specific hardware.ini.
1116622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner     *
111726d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner     * The new file will group all definitions and will be used to
1118622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner     * launch the core with the -android-hw <file> option.
1119622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner     */
1120622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    {
112142074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner        const char* coreHwIniPath = avdInfo_getCoreHwIniPath(avd);
112242074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner        IniFile*    hwIni         = iniFile_newFromMemory("", NULL);
1123622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner        androidHwConfig_write(hw, hwIni);
112426d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner
112526d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner        if (filelock_create(coreHwIniPath) == NULL) {
112626d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner            /* The AVD is already in use, we still support this as an
112726d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner             * experimental feature. Use a temporary hardware-qemu.ini
112826d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner             * file though to avoid overwriting the existing one. */
112926d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner             TempFile*  tempIni = tempfile_create();
113026d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner             coreHwIniPath = tempfile_path(tempIni);
113126d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner        }
113226d415322b75784f123d39f36616b8ebd1fbb359David 'Digit' Turner
113342074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner        if (iniFile_saveToFile(hwIni, coreHwIniPath) < 0) {
113442074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner            derror("Could not write hardware.ini to %s: %s", coreHwIniPath, strerror(errno));
1135622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner            exit(2);
1136622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner        }
1137622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner        args[n++] = "-android-hw";
113842074e5e184aed78dee0efb14d7376325516c070David 'Digit' Turner        args[n++] = strdup(coreHwIniPath);
11390a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner
11400a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner        /* In verbose mode, dump the file's content */
11410a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner        if (VERBOSE_CHECK(init)) {
11420a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner            FILE* file = fopen(coreHwIniPath, "rt");
11430a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner            if (file == NULL) {
11440a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                derror("Could not open hardware configuration file: %s\n",
11450a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                       coreHwIniPath);
11460a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner            } else {
11470a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                LineInput* input = lineInput_newFromStdFile(file);
11480a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                const char* line;
11490a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                printf("Content of hardware configuration file:\n");
11500a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                while ((line = lineInput_getLine(input)) !=  NULL) {
11510a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                    printf("  %s\n", line);
11520a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                }
11530a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                printf(".\n");
11540a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                lineInput_free(input);
11550a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner                fclose(file);
11560a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner            }
11570a879bf9ba318562e41a1bd4a6f9547f124a9831David 'Digit' Turner        }
1158622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner    }
1159622f1530c8a6badfbcaf8c59976348678fbe248bDavid 'Digit' Turner
11608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if(VERBOSE_CHECK(init)) {
11618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int i;
11623336176fc898915b7b5544f3a7c60ec2794507c3David 'Digit' Turner        printf("QEMU options list:\n");
11638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for(i = 0; i < n; i++) {
11643336176fc898915b7b5544f3a7c60ec2794507c3David 'Digit' Turner            printf("emulator: argv[%02d] = \"%s\"\n", i, args[i]);
11658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
11663336176fc898915b7b5544f3a7c60ec2794507c3David 'Digit' Turner        /* Dump final command-line option to make debugging the core easier */
11673336176fc898915b7b5544f3a7c60ec2794507c3David 'Digit' Turner        printf("Concatenated QEMU options:\n");
11683336176fc898915b7b5544f3a7c60ec2794507c3David 'Digit' Turner        for (i = 0; i < n; i++) {
116926722dde31c3467cd31a078662810927eec05de5David 'Digit' Turner            /* To make it easier to copy-paste the output to a command-line,
117026722dde31c3467cd31a078662810927eec05de5David 'Digit' Turner             * quote anything that contains spaces.
117126722dde31c3467cd31a078662810927eec05de5David 'Digit' Turner             */
117226722dde31c3467cd31a078662810927eec05de5David 'Digit' Turner            if (strchr(args[i], ' ') != NULL) {
117326722dde31c3467cd31a078662810927eec05de5David 'Digit' Turner                printf(" '%s'", args[i]);
117426722dde31c3467cd31a078662810927eec05de5David 'Digit' Turner            } else {
117526722dde31c3467cd31a078662810927eec05de5David 'Digit' Turner                printf(" %s", args[i]);
117626722dde31c3467cd31a078662810927eec05de5David 'Digit' Turner            }
11773336176fc898915b7b5544f3a7c60ec2794507c3David 'Digit' Turner        }
11783336176fc898915b7b5544f3a7c60ec2794507c3David 'Digit' Turner        printf("\n");
11798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
118074d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner
118174d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner    /* Setup SDL UI just before calling the code */
118274d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner    init_sdl_ui(skinConfig, skinPath, opts);
118374d7acec6643694132a127feb5ccadda7ea793d6David 'Digit' Turner
1184bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner    if (attach_ui_to_core(opts) < 0) {
1185bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner        derror("Can't attach to core!");
1186bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner        exit(1);
1187bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner    }
1188bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner
11898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return qemu_main(n, args);
11908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1191