[bootproto] Create new bootproto lib
This is a rather large commit that is widely focused on cleaning things out of the 'junk drawer' that is src/include. Most notably, several things that were put in there because they needed somewhere where both the kernel, boot, and init could read them have been moved to a new lib, 'bootproto'. - Moved kernel_args.h and init_args.h to bootproto as kernel.h and init.h, respectively. - Moved counted.h and pointer_manipulation.h into util, renaming the latter to util/pointers.h. - Created a new src/include/arch for very arch-dependent definitions, and moved some kernel_memory.h constants like frame size, page table entry count, etc to arch/amd64/memory.h. Also created arch/memory.h which detects platform and includes the former. - Got rid of kernel_memory.h entirely in favor of a new, cog-based approach. The new definitions/memory_layout.csv lists memory regions in descending order from the top of memory, their sizes, and whether they are shared outside the kernel (ie, boot needs to know them). The new header bootproto/memory.h exposes the addresses of the shared regions, while the kernel's memory.h gains the start and size of all the regions. Also renamed the badly-named page-offset area the linear area. - The python build scripts got a few new features: the ability to parse the csv mentioned above in a new memory.py module; the ability to add dependencies to existing source files (The list of files that I had to pull out of the main list just to add them with the dependency on memory.h was getting too large. So I put them back into the sources list, and added the dependency post-hoc.); and the ability to reference 'source_root', 'build_root', and 'module_root' variables in .module files. - Some utility functions that were in the kernel's memory.h got moved to util/pointers.h and util/misc.h, and misc.h's byteswap was renamed byteswap32 to be more specific.
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
#include <uefi/boot_services.h>
|
||||
#include <uefi/types.h>
|
||||
|
||||
#include <bootproto/init.h>
|
||||
#include <bootproto/kernel.h>
|
||||
#include <util/no_construct.h>
|
||||
#include <util/pointers.h>
|
||||
|
||||
#include "allocator.h"
|
||||
#include "error.h"
|
||||
#include "init_args.h"
|
||||
#include "kernel_args.h"
|
||||
#include "memory.h"
|
||||
|
||||
namespace boot {
|
||||
@@ -15,9 +17,9 @@ memory::allocator &g_alloc = __g_alloc_storage.value;
|
||||
|
||||
namespace memory {
|
||||
|
||||
using kernel::init::allocation_register;
|
||||
using kernel::init::module;
|
||||
using kernel::init::page_allocation;
|
||||
using bootproto::allocation_register;
|
||||
using bootproto::module;
|
||||
using bootproto::page_allocation;
|
||||
|
||||
static_assert(sizeof(allocation_register) == page_size);
|
||||
|
||||
@@ -119,7 +121,7 @@ allocator::allocate_module_untyped(size_t size)
|
||||
|
||||
++m_modules->count;
|
||||
module *m = m_next_mod;
|
||||
m_next_mod = offset_ptr<module>(m_next_mod, size);
|
||||
m_next_mod = util::offset_pointer(m_next_mod, size);
|
||||
|
||||
m->mod_length = size;
|
||||
return m;
|
||||
|
||||
@@ -6,25 +6,24 @@ namespace uefi {
|
||||
class boot_services;
|
||||
}
|
||||
|
||||
namespace kernel {
|
||||
namespace init {
|
||||
namespace bootproto {
|
||||
enum class allocation_type : uint8_t;
|
||||
struct allocation_register;
|
||||
struct module;
|
||||
struct modules_page;
|
||||
}}
|
||||
}
|
||||
|
||||
namespace boot {
|
||||
namespace memory {
|
||||
|
||||
using alloc_type = kernel::init::allocation_type;
|
||||
using alloc_type = bootproto::allocation_type;
|
||||
|
||||
class allocator
|
||||
{
|
||||
public:
|
||||
using allocation_register = kernel::init::allocation_register;
|
||||
using module = kernel::init::module;
|
||||
using modules_page = kernel::init::modules_page;
|
||||
using allocation_register = bootproto::allocation_register;
|
||||
using module = bootproto::module;
|
||||
using modules_page = bootproto::modules_page;
|
||||
|
||||
allocator(uefi::boot_services &bs);
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ module("boot",
|
||||
kind = "exe",
|
||||
output = "boot.efi",
|
||||
targets = [ "boot" ],
|
||||
deps = [ "cpu", "elf", "util" ],
|
||||
deps = [ "cpu", "elf", "util", "bootproto" ],
|
||||
sources = [
|
||||
"allocator.cpp",
|
||||
"console.cpp",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "error.h"
|
||||
#include "console.h"
|
||||
#include "kernel_args.h"
|
||||
#include "status.h"
|
||||
|
||||
namespace boot {
|
||||
|
||||
@@ -5,11 +5,12 @@
|
||||
#include <uefi/protos/loaded_image.h>
|
||||
#include <uefi/protos/simple_file_system.h>
|
||||
|
||||
#include <bootproto/kernel.h>
|
||||
|
||||
#include "allocator.h"
|
||||
#include "console.h"
|
||||
#include "error.h"
|
||||
#include "fs.h"
|
||||
#include "kernel_args.h"
|
||||
#include "memory.h"
|
||||
#include "status.h"
|
||||
|
||||
@@ -53,7 +54,7 @@ file::open(const wchar_t *path)
|
||||
return file(fh);
|
||||
}
|
||||
|
||||
buffer
|
||||
util::buffer
|
||||
file::load()
|
||||
{
|
||||
uint8_t info_buf[sizeof(uefi::protos::file_info) + 100];
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <uefi/types.h>
|
||||
#include "counted.h"
|
||||
#include <util/counted.h>
|
||||
|
||||
namespace uefi {
|
||||
struct boot_services;
|
||||
@@ -29,7 +29,7 @@ public:
|
||||
/// Load the contents of this file into memory.
|
||||
/// \returns A buffer describing the loaded memory. The
|
||||
/// memory will be page-aligned.
|
||||
buffer load();
|
||||
util::buffer load();
|
||||
|
||||
private:
|
||||
friend file get_boot_volume(uefi::handle, uefi::boot_services*);
|
||||
|
||||
@@ -1,27 +1,26 @@
|
||||
#include <uefi/boot_services.h>
|
||||
#include <uefi/types.h>
|
||||
|
||||
#include <bootproto/init.h>
|
||||
#include <elf/file.h>
|
||||
#include <elf/headers.h>
|
||||
#include <util/pointers.h>
|
||||
|
||||
#include "allocator.h"
|
||||
#include "console.h"
|
||||
#include "elf/file.h"
|
||||
#include "elf/headers.h"
|
||||
#include "error.h"
|
||||
#include "fs.h"
|
||||
#include "init_args.h"
|
||||
#include "loader.h"
|
||||
#include "memory.h"
|
||||
#include "paging.h"
|
||||
#include "pointer_manipulation.h"
|
||||
#include "status.h"
|
||||
|
||||
namespace init = kernel::init;
|
||||
|
||||
namespace boot {
|
||||
namespace loader {
|
||||
|
||||
using memory::alloc_type;
|
||||
|
||||
buffer
|
||||
util::buffer
|
||||
load_file(
|
||||
fs::file &disk,
|
||||
const program_desc &desc)
|
||||
@@ -29,7 +28,7 @@ load_file(
|
||||
status_line status(L"Loading file", desc.path);
|
||||
|
||||
fs::file file = disk.open(desc.path);
|
||||
buffer b = file.load();
|
||||
util::buffer b = file.load();
|
||||
|
||||
//console::print(L" Loaded at: 0x%lx, %d bytes\r\n", b.data, b.size);
|
||||
return b;
|
||||
@@ -37,17 +36,17 @@ load_file(
|
||||
|
||||
|
||||
static void
|
||||
create_module(buffer data, const program_desc &desc, bool loaded)
|
||||
create_module(util::buffer data, const program_desc &desc, bool loaded)
|
||||
{
|
||||
size_t path_len = wstrlen(desc.path);
|
||||
init::module_program *mod = g_alloc.allocate_module<init::module_program>(path_len);
|
||||
mod->mod_type = init::module_type::program;
|
||||
bootproto::module_program *mod = g_alloc.allocate_module<bootproto::module_program>(path_len);
|
||||
mod->mod_type = bootproto::module_type::program;
|
||||
mod->base_address = reinterpret_cast<uintptr_t>(data.pointer);
|
||||
mod->size = data.count;
|
||||
if (loaded)
|
||||
mod->mod_flags = static_cast<init::module_flags>(
|
||||
mod->mod_flags = static_cast<bootproto::module_flags>(
|
||||
static_cast<uint8_t>(mod->mod_flags) |
|
||||
static_cast<uint8_t>(init::module_flags::no_load));
|
||||
static_cast<uint8_t>(bootproto::module_flags::no_load));
|
||||
|
||||
// TODO: support non-ascii path characters and do real utf-16 to utf-8
|
||||
// conversion
|
||||
@@ -56,7 +55,7 @@ create_module(buffer data, const program_desc &desc, bool loaded)
|
||||
mod->filename[path_len] = 0;
|
||||
}
|
||||
|
||||
init::program *
|
||||
bootproto::program *
|
||||
load_program(
|
||||
fs::file &disk,
|
||||
const program_desc &desc,
|
||||
@@ -64,7 +63,7 @@ load_program(
|
||||
{
|
||||
status_line status(L"Loading program", desc.name);
|
||||
|
||||
buffer data = load_file(disk, desc);
|
||||
util::buffer data = load_file(disk, desc);
|
||||
|
||||
if (add_module)
|
||||
create_module(data, desc, true);
|
||||
@@ -79,20 +78,20 @@ load_program(
|
||||
++num_sections;
|
||||
}
|
||||
|
||||
init::program_section *sections = new init::program_section [num_sections];
|
||||
bootproto::program_section *sections = new bootproto::program_section [num_sections];
|
||||
|
||||
size_t next_section = 0;
|
||||
for (auto &seg : program.programs()) {
|
||||
if (seg.type != elf::segment_type::load)
|
||||
continue;
|
||||
|
||||
init::program_section §ion = sections[next_section++];
|
||||
bootproto::program_section §ion = sections[next_section++];
|
||||
|
||||
size_t page_count = memory::bytes_to_pages(seg.mem_size);
|
||||
|
||||
if (seg.mem_size > seg.file_size) {
|
||||
void *pages = g_alloc.allocate_pages(page_count, alloc_type::program, true);
|
||||
void *source = offset_ptr<void>(data.pointer, seg.offset);
|
||||
void *source = util::offset_pointer(data.pointer, seg.offset);
|
||||
g_alloc.copy(pages, source, seg.file_size);
|
||||
section.phys_addr = reinterpret_cast<uintptr_t>(pages);
|
||||
} else {
|
||||
@@ -101,10 +100,10 @@ load_program(
|
||||
|
||||
section.virt_addr = seg.vaddr;
|
||||
section.size = seg.mem_size;
|
||||
section.type = static_cast<init::section_flags>(seg.flags);
|
||||
section.type = static_cast<bootproto::section_flags>(seg.flags);
|
||||
}
|
||||
|
||||
init::program *prog = new init::program;
|
||||
bootproto::program *prog = new bootproto::program;
|
||||
prog->sections = { .pointer = sections, .count = num_sections };
|
||||
prog->phys_base = program.base();
|
||||
prog->entrypoint = program.entrypoint();
|
||||
@@ -118,25 +117,25 @@ load_module(
|
||||
{
|
||||
status_line status(L"Loading module", desc.name);
|
||||
|
||||
buffer data = load_file(disk, desc);
|
||||
util::buffer data = load_file(disk, desc);
|
||||
create_module(data, desc, false);
|
||||
}
|
||||
|
||||
void
|
||||
verify_kernel_header(init::program &program)
|
||||
verify_kernel_header(bootproto::program &program)
|
||||
{
|
||||
status_line status(L"Verifying kernel header");
|
||||
|
||||
const init::header *header =
|
||||
reinterpret_cast<const init::header *>(program.sections[0].phys_addr);
|
||||
const bootproto::header *header =
|
||||
reinterpret_cast<const bootproto::header *>(program.sections[0].phys_addr);
|
||||
|
||||
if (header->magic != init::header_magic)
|
||||
if (header->magic != bootproto::header_magic)
|
||||
error::raise(uefi::status::load_error, L"Bad kernel magic number");
|
||||
|
||||
if (header->length < sizeof(init::header))
|
||||
if (header->length < sizeof(bootproto::header))
|
||||
error::raise(uefi::status::load_error, L"Bad kernel header length");
|
||||
|
||||
if (header->version < init::min_header_version)
|
||||
if (header->version < bootproto::min_header_version)
|
||||
error::raise(uefi::status::unsupported, L"Kernel header version not supported");
|
||||
|
||||
console::print(L" Loaded kernel vserion: %d.%d.%d %x\r\n",
|
||||
|
||||
@@ -2,13 +2,12 @@
|
||||
/// Definitions for loading the kernel into memory
|
||||
#pragma once
|
||||
|
||||
#include "counted.h"
|
||||
#include <util/counted.h>
|
||||
|
||||
namespace kernel {
|
||||
namespace init {
|
||||
namespace bootproto {
|
||||
struct program;
|
||||
struct module;
|
||||
}}
|
||||
}
|
||||
|
||||
namespace boot {
|
||||
|
||||
@@ -27,7 +26,7 @@ struct program_desc
|
||||
/// Load a file from disk into memory.
|
||||
/// \arg disk The opened UEFI filesystem to load from
|
||||
/// \arg desc The program descriptor identifying the file
|
||||
buffer
|
||||
util::buffer
|
||||
load_file(
|
||||
fs::file &disk,
|
||||
const program_desc &desc);
|
||||
@@ -36,7 +35,7 @@ load_file(
|
||||
/// \arg disk The opened UEFI filesystem to load from
|
||||
/// \arg desc The program descriptor identifying the program
|
||||
/// \arg add_module Also create a module for this loaded program
|
||||
kernel::init::program *
|
||||
bootproto::program *
|
||||
load_program(
|
||||
fs::file &disk,
|
||||
const program_desc &desc,
|
||||
@@ -53,7 +52,7 @@ load_module(
|
||||
/// Verify that a loaded ELF has the j6 kernel header
|
||||
/// \arg program The program to check for a header
|
||||
void
|
||||
verify_kernel_header(kernel::init::program &program);
|
||||
verify_kernel_header(bootproto::program &program);
|
||||
|
||||
} // namespace loader
|
||||
} // namespace boot
|
||||
|
||||
@@ -7,6 +7,11 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <bootproto/kernel.h>
|
||||
#include <bootproto/memory.h>
|
||||
#include <util/counted.h>
|
||||
#include <util/pointers.h>
|
||||
|
||||
#include "allocator.h"
|
||||
#include "console.h"
|
||||
#include "error.h"
|
||||
@@ -19,19 +24,13 @@
|
||||
#include "status.h"
|
||||
#include "video.h"
|
||||
|
||||
#include "kernel_args.h"
|
||||
|
||||
namespace kernel {
|
||||
#include "kernel_memory.h"
|
||||
}
|
||||
|
||||
namespace init = kernel::init;
|
||||
|
||||
namespace boot {
|
||||
|
||||
const loader::program_desc kern_desc = {L"kernel", L"jsix.elf"};
|
||||
const loader::program_desc init_desc = {L"init server", L"srv.init.elf"};
|
||||
const loader::program_desc fb_driver = {L"UEFI framebuffer driver", L"drv.uefi_fb.elf"};
|
||||
const loader::program_desc uart_driver = {L"Serial port driver", L"drv.uart.elf"};
|
||||
|
||||
const loader::program_desc panic_handler = {L"Serial panic handler", L"panic.serial.elf"};
|
||||
|
||||
@@ -44,13 +43,13 @@ const loader::program_desc extra_programs[] = {
|
||||
template <typename T>
|
||||
void change_pointer(T *&pointer)
|
||||
{
|
||||
pointer = offset_ptr<T>(pointer, kernel::memory::page_offset);
|
||||
pointer = util::offset_pointer(pointer, bootproto::mem::linear_offset);
|
||||
}
|
||||
|
||||
/// The main procedure for the portion of the loader that runs while
|
||||
/// UEFI is still in control of the machine. (ie, while the loader still
|
||||
/// has access to boot services.)
|
||||
init::args *
|
||||
bootproto::args *
|
||||
uefi_preboot(uefi::handle image, uefi::system_table *st)
|
||||
{
|
||||
uefi::boot_services *bs = st->boot_services;
|
||||
@@ -61,11 +60,11 @@ uefi_preboot(uefi::handle image, uefi::system_table *st)
|
||||
hw::check_cpu_supported();
|
||||
memory::init_pointer_fixup(bs, rs);
|
||||
|
||||
init::args *args = new init::args;
|
||||
g_alloc.zero(args, sizeof(init::args));
|
||||
bootproto::args *args = new bootproto::args;
|
||||
g_alloc.zero(args, sizeof(bootproto::args));
|
||||
|
||||
args->magic = init::args_magic;
|
||||
args->version = init::args_version;
|
||||
args->magic = bootproto::args_magic;
|
||||
args->version = bootproto::args_version;
|
||||
args->runtime_services = rs;
|
||||
args->acpi_table = hw::find_acpi_table(st);
|
||||
memory::mark_pointer_fixup(&args->runtime_services);
|
||||
@@ -77,7 +76,7 @@ uefi_preboot(uefi::handle image, uefi::system_table *st)
|
||||
|
||||
/// Load the kernel and other programs from disk
|
||||
void
|
||||
load_resources(init::args *args, video::screen *screen, uefi::handle image, uefi::boot_services *bs)
|
||||
load_resources(bootproto::args *args, video::screen *screen, uefi::handle image, uefi::boot_services *bs)
|
||||
{
|
||||
status_line status {L"Loading programs"};
|
||||
|
||||
@@ -86,9 +85,11 @@ load_resources(init::args *args, video::screen *screen, uefi::handle image, uefi
|
||||
if (screen) {
|
||||
video::make_module(screen);
|
||||
loader::load_module(disk, fb_driver);
|
||||
} else {
|
||||
loader::load_module(disk, uart_driver);
|
||||
}
|
||||
|
||||
buffer symbol_table = loader::load_file(disk, {L"symbol table", L"symbol_table.dat"});
|
||||
util::buffer symbol_table = loader::load_file(disk, {L"symbol table", L"symbol_table.dat"});
|
||||
args->symbol_table = reinterpret_cast<uintptr_t>(symbol_table.pointer);
|
||||
|
||||
args->kernel = loader::load_program(disk, kern_desc, true);
|
||||
@@ -102,7 +103,7 @@ load_resources(init::args *args, video::screen *screen, uefi::handle image, uefi
|
||||
}
|
||||
|
||||
memory::efi_mem_map
|
||||
uefi_exit(init::args *args, uefi::handle image, uefi::boot_services *bs)
|
||||
uefi_exit(bootproto::args *args, uefi::handle image, uefi::boot_services *bs)
|
||||
{
|
||||
status_line status {L"Exiting UEFI", nullptr, false};
|
||||
|
||||
@@ -131,14 +132,14 @@ efi_main(uefi::handle image, uefi::system_table *st)
|
||||
uefi::boot_services *bs = st->boot_services;
|
||||
console con(st->con_out);
|
||||
|
||||
init::allocation_register *allocs = nullptr;
|
||||
init::modules_page *modules = nullptr;
|
||||
bootproto::allocation_register *allocs = nullptr;
|
||||
bootproto::modules_page *modules = nullptr;
|
||||
memory::allocator::init(allocs, modules, bs);
|
||||
|
||||
video::screen *screen = video::pick_mode(bs);
|
||||
con.announce();
|
||||
|
||||
init::args *args = uefi_preboot(image, st);
|
||||
bootproto::args *args = uefi_preboot(image, st);
|
||||
load_resources(args, screen, image, bs);
|
||||
memory::efi_mem_map map = uefi_exit(args, image, st->boot_services);
|
||||
|
||||
@@ -153,8 +154,8 @@ efi_main(uefi::handle image, uefi::system_table *st)
|
||||
|
||||
memory::fix_frame_blocks(args);
|
||||
|
||||
init::entrypoint kentry =
|
||||
reinterpret_cast<init::entrypoint>(args->kernel->entrypoint);
|
||||
bootproto::entrypoint kentry =
|
||||
reinterpret_cast<bootproto::entrypoint>(args->kernel->entrypoint);
|
||||
//status.next();
|
||||
|
||||
hw::setup_control_regs();
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
#include <uefi/runtime_services.h>
|
||||
#include <uefi/types.h>
|
||||
|
||||
#include <bootproto/memory.h>
|
||||
|
||||
#include "console.h"
|
||||
#include "error.h"
|
||||
#include "kernel_memory.h"
|
||||
#include "memory.h"
|
||||
#include "memory_map.h"
|
||||
#include "paging.h"
|
||||
@@ -61,7 +62,7 @@ virtualize(void *pml4, efi_mem_map &map, uefi::runtime_services *rs)
|
||||
paging::add_current_mappings(reinterpret_cast<paging::page_table*>(pml4));
|
||||
|
||||
for (auto &desc : map)
|
||||
desc.virtual_start = desc.physical_start + ::memory::page_offset;
|
||||
desc.virtual_start = desc.physical_start + bootproto::mem::linear_offset;
|
||||
|
||||
// Write our new PML4 pointer to CR3
|
||||
asm volatile ( "mov %0, %%cr3" :: "r" (pml4) );
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
#include <uefi/boot_services.h>
|
||||
#include <uefi/types.h>
|
||||
|
||||
#include <bootproto/kernel.h>
|
||||
#include <bootproto/memory.h>
|
||||
#include <util/pointers.h>
|
||||
|
||||
#include "allocator.h"
|
||||
#include "error.h"
|
||||
#include "kernel_memory.h"
|
||||
#include "memory.h"
|
||||
#include "memory_map.h"
|
||||
#include "paging.h"
|
||||
@@ -12,10 +15,10 @@
|
||||
namespace boot {
|
||||
namespace memory {
|
||||
|
||||
using kernel::init::frame_block;
|
||||
using kernel::init::frames_per_block;
|
||||
using kernel::init::mem_entry;
|
||||
using kernel::init::mem_type;
|
||||
using bootproto::frame_block;
|
||||
using bootproto::frames_per_block;
|
||||
using bootproto::mem_entry;
|
||||
using bootproto::mem_type;
|
||||
|
||||
|
||||
void
|
||||
@@ -89,7 +92,7 @@ memory_type_name(uefi::memory_type t)
|
||||
}
|
||||
|
||||
static const wchar_t *
|
||||
kernel_memory_type_name(kernel::init::mem_type t)
|
||||
kernel_memory_type_name(bootproto::mem_type t)
|
||||
{
|
||||
return kernel_memory_type_names[static_cast<uint32_t>(t)];
|
||||
}
|
||||
@@ -103,7 +106,7 @@ can_merge(mem_entry &prev, mem_type type, uefi::memory_descriptor &next)
|
||||
prev.attr == (next.attribute & 0xffffffff);
|
||||
}
|
||||
|
||||
counted<mem_entry>
|
||||
util::counted<mem_entry>
|
||||
build_kernel_map(efi_mem_map &map)
|
||||
{
|
||||
status_line status {L"Creating kernel memory map"};
|
||||
@@ -200,8 +203,8 @@ build_kernel_map(efi_mem_map &map)
|
||||
inline size_t bitmap_size(size_t frames) { return (frames + 63) / 64; }
|
||||
inline size_t num_blocks(size_t frames) { return (frames + (frames_per_block-1)) / frames_per_block; }
|
||||
|
||||
counted<kernel::init::frame_block>
|
||||
build_frame_blocks(const counted<kernel::init::mem_entry> &kmap)
|
||||
util::counted<bootproto::frame_block>
|
||||
build_frame_blocks(const util::counted<bootproto::mem_entry> &kmap)
|
||||
{
|
||||
status_line status {L"Creating kernel frame accounting map"};
|
||||
|
||||
@@ -232,7 +235,7 @@ build_frame_blocks(const counted<kernel::init::mem_entry> &kmap)
|
||||
while (page_count) {
|
||||
frame_block *blk = next_block++;
|
||||
|
||||
blk->flags = static_cast<kernel::init::frame_flags>(ent.attr);
|
||||
blk->flags = static_cast<bootproto::frame_flags>(ent.attr);
|
||||
blk->base = base_addr;
|
||||
base_addr += frames_per_block * page_size;
|
||||
|
||||
@@ -275,9 +278,9 @@ build_frame_blocks(const counted<kernel::init::mem_entry> &kmap)
|
||||
}
|
||||
|
||||
void
|
||||
fix_frame_blocks(kernel::init::args *args)
|
||||
fix_frame_blocks(bootproto::args *args)
|
||||
{
|
||||
counted<frame_block> &blocks = args->frame_blocks;
|
||||
util::counted<frame_block> &blocks = args->frame_blocks;
|
||||
|
||||
size_t size = blocks.count * sizeof(frame_block);
|
||||
for (unsigned i = 0; i < blocks.count; ++i)
|
||||
@@ -288,13 +291,13 @@ fix_frame_blocks(kernel::init::args *args)
|
||||
|
||||
// Map the frame blocks to the appropriate address
|
||||
paging::map_pages(args, addr,
|
||||
::memory::bitmap_start, pages, true, false);
|
||||
bootproto::mem::bitmap_offset, pages, true, false);
|
||||
|
||||
uintptr_t offset = ::memory::bitmap_start - addr;
|
||||
uintptr_t offset = bootproto::mem::bitmap_offset - addr;
|
||||
|
||||
for (unsigned i = 0; i < blocks.count; ++i) {
|
||||
frame_block &blk = blocks[i];
|
||||
blk.bitmap = offset_ptr<uint64_t>(blk.bitmap, offset);
|
||||
blk.bitmap = util::offset_pointer(blk.bitmap, offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,20 +2,19 @@
|
||||
/// \file memory_map.h
|
||||
/// Memory-map related types and functions
|
||||
|
||||
#include "counted.h"
|
||||
#include "pointer_manipulation.h"
|
||||
#include <util/counted.h>
|
||||
#include <util/pointers.h>
|
||||
|
||||
namespace uefi {
|
||||
struct boot_services;
|
||||
struct memory_descriptor;
|
||||
}
|
||||
|
||||
namespace kernel {
|
||||
namespace init {
|
||||
namespace bootproto {
|
||||
struct args;
|
||||
struct frame_block;
|
||||
struct mem_entry;
|
||||
}}
|
||||
}
|
||||
|
||||
namespace boot {
|
||||
namespace memory {
|
||||
@@ -25,7 +24,7 @@ namespace memory {
|
||||
struct efi_mem_map
|
||||
{
|
||||
using desc = uefi::memory_descriptor;
|
||||
using iterator = offset_iterator<desc>;
|
||||
using iterator = util::offset_iterator<desc>;
|
||||
|
||||
size_t length; ///< Total length of the map data
|
||||
size_t total; ///< Total allocated space for map data
|
||||
@@ -46,18 +45,18 @@ struct efi_mem_map
|
||||
inline iterator begin() { return iterator(entries, size); }
|
||||
|
||||
/// Return an iterator to the end of the array
|
||||
inline iterator end() { return offset_ptr<desc>(entries, length); }
|
||||
inline iterator end() { return util::offset_pointer(entries, length); }
|
||||
};
|
||||
|
||||
/// Add the kernel's memory map as a module to the kernel args.
|
||||
/// \returns The uefi memory map used to build the kernel map
|
||||
counted<kernel::init::mem_entry> build_kernel_map(efi_mem_map &map);
|
||||
util::counted<bootproto::mem_entry> build_kernel_map(efi_mem_map &map);
|
||||
|
||||
/// Create the kernel frame allocation maps
|
||||
counted<kernel::init::frame_block> build_frame_blocks(const counted<kernel::init::mem_entry> &kmap);
|
||||
util::counted<bootproto::frame_block> build_frame_blocks(const util::counted<bootproto::mem_entry> &kmap);
|
||||
|
||||
/// Map the frame allocation maps to the right spot and fix up pointers
|
||||
void fix_frame_blocks(kernel::init::args *args);
|
||||
void fix_frame_blocks(bootproto::args *args);
|
||||
|
||||
} // namespace boot
|
||||
} // namespace memory
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#include "kernel_memory.h"
|
||||
#include <arch/memory.h>
|
||||
#include <bootproto/memory.h>
|
||||
#include <util/counted.h>
|
||||
#include <util/pointers.h>
|
||||
|
||||
#include "allocator.h"
|
||||
#include "console.h"
|
||||
@@ -6,7 +9,6 @@
|
||||
#include "loader.h"
|
||||
#include "memory.h"
|
||||
#include "paging.h"
|
||||
#include "pointer_manipulation.h"
|
||||
#include "status.h"
|
||||
|
||||
namespace boot {
|
||||
@@ -14,8 +16,6 @@ namespace paging {
|
||||
|
||||
using memory::alloc_type;
|
||||
using memory::page_size;
|
||||
using ::memory::pml4e_kernel;
|
||||
using ::memory::table_entries;
|
||||
|
||||
// Flags: 0 0 0 1 0 0 0 0 0 0 0 1 = 0x0101
|
||||
// IGN | | | | | | | | +- Present
|
||||
@@ -58,13 +58,13 @@ constexpr uint64_t table_flags = 0x003;
|
||||
|
||||
|
||||
inline void *
|
||||
pop_pages(counted<void> &pages, size_t count)
|
||||
pop_pages(util::counted<void> &pages, size_t count)
|
||||
{
|
||||
if (count > pages.count)
|
||||
error::raise(uefi::status::out_of_resources, L"Page table cache empty", 0x7ab1e5);
|
||||
|
||||
void *next = pages.pointer;
|
||||
pages.pointer = offset_ptr<void>(pages.pointer, count*page_size);
|
||||
pages.pointer = util::offset_pointer(pages.pointer, count*page_size);
|
||||
pages.count -= count;
|
||||
return next;
|
||||
}
|
||||
@@ -81,7 +81,7 @@ public:
|
||||
page_entry_iterator(
|
||||
uintptr_t virt,
|
||||
page_table *pml4,
|
||||
counted<void> &pages) :
|
||||
util::counted<void> &pages) :
|
||||
m_pages(pages)
|
||||
{
|
||||
m_table[0] = pml4;
|
||||
@@ -137,17 +137,17 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
counted<void> &m_pages;
|
||||
util::counted<void> &m_pages;
|
||||
page_table *m_table[D];
|
||||
uint16_t m_index[D];
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
add_offset_mappings(page_table *pml4, counted<void> &pages)
|
||||
add_offset_mappings(page_table *pml4, util::counted<void> &pages)
|
||||
{
|
||||
uintptr_t phys = 0;
|
||||
uintptr_t virt = ::memory::page_offset; // Start of offset-mapped area
|
||||
uintptr_t virt = bootproto::mem::linear_offset; // Start of offset-mapped area
|
||||
size_t page_count = 64 * 1024; // 64 TiB of 1 GiB pages
|
||||
constexpr size_t GiB = 0x40000000ull;
|
||||
|
||||
@@ -164,9 +164,12 @@ add_offset_mappings(page_table *pml4, counted<void> &pages)
|
||||
}
|
||||
|
||||
static void
|
||||
add_kernel_pds(page_table *pml4, counted<void> &pages)
|
||||
add_kernel_pds(page_table *pml4, util::counted<void> &pages)
|
||||
{
|
||||
for (unsigned i = pml4e_kernel; i < table_entries; ++i)
|
||||
constexpr unsigned start = arch::kernel_root_index;
|
||||
constexpr unsigned end = arch::table_entries;
|
||||
|
||||
for (unsigned i = start; i < end; ++i)
|
||||
pml4->set(i, pop_pages(pages, 1), table_flags);
|
||||
}
|
||||
|
||||
@@ -178,7 +181,8 @@ add_current_mappings(page_table *new_pml4)
|
||||
asm volatile ( "mov %%cr3, %0" : "=r" (old_pml4) );
|
||||
|
||||
// Only copy mappings in the lower half
|
||||
for (int i = 0; i < ::memory::pml4e_kernel; ++i) {
|
||||
constexpr unsigned halfway = arch::kernel_root_index;
|
||||
for (int i = 0; i < halfway; ++i) {
|
||||
uint64_t entry = old_pml4->entries[i];
|
||||
if (entry & 1)
|
||||
new_pml4->entries[i] = entry;
|
||||
@@ -186,7 +190,7 @@ add_current_mappings(page_table *new_pml4)
|
||||
}
|
||||
|
||||
void
|
||||
allocate_tables(kernel::init::args *args)
|
||||
allocate_tables(bootproto::args *args)
|
||||
{
|
||||
status_line status(L"Allocating initial page tables");
|
||||
|
||||
@@ -221,7 +225,7 @@ constexpr bool has_flag(E set, E flag) {
|
||||
|
||||
void
|
||||
map_pages(
|
||||
kernel::init::args *args,
|
||||
bootproto::args *args,
|
||||
uintptr_t phys, uintptr_t virt,
|
||||
size_t count, bool write_flag, bool exe_flag)
|
||||
{
|
||||
@@ -251,10 +255,10 @@ map_pages(
|
||||
|
||||
void
|
||||
map_section(
|
||||
kernel::init::args *args,
|
||||
const kernel::init::program_section §ion)
|
||||
bootproto::args *args,
|
||||
const bootproto::program_section §ion)
|
||||
{
|
||||
using kernel::init::section_flags;
|
||||
using bootproto::section_flags;
|
||||
|
||||
map_pages(
|
||||
args,
|
||||
@@ -267,8 +271,8 @@ map_section(
|
||||
|
||||
void
|
||||
map_program(
|
||||
kernel::init::args *args,
|
||||
kernel::init::program &program)
|
||||
bootproto::args *args,
|
||||
bootproto::program &program)
|
||||
{
|
||||
for (auto §ion : program.sections)
|
||||
paging::map_section(args, section);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/// Page table structure and related definitions
|
||||
#include <stdint.h>
|
||||
#include <uefi/boot_services.h>
|
||||
#include "kernel_args.h"
|
||||
#include <bootproto/kernel.h>
|
||||
|
||||
namespace boot {
|
||||
namespace paging {
|
||||
@@ -30,7 +30,7 @@ struct page_table
|
||||
/// and kernel args' `page_table_cache` and `num_free_tables` are updated with
|
||||
/// the leftover space.
|
||||
/// \arg args The kernel args struct, used for the page table cache and pml4
|
||||
void allocate_tables(kernel::init::args *args);
|
||||
void allocate_tables(bootproto::args *args);
|
||||
|
||||
/// Copy existing page table entries to a new page table. Does not do a deep
|
||||
/// copy - the new PML4 is updated to point to the existing next-level page
|
||||
@@ -46,7 +46,7 @@ void add_current_mappings(page_table *new_pml4);
|
||||
/// \arg write_flag If true, mark the pages writeable
|
||||
/// \arg exe_flag If true, mark the pages executable
|
||||
void map_pages(
|
||||
kernel::init::args *args,
|
||||
bootproto::args *args,
|
||||
uintptr_t phys, uintptr_t virt,
|
||||
size_t count, bool write_flag, bool exe_flag);
|
||||
|
||||
@@ -55,8 +55,8 @@ void map_pages(
|
||||
/// \arg args The kernel args struct, used for the page table cache and pml4
|
||||
/// \arg program The program to load
|
||||
void map_program(
|
||||
kernel::init::args *args,
|
||||
kernel::init::program &program);
|
||||
bootproto::args *args,
|
||||
bootproto::program &program);
|
||||
|
||||
} // namespace paging
|
||||
} // namespace boot
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#include "console.h"
|
||||
#include "error.h"
|
||||
#include "init_args.h"
|
||||
#include "status.h"
|
||||
#include "video.h"
|
||||
|
||||
|
||||
@@ -5,17 +5,16 @@
|
||||
#include "allocator.h"
|
||||
#include "console.h"
|
||||
#include "error.h"
|
||||
#include "init_args.h"
|
||||
#include "video.h"
|
||||
|
||||
namespace boot {
|
||||
namespace video {
|
||||
|
||||
using kernel::init::fb_layout;
|
||||
using kernel::init::fb_type;
|
||||
using kernel::init::module_flags;
|
||||
using kernel::init::module_framebuffer;
|
||||
using kernel::init::module_type;
|
||||
using bootproto::fb_layout;
|
||||
using bootproto::fb_type;
|
||||
using bootproto::module_flags;
|
||||
using bootproto::module_framebuffer;
|
||||
using bootproto::module_type;
|
||||
|
||||
static uefi::protos::graphics_output *
|
||||
get_gop(uefi::boot_services *bs)
|
||||
@@ -109,7 +108,7 @@ pick_mode(uefi::boot_services *bs)
|
||||
void
|
||||
make_module(screen *s)
|
||||
{
|
||||
using kernel::init::module_framebuffer;
|
||||
using bootproto::module_framebuffer;
|
||||
module_framebuffer *modfb = g_alloc.allocate_module<module_framebuffer>();
|
||||
modfb->mod_type = module_type::framebuffer;
|
||||
modfb->type = fb_type::uefi;
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "init_args.h"
|
||||
#include <bootproto/init.h>
|
||||
#include <util/counted.h>
|
||||
|
||||
namespace uefi {
|
||||
struct boot_services;
|
||||
@@ -14,11 +15,11 @@ namespace uefi {
|
||||
namespace boot {
|
||||
namespace video {
|
||||
|
||||
using kernel::init::video_mode;
|
||||
using layout = kernel::init::fb_layout;
|
||||
using bootproto::video_mode;
|
||||
using layout = bootproto::fb_layout;
|
||||
|
||||
struct screen {
|
||||
buffer framebuffer;
|
||||
util::buffer framebuffer;
|
||||
video_mode mode;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user