mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 02:47:34 +00:00
Kernel/aarch64: Support reading the command line via the RPi Mailbox
This reuses the existing `RPi::Mailbox` interface to read the command line via a VideoCore-specific mailbox message. This will have to be replaced if that interface starts being smarter, as this is needed very early, and nothing guarantees that a smarter Mailbox interface wouldn't need to allocate or log, which is a no-no during early boot. As the response string can be arbitrarily long, it's the caller's job to provide a long enough buffer for `Mailbox::query_kernel_command_line`. This commit chose 512 bytes, as it provides a large enough headroom over the 150-200 characters implicitly added by the VC firmware. The portable way would be to parse the `/chosen/bootargs` property of the device tree, but we currently lack the scaffolding for doing that. Support for this in QEMU relies on a patch that has not yet been accepted upstream, but is available via our `Toolchain/BuildQEMU.sh` script. It should, however, work on bare metal. Tested-By: Timon Kruiper <timonkruiper@gmail.com>
This commit is contained in:
parent
20fcbcb860
commit
81dd29f713
3 changed files with 46 additions and 1 deletions
|
@ -130,4 +130,40 @@ u32 Mailbox::query_firmware_version()
|
|||
return message_queue.query_firmware_version.version;
|
||||
}
|
||||
|
||||
// https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface#get-command-line
|
||||
//
|
||||
// Note: This function is called very early in the boot process, before the heap or the console
|
||||
// is initialized. Please ensure that it does the minimum amount of work possible.
|
||||
StringView Mailbox::query_kernel_command_line(Bytes buffer)
|
||||
{
|
||||
// We want to use the user-provided buffer rather than a fixed-size one on the stack,
|
||||
// so we need to construct the message manually.
|
||||
auto aligned_buffer = buffer.align_to(16);
|
||||
if (aligned_buffer.size() < 24)
|
||||
return ""sv;
|
||||
|
||||
auto max_response_length = aligned_buffer.size() - 24;
|
||||
|
||||
auto* message = reinterpret_cast<u32*>(aligned_buffer.data());
|
||||
message[0] = aligned_buffer.size();
|
||||
message[1] = MBOX_REQUEST;
|
||||
|
||||
message[2] = 0x0005'0001; // Query command line
|
||||
message[3] = max_response_length;
|
||||
message[4] = max_response_length;
|
||||
|
||||
message[aligned_buffer.size() / sizeof(u32) - 1] = 0;
|
||||
|
||||
if (!the().send_queue(message, aligned_buffer.size()))
|
||||
return ""sv;
|
||||
|
||||
// Bit 31 indicates that this is a response, the rest denote the length.
|
||||
auto response_length = message[4] & 0x7fff'ffff;
|
||||
|
||||
if (response_length > max_response_length)
|
||||
return ""sv; // The buffer was too small to hold the response.
|
||||
|
||||
return StringView { (char const*)&message[5], response_length };
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/StringView.h>
|
||||
#include <AK/Types.h>
|
||||
|
||||
namespace Kernel::RPi {
|
||||
|
@ -51,6 +52,9 @@ public:
|
|||
bool send_queue(void* queue, u32 queue_size) const;
|
||||
|
||||
u32 query_firmware_version();
|
||||
|
||||
// Returns the kernel command line as a StringView into the given buffer.
|
||||
StringView query_kernel_command_line(Bytes buffer);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -149,6 +149,10 @@ READONLY_AFTER_INIT u8 multiboot_framebuffer_type;
|
|||
|
||||
Atomic<Graphics::Console*> g_boot_console;
|
||||
|
||||
#if ARCH(AARCH64)
|
||||
READONLY_AFTER_INIT static u8 s_command_line_buffer[512];
|
||||
#endif
|
||||
|
||||
extern "C" [[noreturn]] UNMAP_AFTER_INIT void init([[maybe_unused]] BootInfo const& boot_info)
|
||||
{
|
||||
g_in_early_boot = true;
|
||||
|
@ -193,7 +197,8 @@ extern "C" [[noreturn]] UNMAP_AFTER_INIT void init([[maybe_unused]] BootInfo con
|
|||
multiboot_module_entry_t modules[] = {};
|
||||
multiboot_modules = modules;
|
||||
multiboot_modules_count = 0;
|
||||
kernel_cmdline = ""sv;
|
||||
// FIXME: Read the /chosen/bootargs property.
|
||||
kernel_cmdline = RPi::Mailbox::the().query_kernel_command_line(s_command_line_buffer);
|
||||
#endif
|
||||
|
||||
setup_serial_debug();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue