diff options
-rw-r--r-- | android/avd/hardware-properties.ini | 23 | ||||
-rw-r--r-- | android/avd/hw-config-defs.h | 12 | ||||
-rw-r--r-- | android/avd/info.c | 50 | ||||
-rw-r--r-- | android/avd/info.h | 9 | ||||
-rw-r--r-- | android/main-common.c | 25 | ||||
-rw-r--r-- | android/main.c | 160 | ||||
-rw-r--r-- | vl-android.c | 36 |
7 files changed, 225 insertions, 90 deletions
diff --git a/android/avd/hardware-properties.ini b/android/avd/hardware-properties.ini index 69abdaa..5ecfcc4 100644 --- a/android/avd/hardware-properties.ini +++ b/android/avd/hardware-properties.ini @@ -222,26 +222,33 @@ default = abstract = Path to the ramdisk image description = Path to the ramdisk image. -# Path to the system partition. +# System partition image(s). +# +# disk.systemPartition.path points to the read/write system partition image. +# if empty, a temporary file will be created, initialized with the content +# of .initPath +# +# disk.systemPartition.initPath is only used when .path is empty. It must +# then point to a read-only initialization system image file. +# +# disk.systemPartition.size is the ideal size of the system partition. The +# size is ignored if the actual system partition image is larger. Otherwise, +# it indicates the maximum size the disk image file can grow to. +# name = disk.systemPartition.path type = string -default = <init> -abstract = Path to system partition image -description = Path to read/write system partition image during emulation. If special value '<init>' is used, a temporary file will be created, populated with the content of .initPath +default = +abstract = Path to runtime system partition image -# Initial path to the system partition. name = disk.systemPartition.initPath type = string default = abstract = Initial system partition image -description = Only used if .path is '<init>', path to an initial system image that will be copied into the temporary system image file before launch. -# System partition size. name = disk.systemPartition.size type = diskSize default = 0 abstract = Ideal size of system partition -description = ideal size of system partition. Ignored if smaller than the size of .path (or .initPath). Otherwise, gives the maximum size the partition is allowed to grow dynamically. # Path to the data partition. name = disk.dataPartition.path diff --git a/android/avd/hw-config-defs.h b/android/avd/hw-config-defs.h index 6c8ccae..e2def30 100644 --- a/android/avd/hw-config-defs.h +++ b/android/avd/hw-config-defs.h @@ -223,23 +223,23 @@ HWCFG_STRING( HWCFG_STRING( disk_systemPartition_path, "disk.systemPartition.path", - "<init>", - "Path to system partition image", - "Path to read/write system partition image during emulation. If special value '<init>' is used, a temporary file will be created, populated with the content of .initPath") + "", + "Path to runtime system partition image", + "") HWCFG_STRING( disk_systemPartition_initPath, "disk.systemPartition.initPath", "", "Initial system partition image", - "Only used if .path is '<init>', path to an initial system image that will be copied into the temporary system image file before launch.") + "") HWCFG_DISKSIZE( disk_systemPartition_size, "disk.systemPartition.size", "0", "Ideal size of system partition", - "ideal size of system partition. Ignored if smaller than the size of .path (or .initPath). Otherwise, gives the maximum size the partition is allowed to grow dynamically.") + "") HWCFG_STRING( disk_dataPartition_path, @@ -260,7 +260,7 @@ HWCFG_DISKSIZE( "disk.dataPartition.size", "0", "Ideal size of data partition", - "ideal size of data partition. Ignored if smaller than the size of .path (or .initPath). Otherwise, gives the maximum size the partition is allowed to grow dynamically.") + "") HWCFG_STRING( disk_snapStorage_path, diff --git a/android/avd/info.c b/android/avd/info.c index ca4f0cf..a23cd63 100644 --- a/android/avd/info.c +++ b/android/avd/info.c @@ -470,6 +470,7 @@ _checkSkinSkinsDir( const char* skinDirRoot, char temp[MAX_PATH], *p = temp, *end = p + sizeof(temp); p = bufprint(temp, end, "%s/skins/%s", skinDirRoot, skinName); + DD("Probing skin directory: %s", temp); if (p >= end || !path_exists(temp)) { DD(" ignore bad skin directory %s", temp); return NULL; @@ -1098,31 +1099,6 @@ EXIT: return l->pPath[0]; } -/* Attempts to load an AVD image, but does not kill the process if loading - * fails. - */ -static void -imageLoader_loadOptional( ImageLoader *l, AvdImageType img_type, - const char *forcedPath ) -{ - imageLoader_set (l, img_type); - imageLoader_load(l, IMAGE_OPTIONAL | - IMAGE_IGNORE_IF_LOCKED); - - /* if the file was not found, ignore it */ - if (l->pPath[0] && !path_exists(l->pPath[0])) - { - D("ignoring non-existing %s at %s: %s", - l->imageText, l->pPath[0], strerror(errno)); - - /* if the user provided the path by hand, warn him. */ - if (forcedPath != NULL) - dwarning("ignoring non-existing %s image", l->imageText); - - imageLoader_setPath(l, NULL); - } -} - /* find the correct path of all image files we're going to need * and lock the files that need it. */ @@ -1135,14 +1111,6 @@ _avdInfo_getImagePaths(AvdInfo* i, AvdInfoParams* params ) imageLoader_init(l, i, params); - /* the system image - * - * if there is one in the content directory just lock - * and use it. - */ - imageLoader_set ( l, AVD_IMAGE_INITSYSTEM ); - imageLoader_load( l, IMAGE_REQUIRED | IMAGE_SEARCH_SDK | IMAGE_DONT_LOCK ); - /* the data partition - this one is special because if it * is missing, we need to copy the initial image file into it. * @@ -1335,15 +1303,6 @@ _avdInfo_getBuildImagePaths( AvdInfo* i, AvdInfoParams* params ) AFREE(srcData); - /** load the system image. read-only. the caller must - ** take care of checking the state - **/ - imageLoader_set ( l, AVD_IMAGE_INITSYSTEM ); - imageLoader_load( l, IMAGE_REQUIRED | IMAGE_DONT_LOCK ); - - /* force the system image to read-only status */ - l->pState[0] = IMAGE_STATE_READONLY; - return 0; } @@ -1522,6 +1481,13 @@ avdInfo_getSnapStoragePath( AvdInfo* i ) } char* +avdInfo_getSystemImagePath( AvdInfo* i ) +{ + const char* imageName = _imageFileNames[ AVD_IMAGE_USERSYSTEM ]; + return _avdInfo_getContentFilePath(i, imageName); +} + +char* avdInfo_getSystemInitImagePath( AvdInfo* i ) { const char* imageName = _imageFileNames[ AVD_IMAGE_INITSYSTEM ]; diff --git a/android/avd/info.h b/android/avd/info.h index afc71fb..4191165 100644 --- a/android/avd/info.h +++ b/android/avd/info.h @@ -147,7 +147,16 @@ char* avdInfo_getCachePath( AvdInfo* i ); char* avdInfo_getDefaultCachePath( AvdInfo* i ); +/* avdInfo_getSystemImagePath() will return NULL, except if the AVD content + * directory contains a file named "system-qemu.img". + */ +char* avdInfo_getSystemImagePath( AvdInfo* i ); + +/* avdInfo_getSystemInitImagePath() retrieves the path to the read-only + * initialization image for this disk image. + */ char* avdInfo_getSystemInitImagePath( 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/main-common.c b/android/main-common.c index 740f59a..9e5318d 100644 --- a/android/main-common.c +++ b/android/main-common.c @@ -1031,13 +1031,7 @@ updateHwConfigFromAVD(AndroidHwConfig* hwConfig, { unsigned defaultPartitionSize = convertMBToBytes(66); - if (_update_hwconfig_path(&hwConfig->disk_systemPartition_initPath, avd, AVD_IMAGE_INITSYSTEM)) { - dprint("system path %s is invalid", hwConfig->disk_systemPartition_initPath); - exit(1); - } - _update_hwconfig_path(&hwConfig->disk_dataPartition_path, avd, AVD_IMAGE_USERDATA); - _update_hwconfig_path(&hwConfig->disk_systemPartition_path, avd, AVD_IMAGE_USERSYSTEM); _update_hwconfig_path(&hwConfig->disk_dataPartition_path, avd, AVD_IMAGE_INITDATA); if (opts->partition_size) { @@ -1057,25 +1051,6 @@ updateHwConfigFromAVD(AndroidHwConfig* hwConfig, } defaultPartitionSize = sizeMB * ONE_MB; } - - /* Check the size of the system partition image. - * If we have an AVD, it must be smaller than - * the disk.systemPartition.size hardware property. - * - * Otherwise, we need to adjust the systemPartitionSize - * automatically, and print a warning. - * - */ - { - uint64_t systemBytes = avdInfo_getImageFileSize(avd, AVD_IMAGE_INITSYSTEM); - uint64_t defaultBytes = defaultPartitionSize; - - if (defaultBytes == 0 || opts->partition_size) - defaultBytes = defaultPartitionSize; - hwConfig->disk_systemPartition_size = - _adjustPartitionSize("system", systemBytes, defaultBytes, inAndroidBuild); - } - /* 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. diff --git a/android/main.c b/android/main.c index 240574a..33a96ea 100644 --- a/android/main.c +++ b/android/main.c @@ -108,6 +108,52 @@ void emulator_help( void ) exit(1); } +/* TODO: Put in shared source file */ +static char* +_getFullFilePath( const char* rootPath, const char* fileName ) +{ + if (path_is_absolute(fileName)) { + return ASTRDUP(fileName); + } else { + char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); + + p = bufprint(temp, end, "%s/%s", rootPath, fileName); + if (p >= end) { + return NULL; + } + return ASTRDUP(temp); + } +} + +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); +} + int main(int argc, char **argv) { char tmp[MAX_PATH]; @@ -126,6 +172,7 @@ int main(int argc, char **argv) AConfig* skinConfig; char* skinPath; int inAndroidBuild; + uint64_t defaultPartitionSize = convertMBToBytes(66); AndroidOptions opts[1]; /* net.shared_net_ip boot property value. */ @@ -426,21 +473,116 @@ int main(int argc, char **argv) hw->disk_ramdisk_path = avdInfo_getRamdiskPath(avd); D("autoconfig: -ramdisk %s", hw->disk_ramdisk_path); + /* -partition-size is used to specify the max size of both the system + * and data partition sizes. + */ + 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 = (uint64_t) sizeMB * ONE_MB; + } + + + /** SYSTEM PARTITION **/ + + if (opts->sysdir == NULL) { + if (avdInfo_inAndroidBuild(avd)) { + opts->sysdir = ASTRDUP(avdInfo_getContentPath(avd)); + D("autoconfig: -sysdir %s", opts->sysdir); + } + } + + if (opts->sysdir != NULL) { + if (!path_exists(opts->sysdir)) { + derror("Directory does not exist: %s", opts->sysdir); + exit(1); + } + } + { - const char* filetype = "file"; + char* rwImage = NULL; + char* initImage = NULL; + + do { + if (opts->system == NULL) { + /* If -system is not used, try to find a runtime system image + * (i.e. system-qemu.img) in the content directory. + */ + rwImage = avdInfo_getSystemImagePath(avd); + if (rwImage != NULL) { + break; + } + /* Otherwise, try to find the initial system image */ + initImage = avdInfo_getSystemInitImagePath(avd); + if (initImage == NULL) { + derror("No initial system image for this configuration!"); + exit(1); + } + break; + } - // TODO: This should go to core - if (avdInfo_isImageReadOnly(avd, AVD_IMAGE_INITSYSTEM)) - filetype = "initfile"; + /* If -system <name> is used, use it to find the initial image */ + if (opts->sysdir != NULL) { + initImage = _getFullFilePath(opts->sysdir, opts->system); + } else { + initImage = ASTRDUP(opts->system); + } + if (!path_exists(initImage)) { + derror("System image file doesn't exist: %s", initImage); + exit(1); + } - bufprint(tmp, tmpend, - "system,size=0x%x,%s=%s", (uint32_t)hw->disk_systemPartition_size, - filetype, avdInfo_getImageFile(avd, AVD_IMAGE_INITSYSTEM)); + } while (0); + + if (rwImage != NULL) { + /* Use the read/write image file directly */ + hw->disk_systemPartition_path = rwImage; + hw->disk_systemPartition_initPath = NULL; + D("Using direct system image: %s", rwImage); + } else if (initImage != NULL) { + hw->disk_systemPartition_path = NULL; + hw->disk_systemPartition_initPath = initImage; + D("Using initial system image: %s", initImage); + } - args[n++] = "-nand"; - args[n++] = strdup(tmp); + /* Check the size of the system partition image. + * If we have an AVD, it must be smaller than + * the disk.systemPartition.size hardware property. + * + * Otherwise, we need to adjust the systemPartitionSize + * automatically, and print a warning. + * + */ + const char* systemImage = hw->disk_systemPartition_path; + uint64_t systemBytes; + + if (systemImage == NULL) + systemImage = hw->disk_systemPartition_initPath; + + if (path_get_size(systemImage, &systemBytes) < 0) { + derror("Missing system image: %s", systemImage); + exit(1); + } + + hw->disk_systemPartition_size = + _adjustPartitionSize("system", systemBytes, defaultPartitionSize, + avdInfo_inAndroidBuild(avd)); } + /** DATA PARTITION **/ + bufprint(tmp, tmpend, "userdata,size=0x%x,file=%s", (uint32_t)hw->disk_dataPartition_size, diff --git a/vl-android.c b/vl-android.c index 04fed59..36289e4 100644 --- a/vl-android.c +++ b/vl-android.c @@ -60,6 +60,7 @@ #include "android/utils/filelock.h" #include "android/utils/path.h" #include "android/utils/stralloc.h" +#include "android/utils/tempfile.h" #include "android/display-core.h" #include "android/utils/timezone.h" #include "android/snapshot.h" @@ -4841,6 +4842,41 @@ int main(int argc, char **argv, char **envp) } #endif // CONFIG_NAND_LIMITS + /* Initialize system partition image */ + { + char tmp[PATH_MAX+32]; + const char* sysImage = android_hw->disk_systemPartition_path; + const char* initImage = android_hw->disk_systemPartition_initPath; + uint64_t sysBytes = android_hw->disk_systemPartition_size; + + if (sysBytes == 0) { + PANIC("Invalid system partition size: %" PRUd64, sysBytes); + } + + snprintf(tmp,sizeof(tmp),"system,size=0x%" PRUx64, sysBytes); + + if (sysImage && *sysImage) { + if (filelock_create(sysImage) == NULL) { + fprintf(stderr,"WARNING: System image already in use, changes will not persist!\n"); + /* If there is no file= parameters, nand_add_dev will create + * a temporary file to back the partition image. */ + } else { + pstrcat(tmp,sizeof(tmp),",file="); + pstrcat(tmp,sizeof(tmp),sysImage); + } + } + if (initImage && *initImage) { + if (!path_exists(initImage)) { + PANIC("Invalid initial system image path: %s", initImage); + } + pstrcat(tmp,sizeof(tmp),",initfile="); + pstrcat(tmp,sizeof(tmp),initImage); + } else { + PANIC("Missing initial system image path!"); + } + 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) { |