aboutsummaryrefslogtreecommitdiff
path: root/host/commands/assemble_cvd/disk_flags.cc
diff options
context:
space:
mode:
Diffstat (limited to 'host/commands/assemble_cvd/disk_flags.cc')
-rw-r--r--host/commands/assemble_cvd/disk_flags.cc141
1 files changed, 91 insertions, 50 deletions
diff --git a/host/commands/assemble_cvd/disk_flags.cc b/host/commands/assemble_cvd/disk_flags.cc
index 7c6ede198..b046339a5 100644
--- a/host/commands/assemble_cvd/disk_flags.cc
+++ b/host/commands/assemble_cvd/disk_flags.cc
@@ -45,6 +45,10 @@ DECLARE_string(system_image_dir);
DEFINE_string(boot_image, "",
"Location of cuttlefish boot image. If empty it is assumed to be "
"boot.img in the directory specified by -system_image_dir.");
+DEFINE_string(
+ init_boot_image, "",
+ "Location of cuttlefish init boot image. If empty it is assumed to "
+ "be init_boot.img in the directory specified by -system_image_dir.");
DEFINE_string(data_image, "", "Location of the data partition image.");
DEFINE_string(super_image, "", "Location of the super partition image.");
DEFINE_string(misc_image, "",
@@ -100,6 +104,11 @@ bool ResolveInstanceFiles() {
std::string default_boot_image = FLAGS_system_image_dir + "/boot.img";
SetCommandLineOptionWithMode("boot_image", default_boot_image.c_str(),
google::FlagSettingMode::SET_FLAGS_DEFAULT);
+ std::string default_init_boot_image =
+ FLAGS_system_image_dir + "/init_boot.img";
+ SetCommandLineOptionWithMode("init_boot_image",
+ default_init_boot_image.c_str(),
+ google::FlagSettingMode::SET_FLAGS_DEFAULT);
std::string default_data_image = FLAGS_system_image_dir + "/userdata.img";
SetCommandLineOptionWithMode("data_image", default_data_image.c_str(),
google::FlagSettingMode::SET_FLAGS_DEFAULT);
@@ -159,6 +168,16 @@ std::vector<ImagePartition> GetOsCompositeDiskConfig() {
.read_only = true,
});
partitions.push_back(ImagePartition{
+ .label = "init_boot_a",
+ .image_file_path = FLAGS_init_boot_image,
+ .read_only = true,
+ });
+ partitions.push_back(ImagePartition{
+ .label = "init_boot_b",
+ .image_file_path = FLAGS_init_boot_image,
+ .read_only = true,
+ });
+ partitions.push_back(ImagePartition{
.label = "vendor_boot_a",
.image_file_path = FLAGS_vendor_boot_image,
.read_only = true,
@@ -410,6 +429,11 @@ class BootImageRepacker : public Feature {
LOG(ERROR) << "File not found: " << FLAGS_boot_image;
return false;
}
+ // The init_boot partition is be optional for testing boot.img
+ // with the ramdisk inside.
+ if (!FileHasContent(FLAGS_init_boot_image)) {
+ LOG(WARNING) << "File not found: " << FLAGS_init_boot_image;
+ }
if (!FileHasContent(FLAGS_vendor_boot_image)) {
LOG(ERROR) << "File not found: " << FLAGS_vendor_boot_image;
@@ -467,41 +491,70 @@ class BootImageRepacker : public Feature {
const CuttlefishConfig& config_;
};
-static void GeneratePersistentBootconfig(
- const CuttlefishConfig& config,
- const CuttlefishConfig::InstanceSpecific& instance) {
- const auto bootconfig_path = instance.persistent_bootconfig_path();
- if (!FileExists(bootconfig_path)) {
- CreateBlankImage(bootconfig_path, 1 /* mb */, "none");
- }
+class GeneratePersistentBootconfig : public Feature {
+ public:
+ INJECT(GeneratePersistentBootconfig(
+ const CuttlefishConfig& config,
+ const CuttlefishConfig::InstanceSpecific& instance))
+ : config_(config), instance_(instance) {}
+
+ // Feature
+ std::string Name() const override { return "GeneratePersistentBootconfig"; }
+ bool Enabled() const override { return !config_.protected_vm(); }
- auto bootconfig_fd = SharedFD::Open(bootconfig_path, O_RDWR);
- CHECK(bootconfig_fd->IsOpen())
- << "Unable to open bootconfig file: " << bootconfig_fd->StrError();
-
- // Cuttlefish for the time being won't be able to support OTA from a
- // non-bootconfig kernel to a bootconfig-kernel (or vice versa) IF the device
- // is stopped (via stop_cvd). This is rarely an issue since OTA testing run
- // on cuttlefish is done within one launch cycle of the device. If this ever
- // becomes an issue, this code will have to be rewritten.
- if (!config.bootconfig_supported()) {
- return;
+ private:
+ std::unordered_set<Feature*> Dependencies() const override { return {}; }
+ bool Setup() override {
+ const auto bootconfig_path = instance_.persistent_bootconfig_path();
+ if (!FileExists(bootconfig_path)) {
+ if (!CreateBlankImage(bootconfig_path, 1 /* mb */, "none")) {
+ LOG(ERROR) << "Failed to create image at " << bootconfig_path;
+ return false;
+ }
+ }
+
+ auto bootconfig_fd = SharedFD::Open(bootconfig_path, O_RDWR);
+ if (!bootconfig_fd->IsOpen()) {
+ LOG(ERROR) << "Unable to open bootconfig file: "
+ << bootconfig_fd->StrError();
+ return false;
+ }
+
+ // Cuttlefish for the time being won't be able to support OTA from a
+ // non-bootconfig kernel to a bootconfig-kernel (or vice versa) IF the
+ // device is stopped (via stop_cvd). This is rarely an issue since OTA
+ // testing run on cuttlefish is done within one launch cycle of the device.
+ // If this ever becomes an issue, this code will have to be rewritten.
+ if (!config_.bootconfig_supported()) {
+ return true;
+ }
+
+ const std::string bootconfig =
+ android::base::Join(BootconfigArgsFromConfig(config_, instance_),
+ "\n") +
+ "\n";
+ ssize_t bytesWritten = WriteAll(bootconfig_fd, bootconfig);
+ if (bytesWritten != bootconfig.size()) {
+ LOG(ERROR) << "Failed to write contents of bootconfig to \""
+ << bootconfig_path << "\"";
+ return false;
+ }
+ LOG(DEBUG) << "Bootconfig parameters from vendor boot image and config are "
+ << ReadFile(bootconfig_path);
+
+ const off_t bootconfig_size_bytes =
+ AlignToPowerOf2(bootconfig.size(), PARTITION_SIZE_SHIFT);
+ if (bootconfig_fd->Truncate(bootconfig_size_bytes) != 0) {
+ LOG(ERROR) << "`truncate --size=" << bootconfig_size_bytes << " bytes "
+ << bootconfig_path << "` failed:" << bootconfig_fd->StrError();
+ return false;
+ }
+ return true;
}
- const std::string bootconfig =
- android::base::Join(BootconfigArgsFromConfig(config, instance), "\n") +
- "\n";
- ssize_t bytesWritten = WriteAll(bootconfig_fd, bootconfig);
- CHECK(bytesWritten == bootconfig.size());
- LOG(DEBUG) << "Bootconfig parameters from vendor boot image and config are "
- << ReadFile(bootconfig_path);
-
- const off_t bootconfig_size_bytes =
- AlignToPowerOf2(bootconfig.size(), PARTITION_SIZE_SHIFT);
- CHECK(bootconfig_fd->Truncate(bootconfig_size_bytes) == 0)
- << "`truncate --size=" << bootconfig_size_bytes << " bytes "
- << bootconfig_path << "` failed:" << bootconfig_fd->StrError();
-}
+ const CuttlefishConfig& config_;
+ const CuttlefishConfig::InstanceSpecific& instance_;
+};
class InitializeMetadataImage : public Feature {
public:
@@ -661,7 +714,11 @@ static fruit::Component<> DiskChangesComponent(const FetcherConfig* fetcher,
.install(FixedMiscImagePathComponent, &FLAGS_misc_image)
.install(InitializeMiscImageComponent)
.install(FixedDataImagePathComponent, &FLAGS_data_image)
- .install(InitializeDataImageComponent);
+ .install(InitializeDataImageComponent)
+ // Create esp if necessary
+ .install(InitializeEspImageComponent, &FLAGS_otheros_esp_image,
+ &FLAGS_otheros_kernel_path, &FLAGS_otheros_initramfs_path,
+ &FLAGS_otheros_root_image);
}
static fruit::Component<> DiskChangesPerInstanceComponent(
@@ -675,6 +732,7 @@ static fruit::Component<> DiskChangesPerInstanceComponent(
.addMultibinding<Feature, InitializePstore>()
.addMultibinding<Feature, InitializeSdCard>()
.addMultibinding<Feature, InitializeFactoryResetProtected>()
+ .addMultibinding<Feature, GeneratePersistentBootconfig>()
.install(InitBootloaderEnvPartitionComponent);
}
@@ -687,13 +745,6 @@ void CreateDynamicDiskFiles(const FetcherConfig& fetcher_config,
const auto& features = injector.getMultibindings<Feature>();
CHECK(Feature::RunSetup(features)) << "Failed to run feature setup.";
- // Create esp if necessary
- if (!FLAGS_otheros_root_image.empty()) {
- CHECK(InitializeEspImage(FLAGS_otheros_esp_image, FLAGS_otheros_kernel_path,
- FLAGS_otheros_initramfs_path))
- << "Failed to create esp image";
- }
-
for (const auto& instance : config.Instances()) {
fruit::Injector<> instance_injector(DiskChangesPerInstanceComponent,
&fetcher_config, &config, &instance);
@@ -703,16 +754,6 @@ void CreateDynamicDiskFiles(const FetcherConfig& fetcher_config,
<< "Failed to run instance feature setup.";
}
- // If we are booting a protected VM, for now, assume we want a super minimal
- // environment with no userdata encryption, limited debug, no FRP emulation, a
- // static env for the bootloader, no SD-Card and no resume-on-reboot HAL
- // support.
- if (!FLAGS_protected_vm) {
- for (const auto& instance : config.Instances()) {
- GeneratePersistentBootconfig(config, instance);
- }
- }
-
for (const auto& instance : config.Instances()) {
bool compositeMatchesDiskConfig = DoesCompositeMatchCurrentDiskConfig(
instance.PerInstancePath("persistent_composite_disk_config.txt"),