21#include "pedigree/kernel/BootstrapInfo.h"
22#include "pedigree/kernel/LockGuard.h"
23#include "pedigree/kernel/Version.h"
24#include "pedigree/kernel/machine/Device.h"
25#include "pedigree/kernel/process/Scheduler.h"
26#include "pedigree/kernel/processor/PhysicalMemoryManager.h"
27#include "pedigree/kernel/time/Time.h"
29#include "PosixProcess.h"
30#include "file-syscalls.h"
31#include "modules/system/users/Group.h"
32#include "modules/system/users/User.h"
35extern size_t g_FreePages;
36extern size_t g_AllocedPages;
38MeminfoFile::MeminfoFile(
size_t inode,
Filesystem* pParentFS,
File* pParent)
39 :
File(
String(
"meminfo"), 0, 0, 0, inode, pParentFS, 0, pParent), m_Contents(), m_Lock() {
40 setPermissionsOnly(FILE_UR | FILE_GR | FILE_OR);
47MeminfoFile::~MeminfoFile() =
default;
49size_t MeminfoFile::getSize() {
52 return m_Contents.length();
55void MeminfoFile::updateContents() {
57 const uint64_t totalPages = memory.available ? memory.totalPages : g_FreePages + g_AllocedPages;
58 const uint64_t freePages = memory.available ? memory.freePages : g_FreePages;
65 "MemAvailable: %lu kB\n"
71 totalKb, freeKb, freeKb);
73 m_Contents = contents;
81 if (location >= m_Contents.length()) {
83 }
else if (size > m_Contents.length() - location) {
84 size = m_Contents.length() - location;
87 char* destination =
reinterpret_cast<char*
>(buffer);
88 const char* source =
static_cast<const char*
>(m_Contents);
90 MemoryCopy(destination, source + location, size);
100PciDevicesFile::PciDevicesFile(
size_t inode,
Filesystem* pParentFS,
File* pParent)
101 :
File(
String(
"devices"), 0, 0, 0, inode, pParentFS, 0, pParent), m_Contents() {
109PciDevicesFile::~PciDevicesFile() {}
111size_t PciDevicesFile::getSize() {
112 return m_Contents.length();
119 if (location >= m_Contents.length()) {
121 }
else if ((location + size) > m_Contents.length()) {
122 size = m_Contents.length() - location;
125 char* destination =
reinterpret_cast<char*
>(buffer);
126 const char* source =
static_cast<const char*
>(m_Contents);
128 StringCopy(destination, source);
143 initial.Format(
"%02x%02x\t%04x%04x\t%x", p->getPciBusPosition(),
144 (p->getPciDevicePosition() << 4) | p->getPciFunctionNumber(),
145 p->getPciVendorId(), p->getPciDeviceId(), p->getInterruptNumber());
149 for (
size_t i = 0; i < 7; ++i) {
153 if (i < p->addresses().count()) {
154 size_t length = p->addresses()[i]->m_Size;
156 uintptr_t address = p->addresses()[i]->m_Address;
158 if (p->addresses()[i]->m_IsIoSpace) {
163 thisResStart.Format(
"\t%16lx", address | flags);
164 thisResLength.Format(
"\t%16lx", length ? length + 1 : 0);
166 thisResStart.Format(
"\t%16lx", 0);
167 thisResLength.Format(
"\t%16lx", 0);
170 resStart += thisResStart;
171 resLength += thisResLength;
174 m_Contents += initial;
175 m_Contents += resStart;
176 m_Contents += resLength;
183 auto callback = pedigree_std::make_callable(printer);
187MountFile::MountFile(
size_t inode,
Filesystem* pParentFS,
File* pParent)
188 :
File(
String(
"mounts"), 0, 0, 0, inode, pParentFS, 0, pParent) {
194MountFile::~MountFile() =
default;
199 generate_mtab(mounts);
201 if (location >= mounts.length()) {
206 if ((location + size) >= mounts.length()) {
207 size = mounts.length() - location;
210 char* destination =
reinterpret_cast<char*
>(buffer);
211 StringCopyN(destination,
static_cast<const char*
>(mounts) + location, size);
221size_t MountFile::getSize() {
223 generate_mtab(mounts);
224 return mounts.length();
227UptimeFile::UptimeFile(
size_t inode,
Filesystem* pParentFS,
File* pParent)
228 :
File(
String(
"uptime"), 0, 0, 0, inode, pParentFS, 0, pParent) {
234UptimeFile::~UptimeFile() =
default;
238 String f = generateString();
240 if (location >= f.length()) {
245 if ((location + size) >= f.length()) {
246 size = f.length() - location;
249 char* destination =
reinterpret_cast<char*
>(buffer);
250 StringCopyN(destination,
static_cast<const char*
>(f) + location, size);
260size_t UptimeFile::getSize() {
261 String f = generateString();
265String UptimeFile::generateString() {
266 const uint64_t uptime = Time::getTicks();
270 f.Format(
"%lu.%02lu %lu.%02lu\n", uptime / Time::Multiplier::Second,
271 (uptime % Time::Multiplier::Second) / (Time::Multiplier::Second / 100),
272 idle / Time::Multiplier::Second,
273 (idle % Time::Multiplier::Second) / (Time::Multiplier::Second / 100));
278ConstantFile::ConstantFile(
String name,
const char* value,
size_t size,
size_t inode,
280 :
File(name, 0, 0, 0, inode, pParentFS, 0, pParent), m_Contents() {
285 m_Contents =
new char[size];
287 MemoryCopy(m_Contents, value, size);
290ConstantFile::~ConstantFile() {
296 if (location >= m_Size) {
298 }
else if ((location + size) > m_Size) {
299 size = m_Size - location;
302 char* destination =
reinterpret_cast<char*
>(buffer);
303 const char* source = m_Contents + location;
305 MemoryCopy(destination, source, size);
315size_t ConstantFile::getSize() {
319ProcFsDirectory::~ProcFsDirectory() =
default;
340 m_pRoot->setPermissions(FILE_UR | FILE_UW | FILE_UX | FILE_GR | FILE_GW | FILE_GX | FILE_OR |
346 dot->setPermissions(m_pRoot->getPermissions());
347 m_pRoot->addEntry(dot->
getName(), dot);
350 m_pRoot->addEntry(meminfo->
getName(), meminfo);
354 m_pRoot->addEntry(mounts->
getName(), mounts);
356 initialiseResolverFile();
357 initialiseNetworkFile();
360 m_pRoot->addEntry(uptime->
getName(), uptime);
362 if (!procfsAddSystemStatusFiles(*
this, *m_pRoot))
365 static String fs(
"\text2\nnodev\tproc\nnodev\tsysfs\nnodev\ttmpfs\n");
367 getNextInode(),
this, m_pRoot);
368 m_pRoot->addEntry(pFilesystems->
getName(), pFilesystems);
371 static String cmdline(
"noswap quiet boot=live\n", 25);
372 NOTICE(
"cmdline is '" << cmdline <<
"'");
374 getNextInode(),
this, m_pRoot);
375 m_pRoot->addEntry(pCmdline->
getName(), pCmdline);
379 version.Format(
"Pedigree version %s (%s@%s) %s", g_pBuildRevision, g_pBuildUser, g_pBuildMachine,
382 getNextInode(),
this, m_pRoot);
383 m_pRoot->addEntry(pVersion->
getName(), pVersion);
390 pBusDir->setPermissions(FILE_UR | FILE_UX | FILE_GR | FILE_GX | FILE_OR | FILE_OX);
391 pPciDir->setPermissions(FILE_UR | FILE_UX | FILE_GR | FILE_GX | FILE_OR | FILE_OX);
393 m_pRoot->addEntry(pBusDir->
getName(), pBusDir);
394 pBusDir->addEntry(pPciDir->
getName(), pPciDir);
399 bus.Format(
"%02x", p->getPciBusPosition());
405 pPciDir->addEntry(dir->
getName(), dir);
413 fn.Format(
"%02x.%01x", p->getPciDevicePosition(), p->getPciFunctionNumber());
422 getNextInode(),
this, dir);
423 dir->addEntry(cf->
getName(), cf);
427 initial.Format(
"%02x%02x\t%04x%04x\t%x", p->getPciBusPosition(),
428 (p->getPciDevicePosition() << 4) | p->getPciFunctionNumber(),
429 p->getPciVendorId(), p->getPciDeviceId(), p->getInterruptNumber());
433 for (
size_t i = 0; i < 7; ++i) {
437 if (i < p->addresses().count()) {
438 size_t length = p->addresses()[i]->m_Size;
440 uintptr_t address = p->addresses()[i]->m_Address;
442 if (p->addresses()[i]->m_IsIoSpace) {
447 thisResStart.Format(
"\t%16lx", address | flags);
448 thisResLength.Format(
"\t%16lx", length ? length + 1 : 0);
450 thisResStart.Format(
"\t%16lx", 0);
451 thisResLength.Format(
"\t%16lx", 0);
454 resStart += thisResStart;
455 resLength += thisResLength;
458 m_PciDevices += initial;
459 m_PciDevices += resStart;
460 m_PciDevices += resLength;
461 m_PciDevices +=
"\t";
462 m_PciDevices +=
"\n";
467 auto callback = pedigree_std::make_callable(printer);
471 String(
"devices"), m_PciDevices.cstr(), m_PciDevices.length(), getNextInode(),
this, pPciDir);
472 pPciDir->addEntry(pPciDevices->
getName(), pPciDevices);
474 return initialiseNamespaceLinks();
477size_t ProcFs::getNextInode() {
478 return (m_NextInode += 1) - 1;
481void ProcFs::revertInode() {
489 auto procDir = createProcessDirectory(proc);
491 WARNING(
"ProcFs: could not prepare process directory for " <<
Dec << pid);
494 procDir->setPermissions(FILE_UR | FILE_UX | FILE_GR | FILE_GX | FILE_OR | FILE_OX);
505 m_pRoot->addEntry(procDir->getName(), procDir);
virtual uint64_t writeBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
virtual uint64_t readBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
static void foreach(Callback callback, Device *root=0)
static Directory * fromFile(File *pF)
void remove(const HashedStringView &s)
void setGidOnly(size_t gid)
void setPermissionsOnly(uint32_t perms)
void setUidOnly(size_t uid)
virtual uint64_t readBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
virtual uint64_t writeBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
virtual uint64_t writeBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
virtual uint64_t readBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
virtual uint64_t readBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
virtual uint64_t writeBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
static PhysicalMemoryManager & instance()
static constexpr size_t getPageSize() PURE
void addProcess(PosixProcess *proc)
virtual bool initialise(Disk *pDisk)
size_t getUserspaceId() const
static Scheduler & instance()
virtual uint64_t writeBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
virtual uint64_t readBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
File * find(const String &path, File *pStartNode=0)