diff --git a/AK/Vector.h b/AK/Vector.h index 330d33cd0d2..10b7ee5dcdd 100644 --- a/AK/Vector.h +++ b/AK/Vector.h @@ -116,6 +116,21 @@ public: m_impl->remove(index); } + void append(Vector&& other) + { + Vector tmp = move(other); + ensureCapacity(size() + tmp.size()); + for (auto&& v : tmp) { + uncheckedAppend(move(v)); + } + } + + void uncheckedAppend(T&& value) + { + new (m_impl->slot(m_impl->m_size)) T(move(value)); + ++m_impl->m_size; + } + void append(T&& value) { ensureCapacity(size() + 1); diff --git a/Kernel/MemoryManager.cpp b/Kernel/MemoryManager.cpp index 0f32eb96795..c22e8b3e0e4 100644 --- a/Kernel/MemoryManager.cpp +++ b/Kernel/MemoryManager.cpp @@ -34,9 +34,7 @@ void MemoryManager::initializePaging() memset(m_pageTableOne, 0, 4096); memset(m_pageDirectory, 0, 4096); - kprintf("MM: Page directory @ %p\n", m_pageDirectory); - kprintf("MM: Page table zero @ %p\n", m_pageTableZero); - kprintf("MM: Page table one @ %p\n", m_pageTableOne); + kprintf("[MM] Page directory @ %p\n", m_pageDirectory); // Make null dereferences crash. protectMap(LinearAddress(0), 4 * KB); @@ -72,7 +70,7 @@ auto MemoryManager::ensurePTE(LinearAddress linearAddress) -> PageTableEntry PageDirectoryEntry pde = PageDirectoryEntry(&m_pageDirectory[pageDirectoryIndex]); if (!pde.isPresent()) { - kprintf("PDE %u !present, allocating\n", pageDirectoryIndex); + kprintf("[MM] PDE %u not present, allocating\n", pageDirectoryIndex); if (pageDirectoryIndex == 0) { pde.setPageTableBase((dword)m_pageTableZero); pde.setUserAllowed(true); @@ -85,7 +83,7 @@ auto MemoryManager::ensurePTE(LinearAddress linearAddress) -> PageTableEntry pde.setWritable(true); } else { auto* pageTable = allocatePageTable(); - kprintf("allocated page table %u (for laddr=%p) at %p\n", pageDirectoryIndex, linearAddress.get(), pageTable); + kprintf("[MM] Allocated page table #%u (for laddr=%p) at %p\n", pageDirectoryIndex, linearAddress.get(), pageTable); memset(pageTable, 0, 4096); pde.setPageTableBase((dword)pageTable); pde.setUserAllowed(true); @@ -134,7 +132,7 @@ void MemoryManager::initialize() PageFaultResponse MemoryManager::handlePageFault(const PageFault& fault) { ASSERT_INTERRUPTS_DISABLED(); - kprintf("MM: handlePageFault(%w) at laddr=%p\n", fault.code(), fault.address().get()); + kprintf("[MM] handlePageFault(%w) at laddr=%p\n", fault.code(), fault.address().get()); if (fault.isNotPresent()) { kprintf(" >> NP fault!\n"); } else if (fault.isProtectionViolation()) { @@ -143,11 +141,36 @@ PageFaultResponse MemoryManager::handlePageFault(const PageFault& fault) return PageFaultResponse::ShouldCrash; } +void MemoryManager::registerZone(Zone& zone) +{ + ASSERT_INTERRUPTS_DISABLED(); + m_zones.set(&zone); +} + +void MemoryManager::unregisterZone(Zone& zone) +{ + ASSERT_INTERRUPTS_DISABLED(); + m_zones.remove(&zone); + m_freePages.append(move(zone.m_pages)); +} + +Zone::Zone(Vector&& pages) + : m_pages(move(pages)) +{ + MM.registerZone(*this); +} + +Zone::~Zone() +{ + MM.unregisterZone(*this); +} + RetainPtr MemoryManager::createZone(size_t size) { + InterruptDisabler disabler; auto pages = allocatePhysicalPages(ceilDiv(size, PAGE_SIZE)); if (pages.isEmpty()) { - kprintf("MM: createZone: no physical pages for size %u", size); + kprintf("[MM] createZone: no physical pages for size %u", size); return nullptr; } return adopt(*new Zone(move(pages))); @@ -170,7 +193,7 @@ byte* MemoryManager::quickMapOnePage(PhysicalAddress physicalAddress) { ASSERT_INTERRUPTS_DISABLED(); auto pte = ensurePTE(LinearAddress(4 * MB)); - kprintf("quickmap %x @ %x {pte @ %p}\n", physicalAddress.get(), 4*MB, pte.ptr()); + kprintf("[MM] quickmap %x @ %x {pte @ %p}\n", physicalAddress.get(), 4*MB, pte.ptr()); pte.setPhysicalPageBase(physicalAddress.pageBase()); pte.setPresent(true); pte.setWritable(true); @@ -297,7 +320,7 @@ bool MemoryManager::mapRegionsForTask(Task& task) bool copyToZone(Zone& zone, const void* data, size_t size) { if (zone.size() < size) { - kprintf("copyToZone: can't fit %u bytes into zone with size %u\n", size, zone.size()); + kprintf("[MM] copyToZone: can't fit %u bytes into zone with size %u\n", size, zone.size()); return false; } @@ -314,4 +337,3 @@ bool copyToZone(Zone& zone, const void* data, size_t size) return true; } - diff --git a/Kernel/MemoryManager.h b/Kernel/MemoryManager.h index 0c886074334..4ed3ff66f7a 100644 --- a/Kernel/MemoryManager.h +++ b/Kernel/MemoryManager.h @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include "Task.h" class Task; @@ -17,7 +17,7 @@ enum class PageFaultResponse { struct Zone : public Retainable { public: - ~Zone() { } + ~Zone(); size_t size() const { return m_pages.size() * PAGE_SIZE; } const Vector& pages() const { return m_pages; } @@ -25,10 +25,7 @@ public: private: friend class MemoryManager; friend bool copyToZone(Zone&, const void* data, size_t); - explicit Zone(Vector&& pages) - : m_pages(move(pages)) - { - } + explicit Zone(Vector&&); Vector m_pages; }; @@ -38,6 +35,7 @@ bool copyToZone(Zone&, const void* data, size_t); #define MM MemoryManager::the() class MemoryManager { + friend ByteBuffer procfs$mm(); public: static MemoryManager& the() PURE; @@ -62,6 +60,9 @@ public: bool mapRegionsForTask(Task&); bool unmapRegionsForTask(Task&); + void registerZone(Zone&); + void unregisterZone(Zone&); + private: MemoryManager(); ~MemoryManager(); @@ -161,7 +162,7 @@ private: dword* m_pageTableZero; dword* m_pageTableOne; - HashMap> m_zones; + HashTable m_zones; Vector m_freePages; }; diff --git a/Kernel/ProcFileSystem.cpp b/Kernel/ProcFileSystem.cpp index 8457361cf4c..f7b7f3f5cbc 100644 --- a/Kernel/ProcFileSystem.cpp +++ b/Kernel/ProcFileSystem.cpp @@ -118,6 +118,18 @@ void ProcFileSystem::removeProcess(Task& task) m_pid2inode.remove(pid); } +ByteBuffer procfs$mm() +{ + InterruptDisabler disabler; + auto buffer = ByteBuffer::createUninitialized(1024); + char* ptr = (char*)buffer.pointer(); + ptr += ksprintf(ptr, "Zone count: %u\n", MM.m_zones.size()); + ptr += ksprintf(ptr, "Free physical pages: %u\n", MM.m_freePages.size()); + buffer.trim(ptr - (char*)buffer.pointer()); + return buffer; +} + + ByteBuffer procfs$mounts() { InterruptDisabler disabler; @@ -171,6 +183,7 @@ ByteBuffer procfs$summary() bool ProcFileSystem::initialize() { SyntheticFileSystem::initialize(); + addFile(createGeneratedFile("mm", procfs$mm)); addFile(createGeneratedFile("mounts", procfs$mounts)); addFile(createGeneratedFile("kmalloc", procfs$kmalloc)); addFile(createGeneratedFile("summary", procfs$summary)); diff --git a/Kernel/sync-sh b/Kernel/sync-sh index 8584eaa626a..4847c68a401 100755 --- a/Kernel/sync-sh +++ b/Kernel/sync-sh @@ -15,6 +15,7 @@ cp ../Userland/cat mnt/bin/cat cp ../Userland/uname mnt/bin/uname cp ../Userland/clear mnt/bin/clear cp ../Userland/tst mnt/bin/tst +cp ../Userland/mm mnt/bin/mm cp kernel.map mnt/ umount mnt sync diff --git a/Userland/.gitignore b/Userland/.gitignore index e365fd391b0..f6b0db76150 100644 --- a/Userland/.gitignore +++ b/Userland/.gitignore @@ -13,3 +13,4 @@ cat uname clear tst +mm diff --git a/Userland/Makefile b/Userland/Makefile index 72057879704..bc8e0ecaee3 100644 --- a/Userland/Makefile +++ b/Userland/Makefile @@ -12,7 +12,8 @@ OBJS = \ cat.o \ uname.o \ clear.o \ - tst.o + tst.o \ + mm.o APPS = \ id \ @@ -28,7 +29,8 @@ APPS = \ cat \ uname \ clear \ - tst + tst \ + mm ARCH_FLAGS = STANDARD_FLAGS = -std=c++17 -nostdinc++ -nostdlib @@ -90,6 +92,9 @@ clear: clear.o tst: tst.o $(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a +mm: mm.o + $(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a + .cpp.o: @echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $< diff --git a/Userland/mm.cpp b/Userland/mm.cpp new file mode 100644 index 00000000000..ee035988677 --- /dev/null +++ b/Userland/mm.cpp @@ -0,0 +1,25 @@ +#include +#include + +int main(int c, char** v) +{ + int fd = open("/proc/mm"); + if (fd == -1) { + perror("failed to open /proc/mm"); + return 1; + } + for (;;) { + char buf[128]; + ssize_t nread = read(fd, buf, sizeof(buf)); + if (nread == 0) + break; + if (nread < 0) { + perror("failed to read"); + return 2; + } + for (ssize_t i = 0; i < nread; ++i) { + putchar(buf[i]); + } + } + return 0; +} diff --git a/Userland/ps.cpp b/Userland/ps.cpp index a1cc620c208..ec49c480d0e 100644 --- a/Userland/ps.cpp +++ b/Userland/ps.cpp @@ -5,7 +5,7 @@ int main(int c, char** v) { int fd = open("/proc/summary"); if (fd == -1) { - printf("failed to open /proc/summary :(\n"); + perror("failed to open /proc/summary"); return 1; } for (;;) { @@ -14,7 +14,7 @@ int main(int c, char** v) if (nread == 0) break; if (nread < 0) { - printf("failed to read :(\n"); + perror("failed to read"); return 2; } for (ssize_t i = 0; i < nread; ++i) { diff --git a/Userland/sh.cpp b/Userland/sh.cpp index b172f6fa9c9..3f503419a63 100644 --- a/Userland/sh.cpp +++ b/Userland/sh.cpp @@ -26,6 +26,13 @@ static int sh_pwd(int, const char**) return 0; } +static int sh_exit(int, const char**) +{ + printf("Good-bye!\n"); + exit(0); + return 0; +} + static int sh_cd(int argc, const char** argv) { if (argc == 1) { @@ -77,6 +84,10 @@ static bool handle_builtin(int argc, const char** argv, int& retval) retval = sh_pwd(argc, argv); return true; } + if (!strcmp(argv[0], "exit")) { + retval = sh_exit(argc, argv); + return true; + } return false; }