Merge changes I5d034506,I05390f79
* changes:
[MIPS64] target-mips : implement unaligned loads using TCG
[MIPS] Refactor page table walk
diff --git a/Makefile.qemu-launcher b/Makefile.qemu-launcher
index 9c26567..16c1dbf 100644
--- a/Makefile.qemu-launcher
+++ b/Makefile.qemu-launcher
@@ -26,6 +26,9 @@
LOCAL_CFLAGS := $(qemu_launcher_CFLAGS)
LOCAL_STATIC_LIBRARIES := \
emulator-common \
+ emulator-libext4_utils \
+ emulator-libsparse \
+ emulator-libselinux \
emulator-zlib
LOCAL_LDLIBS := $(qemu_launcher_LDLIBS)
$(call gen-hw-config-defs)
@@ -36,6 +39,9 @@
LOCAL_CFLAGS := $(qemu_launcher_CFLAGS)
LOCAL_STATIC_LIBRARIES := \
emulator64-common \
+ emulator64-libext4_utils \
+ emulator64-libsparse \
+ emulator64-libselinux \
emulator64-zlib
LOCAL_LDLIBS := $(qemu_launcher_LDLIBS)
$(call gen-hw-config-defs)
diff --git a/android-configure.sh b/android-configure.sh
index 3e13cc2..5d5e725 100755
--- a/android-configure.sh
+++ b/android-configure.sh
@@ -31,6 +31,8 @@
PCBIOS_PROBE=yes
+QEMU_PREBUILTS_DIR=
+
HOST_CC=${CC:-gcc}
OPTION_CC=
@@ -68,6 +70,8 @@
;;
--gles-dir=*) GLES_DIR=$optarg
;;
+ --qemu-prebuilts-dir=*) QEMU_PREBUILTS_DIR=$optarg
+ ;;
--no-gles) GLES_PROBE=no
;;
--no-pcbios) PCBIOS_PROBE=no
@@ -90,23 +94,24 @@
Options: [defaults in brackets after descriptions]
EOF
echo "Standard options:"
- echo " --help print this message"
- echo " --install=FILEPATH copy emulator executable to FILEPATH [$TARGETS]"
- echo " --cc=PATH specify C compiler [$HOST_CC]"
- echo " --sdl-config=FILE use specific sdl-config script [$SDL_CONFIG]"
- echo " --no-strip do not strip emulator executable"
- echo " --debug enable debug (-O0 -g) build"
- echo " --ignore-audio ignore audio messages (may build sound-less emulator)"
- echo " --no-prebuilts do not use prebuilt libraries and compiler"
- echo " --out-dir=<path> use specific output directory [objs/]"
- echo " --mingw build Windows executable on Linux"
- echo " --static build a completely static executable"
- echo " --verbose verbose configuration"
- echo " --debug build debug version of the emulator"
- echo " --gles-dir=PATH specify path to GLES host emulation sources [auto-detected]"
- echo " --no-gles disable GLES emulation support"
- echo " --no-pcbios disable copying of PC Bios files"
- echo " --no-tests don't run unit test suite"
+ echo " --help Print this message"
+ echo " --install=FILEPATH Copy emulator executable to FILEPATH [$TARGETS]"
+ echo " --cc=PATH Specify C compiler [$HOST_CC]"
+ echo " --sdl-config=FILE Use specific sdl-config script [$SDL_CONFIG]"
+ echo " --no-strip Do not strip emulator executable"
+ echo " --debug Enable debug (-O0 -g) build"
+ echo " --ignore-audio Ignore audio messages (may build sound-less emulator)"
+ echo " --no-prebuilts Do not use prebuilt libraries and compiler"
+ echo " --out-dir=<path> Use specific output directory [objs/]"
+ echo " --mingw Build Windows executable on Linux"
+ echo " --static Build a completely static executable"
+ echo " --verbose Verbose configuration"
+ echo " --debug Build debug version of the emulator"
+ echo " --gles-dir=PATH Specify path to GLES host emulation sources [auto-detected]"
+ echo " --qemu-prebuilts-dir=PATH Specify path to QEMU prebuilt binaries"
+ echo " --no-gles Disable GLES emulation support"
+ echo " --no-pcbios Disable copying of PC Bios files"
+ echo " --no-tests Don't run unit test suite"
echo ""
exit 1
fi
@@ -753,6 +758,15 @@
python scripts/qapi-commands.py --output-dir=$AUTOGENERATED_DIR -m < qapi-schema.json
log "Generate : $AUTOGENERATED_DIR"
+if [ "$QEMU_PREBUILTS_DIR" ]; then
+ if [ ! -d "$QEMU_PREBUILTS_DIR/binaries" ]; then
+ panic "Missing QEMU prebuilts directory: $QEMU_PREBUILTS_DIR/binaries"
+ fi
+ log "Copying QEMU prebuilt binaries to: $OUT_DIR/qemu"
+ mkdir -p "$OUT_DIR"/qemu || panic "Could not create $OUT_DIR/qemu"
+ cp -rp "$QEMU_PREBUILTS_DIR/binaries"/* "$OUT_DIR/qemu"
+fi
+
clean_temp
echo "Ready to go. Type 'make' to build emulator"
diff --git a/android/avd/util.c b/android/avd/util.c
index 51236ac..39e25d9 100644
--- a/android/avd/util.c
+++ b/android/avd/util.c
@@ -170,6 +170,7 @@
} kData[] = {
{ "armeabi", "arm" },
{ "armeabi-v7a", "arm" },
+ { "arm64-v8a", "arm64" },
};
size_t n;
for (n = 0; n < sizeof(kData)/sizeof(kData[0]); ++n) {
diff --git a/android/kernel/kernel_utils.cpp b/android/kernel/kernel_utils.cpp
index cbc4f4e..5f5ace8 100755
--- a/android/kernel/kernel_utils.cpp
+++ b/android/kernel/kernel_utils.cpp
@@ -34,14 +34,13 @@
using android::base::PodVector;
-namespace android {
-namespace kernel {
+namespace {
-static const char kVersionStringPrefix[] = "Linux version ";
-static const size_t kVersionStringPrefixLen = sizeof(kVersionStringPrefix) - 1U;
+const char kLinuxVersionStringPrefix[] = "Linux version ";
+const size_t kLinuxVersionStringPrefixLen =
+ sizeof(kLinuxVersionStringPrefix) - 1U;
-} // namespace kernel
-} // namespace android
+} // namespace
#ifndef __APPLE__
size_t strlcpy(char* dst, const char * src, size_t size)
@@ -84,13 +83,13 @@
bool android_parseLinuxVersionString(const char* versionString,
KernelVersion* kernelVersion) {
- if (strncmp(versionString, android::kernel::kVersionStringPrefix,
- android::kernel::kVersionStringPrefixLen)) {
+ if (strncmp(versionString, kLinuxVersionStringPrefix,
+ kLinuxVersionStringPrefixLen)) {
KERNEL_ERROR << "unsupported kernel version string:" << versionString;
return false;
}
// skip past the prefix to the version number
- versionString += android::kernel::kVersionStringPrefixLen;
+ versionString += kLinuxVersionStringPrefixLen;
uint32_t temp = 0;
for (int i = 0; i < 3; i++) {
@@ -139,6 +138,8 @@
return false;
}
+ const char* versionStringStart = NULL;
+
if (0 == memcmp(kElfHeader, kernelFileData, sizeof(kElfHeader))) {
// this is an uncompressed ELF file (probably mips)
uncompressedKernel = kernelFileData;
@@ -156,37 +157,49 @@
return false;
}
- size_t compressedKernelLen = kernelFileSize -
- (compressedKernel - kernelFileData);
+ // Special case: certain images, like the ARM64 one, contain a GZip
+ // header _after_ the actual Linux version string. So first try to
+ // see if there is something before the header.
+ versionStringStart = (const char*)memmem(
+ kernelFileData,
+ (compressedKernel - kernelFileData),
+ kLinuxVersionStringPrefix,
+ kLinuxVersionStringPrefixLen);
- // inflate ratios for all prebuilt kernels on 2014-07-14 is 1.9:1 ~
- // 3.43:1 not sure how big the uncompressed size is, so make an
- // absurdly large buffer
- uncompressedKernelLen = compressedKernelLen * 10;
- uncompressed.resize(uncompressedKernelLen);
- uncompressedKernel = uncompressed.begin();
+ if (!versionStringStart) {
+ size_t compressedKernelLen = kernelFileSize -
+ (compressedKernel - kernelFileData);
- bool zOk = uncompress_gzipStream(uncompressed.begin(),
- &uncompressedKernelLen,
- compressedKernel,
- compressedKernelLen);
- if (!zOk) {
- KERNEL_ERROR << "Kernel decompression error";
- // it may have been partially decompressed, so we're going to
- // try to find the version string anyway
+ // inflate ratios for all prebuilt kernels on 2014-07-14 is 1.9:1 ~
+ // 3.43:1 not sure how big the uncompressed size is, so make an
+ // absurdly large buffer
+ uncompressedKernelLen = compressedKernelLen * 10;
+ uncompressed.resize(uncompressedKernelLen);
+ uncompressedKernel = uncompressed.begin();
+
+ bool zOk = uncompress_gzipStream(uncompressed.begin(),
+ &uncompressedKernelLen,
+ compressedKernel,
+ compressedKernelLen);
+ if (!zOk) {
+ KERNEL_ERROR << "Kernel decompression error";
+ // it may have been partially decompressed, so we're going to
+ // try to find the version string anyway
+ }
}
}
- // okay, now we have a pointer to an uncompressed kernel, let's find the
- // version string
- const char* versionStringStart = (const char*)memmem(
- uncompressedKernel,
- uncompressedKernelLen,
- android::kernel::kVersionStringPrefix,
- android::kernel::kVersionStringPrefixLen);
if (!versionStringStart) {
- KERNEL_ERROR << "Could not find 'Linux version ' in kernel!";
- return false;
+ versionStringStart = (const char*)memmem(
+ uncompressedKernel,
+ uncompressedKernelLen,
+ kLinuxVersionStringPrefix,
+ kLinuxVersionStringPrefixLen);
+
+ if (!versionStringStart) {
+ KERNEL_ERROR << "Could not find 'Linux version ' in kernel!";
+ return false;
+ }
}
strlcpy(dst, versionStringStart, dstLen);
diff --git a/android/kernel/kernel_utils_unittest.cpp b/android/kernel/kernel_utils_unittest.cpp
index 40ad06c..f24845a 100755
--- a/android/kernel/kernel_utils_unittest.cpp
+++ b/android/kernel/kernel_utils_unittest.cpp
@@ -85,6 +85,27 @@
0x00, 0x00, 0x00
};
+ // a mock semi-compressed kernel
+ // an unspecified number of bytes, followed by a version string,
+ // followed by a gzip header
+ static const unsigned char kMockKernelSemiCompressed[] = {
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x39, 0x61,
+ 0x62, 0x63, 0x64, 0x65, 0x66, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20, 0x76,
+ 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x2e, 0x31, 0x30, 0x2e,
+ 0x30, 0x2b, 0x20, 0x28, 0x76, 0x68, 0x61, 0x72, 0x72, 0x6f, 0x6e, 0x40,
+ 0x74, 0x69, 0x66, 0x61, 0x2e, 0x6d, 0x74, 0x76, 0x2e, 0x63, 0x6f, 0x72,
+ 0x70, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x29, 0x20, 0x28, 0x67, 0x63, 0x63, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
+ 0x6f, 0x6e, 0x20, 0x34, 0x2e, 0x37, 0x20, 0x28, 0x47, 0x43, 0x43, 0x29,
+ 0x20, 0x29, 0x20, 0x23, 0x31, 0x20, 0x50, 0x52, 0x45, 0x45, 0x4d, 0x50,
+ 0x54, 0x20, 0x53, 0x61, 0x74, 0x20, 0x4a, 0x61, 0x6e, 0x20, 0x35, 0x20,
+ 0x32, 0x3a, 0x34, 0x35, 0x3a, 0x32, 0x34, 0x20, 0x50, 0x44, 0x54, 0x20,
+ 0x32, 0x30, 0x30, 0x38, 0x0a, 0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x35,
+ 0x37, 0x38, 0x39, 0x1f, 0x8b, 0x08, 0x00, 0x3e, 0xa9, 0xc7, 0x53, 0x00,
+ 0x03, 0x0b, 0xf7, 0x70, 0x0c, 0x71, 0x0d, 0x73, 0x0d, 0x02, 0x00, 0xff,
+ 0xdf, 0x22, 0x88, 0x08, 0x00, 0x00, 0x00
+ };
+
char kernelVersionString[256];
kernelVersionString[0] = 0;
@@ -103,8 +124,16 @@
sizeof(kernelVersionString)));
EXPECT_STREQ(kMockKernelVersion, kernelVersionString);
+ kernelVersionString[0] = 0;
+ EXPECT_EQ(true, android_imageProbeKernelVersionString(
+ kMockKernelSemiCompressed,
+ sizeof(kMockKernelSemiCompressed),
+ kernelVersionString,
+ sizeof(kernelVersionString)));
+ EXPECT_STREQ(kMockKernelVersion, kernelVersionString);
+
kernelVersionString[0] = 127;
- EXPECT_EQ(false, android_imageProbeKernelVersionString(
+ EXPECT_FALSE(android_imageProbeKernelVersionString(
0,
0,
kernelVersionString,
@@ -112,7 +141,7 @@
EXPECT_EQ(127, kernelVersionString[0]);
kernelVersionString[0] = 127;
- EXPECT_EQ(false, android_imageProbeKernelVersionString(
+ EXPECT_FALSE(android_imageProbeKernelVersionString(
kMockKernelElfNoString,
sizeof(kMockKernelElfNoString),
kernelVersionString,
diff --git a/android/kernel/testing/print_mock_kernel_data.sh b/android/kernel/testing/print_mock_kernel_data.sh
index 1a1a5cb..c6ce113 100755
--- a/android/kernel/testing/print_mock_kernel_data.sh
+++ b/android/kernel/testing/print_mock_kernel_data.sh
@@ -26,6 +26,15 @@
cat $TMP_FILE | xxd -i
printf "};\n\n"
+printf "// a mock semi-compressed kernel\n"
+printf "// an unspecified number of bytes, followed by a version string,\n"
+printf "// followed by a gzip header\n"
+printf "static const unsigned char kMockKernelSemiCompressed[] = {\n"
+printf "01234567899abcdef${LINUX_VERSION}0123455789" > $TMP_FILE
+printf "WHATEVER" | gzip >> $TMP_FILE
+cat $TMP_FILE | xxd -i
+printf "};\n\n"
+
rm $TMP_FILE
diff --git a/android/qemu-launcher/emulator-qemu.cpp b/android/qemu-launcher/emulator-qemu.cpp
index 280bd58..fdd38a7 100644
--- a/android/qemu-launcher/emulator-qemu.cpp
+++ b/android/qemu-launcher/emulator-qemu.cpp
@@ -23,6 +23,7 @@
#include "android/cmdline-option.h"
#include "android/globals.h"
#include "android/help.h"
+#include "android/filesystems/ext4_utils.h"
#include "android/kernel/kernel_utils.h"
#include "android/main-common.h"
#include "android/utils/bufprint.h"
@@ -85,6 +86,16 @@
// The target CPU architecture.
const char kTargetArch[] = "aarch64";
+String getNthParentDir(const char* path, size_t n) {
+ StringVector dir = PathUtils::decompose(path);
+ PathUtils::simplifyComponents(&dir);
+ if (dir.size() < n + 1U) {
+ return String("");
+ }
+ dir.resize(dir.size() - n);
+ return PathUtils::recompose(dir);
+}
+
// Return the path of the QEMU executable
String getQemuExecutablePath(const char* programPath) {
StringVector path = PathUtils::decompose(programPath);
@@ -702,6 +713,38 @@
String qemuExecutable = getQemuExecutablePath(argv[0]);
D("QEMU EXECUTABLE=%s\n", qemuExecutable.c_str());
+ // Create userdata file from init version if needed.
+ if (!path_exists(hw->disk_dataPartition_path)) {
+ if (!path_exists(hw->disk_dataPartition_initPath)) {
+ derror("Missing initial data partition file: %s",
+ hw->disk_dataPartition_initPath);
+ exit(1);
+ }
+ D("Creating: %s\n", hw->disk_dataPartition_path);
+
+ if (path_copy_file(hw->disk_dataPartition_path,
+ hw->disk_dataPartition_initPath) < 0) {
+ derror("Could not create %s: %s", hw->disk_dataPartition_path,
+ strerror(errno));
+ exit(1);
+ }
+ }
+
+ // Create cache partition image if it doesn't exist already.
+ if (!path_exists(hw->disk_cachePartition_path)) {
+ D("Creating empty ext4 cache partition: %s",
+ hw->disk_cachePartition_path);
+ int ret = android_createEmptyExt4Image(
+ hw->disk_cachePartition_path,
+ hw->disk_cachePartition_size,
+ "cache");
+ if (ret < 0) {
+ derror("Could not create %s: %s", hw->disk_cachePartition_path,
+ strerror(-ret));
+ exit(1);
+ }
+ }
+
// Now build the QEMU parameters.
const char* args[128];
int n = 0;
@@ -769,6 +812,12 @@
args[n++] = "virtio-net-device,netdev=mynet";
args[n++] = "-show-cursor";
+ // Data directory (for keymaps and PC Bios).
+ args[n++] = "-L";
+ String dataDir = getNthParentDir(qemuExecutable.c_str(), 2U);
+ dataDir += "/pc-bios";
+ args[n++] = dataDir.c_str();
+
if(VERBOSE_CHECK(init)) {
int i;
printf("QEMU options list:\n");