diff options
-rw-r--r-- | android/avd/info.c | 480 | ||||
-rw-r--r-- | android/avd/info.h | 2 | ||||
-rw-r--r-- | android/cmdline-options.h | 2 | ||||
-rw-r--r-- | android/main-common.c | 144 | ||||
-rw-r--r-- | android/main.c | 72 | ||||
-rw-r--r-- | hw/goldfish_nand.c | 2 | ||||
-rw-r--r-- | vl-android.c | 34 |
7 files changed, 116 insertions, 620 deletions
diff --git a/android/avd/info.c b/android/avd/info.c index a23cd63..aaf1111 100644 --- a/android/avd/info.c +++ b/android/avd/info.c @@ -780,398 +780,6 @@ _avdInfo_getCoreHwIniPath( AvdInfo* i, const char* basePath ) return 0; } - -/*************************************************************** - *************************************************************** - ***** - ***** KERNEL/DISK IMAGE LOADER - ***** - *****/ - -/* a structure used to handle the loading of - * kernel/disk images. - */ -typedef struct { - AvdInfo* info; - AvdInfoParams* params; - AvdImageType id; - const char* imageFile; - const char* imageText; - char** pPath; - char* pState; - char temp[PATH_MAX]; -} ImageLoader; - -static void -imageLoader_init( ImageLoader* l, AvdInfo* info, AvdInfoParams* params ) -{ - memset(l, 0, sizeof(*l)); - l->info = info; - l->params = params; -} - -/* set the type of the image to load */ -static void -imageLoader_set( ImageLoader* l, AvdImageType id ) -{ - l->id = id; - l->imageFile = _imageFileNames[id]; - l->imageText = _imageFileText[id]; - l->pPath = &l->info->imagePath[id]; - l->pState = &l->info->imageState[id]; - - l->pState[0] = IMAGE_STATE_READONLY; -} - -/* change the image path */ -static char* -imageLoader_setPath( ImageLoader* l, const char* path ) -{ - path = path ? ASTRDUP(path) : NULL; - - AFREE(l->pPath[0]); - l->pPath[0] = (char*) path; - - return (char*) path; -} - -static char* -imageLoader_extractPath( ImageLoader* l ) -{ - char* result = l->pPath[0]; - l->pPath[0] = NULL; - return result; -} - -/* flags used when loading images */ -enum { - IMAGE_REQUIRED = (1<<0), /* image is required */ - IMAGE_SEARCH_SDK = (1<<1), /* search image in SDK */ - IMAGE_EMPTY_IF_MISSING = (1<<2), /* create empty file if missing */ - IMAGE_DONT_LOCK = (1<<4), /* don't try to lock image */ - IMAGE_IGNORE_IF_LOCKED = (1<<5), /* ignore file if it's locked */ -}; - -#define IMAGE_OPTIONAL 0 - -/* find an image from the SDK search directories. - * returns the full path or NULL if the file could not be found. - * - * note: this stores the result in the image's path as well - */ -static char* -imageLoader_lookupSdk( ImageLoader* l ) -{ - AvdInfo* i = l->info; - const char* image = l->imageFile; - char* temp = l->temp, *p = temp, *end = p + sizeof(l->temp); - - do { - /* try the search paths */ - int nn; - - for (nn = 0; nn < i->numSearchPaths; nn++) { - const char* searchDir = i->searchPaths[nn]; - - p = bufprint(temp, end, "%s/%s", searchDir, image); - if (p < end && path_exists(temp)) { - DD("found %s in search dir: %s", image, searchDir); - goto FOUND; - } - DD(" no %s in search dir: %s", image, searchDir); - } - - return NULL; - - } while (0); - -FOUND: - l->pState[0] = IMAGE_STATE_READONLY; - - return imageLoader_setPath(l, temp); -} - -/* search for a file in the content directory. - * returns NULL if the file cannot be found. - * - * note that this formats l->temp with the file's path - * allowing you to retrieve it if the function returns NULL - */ -static char* -imageLoader_lookupContent( ImageLoader* l ) -{ - AvdInfo* i = l->info; - char* temp = l->temp, *p = temp, *end = p + sizeof(l->temp); - - p = bufprint(temp, end, "%s/%s", i->contentPath, l->imageFile); - if (p >= end) { - derror("content directory path too long"); - exit(2); - } - if (!path_exists(temp)) { - DD(" no %s in content directory", l->imageFile); - return NULL; - } - DD("found %s in content directory", l->imageFile); - - /* assume content image files must be locked */ - l->pState[0] = IMAGE_STATE_MUSTLOCK; - - return imageLoader_setPath(l, temp); -} - -/* lock a file image depending on its state and user flags - * note that this clears l->pPath[0] if the lock could not - * be acquired and that IMAGE_IGNORE_IF_LOCKED is used. - */ -static void -imageLoader_lock( ImageLoader* l, unsigned flags ) -{ - const char* path = l->pPath[0]; - - if (flags & IMAGE_DONT_LOCK) - return; - - if (l->pState[0] != IMAGE_STATE_MUSTLOCK) - return; - - D(" locking %s image at %s", l->imageText, path); - - if (filelock_create(path) != NULL) { - /* succesful lock */ - l->pState[0] = IMAGE_STATE_LOCKED; - return; - } - - if (flags & IMAGE_IGNORE_IF_LOCKED) { - dwarning("ignoring locked %s image at %s", l->imageText, path); - imageLoader_setPath(l, NULL); - return; - } - - derror("the %s image is used by another emulator. aborting", - l->imageText); - exit(2); -} - -/* make a file image empty, this may require locking */ -static void -imageLoader_empty( ImageLoader* l, unsigned flags ) -{ - const char* path; - - imageLoader_lock(l, flags); - - path = l->pPath[0]; - if (path == NULL) /* failed to lock, caller will handle it */ - return; - - if (path_empty_file(path) < 0) { - derror("could not create %s image at %s: %s", - l->imageText, path, strerror(errno)); - exit(2); - } - l->pState[0] = IMAGE_STATE_LOCKED_EMPTY; -} - - -/* copy image file from a given source - * assumes locking is needed. - */ -static void -imageLoader_copyFrom( ImageLoader* l, const char* srcPath ) -{ - const char* dstPath = NULL; - - /* find destination file */ - if (l->params) { - dstPath = l->params->forcePaths[l->id]; - } - if (!dstPath) { - imageLoader_lookupContent(l); - dstPath = l->temp; - } - - /* lock destination */ - imageLoader_setPath(l, dstPath); - l->pState[0] = IMAGE_STATE_MUSTLOCK; - imageLoader_lock(l, 0); - - /* make the copy */ - if (path_copy_file(dstPath, srcPath) < 0) { - derror("can't initialize %s image from SDK: %s: %s", - l->imageText, dstPath, strerror(errno)); - exit(2); - } -} - -/* this will load and eventually lock and image file, depending - * on the flags being used. on exit, this function udpates - * l->pState[0] and l->pPath[0] - * - * returns the path to the file. Note that it returns NULL - * only if the file was optional and could not be found. - * - * if the file is required and missing, the function aborts - * the program. - */ -static char* -imageLoader_load( ImageLoader* l, - unsigned flags ) -{ - const char* path = NULL; - - /* set image state */ - l->pState[0] = (flags & IMAGE_DONT_LOCK) == 0 - ? IMAGE_STATE_MUSTLOCK - : IMAGE_STATE_READONLY; - - /* check user-provided path */ - path = l->params->forcePaths[l->id]; - if (path != NULL) { - imageLoader_setPath(l, path); - if (path_exists(path)) { - DD("found user-provided %s image: %s", l->imageText, l->imageFile); - goto EXIT; - } - D("user-provided %s image does not exist: %s", - l->imageText, path); - - /* if the file is required, abort */ - if (flags & IMAGE_REQUIRED) { - derror("user-provided %s image at %s doesn't exist", - l->imageText, path); - exit(2); - } - } - else { - const char* contentFile; - - /* second, look in the content directory */ - path = imageLoader_lookupContent(l); - if (path) goto EXIT; - - contentFile = ASTRDUP(l->temp); - - /* it's not there */ - if (flags & IMAGE_SEARCH_SDK) { - /* third, look in the SDK directory */ - path = imageLoader_lookupSdk(l); - if (path) { - AFREE((char*)contentFile); - goto EXIT; - } - } - DD("found no %s image (%s)", l->imageText, l->imageFile); - - /* if the file is required, abort */ - if (flags & IMAGE_REQUIRED) { - AvdInfo* i = l->info; - - derror("could not find required %s image (%s).", - l->imageText, l->imageFile); - - if (i->inAndroidBuild) { - dprint( "Did you build everything ?" ); - } else if (!i->sdkRootPathFromEnv) { - dprint( "Maybe defining %s to point to a valid SDK " - "installation path might help ?", SDK_ROOT_ENV ); - } else { - dprint( "Your %s is probably wrong: %s", SDK_ROOT_ENV, - i->sdkRootPath ); - } - exit(2); - } - - path = imageLoader_setPath(l, contentFile); - AFREE((char*)contentFile); - } - - /* otherwise, do we need to create it ? */ - if (flags & IMAGE_EMPTY_IF_MISSING) { - imageLoader_empty(l, flags); - return l->pPath[0]; - } - return NULL; - -EXIT: - imageLoader_lock(l, flags); - return l->pPath[0]; -} - -/* find the correct path of all image files we're going to need - * and lock the files that need it. - */ -static int -_avdInfo_getImagePaths(AvdInfo* i, AvdInfoParams* params ) -{ - int wipeData = (params->flags & AVDINFO_WIPE_DATA) != 0; - - ImageLoader l[1]; - - imageLoader_init(l, i, params); - - /* the data partition - this one is special because if it - * is missing, we need to copy the initial image file into it. - * - * first, try to see if it is in the content directory - * (or the user-provided path) - */ - imageLoader_set( l, AVD_IMAGE_USERDATA ); - if ( !imageLoader_load( l, IMAGE_OPTIONAL | - IMAGE_DONT_LOCK ) ) - { - /* it's not, we're going to initialize it. simply - * forcing a data wipe should be enough */ - D("initializing new data partition image: %s", l->pPath[0]); - wipeData = 1; - } - - if (wipeData) { - /* find SDK source file */ - const char* srcPath; - - imageLoader_set( l, AVD_IMAGE_INITDATA ); - if (imageLoader_lookupSdk(l) == NULL) { - derror("can't locate initial %s image in SDK", - l->imageText); - exit(2); - } - srcPath = imageLoader_extractPath(l); - - imageLoader_set( l, AVD_IMAGE_USERDATA ); - imageLoader_copyFrom( l, srcPath ); - AFREE((char*) srcPath); - } - else - { - /* lock the data partition image */ - l->pState[0] = IMAGE_STATE_MUSTLOCK; - imageLoader_lock( l, 0 ); - } - - return 0; -} - -/* If the user didn't explicitely provide an SD Card path, - * check the SDCARD_PATH key in config.ini and use that if - * available. - */ -static void -_avdInfo_getSDCardPath( AvdInfo* i, AvdInfoParams* params ) -{ - const char* path; - - if (params->forcePaths[AVD_IMAGE_SDCARD] != NULL) - return; - - path = iniFile_getString(i->configIni, SDCARD_PATH, NULL); - if (path == NULL) - return; - - params->forcePaths[AVD_IMAGE_SDCARD] = path; -} - AvdInfo* avdInfo_new( const char* name, AvdInfoParams* params ) { @@ -1199,15 +807,11 @@ avdInfo_new( const char* name, AvdInfoParams* params ) * obsolete SDKs. */ _avdInfo_getSearchPaths(i); - _avdInfo_getSDCardPath(i, params); /* don't need this anymore */ iniFile_free(i->rootIni); i->rootIni = NULL; - if ( _avdInfo_getImagePaths(i, params) < 0 ) - goto FAIL; - return i; FAIL: @@ -1239,73 +843,6 @@ FAIL: ***** the content directory, no SDK images search path. *****/ -static int -_avdInfo_getBuildImagePaths( AvdInfo* i, AvdInfoParams* params ) -{ - int wipeData = (params->flags & AVDINFO_WIPE_DATA) != 0; - - char temp[PATH_MAX]; - char* srcData; - ImageLoader l[1]; - - imageLoader_init(l, i, params); - - /** load the data partition. note that we use userdata-qemu.img - ** since we don't want to modify userdata.img at all - **/ - imageLoader_set ( l, AVD_IMAGE_USERDATA ); - imageLoader_load( l, IMAGE_OPTIONAL | IMAGE_DONT_LOCK ); - - /* get the path of the source file, and check that it actually exists - * if the user didn't provide an explicit data file - */ - srcData = imageLoader_extractPath(l); - if (srcData == NULL && params->forcePaths[AVD_IMAGE_USERDATA] == NULL) { - derror("There is no %s image in your build directory. Please make a full build", - l->imageText, l->imageFile); - exit(2); - } - - /* get the path of the target file */ - l->imageFile = "userdata-qemu.img"; - imageLoader_load( l, IMAGE_OPTIONAL | - IMAGE_EMPTY_IF_MISSING | - IMAGE_IGNORE_IF_LOCKED ); - - /* force a data wipe if we just created the image */ - if (l->pState[0] == IMAGE_STATE_LOCKED_EMPTY) - wipeData = 1; - - /* if the image was already locked, create a temp file - * then force a data wipe. - */ - if (l->pPath[0] == NULL) { - TempFile* temp = tempfile_create(); - imageLoader_setPath(l, tempfile_path(temp)); - dwarning( "Another emulator is running. user data changes will *NOT* be saved"); - wipeData = 1; - } - - /* in the case of a data wipe, copy userdata.img into - * the destination */ - if (wipeData) { - if (srcData == NULL || !path_exists(srcData)) { - derror("There is no %s image in your build directory. Please make a full build", - l->imageText, _imageFileNames[l->id]); - exit(2); - } - if (path_copy_file( l->pPath[0], srcData ) < 0) { - derror("could not initialize %s image from %s: %s", - l->imageText, temp, strerror(errno)); - exit(2); - } - } - - AFREE(srcData); - - return 0; -} - /* Read a hardware.ini if it is located in the skin directory */ static int _avdInfo_getBuildSkinHardwareIni( AvdInfo* i ) @@ -1353,8 +890,7 @@ avdInfo_newForAndroidBuild( const char* androidBuildRoot, /* There is no config.ini in the build */ i->configIni = NULL; - if (_avdInfo_getBuildImagePaths(i, params) < 0 || - _avdInfo_getCoreHwIniPath(i, i->androidOut) < 0 ) + if (_avdInfo_getCoreHwIniPath(i, i->androidOut) < 0 ) goto FAIL; /* Read the build skin's hardware.ini, if any */ @@ -1495,6 +1031,20 @@ avdInfo_getSystemInitImagePath( AvdInfo* i ) } char* +avdInfo_getDataImagePath( AvdInfo* i ) +{ + const char* imageName = _imageFileNames[ AVD_IMAGE_USERDATA ]; + return _avdInfo_getContentFilePath(i, imageName); +} + +char* +avdInfo_getDefaultDataImagePath( AvdInfo* i ) +{ + const char* imageName = _imageFileNames[ AVD_IMAGE_USERDATA ]; + return _getFullFilePath(i->contentPath, imageName); +} + +char* avdInfo_getDataInitImagePath( AvdInfo* i ) { const char* imageName = _imageFileNames[ AVD_IMAGE_INITDATA ]; diff --git a/android/avd/info.h b/android/avd/info.h index 4191165..aa3ddcd 100644 --- a/android/avd/info.h +++ b/android/avd/info.h @@ -157,6 +157,8 @@ char* avdInfo_getSystemImagePath( AvdInfo* i ); */ char* avdInfo_getSystemInitImagePath( AvdInfo* i ); +char* avdInfo_getDataImagePath( AvdInfo* i ); +char* avdInfo_getDefaultDataImagePath( AvdInfo* i ); char* avdInfo_getDataInitImagePath( AvdInfo* i ); /* Returns the path to a given AVD image file. This will return NULL if diff --git a/android/cmdline-options.h b/android/cmdline-options.h index 1494337..b9105af 100644 --- a/android/cmdline-options.h +++ b/android/cmdline-options.h @@ -83,7 +83,7 @@ OPT_FLAG ( no_snapshot_save, "do not auto-save to snapshot on exit: abandon chan OPT_FLAG ( no_snapshot_load, "do not auto-start from snapshot: perform a full boot" ) OPT_FLAG ( snapshot_list, "show a list of available snapshots" ) OPT_FLAG ( no_snapshot_update_time, "do not do try to correct snapshot time on restore" ) -OPT_FLAG ( wipe_data, "reset the use data image (copy it from initdata)" ) +OPT_FLAG ( wipe_data, "reset the user data image (copy it from initdata)" ) CFG_PARAM( avd, "<name>", "use a specific android virtual device" ) CFG_PARAM( skindir, "<dir>", "search skins in <dir> (default <system>/skins)" ) CFG_PARAM( skin, "<name>", "select a given skin" ) diff --git a/android/main-common.c b/android/main-common.c index 9e5318d..9cb97f8 100644 --- a/android/main-common.c +++ b/android/main-common.c @@ -694,23 +694,6 @@ _getSdkSystemImage( const char* path, const char* optionName, const char* fil return image; } -static void -_forceAvdImagePath( AvdImageType imageType, - const char* path, - const char* description, - int required ) -{ - if (path == NULL) - return; - - if (required && !path_exists(path)) { - derror("Cannot find %s image file: %s", description, path); - exit(1); - } - android_avdParams->forcePaths[imageType] = path; -} - - void sanitizeOptions( AndroidOptions* opts ) { /* legacy support: we used to use -system <dir> and -image <file> @@ -811,18 +794,6 @@ AvdInfo* createAVD(AndroidOptions* opts, int* inAndroidBuild) char* android_build_root = NULL; char* android_build_out = NULL; - /* setup the virtual device parameters from our options - */ - if (opts->no_cache) { - android_avdParams->flags |= AVDINFO_NO_CACHE; - } - if (opts->wipe_data) { - android_avdParams->flags |= AVDINFO_WIPE_DATA | AVDINFO_WIPE_CACHE; - } - if (opts->no_snapstorage) { - android_avdParams->flags |= AVDINFO_NO_SNAPSHOTS; - } - /* If no AVD name was given, try to find the top of the * Android build tree */ @@ -926,16 +897,6 @@ AvdInfo* createAVD(AndroidOptions* opts, int* inAndroidBuild) } } - /* if certain options are set, we can force the path of - * certain kernel/disk image files - */ - _forceAvdImagePath(AVD_IMAGE_INITSYSTEM, opts->system, "system", 1); - _forceAvdImagePath(AVD_IMAGE_USERDATA, opts->data, "user data", 0); - _forceAvdImagePath(AVD_IMAGE_SNAPSHOTS, opts->snapstorage, "snapshots", 0); - - android_avdParams->skinName = opts->skin; - android_avdParams->skinRootPath = opts->skindir; - /* setup the virtual device differently depending on whether * we are in the Android build system or not */ @@ -973,111 +934,6 @@ AvdInfo* createAVD(AndroidOptions* opts, int* inAndroidBuild) return ret; } -static int -_is_valid_hw_disk_path(const char* path) -{ - if (path == NULL || '\0' == *path || !strcmp(path, "<init>")) { - return 0; - } - return 1; -} - -static int -_update_hwconfig_path(char** path, AvdInfo* avd, int image_type) -{ - if (!_is_valid_hw_disk_path(*path)) { - *path = android_strdup(avdInfo_getImageFile(avd, image_type)); - if (!_is_valid_hw_disk_path(*path)) { - return -1; - } - } - return 0; -} - -static uint64_t -_adjustPartitionSize( const char* description, - uint64_t imageBytes, - uint64_t defaultBytes, - int inAndroidBuild ) -{ - char temp[64]; - unsigned imageMB; - unsigned defaultMB; - - if (imageBytes <= defaultBytes) - return defaultBytes; - - imageMB = convertBytesToMB(imageBytes); - defaultMB = convertBytesToMB(defaultBytes); - - if (imageMB > defaultMB) { - snprintf(temp, sizeof temp, "(%d MB > %d MB)", imageMB, defaultMB); - } else { - snprintf(temp, sizeof temp, "(%lld bytes > %lld bytes)", imageBytes, defaultBytes); - } - - if (inAndroidBuild) { - dwarning("%s partition size adjusted to match image file %s\n", description, temp); - } - - return convertMBToBytes(imageMB); -} - -void -updateHwConfigFromAVD(AndroidHwConfig* hwConfig, - AvdInfo* avd, - AndroidOptions* opts, - int inAndroidBuild) -{ - unsigned defaultPartitionSize = convertMBToBytes(66); - - _update_hwconfig_path(&hwConfig->disk_dataPartition_path, avd, AVD_IMAGE_USERDATA); - _update_hwconfig_path(&hwConfig->disk_dataPartition_path, avd, AVD_IMAGE_INITDATA); - - if (opts->partition_size) { - char* end; - long sizeMB = strtol(opts->partition_size, &end, 0); - long minSizeMB = 10; - long maxSizeMB = LONG_MAX / ONE_MB; - - if (sizeMB < 0 || *end != 0) { - derror( "-partition-size must be followed by a positive integer" ); - exit(1); - } - if (sizeMB < minSizeMB || sizeMB > maxSizeMB) { - derror( "partition-size (%d) must be between %dMB and %dMB", - sizeMB, minSizeMB, maxSizeMB ); - exit(1); - } - defaultPartitionSize = sizeMB * ONE_MB; - } - /* Check the size of the /data partition. The only interesting cases here are: - * - when the USERDATA image already exists and is larger than the default - * - when we're wiping data and the INITDATA is larger than the default. - */ - - { - const char* dataPath = avdInfo_getImageFile(avd, AVD_IMAGE_USERDATA); - uint64_t defaultBytes = defaultPartitionSize; - - if (defaultBytes == 0 || opts->partition_size) - defaultBytes = defaultPartitionSize; - - if (dataPath == NULL || !path_exists(dataPath) || opts->wipe_data) { - dataPath = avdInfo_getImageFile(avd, AVD_IMAGE_INITDATA); - } - if (dataPath == NULL || !path_exists(dataPath)) { - hwConfig->disk_dataPartition_size = defaultBytes; - } - else { - uint64_t dataBytes; - path_get_size(dataPath, &dataBytes); - - hwConfig->disk_dataPartition_size = - _adjustPartitionSize("data", dataBytes, defaultBytes, inAndroidBuild); - } - } -} diff --git a/android/main.c b/android/main.c index 33a96ea..808ca4d 100644 --- a/android/main.c +++ b/android/main.c @@ -309,9 +309,6 @@ int main(int argc, char **argv) exit(1); } - /* Update HW config with the AVD information. */ - updateHwConfigFromAVD(hw, avd, opts, inAndroidBuild); - if (opts->keyset) { parse_keyset(opts->keyset, opts); if (!android_keyset) { @@ -583,13 +580,70 @@ int main(int argc, char **argv) /** DATA PARTITION **/ - bufprint(tmp, tmpend, - "userdata,size=0x%x,file=%s", - (uint32_t)hw->disk_dataPartition_size, - avdInfo_getImageFile(avd, AVD_IMAGE_USERDATA)); + if (opts->datadir) { + if (!path_exists(opts->datadir)) { + derror("Invalid -datadir directory: %s", opts->datadir); + } + } + + { + char* dataImage = NULL; + char* initImage = NULL; + + do { + if (!opts->data) { + dataImage = avdInfo_getDataImagePath(avd); + if (dataImage != NULL) { + D("autoconfig: -data %s", dataImage); + break; + } + dataImage = avdInfo_getDefaultDataImagePath(avd); + if (dataImage == NULL) { + derror("No data image path for this configuration!"); + exit (1); + } + opts->wipe_data = 1; + break; + } - args[n++] = "-nand"; - args[n++] = strdup(tmp); + if (opts->datadir) { + dataImage = _getFullFilePath(opts->datadir, opts->data); + } else { + dataImage = ASTRDUP(opts->data); + } + } while (0); + + if (opts->initdata != NULL) { + initImage = ASTRDUP(opts->initdata); + if (!path_exists(initImage)) { + derror("Invalid initial data image path: %s", initImage); + exit(1); + } + } else { + initImage = avdInfo_getDataInitImagePath(avd); + D("autoconfig: -initdata %s", initImage); + } + + hw->disk_dataPartition_path = dataImage; + if (opts->wipe_data) { + hw->disk_dataPartition_initPath = initImage; + } else { + hw->disk_dataPartition_initPath = NULL; + } + + uint64_t defaultBytes = defaultPartitionSize; + uint64_t dataBytes; + const char* dataPath = hw->disk_dataPartition_initPath; + + if (dataPath == NULL) + dataPath = hw->disk_dataPartition_path; + + path_get_size(dataPath, &dataBytes); + + hw->disk_dataPartition_size = + _adjustPartitionSize("data", dataBytes, defaultBytes, + avdInfo_inAndroidBuild(avd)); + } /** CACHE PARTITION **/ diff --git a/hw/goldfish_nand.c b/hw/goldfish_nand.c index c9567d3..6d2182f 100644 --- a/hw/goldfish_nand.c +++ b/hw/goldfish_nand.c @@ -794,7 +794,7 @@ void nand_add_dev(const char *arg) exit(1); } if(do_write(rwfd, dev->data, read_size) != read_size) { - XLOG("could not write file %s, %s\n", initfilename, strerror(errno)); + XLOG("could not write file %s, %s\n", rwfilename, strerror(errno)); exit(1); } } while(read_size == dev->erase_size); diff --git a/vl-android.c b/vl-android.c index 36289e4..fd587ae 100644 --- a/vl-android.c +++ b/vl-android.c @@ -4877,6 +4877,40 @@ int main(int argc, char **argv, char **envp) nand_add_dev(tmp); } + /* Initialize data partition image */ + { + char tmp[PATH_MAX+32]; + const char* dataImage = android_hw->disk_dataPartition_path; + const char* initImage = android_hw->disk_dataPartition_initPath; + uint64_t dataBytes = android_hw->disk_dataPartition_size; + + if (dataBytes == 0) { + PANIC("Invalid data partition size: %" PRUd64, dataBytes); + } + + snprintf(tmp,sizeof(tmp),"userdata,size=0x%" PRUx64, dataBytes); + + if (dataImage && *dataImage) { + if (filelock_create(dataImage) == NULL) { + fprintf(stderr, "WARNING: Data partition already in use. Changes will not persist!\n"); + /* Note: if there is no file= parameters, nand_add_dev() will + * create a temporary file to back the partition image. */ + } else { + /* Create the file if needed */ + if (!path_exists(dataImage)) { + path_empty_file(dataImage); + } + pstrcat(tmp, sizeof(tmp), ",file="); + pstrcat(tmp, sizeof(tmp), dataImage); + } + } + if (initImage && *initImage) { + pstrcat(tmp, sizeof(tmp), ",initfile="); + pstrcat(tmp, sizeof(tmp), initImage); + } + nand_add_dev(tmp); + } + /* Init SD-Card stuff. For Android, it is always hda */ /* If the -hda option was used, ignore the Android-provided one */ if (hda_opts == NULL) { |