[boot] Create bootconfig to tell boot what to load
While bonnibel already had the concept of a manifest, which controls what goes into the built disk image, the bootloader still had filenames hard-coded. Now bonnibel creates a 'jsix_boot.dat' file that tells the bootloader what it should load. Changes include: - Modules have two new fields: location and description. location is their intended directory on the EFI boot volume. description is self-explanatory, and is used in log messages. - New class, boot::bootconfig, implements reading of jsix_boot.dat - New header, bootproto/bootconfig.h, specifies flags used in the manifest and jsix_boot.dat - New python module, bonnibel/manifest.py, encapsulates reading of the manifest and writing jsix_boot.dat - Syntax of the manifest changed slightly, including adding flags - Boot and Kernel target ccflags unified a bit (this was partly due to trying to get enum_bitfields to work in boot) - util::counted gained operator+= and new free function util::read<T>
This commit is contained in:
62
src/boot/bootconfig.cpp
Normal file
62
src/boot/bootconfig.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#include <uefi/boot_services.h>
|
||||
#include <uefi/types.h>
|
||||
|
||||
#include "bootconfig.h"
|
||||
#include "error.h"
|
||||
#include "fs.h"
|
||||
#include "status.h"
|
||||
|
||||
namespace boot {
|
||||
|
||||
constexpr uint64_t jsixboot = 0x746f6f627869736a; // "jsixboot"
|
||||
|
||||
static const wchar_t *
|
||||
read_string(util::buffer &data)
|
||||
{
|
||||
uint16_t size = *util::read<uint16_t>(data);
|
||||
const wchar_t *string = reinterpret_cast<const wchar_t*>(data.pointer);
|
||||
data += size;
|
||||
return string;
|
||||
}
|
||||
|
||||
static void
|
||||
read_descriptor(descriptor &e, util::buffer &data)
|
||||
{
|
||||
e.flags = static_cast<desc_flags>(*util::read<uint16_t>(data));
|
||||
e.path = read_string(data);
|
||||
e.desc = read_string(data);
|
||||
}
|
||||
|
||||
bootconfig::bootconfig(util::buffer data, uefi::boot_services *bs)
|
||||
{
|
||||
status_line status {L"Loading boot config"};
|
||||
|
||||
if (*util::read<uint64_t>(data) != jsixboot)
|
||||
error::raise(uefi::status::load_error, L"Bad header in jsix_boot.dat");
|
||||
|
||||
const uint8_t version = *util::read<uint8_t>(data);
|
||||
if (version != 0)
|
||||
error::raise(uefi::status::incompatible_version, L"Bad version in jsix_boot.dat");
|
||||
|
||||
data += 1; // reserved byte
|
||||
uint16_t num_programs = *util::read<uint16_t>(data);
|
||||
uint16_t num_data = *util::read<uint16_t>(data);
|
||||
data += 2; // reserved short
|
||||
|
||||
read_descriptor(m_kernel, data);
|
||||
read_descriptor(m_init, data);
|
||||
|
||||
m_programs.count = num_programs;
|
||||
m_programs.pointer = new descriptor [num_programs];
|
||||
|
||||
for (unsigned i = 0; i < num_programs; ++i)
|
||||
read_descriptor(m_programs[i], data);
|
||||
|
||||
m_data.count = num_programs;
|
||||
m_data.pointer = new descriptor [num_data];
|
||||
|
||||
for (unsigned i = 0; i < num_data; ++i)
|
||||
read_descriptor(m_data[i], data);
|
||||
}
|
||||
|
||||
} // namespace boot
|
||||
Reference in New Issue
Block a user