blob: 7cb4ebb9209a302a630040ec06be98909dd74021 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <lib/zx/vmar.h>
#include "boot-args.h"
namespace devmgr {
zx_status_t BootArgs::Create(zx::vmo vmo, size_t size, BootArgs* out) {
// If we have no valid data in the VMO, return early success.
if (size == 0) {
return ZX_OK;
}
uintptr_t addr;
zx_status_t status = zx::vmar::root_self()->map(0, vmo, 0, size, ZX_VM_PERM_READ, &addr);
if (status != ZX_OK) {
return status;
}
// Build boot arguments map for fast lookup.
std::string_view view(reinterpret_cast<char*>(addr), size);
ArgsMap args;
for (size_t begin = 0, end; (end = view.find_first_of('\0', begin)) != std::string_view::npos;
begin = end + 1) {
size_t sep = view.find_first_of('=', begin);
std::string_view key;
const char* value;
if (sep < end) {
// Handle arguments of the form "key=value".
key = std::string_view(&view[begin], sep - begin);
value = &view[sep + 1];
} else {
// Handle arguments of the form "key".
key = std::string_view(&view[begin], end - begin);
value = &view[end];
}
args.insert_or_assign(key, value);
}
out->addr_ = addr;
out->size_ = size;
out->args_ = std::move(args);
return ZX_OK;
}
BootArgs::~BootArgs() {
if (addr_ != 0) {
zx::vmar::root_self()->unmap(addr_, size_);
}
}
const char* BootArgs::Get(std::string_view name) const {
auto it = args_.find(name);
if (it == args_.end()) {
return nullptr;
}
return it->second;
}
bool BootArgs::GetBool(std::string_view name, bool default_value) const {
const char* value = Get(name);
if (value == nullptr) {
return default_value;
} else if (strcmp(value, "0") == 0 || strcmp(value, "false") == 0 ||
strcmp(value, "off") == 0) {
return false;
} else {
return true;
}
}
void BootArgs::Collect(std::string_view prefix, fbl::Vector<const char*>* out) const {
std::string_view view(reinterpret_cast<char*>(addr_), size_);
for (size_t pos = 0; (pos = view.find(prefix, pos)) != std::string_view::npos;
pos = view.find_first_of('\0', pos)) {
out->push_back(&view[pos]);
}
}
} // namespace devmgr