blob: a77d1c2d891c6f55b85567767a0dff622fe89ae3 [file] [log] [blame]
// Copyright 2023 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include "phys/boot-options.h"
#include <lib/boot-options/boot-options.h>
#include <lib/boot-options/word-view.h>
#include <lib/uart/all.h>
#include <lib/uart/sync.h>
#include <lib/zbi-format/zbi.h>
#include <lib/zbitl/view.h>
#include <explicit-memory/bytes.h>
#include <ktl/string_view.h>
void SetBootOptions(BootOptions& boot_opts, zbitl::ByteView zbi, ktl::string_view legacy_cmdline) {
{
// Select UART configuration from a UART driver item in the ZBI.
zbitl::View view(zbi);
// The |IoProvider| and |SyncPolicy| choice in the driver below aren't relevant, and the sole
// purpose of |driver| is performing a match.
uart::all::KernelDriver<uart::BasicIoProvider, uart::UnsynchronizedPolicy> driver;
for (auto [header, payload] : view) {
if (driver.Match(*header, payload.data())) {
boot_opts.serial = driver.uart();
}
}
view.ignore_error();
// Select UART configuration from cmdline item in the ZBI.
for (auto [header, payload] : view) {
if (header->type == ZBI_TYPE_CMDLINE) {
boot_opts.SetMany({reinterpret_cast<const char*>(payload.data()), payload.size()});
}
}
view.ignore_error();
}
// At last the bootloader provided arguments trumps everything.
boot_opts.SetMany(legacy_cmdline);
}
void SetBootOptionsWithoutEntropy(BootOptions& boot_opts, zbitl::ByteView zbi,
ktl::string_view legacy_cmdline) {
SetBootOptions(boot_opts, zbi, legacy_cmdline);
// Restore the entropy bits.
// We only use boot-options parsing for kernel.serial and ignore the rest.
// But it destructively scrubs the RedactedHex input so we have to undo that.
if (boot_opts.entropy_mixin.len > 0) {
// BootOptions already parsed and redacted, so put it back.
for (auto word : WordView(legacy_cmdline)) {
constexpr ktl::string_view kPrefix = "kernel.entropy-mixin=";
if (ktl::starts_with(word, kPrefix)) {
word.remove_prefix(kPrefix.length());
memcpy(const_cast<char*>(word.data()), boot_opts.entropy_mixin.hex.data(),
std::min(boot_opts.entropy_mixin.len, word.size()));
mandatory_memset(boot_opts.entropy_mixin.hex.data(), 0, boot_opts.entropy_mixin.len);
break;
}
}
}
}