• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "host/libs/config/bootconfig_args.h"
18 
19 #include <array>
20 #include <sstream>
21 #include <string>
22 #include <vector>
23 
24 #include "common/libs/utils/environment.h"
25 #include "common/libs/utils/files.h"
26 #include "host/libs/config/cuttlefish_config.h"
27 #include "host/libs/config/known_paths.h"
28 #include "host/libs/vm_manager/crosvm_manager.h"
29 #include "host/libs/vm_manager/qemu_manager.h"
30 #include "host/libs/vm_manager/vm_manager.h"
31 
32 namespace cuttlefish {
33 
34 using vm_manager::CrosvmManager;
35 using vm_manager::QemuManager;
36 
37 namespace {
38 
39 template <typename T>
AppendVector(std::vector<T> * destination,const std::vector<T> & source)40 void AppendVector(std::vector<T>* destination, const std::vector<T>& source) {
41   destination->insert(destination->end(), source.begin(), source.end());
42 }
43 
44 template <typename S, typename T>
concat(const S & s,const T & t)45 std::string concat(const S& s, const T& t) {
46   std::ostringstream os;
47   os << s << t;
48   return os.str();
49 }
50 
51 // TODO(schuffelen): Move more of this into host/libs/vm_manager, as a
52 // substitute for the vm_manager comparisons.
VmManagerBootconfig(const CuttlefishConfig & config)53 std::vector<std::string> VmManagerBootconfig(const CuttlefishConfig& config) {
54   std::vector<std::string> vm_manager_cmdline;
55   if (config.console()) {
56     vm_manager_cmdline.push_back("androidboot.console=" + config.console_dev());
57   } else {
58     // Specify an invalid path under /dev, so the init process will disable the
59     // console service due to the console not being found. On physical devices,
60     // it is enough to not specify androidboot.console= *and* not specify the
61     // console= kernel command line parameter, because the console and kernel
62     // dmesg are muxed. However, on cuttlefish, we don't need to mux, and would
63     // prefer to retain the kernel dmesg logging, so we must work around init
64     // falling back to the check for /dev/console (which we'll always have).
65     vm_manager_cmdline.push_back("androidboot.console=invalid");
66   }
67   return vm_manager_cmdline;
68 }
69 
70 }  // namespace
71 
BootconfigArgsFromConfig(const CuttlefishConfig & config,const CuttlefishConfig::InstanceSpecific & instance)72 std::vector<std::string> BootconfigArgsFromConfig(
73     const CuttlefishConfig& config,
74     const CuttlefishConfig::InstanceSpecific& instance) {
75   std::vector<std::string> bootconfig_args;
76 
77   AppendVector(&bootconfig_args, VmManagerBootconfig(config));
78   auto vmm = vm_manager::GetVmManager(config.vm_manager(), config.target_arch());
79   bootconfig_args.push_back(
80       vmm->ConfigureBootDevices(instance.virtual_disk_paths().size()));
81   AppendVector(&bootconfig_args, vmm->ConfigureGraphics(config));
82 
83   bootconfig_args.push_back(
84       concat("androidboot.serialno=", instance.serial_number()));
85 
86   // TODO(b/131884992): update to specify multiple once supported.
87   const auto display_configs = config.display_configs();
88   CHECK_GE(display_configs.size(), 1);
89   bootconfig_args.push_back(
90       concat("androidboot.lcd_density=", display_configs[0].dpi));
91 
92   bootconfig_args.push_back(
93       concat("androidboot.setupwizard_mode=", config.setupwizard_mode()));
94   if (!config.guest_enforce_security()) {
95     bootconfig_args.push_back("androidboot.selinux=permissive");
96   }
97 
98   if (instance.tombstone_receiver_port()) {
99     bootconfig_args.push_back(concat("androidboot.vsock_tombstone_port=",
100                                      instance.tombstone_receiver_port()));
101   }
102 
103   if (instance.confui_host_vsock_port()) {
104     bootconfig_args.push_back(concat("androidboot.vsock_confirmationui_port=",
105                                      instance.confui_host_vsock_port()));
106   }
107 
108   if (instance.config_server_port()) {
109     bootconfig_args.push_back(
110         concat("androidboot.cuttlefish_config_server_port=",
111                instance.config_server_port()));
112   }
113 
114   if (instance.keyboard_server_port()) {
115     bootconfig_args.push_back(concat("androidboot.vsock_keyboard_port=",
116                                      instance.keyboard_server_port()));
117   }
118 
119   if (instance.touch_server_port()) {
120     bootconfig_args.push_back(
121         concat("androidboot.vsock_touch_port=", instance.touch_server_port()));
122   }
123 
124   if (config.enable_vehicle_hal_grpc_server() &&
125       instance.vehicle_hal_server_port() &&
126       FileExists(VehicleHalGrpcServerBinary())) {
127     constexpr int vehicle_hal_server_cid = 2;
128     bootconfig_args.push_back(concat(
129         "androidboot.vendor.vehiclehal.server.cid=", vehicle_hal_server_cid));
130     bootconfig_args.push_back(
131         concat("androidboot.vendor.vehiclehal.server.port=",
132                instance.vehicle_hal_server_port()));
133   }
134 
135   if (instance.audiocontrol_server_port()) {
136     bootconfig_args.push_back(
137         concat("androidboot.vendor.audiocontrol.server.cid=",
138                instance.vsock_guest_cid()));
139     bootconfig_args.push_back(
140         concat("androidboot.vendor.audiocontrol.server.port=",
141                instance.audiocontrol_server_port()));
142   }
143 
144   if (instance.camera_server_port()) {
145     bootconfig_args.push_back(concat("androidboot.vsock_camera_port=",
146                                      instance.camera_server_port()));
147     bootconfig_args.push_back(
148         concat("androidboot.vsock_camera_cid=", instance.vsock_guest_cid()));
149   }
150 
151   if (config.enable_modem_simulator() &&
152       instance.modem_simulator_ports() != "") {
153     bootconfig_args.push_back(concat("androidboot.modem_simulator_ports=",
154                                      instance.modem_simulator_ports()));
155   }
156 
157   bootconfig_args.push_back(concat("androidboot.fstab_suffix=",
158                                    config.userdata_format()));
159 
160   bootconfig_args.push_back(
161       concat("androidboot.wifi_mac_prefix=", instance.wifi_mac_prefix()));
162 
163   // Non-native architecture implies a significantly slower execution speed, so
164   // set a large timeout multiplier.
165   if (!IsHostCompatible(config.target_arch())) {
166     bootconfig_args.push_back("androidboot.hw_timeout_multiplier=50");
167   }
168 
169   // TODO(b/217564326): improve this checks for a hypervisor in the VM.
170   if (config.target_arch() == Arch::X86 ||
171       config.target_arch() == Arch::X86_64) {
172     bootconfig_args.push_back(
173         concat("androidboot.hypervisor.version=cf-", config.vm_manager()));
174     bootconfig_args.push_back("androidboot.hypervisor.vm.supported=1");
175     bootconfig_args.push_back(
176         "androidboot.hypervisor.protected_vm.supported=0");
177   }
178 
179   AppendVector(&bootconfig_args, config.extra_bootconfig_args());
180 
181   return bootconfig_args;
182 }
183 
184 }  // namespace cuttlefish
185