Merge "Revert "Disabled audio on arm64 host""
diff --git a/common/libs/fs/shared_fd.cpp b/common/libs/fs/shared_fd.cpp
index f5c12c6..8b21f0c 100644
--- a/common/libs/fs/shared_fd.cpp
+++ b/common/libs/fs/shared_fd.cpp
@@ -319,6 +319,15 @@
}
}
+SharedFD SharedFD::Mkstemp(std::string* path) {
+ int fd = mkstemp(path->data());
+ if (fd == -1) {
+ return SharedFD(std::shared_ptr<FileInstance>(new FileInstance(fd, errno)));
+ } else {
+ return SharedFD(std::shared_ptr<FileInstance>(new FileInstance(fd, 0)));
+ }
+}
+
SharedFD SharedFD::ErrorFD(int error) {
return SharedFD(std::shared_ptr<FileInstance>(new FileInstance(-1, error)));
}
diff --git a/common/libs/fs/shared_fd.h b/common/libs/fs/shared_fd.h
index ad962de..e712ab9 100644
--- a/common/libs/fs/shared_fd.h
+++ b/common/libs/fs/shared_fd.h
@@ -129,6 +129,7 @@
static bool Pipe(SharedFD* fd0, SharedFD* fd1);
static SharedFD Event(int initval = 0, int flags = 0);
static SharedFD MemfdCreate(const std::string& name, unsigned int flags = 0);
+ static SharedFD Mkstemp(std::string* path);
static bool SocketPair(int domain, int type, int protocol, SharedFD* fd0,
SharedFD* fd1);
static SharedFD Socket(int domain, int socket_type, int protocol);
diff --git a/common/libs/utils/environment.cpp b/common/libs/utils/environment.cpp
index 5c0de51..ec27290 100644
--- a/common/libs/utils/environment.cpp
+++ b/common/libs/utils/environment.cpp
@@ -21,6 +21,8 @@
#include <stdio.h>
#include <iostream>
+#include <android-base/logging.h>
+
namespace cuttlefish {
std::string StringFromEnv(const std::string& varname,
@@ -39,7 +41,7 @@
*
* @return arch string on success, "" on failure
*/
-std::string HostArch() {
+std::string HostArchStr() {
static std::string arch;
static bool cached = false;
@@ -83,6 +85,29 @@
return arch;
}
+Arch HostArch() {
+ std::string arch_str = HostArchStr();
+ if (arch_str == "aarch64") {
+ return Arch::Arm64;
+ } else if (arch_str == "arm") {
+ return Arch::Arm;
+ } else if (arch_str == "x86_64") {
+ return Arch::X86_64;
+ } else if (arch_str.size() == 4 && arch_str[0] == 'i' && arch_str[2] == '8' &&
+ arch_str[3] == '6') {
+ return Arch::X86;
+ } else {
+ LOG(FATAL) << "Unknown host architecture: " << arch_str;
+ return Arch::X86;
+ }
+}
+
+bool IsHostCompatible(Arch arch) {
+ Arch host_arch = HostArch();
+ return arch == host_arch || (arch == Arch::Arm && host_arch == Arch::Arm64) ||
+ (arch == Arch::X86 && host_arch == Arch::X86_64);
+}
+
static bool IsRunningInDocker() {
// if /.dockerenv exists, it's inside a docker container
static std::string docker_env_path("/.dockerenv");
diff --git a/common/libs/utils/environment.h b/common/libs/utils/environment.h
index 60bcbb6..004a849 100644
--- a/common/libs/utils/environment.h
+++ b/common/libs/utils/environment.h
@@ -19,10 +19,19 @@
namespace cuttlefish {
+enum class Arch {
+ Arm,
+ Arm64,
+ X86,
+ X86_64,
+};
+
std::string StringFromEnv(const std::string& varname,
const std::string& defval);
-std::string HostArch();
+std::string HostArchStr();
+Arch HostArch();
+bool IsHostCompatible(Arch arch);
bool IsRunningInContainer();
diff --git a/common/libs/utils/network.cpp b/common/libs/utils/network.cpp
index df91c23..d1f5f59 100644
--- a/common/libs/utils/network.cpp
+++ b/common/libs/utils/network.cpp
@@ -96,7 +96,7 @@
return tap_fd;
}
- if (HostArch() == "aarch64") {
+ if (HostArch() == Arch::Arm64) {
auto tapsetiff_path = DefaultHostArtifactsPath("bin/tapsetiff");
Command cmd(tapsetiff_path);
cmd.AddParameter(tap_fd);
diff --git a/host/commands/assemble_cvd/assemble_cvd.cc b/host/commands/assemble_cvd/assemble_cvd.cc
index fec1ecf..63a6b4f 100644
--- a/host/commands/assemble_cvd/assemble_cvd.cc
+++ b/host/commands/assemble_cvd/assemble_cvd.cc
@@ -102,7 +102,7 @@
#endif
const CuttlefishConfig* InitFilesystemAndCreateConfig(
- FetcherConfig fetcher_config) {
+ FetcherConfig fetcher_config, KernelConfig kernel_config) {
std::string assembly_dir_parent = AbsolutePath(FLAGS_assembly_dir);
while (assembly_dir_parent[assembly_dir_parent.size() - 1] == '/') {
assembly_dir_parent =
@@ -131,7 +131,7 @@
// two operations, as those will assume they can read the config object from
// disk.
auto config = InitializeCuttlefishConfiguration(
- FLAGS_assembly_dir, FLAGS_instance_dir, FLAGS_modem_simulator_count);
+ FLAGS_instance_dir, FLAGS_modem_simulator_count, kernel_config);
std::set<std::string> preserving;
if (FLAGS_resume && ShouldCreateAllCompositeDisks(config)) {
LOG(INFO) << "Requested resuming a previous session (the default behavior) "
@@ -227,9 +227,10 @@
}
std::vector<std::string> input_files = android::base::Split(input_files_str, "\n");
- CHECK(ParseCommandLineFlags(&argc, &argv)) << "Failed to parse arguments";
+ KernelConfig kernel_config;
+ CHECK(ParseCommandLineFlags(&argc, &argv, &kernel_config)) << "Failed to parse arguments";
- auto config = InitFilesystemAndCreateConfig(FindFetcherConfig(input_files));
+ auto config = InitFilesystemAndCreateConfig(FindFetcherConfig(input_files), kernel_config);
std::cout << GetConfigFilePath(*config) << "\n";
std::cout << std::flush;
diff --git a/host/commands/assemble_cvd/boot_config.cc b/host/commands/assemble_cvd/boot_config.cc
index a6d41dd..b433940 100644
--- a/host/commands/assemble_cvd/boot_config.cc
+++ b/host/commands/assemble_cvd/boot_config.cc
@@ -50,9 +50,6 @@
if (!config.boot_slot().empty()) {
env << "android_slot_suffix=_" << config.boot_slot() << '\0';
}
- // Points to the misc partition.
- // Note that the 0 index points to the GPT table.
- env << "bootdevice=0:2" << '\0';
if(FLAGS_pause_in_bootloader) {
env << "bootdelay=-1" << '\0';
@@ -60,9 +57,10 @@
env << "bootdelay=0" << '\0';
}
- env << "bootcmd=boot_android virtio -" << '\0';
+ // Note that the 0 index points to the GPT table.
+ env << "bootcmd=boot_android virtio 0#misc" << '\0';
if (FLAGS_vm_manager == CrosvmManager::name() &&
- HostArch() == "aarch64") {
+ config.target_arch() == Arch::Arm64) {
env << "fdtaddr=0x80000000" << '\0';
} else {
env << "fdtaddr=0x40000000" << '\0';
diff --git a/host/commands/assemble_cvd/boot_image_utils.cc b/host/commands/assemble_cvd/boot_image_utils.cc
index 5654f93..a222f85 100644
--- a/host/commands/assemble_cvd/boot_image_utils.cc
+++ b/host/commands/assemble_cvd/boot_image_utils.cc
@@ -179,14 +179,6 @@
} // namespace
-std::string ExtractKernelFromBootImage(const std::string& boot_image_path,
- const std::string& unpack_dir) {
- if (UnpackBootImage(boot_image_path, unpack_dir)) {
- return unpack_dir + "/kernel";
- } else {
- return "";
- }
-}
bool RepackBootImage(const std::string& new_kernel_path,
const std::string& boot_image_path,
const std::string& new_boot_image_path,
diff --git a/host/commands/assemble_cvd/boot_image_utils.h b/host/commands/assemble_cvd/boot_image_utils.h
index ae28761..fafb514 100644
--- a/host/commands/assemble_cvd/boot_image_utils.h
+++ b/host/commands/assemble_cvd/boot_image_utils.h
@@ -19,8 +19,6 @@
#include <vector>
namespace cuttlefish {
-std::string ExtractKernelFromBootImage(const std::string& boot_image_path,
- const std::string& unpack_dir);
bool RepackBootImage(const std::string& new_kernel_path,
const std::string& boot_image_path,
const std::string& new_boot_image_path,
diff --git a/host/commands/assemble_cvd/disk_flags.cc b/host/commands/assemble_cvd/disk_flags.cc
index fd9a1dd..774e5ba 100644
--- a/host/commands/assemble_cvd/disk_flags.cc
+++ b/host/commands/assemble_cvd/disk_flags.cc
@@ -330,32 +330,6 @@
return true;
}
-static bool IsBootconfigSupported(const std::string& tmp_dir) {
- const std::string kernel_image_path =
- FLAGS_kernel_path.size()
- ? FLAGS_kernel_path
- : ExtractKernelFromBootImage(FLAGS_boot_image, tmp_dir);
- const std::string ikconfig_path = tmp_dir + "/ikconfig";
-
- Command ikconfig_cmd(HostBinaryPath("extract-ikconfig"));
- ikconfig_cmd.AddParameter(kernel_image_path);
-
- std::string current_path = StringFromEnv("PATH", "");
- std::string bin_folder = DefaultHostArtifactsPath("bin");
- ikconfig_cmd.SetEnvironment({"PATH=" + current_path + ":" + bin_folder});
-
- auto ikconfig_fd = SharedFD::Creat(ikconfig_path, 0666);
- CHECK(ikconfig_fd->IsOpen())
- << "Unable to create ikconfig file: " << ikconfig_fd->StrError();
- ikconfig_cmd.RedirectStdIO(Subprocess::StdIOChannel::kStdOut, ikconfig_fd);
-
- auto ikconfig_proc = ikconfig_cmd.Start();
- CHECK(ikconfig_proc.Started() && ikconfig_proc.Wait() == 0)
- << "Failed to extract ikconfig from " << kernel_image_path;
-
- return ReadFile(ikconfig_path).find("BOOT_CONFIG=y") != std::string::npos;
-}
-
const std::string kKernelDefaultPath = "kernel";
const std::string kInitramfsImg = "initramfs.img";
static void ExtractKernelParamsFromFetcherConfig(
@@ -391,8 +365,6 @@
google::FlagSettingMode::SET_FLAGS_DEFAULT);
}
- const bool bootconfig_supported =
- IsBootconfigSupported(config->assembly_dir());
for (auto instance : config->Instances()) {
const std::string new_vendor_boot_image_path =
instance.vendor_boot_image_path();
@@ -404,7 +376,8 @@
bool success = RepackVendorBootImage(
FLAGS_initramfs_path, FLAGS_vendor_boot_image,
new_vendor_boot_image_path, config->assembly_dir(),
- instance.instance_dir(), boot_config_vector, bootconfig_supported);
+ instance.instance_dir(), boot_config_vector,
+ config->bootconfig_supported());
CHECK(success) << "Failed to regenerate the vendor boot image with the "
"new ramdisk";
} else {
@@ -414,7 +387,7 @@
bool success = RepackVendorBootImageWithEmptyRamdisk(
FLAGS_vendor_boot_image, new_vendor_boot_image_path,
config->assembly_dir(), instance.instance_dir(), boot_config_vector,
- bootconfig_supported);
+ config->bootconfig_supported());
CHECK(success)
<< "Failed to regenerate the vendor boot image without a ramdisk";
}
@@ -424,7 +397,7 @@
bool success = RepackVendorBootImage(
std::string(), FLAGS_vendor_boot_image, new_vendor_boot_image_path,
config->assembly_dir(), instance.instance_dir(), boot_config_vector,
- bootconfig_supported);
+ config->bootconfig_supported());
CHECK(success) << "Failed to regenerate the vendor boot image";
}
}
diff --git a/host/commands/assemble_cvd/flags.cc b/host/commands/assemble_cvd/flags.cc
index 8dc71b0..c23d1fc 100644
--- a/host/commands/assemble_cvd/flags.cc
+++ b/host/commands/assemble_cvd/flags.cc
@@ -72,9 +72,8 @@
"Serial number to use for the device");
DEFINE_bool(use_random_serial, false,
"Whether to use random serial for the device.");
-DEFINE_string(
- vm_manager, CrosvmManager::name(),
- "What virtual machine manager to use, one of {qemu_cli, crosvm}");
+DEFINE_string(vm_manager, "",
+ "What virtual machine manager to use, one of {qemu_cli, crosvm}");
DEFINE_string(gpu_mode, cuttlefish::kGpuModeAuto,
"What gpu configuration to use, one of {auto, drm_virgl, "
"gfxstream, guest_swiftshader}");
@@ -120,7 +119,7 @@
"Enable crosvm sandbox. Use this when you are sure about what you are doing.");
static const std::string kSeccompDir =
- std::string("usr/share/crosvm/") + cuttlefish::HostArch() + "-linux-gnu/seccomp";
+ std::string("usr/share/crosvm/") + cuttlefish::HostArchStr() + "-linux-gnu/seccomp";
DEFINE_string(seccomp_policy_dir, DefaultHostArtifactsPath(kSeccompDir),
"With sandbox'ed crosvm, overrieds the security comp policy directory");
@@ -210,9 +209,8 @@
DEFINE_string(setupwizard_mode, "DISABLED",
"One of DISABLED,OPTIONAL,REQUIRED");
-DEFINE_string(qemu_binary,
- "/usr/bin/qemu-system-x86_64",
- "The qemu binary to use");
+DEFINE_string(qemu_binary_dir, "/usr/bin",
+ "Path to the directory containing the qemu binary to use");
DEFINE_string(crosvm_binary, HostBinaryPath("crosvm"),
"The Crosvm binary to use");
DEFINE_string(tpm_device, "", "A host TPM device to pass through commands to.");
@@ -290,11 +288,13 @@
DEFINE_bool(protected_vm, false, "Boot in Protected VM mode");
-DECLARE_string(system_image_dir);
-
-DEFINE_bool(enable_audio, cuttlefish::HostArch() != "aarch64",
+DEFINE_bool(enable_audio, cuttlefish::HostArch() != cuttlefish::Arch::Arm64,
"Whether to play or capture audio");
+DECLARE_string(assembly_dir);
+DECLARE_string(boot_image);
+DECLARE_string(system_image_dir);
+
namespace cuttlefish {
using vm_manager::QemuManager;
using vm_manager::GetVmManager;
@@ -332,17 +332,60 @@
return stream.str();
}
+void ReadKernelConfig(KernelConfig* kernel_config) {
+ const std::string kernel_image_path =
+ FLAGS_kernel_path.size() ? FLAGS_kernel_path : FLAGS_boot_image;
+
+ Command ikconfig_cmd(HostBinaryPath("extract-ikconfig"));
+ ikconfig_cmd.AddParameter(kernel_image_path);
+
+ std::string current_path = StringFromEnv("PATH", "");
+ std::string bin_folder = DefaultHostArtifactsPath("bin");
+ ikconfig_cmd.SetEnvironment({"PATH=" + current_path + ":" + bin_folder});
+
+ std::string ikconfig_path =
+ StringFromEnv("TEMP", "/tmp") + "/ikconfig.XXXXXX";
+ auto ikconfig_fd = SharedFD::Mkstemp(&ikconfig_path);
+ CHECK(ikconfig_fd->IsOpen())
+ << "Unable to create ikconfig file: " << ikconfig_fd->StrError();
+ ikconfig_cmd.RedirectStdIO(Subprocess::StdIOChannel::kStdOut, ikconfig_fd);
+
+ auto ikconfig_proc = ikconfig_cmd.Start();
+ CHECK(ikconfig_proc.Started() && ikconfig_proc.Wait() == 0)
+ << "Failed to extract ikconfig from " << kernel_image_path;
+
+ std::string config = ReadFile(ikconfig_path);
+
+ if (config.find("\nCONFIG_ARM=y") != std::string::npos) {
+ kernel_config->target_arch = Arch::Arm;
+ } else if (config.find("\nCONFIG_ARM64=y") != std::string::npos) {
+ kernel_config->target_arch = Arch::Arm64;
+ } else if (config.find("\nCONFIG_X86_64=y") != std::string::npos) {
+ kernel_config->target_arch = Arch::X86_64;
+ } else if (config.find("\nCONFIG_X86=y") != std::string::npos) {
+ kernel_config->target_arch = Arch::X86;
+ } else {
+ LOG(FATAL) << "Unknown target architecture";
+ }
+ kernel_config->bootconfig_supported =
+ config.find("\nCONFIG_BOOT_CONFIG=y") != std::string::npos;
+
+ unlink(ikconfig_path.c_str());
+}
+
} // namespace
CuttlefishConfig InitializeCuttlefishConfiguration(
- const std::string& assembly_dir, const std::string& instance_dir,
- int modem_simulator_count) {
+ const std::string& instance_dir, int modem_simulator_count,
+ KernelConfig kernel_config) {
// At most one streamer can be started.
CHECK(NumStreamers() <= 1);
CuttlefishConfig tmp_config_obj;
- tmp_config_obj.set_assembly_dir(assembly_dir);
- auto vmm = GetVmManager(FLAGS_vm_manager);
+ tmp_config_obj.set_assembly_dir(FLAGS_assembly_dir);
+ tmp_config_obj.set_target_arch(kernel_config.target_arch);
+ tmp_config_obj.set_bootconfig_supported(kernel_config.bootconfig_supported);
+ auto vmm = GetVmManager(FLAGS_vm_manager, kernel_config.target_arch);
if (!vmm) {
LOG(FATAL) << "Invalid vm_manager: " << FLAGS_vm_manager;
}
@@ -441,7 +484,7 @@
tmp_config_obj.set_deprecated_boot_completed(FLAGS_deprecated_boot_completed);
- tmp_config_obj.set_qemu_binary(FLAGS_qemu_binary);
+ tmp_config_obj.set_qemu_binary_dir(FLAGS_qemu_binary_dir);
tmp_config_obj.set_crosvm_binary(FLAGS_crosvm_binary);
tmp_config_obj.set_tpm_device(FLAGS_tpm_device);
@@ -801,7 +844,7 @@
// for now, we support only x86_64 by default
bool default_enable_sandbox = false;
- std::set<const std::string> supported_archs{std::string("x86_64")};
+ std::set<Arch> supported_archs{Arch::X86_64};
if (supported_archs.find(HostArch()) != supported_archs.end()) {
if (DirectoryExists(kCrosvmVarEmptyDir)) {
default_enable_sandbox = IsDirectoryEmpty(kCrosvmVarEmptyDir);
@@ -821,10 +864,24 @@
SET_FLAGS_DEFAULT);
}
-bool ParseCommandLineFlags(int* argc, char*** argv) {
+bool ParseCommandLineFlags(int* argc, char*** argv, KernelConfig* kernel_config) {
google::ParseCommandLineNonHelpFlags(argc, argv, true);
SetDefaultFlagsFromConfigPreset();
bool invalid_manager = false;
+
+ if (!ResolveInstanceFiles()) {
+ return false;
+ }
+
+ ReadKernelConfig(kernel_config);
+ if (FLAGS_vm_manager == "") {
+ if (IsHostCompatible(kernel_config->target_arch)) {
+ FLAGS_vm_manager = CrosvmManager::name();
+ } else {
+ FLAGS_vm_manager = QemuManager::name();
+ }
+ }
+
if (FLAGS_vm_manager == QemuManager::name()) {
SetDefaultFlagsForQemu();
} else if (FLAGS_vm_manager == CrosvmManager::name()) {
@@ -846,7 +903,7 @@
// Set the env variable to empty (in case the caller passed a value for it).
unsetenv(kCuttlefishConfigEnvVarName);
- return ResolveInstanceFiles();
+ return true;
}
std::string GetConfigFilePath(const CuttlefishConfig& config) {
diff --git a/host/commands/assemble_cvd/flags.h b/host/commands/assemble_cvd/flags.h
index 3dca9e3..3c02d92 100644
--- a/host/commands/assemble_cvd/flags.h
+++ b/host/commands/assemble_cvd/flags.h
@@ -3,16 +3,23 @@
#include <cstdint>
#include <optional>
+#include "common/libs/utils/environment.h"
#include "host/libs/config/cuttlefish_config.h"
#include "host/libs/config/fetcher_config.h"
namespace cuttlefish {
-bool ParseCommandLineFlags(int* argc, char*** argv);
+struct KernelConfig {
+ Arch target_arch;
+ bool bootconfig_supported;
+};
+
+bool ParseCommandLineFlags(int* argc, char*** argv,
+ KernelConfig* kernel_config);
// Must be called after ParseCommandLineFlags.
CuttlefishConfig InitializeCuttlefishConfiguration(
- const std::string& assembly_dir, const std::string& instance_dir,
- int modem_simulator_count);
+ const std::string& instance_dir, int modem_simulator_count,
+ KernelConfig kernel_config);
std::string GetConfigFilePath(const CuttlefishConfig& config);
std::string GetCuttlefishEnvPath();
diff --git a/host/commands/run_cvd/main.cc b/host/commands/run_cvd/main.cc
index 8945da0..8e61d66 100644
--- a/host/commands/run_cvd/main.cc
+++ b/host/commands/run_cvd/main.cc
@@ -437,7 +437,7 @@
LOG(ERROR) << "Ethernet TAP device already in use";
}
- auto vm_manager = GetVmManager(config->vm_manager());
+ auto vm_manager = GetVmManager(config->vm_manager(), config->target_arch());
#ifndef __ANDROID__
// Check host configuration
diff --git a/host/frontend/webrtc/lib/streamer.cpp b/host/frontend/webrtc/lib/streamer.cpp
index 867dcac..31ec7fe 100644
--- a/host/frontend/webrtc/lib/streamer.cpp
+++ b/host/frontend/webrtc/lib/streamer.cpp
@@ -151,6 +151,9 @@
std::unique_ptr<Streamer> Streamer::Create(
const StreamerConfig& cfg,
std::shared_ptr<ConnectionObserverFactory> connection_observer_factory) {
+
+ rtc::LogMessage::LogToDebug(rtc::LS_ERROR);
+
std::unique_ptr<Streamer::Impl> impl(new Streamer::Impl());
impl->config_ = cfg;
impl->connection_observer_factory_ = connection_observer_factory;
diff --git a/host/libs/config/bootconfig_args.cpp b/host/libs/config/bootconfig_args.cpp
index b7c7f7a..b0a3b3f 100644
--- a/host/libs/config/bootconfig_args.cpp
+++ b/host/libs/config/bootconfig_args.cpp
@@ -83,7 +83,7 @@
std::vector<std::string> bootconfig_args;
AppendVector(&bootconfig_args, VmManagerBootconfig(config));
- auto vmm = vm_manager::GetVmManager(config.vm_manager());
+ auto vmm = vm_manager::GetVmManager(config.vm_manager(), config.target_arch());
AppendVector(&bootconfig_args,
vmm->ConfigureBootDevices(instance.virtual_disk_paths().size()));
AppendVector(&bootconfig_args, vmm->ConfigureGpuMode(config.gpu_mode()));
@@ -155,6 +155,12 @@
bootconfig_args.push_back("androidboot.verifiedbootstate=orange");
+ // Non-native architecture implies a significantly slower execution speed, so
+ // set a large timeout multiplier.
+ if (!IsHostCompatible(config.target_arch())) {
+ bootconfig_args.push_back("androidboot.hw_timeout_multiplier=50");
+ }
+
// TODO(b/173815685): Create an extra_bootconfig flag and add it to bootconfig
return bootconfig_args;
diff --git a/host/libs/config/cuttlefish_config.cpp b/host/libs/config/cuttlefish_config.cpp
index c1978bf..b9b04e5 100644
--- a/host/libs/config/cuttlefish_config.cpp
+++ b/host/libs/config/cuttlefish_config.cpp
@@ -259,12 +259,12 @@
(*dictionary_)[kSetupWizardMode] = mode;
}
-static constexpr char kQemuBinary[] = "qemu_binary";
-std::string CuttlefishConfig::qemu_binary() const {
- return (*dictionary_)[kQemuBinary].asString();
+static constexpr char kQemuBinaryDir[] = "qemu_binary_dir";
+std::string CuttlefishConfig::qemu_binary_dir() const {
+ return (*dictionary_)[kQemuBinaryDir].asString();
}
-void CuttlefishConfig::set_qemu_binary(const std::string& qemu_binary) {
- (*dictionary_)[kQemuBinary] = qemu_binary;
+void CuttlefishConfig::set_qemu_binary_dir(const std::string& qemu_binary_dir) {
+ (*dictionary_)[kQemuBinaryDir] = qemu_binary_dir;
}
static constexpr char kCrosvmBinary[] = "crosvm_binary";
@@ -676,7 +676,8 @@
console_dev = "hvc1";
} else {
// crosvm ARM does not support ttyAMA. ttyAMA is a part of ARM arch.
- if (HostArch() == "aarch64" &&
+ Arch target = target_arch();
+ if ((target == Arch::Arm64 || target == Arch::Arm) &&
vm_manager() != vm_manager::CrosvmManager::name()) {
console_dev = "ttyAMA0";
} else {
@@ -734,6 +735,22 @@
return (*dictionary_)[kProtectedVm].asBool();
}
+static constexpr char kTargetArch[] = "target_arch";
+void CuttlefishConfig::set_target_arch(Arch target_arch) {
+ (*dictionary_)[kTargetArch] = static_cast<int>(target_arch);
+}
+Arch CuttlefishConfig::target_arch() const {
+ return static_cast<Arch>((*dictionary_)[kTargetArch].asInt());
+}
+
+static constexpr char kBootconfigSupported[] = "bootconfig_supported";
+bool CuttlefishConfig::bootconfig_supported() const {
+ return (*dictionary_)[kBootconfigSupported].asBool();
+}
+void CuttlefishConfig::set_bootconfig_supported(bool bootconfig_supported) {
+ (*dictionary_)[kBootconfigSupported] = bootconfig_supported;
+}
+
// Creates the (initially empty) config object and populates it with values from
// the config file if the CUTTLEFISH_CONFIG_FILE env variable is present.
// Returns nullptr if there was an error loading from file
diff --git a/host/libs/config/cuttlefish_config.h b/host/libs/config/cuttlefish_config.h
index 9aa94b0..c2a024f 100644
--- a/host/libs/config/cuttlefish_config.h
+++ b/host/libs/config/cuttlefish_config.h
@@ -25,6 +25,7 @@
#include <set>
#include <vector>
+#include "common/libs/utils/environment.h"
#include "host/libs/config/custom_actions.h"
namespace Json {
@@ -132,8 +133,8 @@
void set_setupwizard_mode(const std::string& title);
std::string setupwizard_mode() const;
- void set_qemu_binary(const std::string& qemu_binary);
- std::string qemu_binary() const;
+ void set_qemu_binary_dir(const std::string& qemu_binary_dir);
+ std::string qemu_binary_dir() const;
void set_crosvm_binary(const std::string& crosvm_binary);
std::string crosvm_binary() const;
@@ -308,6 +309,12 @@
void set_protected_vm(bool protected_vm);
bool protected_vm() const;
+ void set_target_arch(Arch target_arch);
+ Arch target_arch() const;
+
+ void set_bootconfig_supported(bool bootconfig_supported);
+ bool bootconfig_supported() const;
+
class InstanceSpecific;
class MutableInstanceSpecific;
diff --git a/host/libs/config/kernel_args.cpp b/host/libs/config/kernel_args.cpp
index 7a9a40e..421950a 100644
--- a/host/libs/config/kernel_args.cpp
+++ b/host/libs/config/kernel_args.cpp
@@ -46,7 +46,8 @@
// crosvm sets up the console= earlycon= panic= flags for us if booting straight to
// the kernel, but QEMU and the bootloader via crosvm does not.
AppendVector(&vm_manager_cmdline, {"console=hvc0", "panic=-1"});
- if (HostArch() == "aarch64") {
+ Arch target_arch = config.target_arch();
+ if (target_arch == Arch::Arm64 || target_arch == Arch::Arm) {
if (config.vm_manager() == QemuManager::name()) {
// To update the pl011 address:
// $ qemu-system-aarch64 -machine virt -cpu cortex-a57 -machine dumpdtb=virt.dtb
diff --git a/host/libs/vm_manager/crosvm_manager.cpp b/host/libs/vm_manager/crosvm_manager.cpp
index 58ae199..0d5b5c7 100644
--- a/host/libs/vm_manager/crosvm_manager.cpp
+++ b/host/libs/vm_manager/crosvm_manager.cpp
@@ -138,7 +138,7 @@
std::vector<std::string> CrosvmManager::ConfigureBootDevices(int num_disks) {
// TODO There is no way to control this assignment with crosvm (yet)
- if (HostArch() == "x86_64") {
+ if (HostArch() == Arch::X86_64) {
// crosvm has an additional PCI device for an ISA bridge
std::stringstream stream;
stream << std::setfill('0') << std::setw(2) << std::hex
diff --git a/host/libs/vm_manager/crosvm_manager.h b/host/libs/vm_manager/crosvm_manager.h
index d6e0e01..a2865f7 100644
--- a/host/libs/vm_manager/crosvm_manager.h
+++ b/host/libs/vm_manager/crosvm_manager.h
@@ -31,7 +31,7 @@
class CrosvmManager : public VmManager {
public:
static std::string name() { return "crosvm"; }
- CrosvmManager() = default;
+ CrosvmManager(Arch arch) : VmManager(arch) {}
virtual ~CrosvmManager() = default;
bool IsSupported() override;
diff --git a/host/libs/vm_manager/qemu_manager.cpp b/host/libs/vm_manager/qemu_manager.cpp
index dff471d..92da009 100644
--- a/host/libs/vm_manager/qemu_manager.cpp
+++ b/host/libs/vm_manager/qemu_manager.cpp
@@ -121,11 +121,22 @@
}
std::vector<std::string> QemuManager::ConfigureBootDevices(int num_disks) {
- // QEMU has additional PCI devices for an ISA bridge and PIIX4
- std::stringstream stream;
- stream << std::setfill('0') << std::setw(2) << std::hex
- << 2 + VmManager::kDefaultNumHvcs + VmManager::kMaxDisks - num_disks;
- return {"androidboot.boot_devices=pci0000:00/0000:00:" + stream.str() + ".0"};
+ switch (arch_) {
+ case Arch::X86:
+ case Arch::X86_64: {
+ // QEMU has additional PCI devices for an ISA bridge and PIIX4
+ std::stringstream stream;
+ stream << std::setfill('0') << std::setw(2) << std::hex
+ << 2 + VmManager::kDefaultNumHvcs + VmManager::kMaxDisks -
+ num_disks;
+ return {"androidboot.boot_devices=pci0000:00/0000:00:" + stream.str() +
+ ".0"};
+ }
+ case Arch::Arm:
+ return {"androidboot.boot_devices=3f000000.pcie"};
+ case Arch::Arm64:
+ return {"androidboot.boot_devices=4010000000.pcie"};
+ }
}
std::vector<Command> QemuManager::StartCommands(
@@ -141,7 +152,22 @@
<< "attempting to KILL";
return KillSubprocess(proc);
};
- Command qemu_cmd(config.qemu_binary(), stop);
+ std::string qemu_binary = config.qemu_binary_dir();
+ switch (arch_) {
+ case Arch::Arm:
+ qemu_binary += "/qemu-system-arm";
+ break;
+ case Arch::Arm64:
+ qemu_binary += "/qemu-system-aarch64";
+ break;
+ case Arch::X86:
+ qemu_binary += "/qemu-system-i386";
+ break;
+ case Arch::X86_64:
+ qemu_binary += "/qemu-system-x86_64";
+ break;
+ }
+ Command qemu_cmd(qemu_binary, stop);
int hvc_num = 0;
int serial_num = 0;
@@ -207,7 +233,7 @@
hvc_num++;
};
- bool is_arm = android::base::EndsWith(config.qemu_binary(), "system-aarch64");
+ bool is_arm = arch_ == Arch::Arm || arch_ == Arch::Arm64;
auto access_kregistry_size_bytes = 0;
if (FileExists(instance.access_kregistry_path())) {
@@ -229,7 +255,8 @@
qemu_cmd.AddParameter("guest=", instance.instance_name(), ",debug-threads=on");
qemu_cmd.AddParameter("-machine");
- auto machine = is_arm ? "virt,gic-version=2" : "pc-i440fx-2.8,accel=kvm,nvdimm=on";
+ auto machine = is_arm ? "virt,gic-version=2,mte=on"
+ : "pc-i440fx-2.8,accel=kvm,nvdimm=on";
qemu_cmd.AddParameter(machine, ",usb=off,dump-guest-core=off");
qemu_cmd.AddParameter("-m");
@@ -428,7 +455,7 @@
qemu_cmd.AddParameter("virtio-gpu-pci,id=gpu0");
qemu_cmd.AddParameter("-cpu");
- qemu_cmd.AddParameter(is_arm ? "cortex-a53" : "host");
+ qemu_cmd.AddParameter(IsHostCompatible(arch_) ? "host" : "max");
qemu_cmd.AddParameter("-msg");
qemu_cmd.AddParameter("timestamp=on");
diff --git a/host/libs/vm_manager/qemu_manager.h b/host/libs/vm_manager/qemu_manager.h
index 3535246..21455f7 100644
--- a/host/libs/vm_manager/qemu_manager.h
+++ b/host/libs/vm_manager/qemu_manager.h
@@ -31,7 +31,7 @@
public:
static std::string name() { return "qemu_cli"; }
- QemuManager() = default;
+ QemuManager(Arch arch) : VmManager(arch) {}
virtual ~QemuManager() = default;
bool IsSupported() override;
diff --git a/host/libs/vm_manager/vm_manager.cpp b/host/libs/vm_manager/vm_manager.cpp
index 30aeee7..3a5a41d 100644
--- a/host/libs/vm_manager/vm_manager.cpp
+++ b/host/libs/vm_manager/vm_manager.cpp
@@ -27,12 +27,12 @@
namespace cuttlefish {
namespace vm_manager {
-std::unique_ptr<VmManager> GetVmManager(const std::string& name) {
+std::unique_ptr<VmManager> GetVmManager(const std::string& name, Arch arch) {
std::unique_ptr<VmManager> vmm;
if (name == QemuManager::name()) {
- vmm.reset(new QemuManager());
+ vmm.reset(new QemuManager(arch));
} else if (name == CrosvmManager::name()) {
- vmm.reset(new CrosvmManager());
+ vmm.reset(new CrosvmManager(arch));
}
if (!vmm) {
LOG(ERROR) << "Invalid VM manager: " << name;
diff --git a/host/libs/vm_manager/vm_manager.h b/host/libs/vm_manager/vm_manager.h
index b482b2c..74f5725 100644
--- a/host/libs/vm_manager/vm_manager.h
+++ b/host/libs/vm_manager/vm_manager.h
@@ -26,6 +26,9 @@
// Superclass of every guest VM manager.
class VmManager {
+ protected:
+ const Arch arch_;
+
public:
// This is the number of HVC virtual console ports that should be configured
// by the VmManager. Because crosvm currently allocates these ports as the
@@ -48,6 +51,7 @@
// assigned virtual disk PCI ID (i.e. 2 disks = 7 hvcs, 1 disks = 8 hvcs)
static const int kMaxDisks = 3;
+ VmManager(Arch arch) : arch_(arch) {}
virtual ~VmManager() = default;
virtual bool IsSupported() = 0;
@@ -62,7 +66,7 @@
const CuttlefishConfig& config) = 0;
};
-std::unique_ptr<VmManager> GetVmManager(const std::string&);
+std::unique_ptr<VmManager> GetVmManager(const std::string&, Arch arch);
} // namespace vm_manager
} // namespace cuttlefish
diff --git a/shared/BoardConfig.mk b/shared/BoardConfig.mk
index 27114bf..7fa67f5 100644
--- a/shared/BoardConfig.mk
+++ b/shared/BoardConfig.mk
@@ -187,7 +187,8 @@
BOARD_GOOGLE_SYSTEM_DYNAMIC_PARTITIONS_PARTITION_LIST := product system system_ext
BOARD_GOOGLE_SYSTEM_DYNAMIC_PARTITIONS_SIZE := 5368709120 # 5GiB
BOARD_GOOGLE_VENDOR_DYNAMIC_PARTITIONS_PARTITION_LIST := odm vendor vendor_dlkm odm_dlkm
-BOARD_GOOGLE_VENDOR_DYNAMIC_PARTITIONS_SIZE := 1073741824
+# 1020MiB, reserve 4MiB for dynamic partition metadata
+BOARD_GOOGLE_VENDOR_DYNAMIC_PARTITIONS_SIZE := 1069547520
BOARD_BUILD_SUPER_IMAGE_BY_DEFAULT := true
BOARD_SUPER_IMAGE_IN_UPDATE_PACKAGE := true
TARGET_RELEASETOOLS_EXTENSIONS := device/google/cuttlefish/shared
diff --git a/shared/config/init.vendor.rc b/shared/config/init.vendor.rc
index 3cd5a02..184833f 100644
--- a/shared/config/init.vendor.rc
+++ b/shared/config/init.vendor.rc
@@ -9,6 +9,7 @@
setprop ro.hardware.hwcomposer ${ro.boot.hardware.hwcomposer}
setprop ro.hardware.vulkan ${ro.boot.hardware.vulkan}
setprop ro.cpuvulkan.version ${ro.boot.cpuvulkan.version}
+ setprop ro.hw_timeout_multiplier ${ro.boot.hw_timeout_multiplier}
# start module load in the background
start vendor.insmod_sh