21#include "pedigree/kernel/BootstrapInfo.h"
22#include "pedigree/kernel/LockGuard.h"
23#include "pedigree/kernel/Log.h"
24#include "pedigree/kernel/processor/PhysicalMemoryManager.h"
25#include "pedigree/kernel/utilities/assert.h"
26#include "pedigree/kernel/utilities/utility.h"
30DiskImage::~DiskImage() {
34bool DiskImage::initialise() {
35 const BootstrapStruct_t::Module* modules = g_pBootstrapInfo->getModuleArray();
36 const size_t moduleCount = g_pBootstrapInfo->getModuleCount();
37 const BootstrapStruct_t::Module* image =
nullptr;
38 for (
size_t i = 0; i < moduleCount; ++i) {
39 const char* name =
reinterpret_cast<const char*
>(modules[i].name_ptr);
40 if (name && !StringCompare(name,
"rootfs.img")) {
46 if (!image && moduleCount >= 2) {
49 if (!image || image->end <= image->base) {
50 NOTICE(
"no root disk image found in boot modules");
54 uintptr_t baseAddress = image->base;
55 uintptr_t endAddress = image->end;
57 m_pBase =
reinterpret_cast<void*
>(baseAddress);
58 m_nSize = endAddress - baseAddress;
64 if ((location >= m_nSize) || !m_pBase) {
65 ERROR(
"DiskImage::read() - location " << location <<
" >= " << m_nSize);
66 ERROR(
" -> or " << m_pBase <<
" is null");
71 const uint64_t pageLocation = getPageLocation(location);
72 const uint64_t pageOffset = location - pageLocation;
73 if (location >= m_nSize || pageLocation >= m_nSize) {
76 const size_t validLength =
77 pageSize < (m_nSize - pageLocation) ? pageSize : (m_nSize - pageLocation);
79 uintptr_t buffer = m_Cache.
lookup(pageLocation);
81 return BufferView::fromAddress(buffer + pageOffset, validLength - pageOffset);
84 bool didExist =
false;
85 buffer = m_Cache.
insert(pageLocation, &didExist);
90 ByteSet(
reinterpret_cast<void*
>(buffer), 0, pageSize);
91 MemoryCopy(
reinterpret_cast<void*
>(buffer), adjust_pointer(m_pBase, pageLocation), validLength);
96 buffer = m_Cache.
lookup(pageLocation);
97 return buffer ? BufferView::fromAddress(buffer + pageOffset, validLength - pageOffset)
107 for (
size_t i = 0; i < m_nAlignPoints; ++i) {
108 if (m_AlignPoints[i] == location) {
113 assert(m_nAlignPoints < 8);
114 m_AlignPoints[m_nAlignPoints++] = location;
119 if (location >= m_nSize) {
122 return m_Cache.
pin(getPageLocation(location));
127 if (location >= m_nSize) {
130 m_Cache.
release(getPageLocation(location));
133uint64_t DiskImage::getAlignmentPoint(uint64_t location)
const {
134 uint64_t alignPoint = 0;
135 for (
size_t i = 0; i < m_nAlignPoints; ++i) {
136 if (m_AlignPoints[i] <= location && m_AlignPoints[i] > alignPoint) {
137 alignPoint = m_AlignPoints[i];
143uint64_t DiskImage::getPageLocation(uint64_t location)
const {
144 const uint64_t alignPoint = getAlignmentPoint(location);
146 return location - ((location - alignPoint) % pageSize);
void release(uintptr_t key)
uintptr_t insert(uintptr_t key, bool *alreadyExisted=nullptr)
void markNoLongerEditing(uintptr_t key, size_t length=0)
uintptr_t lookup(uintptr_t key)
MUST_USE_RESULT bool pin(uintptr_t key)
virtual BufferView read(uint64_t location)
virtual void align(uint64_t location)
Sets the page boundary alignment after a specific location on the disk.
virtual size_t getSize() const
Gets the size of the disk.
virtual bool pin(uint64_t location)
Pins a cache page.
virtual void unpin(uint64_t location)
static constexpr size_t getPageSize() PURE