From 3d57c84476ce542a7d8d623cf1f208efc1a20026 Mon Sep 17 00:00:00 2001 From: Tianjie Xu Date: Sat, 9 Nov 2019 22:07:20 -0800 Subject: Consolidate the vendor space misc usage for Pixels The layout of the vendor space /misc partition was pretty confusing and lead to some usage conflicts. To formalize the layout, we create a pixel specific library with the definition & offset of various flags. The new library also handles the R/W. As a result, we will leave system domain /misc definitions in the libbootloader_message. We also switch the misc_writer binary to use more specific options instead of writing an arbitrary hex string. So we can avoid redefining the string & offset in both init script and recovery ui. Bug: 131775112 Test: unit tests pass, run misc_writer and check contents of /misc Change-Id: I00f8842a81d1929e31a1de4d5eb09575ffad47c0 --- misc_writer/misc_writer.cpp | 127 ++++++++++++++++++-------------------------- 1 file changed, 52 insertions(+), 75 deletions(-) (limited to 'misc_writer/misc_writer.cpp') diff --git a/misc_writer/misc_writer.cpp b/misc_writer/misc_writer.cpp index 1d9702ebf..bf589d31f 100644 --- a/misc_writer/misc_writer.cpp +++ b/misc_writer/misc_writer.cpp @@ -14,93 +14,70 @@ * limitations under the License. */ -#include -#include -#include -#include -#include +#include "misc_writer/misc_writer.h" -#include -#include -#include -#include +#include +#include #include -#include +#include #include -using namespace std::string_literals; +namespace android { +namespace hardware { +namespace google { +namespace pixel { -static std::vector ParseHexString(std::string_view hex_string) { - auto length = hex_string.size(); - if (length % 2 != 0 || length == 0) { - return {}; - } - - std::vector result(length / 2); - for (size_t i = 0; i < length / 2; i++) { - auto sub = "0x" + std::string(hex_string.substr(i * 2, 2)); - if (!android::base::ParseUint(sub, &result[i])) { - return {}; - } - } - return result; +bool MiscWriter::OffsetAndSizeInVendorSpace(size_t offset, size_t size) { + auto total_size = WIPE_PACKAGE_OFFSET_IN_MISC - VENDOR_SPACE_OFFSET_IN_MISC; + return size <= total_size && offset <= total_size - size; } -static int Usage(std::string_view name) { - std::cerr << name << " usage:\n"; - std::cerr << name << " [--vendor-space-offset ] --hex-string 0xABCDEF\n"; - std::cerr << "Writes the given hex string to the specified offset in vendor space in /misc " - "partition. Offset defaults to 0 if unspecified.\n"; - return EXIT_FAILURE; +bool MiscWriter::WriteMiscPartitionVendorSpace(const void* data, size_t size, size_t offset, + std::string* err) { + if (!OffsetAndSizeInVendorSpace(offset, size)) { + *err = android::base::StringPrintf("Out of bound write (offset %zu size %zu)", offset, size); + return false; + } + auto misc_blk_device = get_misc_blk_device(err); + if (misc_blk_device.empty()) { + return false; + } + return write_misc_partition(data, size, misc_blk_device, VENDOR_SPACE_OFFSET_IN_MISC + offset, + err); } -// misc_writer is a vendor tool that writes data to the vendor space in /misc. -int main(int argc, char** argv) { - constexpr struct option OPTIONS[] = { - { "vendor-space-offset", required_argument, nullptr, 0 }, - { "hex-string", required_argument, nullptr, 0 }, - { nullptr, 0, nullptr, 0 }, - }; - - // Offset defaults to 0 if unspecified. +bool MiscWriter::PerformAction(std::optional override_offset) { size_t offset = 0; - std::string_view hex_string; - - int arg; - int option_index; - while ((arg = getopt_long(argc, argv, "", OPTIONS, &option_index)) != -1) { - if (arg != 0) { - LOG(ERROR) << "Invalid command argument"; - return Usage(argv[0]); - } - auto option_name = OPTIONS[option_index].name; - if (option_name == "vendor-space-offset"s) { - if (!android::base::ParseUint(optarg, &offset)) { - LOG(ERROR) << "Failed to parse the offset: " << optarg; - return Usage(argv[0]); - } - } else if (option_name == "hex-string"s) { - hex_string = optarg; - } - } - - if (hex_string.starts_with("0x") || hex_string.starts_with("0X")) { - hex_string = hex_string.substr(2); - } - if (hex_string.empty()) { - LOG(ERROR) << "Invalid input hex string: " << hex_string; - return Usage(argv[0]); + std::string content; + switch (action_) { + case MiscWriterActions::kSetDarkThemeFlag: + case MiscWriterActions::kClearDarkThemeFlag: + offset = override_offset.value_or(kThemeFlagOffsetInVendorSpace); + content = (action_ == MiscWriterActions::kSetDarkThemeFlag) + ? kDarkThemeFlag + : std::string(strlen(kDarkThemeFlag), 0); + break; + case MiscWriterActions::kSetSotaFlag: + case MiscWriterActions::kClearSotaFlag: + offset = override_offset.value_or(kSotaFlagOffsetInVendorSpace); + content = (action_ == MiscWriterActions::kSetSotaFlag) ? kSotaFlag + : std::string(strlen(kSotaFlag), 0); + break; + case MiscWriterActions::kUnset: + LOG(ERROR) << "The misc writer action must be set"; + return false; } - auto data = ParseHexString(hex_string); - if (data.empty()) { - LOG(ERROR) << "Failed to parse the input hex string: " << hex_string; - return EXIT_FAILURE; - } - if (std::string err; !WriteMiscPartitionVendorSpace(data.data(), data.size(), offset, &err)) { - LOG(ERROR) << "Failed to write to misc partition: " << err; - return EXIT_FAILURE; + if (std::string err; + !WriteMiscPartitionVendorSpace(content.data(), content.size(), offset, &err)) { + LOG(ERROR) << "Failed to write " << content << " at offset " << offset << " : " << err; + return false; } - return EXIT_SUCCESS; + return true; } + +} // namespace pixel +} // namespace google +} // namespace hardware +} // namespace android -- cgit v1.2.3