Support kernels with version >= 3.10
Newer Android Linux kernels modify the way certain devices are
named, i.e.:
/dev/qemu_pipe is renamed as /dev/goldfish_pipe.
/dev/ttyS<num> is renamed as /dev/ttyGF<num>
This patch adds support code to the emulator to deal with this
as transparently as possible:
1) Add a new hardware property 'kernel.newDeviceNaming', a string
which can only take the values 'autodetect', 'no', and 'yes'.
2) Support code to probe the type of a kernel image.
IMPORTANT: The kernel implementation depends on the host
/usr/bin/file to properly recognize kernel files and extract
their version number. This really only works on Linux and
OS X, and only for x86 and x86_64 kernel images.
A future patch will implement more robust detection by
essentially doing its own probing through libmagic or equivalent.
Note that there doesn't seem to be any existing libmagic rules
to recognize ARM and MIPS kernel images at the moment :-(
See android/kernel/kernel_utils*
3) Modify the emulator startup code to perform auto-detection
when possible (broken on Windows, and non Intel archs, see
comment above).
4) Modify the kernel command line generation to handle the new
TTY device naming
5) Modify the Goldfish pipe virtual device implementation
(since the device name presented to the kernel also changed).
This should be enough to auto-detect Linux 3.10+ x86_64 kernel
images on Linux.
Change-Id: Ied517f8a1fdeb18d84fa9a12ebcdc3daa1f41d9a
diff --git a/Makefile.common b/Makefile.common
index 3d6ea6f..5e4daf9 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -125,6 +125,7 @@
android/base/String.cpp \
android/base/StringView.cpp \
android/filesystems/ext4_utils.cpp \
+ android/kernel/kernel_utils.cpp \
android/utils/assert.c \
android/utils/bufprint.c \
android/utils/debug.c \
diff --git a/Makefile.tests b/Makefile.tests
index 2c4b28c..7181c41 100644
--- a/Makefile.tests
+++ b/Makefile.tests
@@ -18,6 +18,7 @@
android/base/String_unittest.cpp \
android/base/StringView_unittest.cpp \
android/filesystems/ext4_utils_unittest.cpp \
+ android/kernel/kernel_utils_unittest.cpp \
$(call start-emulator-program, emulator_unittests)
LOCAL_C_INCLUDES += $(EMULATOR_GTEST_INCLUDES)
diff --git a/android/avd/hardware-properties.ini b/android/avd/hardware-properties.ini
index 7629133..327b75d 100644
--- a/android/avd/hardware-properties.ini
+++ b/android/avd/hardware-properties.ini
@@ -301,6 +301,13 @@
default =
abstract = kernel boot parameters string.
+name = kernel.newDeviceNaming
+type = string
+enum = autodetect, yes, no
+default = autodetect
+abstract = Does the kernel require a new device naming scheme?
+abstract = Used to specify whether the kernel requires a new device naming scheme. Typically for Linux 3.10 and above.
+
# Path to the ramdisk image.
name = disk.ramdisk.path
type = string
diff --git a/android/avd/hw-config.c b/android/avd/hw-config.c
index 2d50ef7..34f2ed4 100644
--- a/android/avd/hw-config.c
+++ b/android/avd/hw-config.c
@@ -143,3 +143,22 @@
{
return strcmp(config->hw_screen, "multi-touch") == 0;
}
+
+int
+androidHwConfig_getKernelDeviceNaming( AndroidHwConfig* config )
+{
+ if (!strcmp(config->kernel_newDeviceNaming, "no"))
+ return 0;
+ if (!strcmp(config->kernel_newDeviceNaming, "yes"))
+ return 1;
+ return -1;
+}
+
+const char* androidHwConfig_getKernelSerialPrefix(AndroidHwConfig* config )
+{
+ if (androidHwConfig_getKernelDeviceNaming(config) >= 1) {
+ return "ttyGF";
+ } else {
+ return "ttyS";
+ }
+}
diff --git a/android/avd/hw-config.h b/android/avd/hw-config.h
index fd99e45..81444fb 100644
--- a/android/avd/hw-config.h
+++ b/android/avd/hw-config.h
@@ -64,4 +64,19 @@
/* Checks if screen supports multi-touch. */
int androidHwConfig_isScreenMultiTouch( AndroidHwConfig* config );
+// Return an integer indicating if the kernel requires a new device
+// naming scheme. More specifically:
+// -1 -> don't know, caller will need to auto-detect.
+// 0 -> legacy device naming
+// 1 -> new device naming.
+//
+// The new device naming was allegedly introduced in Linux 3.10 and
+// replaces /dev/ttyS<num with /dev/ttyGF<num>. Also see related
+// declarations in android/kernel/kernel_utils.h
+int androidHwConfig_getKernelDeviceNaming( AndroidHwConfig* config );
+
+// Return the kernel device prefix for serial ports, depending on
+// kernel.newDeviceNaming.
+const char* androidHwConfig_getKernelSerialPrefix( AndroidHwConfig* config );
+
#endif /* _ANDROID_AVD_HW_CONFIG_H */
diff --git a/android/avd/info.c b/android/avd/info.c
index 405fd04..27809bf 100644
--- a/android/avd/info.c
+++ b/android/avd/info.c
@@ -978,6 +978,12 @@
suffix = "-armv7";
}
+ p = bufprint(temp, end, "%s/kernel", i->androidOut);
+ if (p < end && path_exists(temp)) {
+ kernelPath = ASTRDUP(temp);
+ break;
+ }
+
p = bufprint(temp, end, "%s/prebuilts/qemu-kernel/%s/kernel-qemu%s",
i->androidBuildRoot, i->targetArch, suffix);
if (p >= end || !path_exists(temp)) {
diff --git a/android/kernel/kernel_utils.cpp b/android/kernel/kernel_utils.cpp
new file mode 100644
index 0000000..e396f4a
--- /dev/null
+++ b/android/kernel/kernel_utils.cpp
@@ -0,0 +1,173 @@
+// Copyright 2014 The Android Open Source Project
+//
+// This software is licensed under the terms of the GNU General Public
+// License version 2, as published by the Free Software Foundation, and
+// may be copied, distributed, and modified under those terms.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+#include "android/kernel/kernel_utils.h"
+
+#include "android/base/Log.h"
+#include "android/base/files/ScopedStdioFile.h"
+#include "android/base/String.h"
+#include "android/kernel/kernel_utils_testing.h"
+#include "android/utils/path.h"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+
+#define DEBUG_KERNEL 0
+
+#define KERNEL_LOG LOG_IF(INFO, DEBUG_KERNEL)
+#define KERNEL_PLOG PLOG_IF(INFO, DEBUG_KERNEL)
+#define KERNEL_ERROR LOG_IF(ERROR, DEBUG_KERNEL)
+#define KERNEL_PERROR PLOG_IF(ERROR, DEBUG_KERNEL)
+
+using android::base::String;
+
+namespace {
+
+#ifndef _WIN32
+// Helper class to perform launch a command through popen() and call
+// pclose() on destruction.
+class ScopedPopenFile {
+public:
+ ScopedPopenFile(const char* command) {
+ mFile = ::popen(command, "r");
+ }
+
+ FILE* get() const { return mFile; }
+
+ ~ScopedPopenFile() {
+ if (mFile) {
+ ::pclose(mFile);
+ }
+ }
+
+private:
+ FILE* mFile;
+};
+#endif // !_WIN32
+
+bool getFileDescription(void* opaque, const char* filePath, String* text) {
+ if (!filePath) {
+ KERNEL_ERROR << "NULL path parameter";
+ return false;
+ }
+
+ if (!path_exists(filePath)) {
+ KERNEL_ERROR << "Kernel file doesn't exist: " << filePath;
+ return false;
+ }
+
+#ifdef _WIN32
+ // TODO(digit): Better/portable detection based on libmagic or something.
+ KERNEL_ERROR << "Can't detect kernel version on Windows!";
+ return false;
+#else
+ // NOTE: Use /usr/bin/file instead of 'file' because the latter can
+ // be broken in certain environments (e.g. some versions of MacPorts).
+ String command("/usr/bin/file ");
+ command += filePath;
+
+ ScopedPopenFile file(command.c_str());
+ if (!file.get()) {
+ KERNEL_PERROR << "Could not launch command: " << command.c_str();
+ return false;
+ }
+
+ String result;
+ const size_t kReserveSize = 256U;
+ result.resize(kReserveSize);
+
+ int ret = ::fread(&result[0], 1, kReserveSize, file.get());
+ if (ret < static_cast<int>(kReserveSize) && ferror(file.get())) {
+ KERNEL_ERROR << "Could not read file command output!?";
+ return false;
+ }
+ result.resize(ret);
+ text->assign(result);
+ return true;
+#endif
+}
+
+android::kernel::GetFileDescriptionFunction* sGetFileDescription =
+ getFileDescription;
+
+void* sGetFileDescriptionOpaque = NULL;
+
+} // namespace
+
+namespace android {
+namespace kernel {
+
+void setFileDescriptionFunction(GetFileDescriptionFunction* file_func,
+ void* file_opaque) {
+ sGetFileDescription = file_func ? file_func : &getFileDescription;
+ sGetFileDescriptionOpaque = file_func ? file_opaque : NULL;
+}
+
+} // namespace kernel
+} // namespace android
+
+bool android_pathProbeKernelType(const char* kernelPath, KernelType* ktype) {
+ String description;
+
+ if (!sGetFileDescription(sGetFileDescriptionOpaque,
+ kernelPath,
+ &description)) {
+ return false;
+ }
+ char* bzImage = ::strstr(description.c_str(), "bzImage");
+ if (!bzImage) {
+ KERNEL_ERROR << "Not a compressed Linux kernel image!";
+ return false;
+ }
+ char* version = ::strstr(bzImage, "version ");
+ if (!version) {
+ KERNEL_ERROR << "Could not determine version!";
+ return false;
+ }
+ version += ::strlen("version ");
+ KERNEL_LOG << "Found kernel version " << version;
+
+ char* end;
+ unsigned long major = ::strtoul(version, &end, 10);
+ if (end == version || *end != '.') {
+ KERNEL_ERROR << "Could not find kernel major version!";
+ return false;
+ }
+ KERNEL_LOG << "Kernel major version: " << major;
+ if (major > 3) {
+ *ktype = KERNEL_TYPE_3_10_OR_ABOVE;
+ } else if (major < 3) {
+ *ktype = KERNEL_TYPE_LEGACY;
+ } else /* major == 3 */ {
+ version = end + 1;
+ unsigned long minor = ::strtoul(version, &end, 10);
+ if (end == version) {
+ KERNEL_ERROR << "Could not find kernel minor version!";
+ return false;
+ }
+ KERNEL_LOG << "Kernel minor version: " << minor;
+
+ *ktype = (minor >= 10)
+ ? KERNEL_TYPE_3_10_OR_ABOVE : KERNEL_TYPE_LEGACY;
+ }
+ return true;
+}
+
+const char* android_kernelSerialDevicePrefix(KernelType ktype) {
+ switch (ktype) {
+ case KERNEL_TYPE_LEGACY: return "ttyS";
+ case KERNEL_TYPE_3_10_OR_ABOVE: return "ttyGF";
+ default: return "";
+ }
+}
diff --git a/android/kernel/kernel_utils.h b/android/kernel/kernel_utils.h
new file mode 100644
index 0000000..e10eb34
--- /dev/null
+++ b/android/kernel/kernel_utils.h
@@ -0,0 +1,44 @@
+// Copyright 2014 The Android Open Source Project
+//
+// This software is licensed under the terms of the GNU General Public
+// License version 2, as published by the Free Software Foundation, and
+// may be copied, distributed, and modified under those terms.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+#ifndef ANDROID_KERNEL_KERNEL_UTILS_H
+#define ANDROID_KERNEL_KERNEL_UTILS_H
+
+#include "android/utils/compiler.h"
+#include <stdint.h>
+
+ANDROID_BEGIN_HEADER
+
+// An enum used to list of the types of Linux kernel images we need to
+// handle. Unfortunately, this affects how we setup the kernel command-line
+// when launching the system.
+//
+// KERNEL_TYPE_LEGACY is any Linux kernel image before 3.10
+// KERNEL_TYPE_3_10_OR_ABOVE is anything at 3.10 or above.
+typedef enum {
+ KERNEL_TYPE_LEGACY = 0,
+ KERNEL_TYPE_3_10_OR_ABOVE = 1,
+} KernelType;
+
+// Probe the kernel image at |kernelPath| and returns the corresponding
+// KernelType value. On success, returns true and sets |*ktype| appropriately.
+// On failure (e.g. if the file doesn't exist or cannot be probed), return
+// false and doesn't touch |*ktype|.
+bool android_pathProbeKernelType(const char* kernelPath, KernelType *ktype);
+
+// Return the serial device name prefix matching a given kernel type |ktype|.
+// I.e. this should be "/dev/ttyS" for KERNEL_TYPE_LEGACY, and
+// "/dev/ttyGF" for KERNEL_TYPE_3_10_OR_ABOVE.
+const char* android_kernelSerialDevicePrefix(KernelType ktype);
+
+ANDROID_END_HEADER
+
+#endif // ANDROID_KERNEL_KERNEL_UTILS_H
diff --git a/android/kernel/kernel_utils_testing.h b/android/kernel/kernel_utils_testing.h
new file mode 100644
index 0000000..f2d64ec
--- /dev/null
+++ b/android/kernel/kernel_utils_testing.h
@@ -0,0 +1,47 @@
+// Copyright 2014 The Android Open Source Project
+//
+// This software is licensed under the terms of the GNU General Public
+// License version 2, as published by the Free Software Foundation, and
+// may be copied, distributed, and modified under those terms.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+#ifndef ANDROID_KERNEL_KERNEL_UTILS_TESTING_H
+#define ANDROID_KERNEL_KERNEL_UTILS_TESTING_H
+
+namespace android {
+
+namespace base {
+class String;
+} // namespace base
+
+namespace kernel {
+
+// Type of a function used to retrieve the textual description of a given
+// file at |filePath|. On success, return true and sets |*text| to the
+// description text, as if running through the 'file' command on Unix.
+// |opaque| is a client-provided value set by calling
+// setFileDescriptionFunction() below.
+typedef bool (GetFileDescriptionFunction)(void* opaque,
+ const char* filePath,
+ android::base::String* text);
+
+// Change the implementation of the function that extracts textual
+// descriptions from a given file. |file_func| is a pointer to the
+// new function, and |file_opaque| is the value that will be passed
+// as its first parameter. Note that if |file_func| is NULL, the
+// default implementation will be selected instead.
+//
+// Only use this during unit-testing to force different description
+// values on arbitrary file content.
+void setFileDescriptionFunction(GetFileDescriptionFunction* file_func,
+ void* file_opaque);
+
+} // namespace kernel
+
+} // namespace android
+
+#endif // ANDROID_KERNEL_KERNEL_UTILS_TESTING_H
diff --git a/android/kernel/kernel_utils_unittest.cpp b/android/kernel/kernel_utils_unittest.cpp
new file mode 100644
index 0000000..a5afa2a
--- /dev/null
+++ b/android/kernel/kernel_utils_unittest.cpp
@@ -0,0 +1,132 @@
+// Copyright 2014 The Android Open Source Project
+//
+// This software is licensed under the terms of the GNU General Public
+// License version 2, as published by the Free Software Foundation, and
+// may be copied, distributed, and modified under those terms.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+#include "android/kernel/kernel_utils.h"
+
+#include "android/base/String.h"
+#include "android/kernel/kernel_utils_testing.h"
+
+#include <gtest/gtest.h>
+
+using android::base::String;
+
+namespace android {
+namespace kernel {
+
+namespace {
+
+class ScopedDescriptionFunc {
+public:
+ explicit ScopedDescriptionFunc(GetFileDescriptionFunction* file_func) {
+ setFileDescriptionFunction(file_func, NULL);
+ }
+
+ ScopedDescriptionFunc(GetFileDescriptionFunction* file_func,
+ void* file_opaque) {
+ setFileDescriptionFunction(file_func, file_opaque);
+ }
+
+ ~ScopedDescriptionFunc() {
+ setFileDescriptionFunction(NULL, NULL);
+ }
+};
+
+} // namespace
+
+TEST(KernelUtils, GetKernelSerialDevicePrefix) {
+ EXPECT_STREQ("ttyS",
+ android_kernelSerialDevicePrefix(KERNEL_TYPE_LEGACY));
+ EXPECT_STREQ("ttyGF",
+ android_kernelSerialDevicePrefix(KERNEL_TYPE_3_10_OR_ABOVE));
+}
+
+static bool failFunc(void* opaque, const char* path, String* text) {
+ return false;
+}
+
+TEST(KernelUtils, ProbeKernelTypeWithNoKernelFile) {
+ ScopedDescriptionFunc func(&failFunc);
+
+ KernelType ktype;
+ EXPECT_FALSE(android_pathProbeKernelType("/tmp/kernel", &ktype));
+}
+
+struct Expectation {
+ const char* description;
+ bool result;
+ KernelType ktype;
+
+ static bool getDescriptionFunc(void* opaque,
+ const char* path,
+ String* text) {
+ const Expectation* expectation = static_cast<const Expectation*>(opaque);
+ if (!expectation->result)
+ return false;
+ text->assign(expectation->description);
+ return true;
+ }
+};
+
+#ifdef _WIN32
+#define DISABLED_ON_WIN32(x) DISABLED_ ## x
+#else
+#define DISABLED_ON_WIN32(x) x
+#endif
+
+TEST(KernelUtils, DISABLED_ON_WIN32(PathProbeKernelType)) {
+ static const Expectation kData[] = {
+ { NULL, false, KERNEL_TYPE_LEGACY },
+ // Missing bzImage.
+ { "Linux kernel x86 boot executable raw image, version 3.10.0+",
+ false, KERNEL_TYPE_LEGACY },
+ // Missing version
+ { "Linux kernel x86 boot executable bzImage, 3.10.0+",
+ false, KERNEL_TYPE_LEGACY },
+ // Legacy 2.6.29 kernel
+ { "Linux kernel x86 boot executable bzImage, version 2.6.29 (foo...)",
+ true,
+ KERNEL_TYPE_LEGACY },
+ // Legacy 3.4
+ { "Linux kernel x86 boot executable bzImage, version 3.4.1 (foo...)",
+ true,
+ KERNEL_TYPE_LEGACY },
+ // 3.10
+ { "Linux kernel x86 boot executable bzImage, version 3.10.0+",
+ true,
+ KERNEL_TYPE_3_10_OR_ABOVE },
+ // 3.40
+ { "Linux kernel x86 boot executable bzImage, version 3.40.0",
+ true,
+ KERNEL_TYPE_3_10_OR_ABOVE },
+ // 4.0
+ { "Linux kernel x86 boot executable bzImage, version 4.0.9",
+ true,
+ KERNEL_TYPE_3_10_OR_ABOVE },
+ };
+ const size_t kDataSize = sizeof(kData) / sizeof(kData[0]);
+ static const char kKernelPath[] = "/tmp/kernel";
+ for (size_t n = 0; n < kDataSize; ++n) {
+ KernelType kernelType;
+ const Expectation& expectation = kData[n];
+ ScopedDescriptionFunc func(&Expectation::getDescriptionFunc,
+ (void*)&expectation);
+ EXPECT_EQ(expectation.result,
+ android_pathProbeKernelType(kKernelPath, &kernelType))
+ << "For [" << expectation.description << "]";
+ if (expectation.result) {
+ EXPECT_EQ(expectation.ktype, kernelType) << "For ["
+ << expectation.description << "]";
+ }
+ }
+}
+
+} // namespace kernel
+} // namespace android
diff --git a/android/main.c b/android/main.c
index 0662bfe..c557d95 100644
--- a/android/main.c
+++ b/android/main.c
@@ -37,6 +37,7 @@
#include "android/config-file.h"
#include "android/config/config.h"
+#include "android/kernel/kernel_utils.h"
#include "android/user-config.h"
#include "android/utils/bufprint.h"
#include "android/utils/filelock.h"
@@ -452,6 +453,24 @@
}
}
+ // Auto-detect kernel device naming scheme if needed.
+ if (androidHwConfig_getKernelDeviceNaming(hw) < 0) {
+ KernelType kernelType;
+ const char* newDeviceNaming = "no";
+ if (!android_pathProbeKernelType(hw->kernel_path, &kernelType)) {
+ D("WARNING: Could not determine kernel device naming scheme. Assuming legacy\n"
+ "If this AVD doesn't boot, and uses a recent kernel (3.10 or above) try setting\n"
+ "'kernel.newDeviceNaming' to 'yes' in its configuration.\n");
+ } else if (kernelType == KERNEL_TYPE_3_10_OR_ABOVE) {
+ D("Auto-detect: Kernel image requires new device naming scheme.");
+ newDeviceNaming = "yes";
+ } else {
+ D("Auto-detect: Kernel image requires legacy device naming scheme.");
+ }
+ AFREE(hw->kernel_newDeviceNaming);
+ hw->kernel_newDeviceNaming = ASTRDUP(newDeviceNaming);
+ }
+
if (boot_prop_ip[0]) {
args[n++] = "-boot-property";
args[n++] = boot_prop_ip;
@@ -1027,7 +1046,9 @@
#endif
if (opts->shell || opts->logcat) {
- p = bufprint(p, end, " androidboot.console=ttyS%d", shell_serial );
+ p = bufprint(p, end, " androidboot.console=%s%d",
+ androidHwConfig_getKernelSerialPrefix(android_hw),
+ shell_serial );
}
if (opts->trace) {
diff --git a/android/utils/path.h b/android/utils/path.h
index 2926e5e..ac5fb09 100644
--- a/android/utils/path.h
+++ b/android/utils/path.h
@@ -12,9 +12,12 @@
#ifndef _ANDROID_UTILS_PATH_H
#define _ANDROID_UTILS_PATH_H
+#include <android/utils/compiler.h>
#include <android/utils/system.h>
#include <stdint.h> /* for uint64_t */
+ANDROID_BEGIN_HEADER
+
/** MISC FILE AND DIRECTORY HANDLING
**/
@@ -165,5 +168,6 @@
extern void* path_load_file( const char* path, size_t *pSize );
/* */
+ANDROID_END_HEADER
#endif /* _ANDROID_UTILS_PATH_H */
diff --git a/docs/ANDROID-QEMU-PIPE.TXT b/docs/ANDROID-QEMU-PIPE.TXT
index 5e9ae76..1f18599 100644
--- a/docs/ANDROID-QEMU-PIPE.TXT
+++ b/docs/ANDROID-QEMU-PIPE.TXT
@@ -12,6 +12,9 @@
1/ Open the /dev/qemu_pipe device for read+write
+ NOTE: Starting with Linux 3.10, the device was renamed as
+ /dev/goldfish_pipe but behaves exactly in the same way.
+
2/ Write a zero-terminated string describing which service you want to
connect.
diff --git a/hw/android/android_arm.c b/hw/android/android_arm.c
index ff0e569..010eece 100644
--- a/hw/android/android_arm.c
+++ b/hw/android/android_arm.c
@@ -144,7 +144,9 @@
}
#endif // CONFIG_MEMCHECK
- pipe_dev_init();
+ bool newDeviceNaming =
+ (androidHwConfig_getKernelDeviceNaming(android_hw) >= 1);
+ pipe_dev_init(newDeviceNaming);
#if TEST_SWITCH
{
diff --git a/hw/android/android_mips.c b/hw/android/android_mips.c
index 1d0f34f..d8b6d7b 100644
--- a/hw/android/android_mips.c
+++ b/hw/android/android_mips.c
@@ -245,7 +245,9 @@
trace_dev_init();
}
#endif // CONFIG_MEMCHECK
- pipe_dev_init();
+ bool newDeviceNaming =
+ (androidHwConfig_getKernelDeviceNaming(android_hw) >= 1);
+ pipe_dev_init(newDeviceNaming);
#if TEST_SWITCH
{
diff --git a/hw/android/goldfish/pipe.c b/hw/android/goldfish/pipe.c
index 95b29e6..58817dc 100644
--- a/hw/android/goldfish/pipe.c
+++ b/hw/android/goldfish/pipe.c
@@ -1312,13 +1312,13 @@
}
/* initialize the trace device */
-void pipe_dev_init()
+void pipe_dev_init(bool newDeviceNaming)
{
PipeDevice *s;
s = (PipeDevice *) g_malloc0(sizeof(*s));
- s->dev.name = "qemu_pipe";
+ s->dev.name = newDeviceNaming ? "goldfish_pipe" : "qemu_pipe";
s->dev.id = -1;
s->dev.base = 0; // will be allocated dynamically
s->dev.size = 0x2000;
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 3588044..71b9430 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1042,8 +1042,10 @@
#ifdef CONFIG_NAND
goldfish_add_device_no_io(&nand_device);
nand_dev_init(nand_device.base);
- pipe_dev_init();
#endif
+ bool newDeviceNaming =
+ (androidHwConfig_getKernelDeviceNaming(android_hw) >= 1);
+ pipe_dev_init(newDeviceNaming);
{
DriveInfo* info = drive_get( IF_IDE, 0, 0 );
diff --git a/include/hw/android/goldfish/pipe.h b/include/hw/android/goldfish/pipe.h
index 57496a5..3d36e90 100644
--- a/include/hw/android/goldfish/pipe.h
+++ b/include/hw/android/goldfish/pipe.h
@@ -12,6 +12,7 @@
#ifndef _HW_GOLDFISH_PIPE_H
#define _HW_GOLDFISH_PIPE_H
+#include <stdbool.h>
#include <stdint.h>
#include "hw/hw.h"
@@ -194,7 +195,7 @@
#define PIPE_WAKE_READ (1 << 1) /* pipe can now be read from */
#define PIPE_WAKE_WRITE (1 << 2) /* pipe can now be written to */
-void pipe_dev_init(void);
+void pipe_dev_init(bool newDeviceNaming);
struct access_params{
uint32_t channel;
diff --git a/vl-android.c b/vl-android.c
index 068009b..3c2191c 100644
--- a/vl-android.c
+++ b/vl-android.c
@@ -3237,6 +3237,11 @@
iniFile_free(hw_ini);
+ const char* kernelSerialDevicePrefix =
+ androidHwConfig_getKernelSerialPrefix(android_hw);
+ VERBOSE_PRINT(init, "Using kernel serial device prefix: %s",
+ kernelSerialDevicePrefix);
+
{
int width = android_hw->hw_lcd_width;
int height = android_hw->hw_lcd_height;
@@ -3657,12 +3662,16 @@
/* We always initialize the first serial port for the android-kmsg
* character device (used to send kernel messages) */
serial_hds_add_at(0, "android-kmsg");
- stralloc_add_str(kernel_params, " console=ttyS0");
+ stralloc_add_format(kernel_params,
+ " console=%s0",
+ kernelSerialDevicePrefix);
/* We always initialize the second serial port for the android-qemud
* character device as well */
serial_hds_add_at(1, "android-qemud");
- stralloc_add_str(kernel_params, " android.qemud=ttyS1");
+ stralloc_add_format(kernel_params,
+ " android.qemud=%s1",
+ kernelSerialDevicePrefix);
if (pid_file && qemu_create_pidfile(pid_file) != 0) {
os_pidfile_error();