aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64')
-rw-r--r--arch/x86_64/include/arch/memory/region_allocator.hpp6
-rw-r--r--arch/x86_64/kapi/memory.cpp1
-rw-r--r--arch/x86_64/src/memory/region_allocator.cpp43
3 files changed, 39 insertions, 11 deletions
diff --git a/arch/x86_64/include/arch/memory/region_allocator.hpp b/arch/x86_64/include/arch/memory/region_allocator.hpp
index 1c5885e..c7a836f 100644
--- a/arch/x86_64/include/arch/memory/region_allocator.hpp
+++ b/arch/x86_64/include/arch/memory/region_allocator.hpp
@@ -42,6 +42,11 @@ namespace arch::memory
//! These include available, unavailable, and reclaimable regions. In general, only frames that are located in
//! non-reserved (as in available) regions should be allocated for page storage.
multiboot2::memory_map memory_map;
+
+ //! The loader supplied Multiboot2 information structure.
+ //!
+ //! This is used to query boot module ranges so these frames can be excluded from early allocations.
+ multiboot2::information_view const * mbi;
};
using region = multiboot2::memory_map::region;
@@ -80,6 +85,7 @@ namespace arch::memory
kapi::memory::frame m_kernel_end; //!< The end of the kernel image in physical memory.
kapi::memory::frame m_multiboot_start; //!< The start of the Multiboot2 information in physical memory.
kapi::memory::frame m_multiboot_end; //!< The end of the Multiboot2 information in physical memory.
+ multiboot2::information_view const * m_multiboot_information; //!< Source of Multiboot2 module ranges.
};
} // namespace arch::memory
diff --git a/arch/x86_64/kapi/memory.cpp b/arch/x86_64/kapi/memory.cpp
index f29afe8..a354576 100644
--- a/arch/x86_64/kapi/memory.cpp
+++ b/arch/x86_64/kapi/memory.cpp
@@ -53,6 +53,7 @@ namespace kapi::memory
.image_range = std::make_pair(physical_address{&image_span.front()}, physical_address{&image_span.back()}),
.mbi_range = std::make_pair(physical_address{&mbi_span.front()}, physical_address{&mbi_span.back()}),
.memory_map = *memory_map,
+ .mbi = mbi,
};
}
diff --git a/arch/x86_64/src/memory/region_allocator.cpp b/arch/x86_64/src/memory/region_allocator.cpp
index facb1f2..2690a7c 100644
--- a/arch/x86_64/src/memory/region_allocator.cpp
+++ b/arch/x86_64/src/memory/region_allocator.cpp
@@ -35,7 +35,7 @@ namespace arch::memory
, m_kernel_end{kapi::memory::frame::containing(mem_info.image_range.second)}
, m_multiboot_start{kapi::memory::frame::containing(mem_info.mbi_range.first)}
, m_multiboot_end{kapi::memory::frame::containing(mem_info.mbi_range.second)}
- // TODO BA-FS26: Protect MB2 boot modules
+ , m_multiboot_information{mem_info.mbi}
{
choose_next_region();
}
@@ -76,19 +76,40 @@ namespace arch::memory
}
}
- if (falls_within(m_next_frame, m_kernel_start, m_kernel_end))
+ auto advanced = true;
+ while (advanced)
{
- m_next_frame = m_kernel_end + 1;
- }
+ advanced = false;
- if (falls_within(m_next_frame, m_multiboot_start, m_multiboot_end))
- {
- m_next_frame = m_multiboot_end + 1;
- }
+ if (falls_within(m_next_frame, m_kernel_start, m_kernel_end))
+ {
+ m_next_frame = m_kernel_end + 1;
+ advanced = true;
+ break;
+ }
- if (falls_within(m_next_frame, m_kernel_start, m_kernel_end))
- {
- m_next_frame = m_kernel_end + 1;
+ if (falls_within(m_next_frame, m_multiboot_start, m_multiboot_end))
+ {
+ m_next_frame = m_multiboot_end + 1;
+ advanced = true;
+ break;
+ }
+
+ if (m_multiboot_information)
+ {
+ for (auto const & module : m_multiboot_information->modules())
+ {
+ auto module_start = kapi::memory::frame::containing(kapi::memory::physical_address{module.start_address});
+ auto module_end = kapi::memory::frame::containing(kapi::memory::physical_address{module.end_address});
+
+ if (falls_within(m_next_frame, module_start, module_end))
+ {
+ m_next_frame = module_end + 1;
+ advanced = true;
+ break;
+ }
+ }
+ }
}
if (m_next_frame > last_frame(*m_current_region))