Compare commits
3 Commits
762b7a4276
...
f0b6844feb
Author | SHA1 | Date |
---|---|---|
Bananymous | f0b6844feb | |
Bananymous | b712c70c75 | |
Bananymous | 797ca65c66 |
|
@ -201,6 +201,7 @@ namespace LibELF
|
|||
return BAN::Error::from_errno(ENOMEM);
|
||||
|
||||
m_page_table.map_page_at(paddr, vaddr, flags);
|
||||
m_physical_page_count++;
|
||||
|
||||
memset((void*)vaddr, 0x00, PAGE_SIZE);
|
||||
|
||||
|
@ -280,6 +281,7 @@ namespace LibELF
|
|||
m_page_table.unmap_page(0);
|
||||
|
||||
new_page_table.map_page_at(paddr, start + i * PAGE_SIZE, flags);
|
||||
elf->m_physical_page_count++;
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
@ -34,6 +34,7 @@ namespace LibELF
|
|||
BAN::ErrorOr<BAN::UniqPtr<LoadableELF>> clone(Kernel::PageTable&);
|
||||
|
||||
size_t virtual_page_count() const { return m_virtual_page_count; }
|
||||
size_t physical_page_count() const { return m_physical_page_count; }
|
||||
|
||||
private:
|
||||
LoadableELF(Kernel::PageTable&, BAN::RefPtr<Kernel::Inode>);
|
||||
|
@ -45,6 +46,7 @@ namespace LibELF
|
|||
ElfNativeFileHeader m_file_header;
|
||||
BAN::Vector<ElfNativeProgramHeader> m_program_headers;
|
||||
size_t m_virtual_page_count = 0;
|
||||
size_t m_physical_page_count = 0;
|
||||
};
|
||||
|
||||
}
|
|
@ -20,11 +20,11 @@ namespace Kernel
|
|||
Process& m_process;
|
||||
};
|
||||
|
||||
class ProcMemInode final : public RamInode
|
||||
class ProcROInode final : public RamInode
|
||||
{
|
||||
public:
|
||||
static BAN::ErrorOr<BAN::RefPtr<ProcMemInode>> create(Process&, RamFileSystem&, mode_t, uid_t, gid_t);
|
||||
~ProcMemInode() = default;
|
||||
static BAN::ErrorOr<BAN::RefPtr<ProcROInode>> create(Process&, size_t (Process::*callback)(off_t, void*, size_t) const, RamFileSystem&, mode_t, uid_t, gid_t);
|
||||
~ProcROInode() = default;
|
||||
|
||||
protected:
|
||||
virtual BAN::ErrorOr<size_t> read_impl(off_t, void*, size_t) override;
|
||||
|
@ -35,10 +35,11 @@ namespace Kernel
|
|||
virtual bool has_data_impl() const override { return true; }
|
||||
|
||||
private:
|
||||
ProcMemInode(Process&, RamFileSystem&, const FullInodeInfo&);
|
||||
ProcROInode(Process&, size_t (Process::*)(off_t, void*, size_t) const, RamFileSystem&, const FullInodeInfo&);
|
||||
|
||||
private:
|
||||
Process& m_process;
|
||||
size_t (Process::*m_callback)(off_t, void*, size_t) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -26,10 +26,11 @@ namespace Kernel
|
|||
static BAN::ErrorOr<BAN::UniqPtr<FileBackedRegion>> create(BAN::RefPtr<Inode>, PageTable&, off_t offset, size_t size, AddressRange address_range, Type, PageTable::flags_t);
|
||||
~FileBackedRegion();
|
||||
|
||||
virtual BAN::ErrorOr<bool> allocate_page_containing(vaddr_t vaddr) override;
|
||||
|
||||
virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) override;
|
||||
|
||||
protected:
|
||||
virtual BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t vaddr) override;
|
||||
|
||||
private:
|
||||
FileBackedRegion(BAN::RefPtr<Inode>, PageTable&, off_t offset, ssize_t size, Type flags, PageTable::flags_t page_flags);
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ namespace Kernel
|
|||
static BAN::ErrorOr<BAN::UniqPtr<MemoryBackedRegion>> create(PageTable&, size_t size, AddressRange, Type, PageTable::flags_t);
|
||||
~MemoryBackedRegion();
|
||||
|
||||
virtual BAN::ErrorOr<bool> allocate_page_containing(vaddr_t vaddr) override;
|
||||
|
||||
virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) override;
|
||||
|
||||
|
@ -22,6 +21,9 @@ namespace Kernel
|
|||
// This can fail if no memory is mapped and no free memory was available
|
||||
BAN::ErrorOr<void> copy_data_to_region(size_t offset_into_region, const uint8_t* buffer, size_t buffer_size);
|
||||
|
||||
protected:
|
||||
virtual BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t vaddr) override;
|
||||
|
||||
private:
|
||||
MemoryBackedRegion(PageTable&, size_t size, Type, PageTable::flags_t);
|
||||
};
|
||||
|
|
|
@ -38,11 +38,12 @@ namespace Kernel
|
|||
vaddr_t vaddr() const { return m_vaddr; }
|
||||
|
||||
size_t virtual_page_count() const { return BAN::Math::div_round_up<size_t>(m_size, PAGE_SIZE); }
|
||||
size_t physical_page_count() const { return m_physical_page_count; }
|
||||
|
||||
// Returns error if no memory was available
|
||||
// Returns true if page was succesfully allocated
|
||||
// Returns false if page was already allocated
|
||||
virtual BAN::ErrorOr<bool> allocate_page_containing(vaddr_t address) = 0;
|
||||
BAN::ErrorOr<bool> allocate_page_containing(vaddr_t address);
|
||||
|
||||
virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) = 0;
|
||||
|
||||
|
@ -50,12 +51,15 @@ namespace Kernel
|
|||
MemoryRegion(PageTable&, size_t size, Type type, PageTable::flags_t flags);
|
||||
BAN::ErrorOr<void> initialize(AddressRange);
|
||||
|
||||
virtual BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t address) = 0;
|
||||
|
||||
protected:
|
||||
PageTable& m_page_table;
|
||||
const size_t m_size;
|
||||
const Type m_type;
|
||||
const PageTable::flags_t m_flags;
|
||||
vaddr_t m_vaddr { 0 };
|
||||
size_t m_physical_page_count { 0 };
|
||||
};
|
||||
|
||||
}
|
|
@ -139,7 +139,9 @@ namespace Kernel
|
|||
|
||||
PageTable& page_table() { return m_page_table ? *m_page_table : PageTable::kernel(); }
|
||||
|
||||
void get_meminfo(proc_meminfo_t*) const;
|
||||
size_t proc_meminfo(off_t offset, void* buffer, size_t buffer_size) const;
|
||||
size_t proc_cmdline(off_t offset, void* buffer, size_t buffer_size) const;
|
||||
size_t proc_environ(off_t offset, void* buffer, size_t buffer_size) const;
|
||||
|
||||
bool is_userspace() const { return m_is_userspace; }
|
||||
const userspace_info_t& userspace_info() const { return m_userspace_info; }
|
||||
|
@ -192,6 +194,9 @@ namespace Kernel
|
|||
vaddr_t m_signal_handlers[_SIGMAX + 1] { };
|
||||
uint64_t m_signal_pending_mask { 0 };
|
||||
|
||||
BAN::Vector<BAN::String> m_cmdline;
|
||||
BAN::Vector<BAN::String> m_environ;
|
||||
|
||||
bool m_is_userspace { false };
|
||||
userspace_info_t m_userspace_info;
|
||||
ExitStatus m_exit_status;
|
||||
|
|
|
@ -84,6 +84,7 @@ namespace Kernel
|
|||
bool is_userspace() const { return m_is_userspace; }
|
||||
|
||||
size_t virtual_page_count() const { return m_stack->size() / PAGE_SIZE; }
|
||||
size_t physical_page_count() const { return virtual_page_count(); }
|
||||
|
||||
#if __enable_sse
|
||||
void save_sse() { asm volatile("fxsave %0" :: "m"(m_sse_storage)); }
|
||||
|
|
|
@ -12,7 +12,9 @@ namespace Kernel
|
|||
return BAN::Error::from_errno(ENOMEM);
|
||||
auto inode = BAN::RefPtr<ProcPidInode>::adopt(inode_ptr);
|
||||
|
||||
TRY(inode->add_inode("meminfo"sv, MUST(ProcMemInode::create(process, fs, 0755, 0, 0))));
|
||||
TRY(inode->add_inode("meminfo"sv, MUST(ProcROInode::create(process, &Process::proc_meminfo, fs, 0755, 0, 0))));
|
||||
TRY(inode->add_inode("cmdline"sv, MUST(ProcROInode::create(process, &Process::proc_cmdline, fs, 0755, 0, 0))));
|
||||
TRY(inode->add_inode("environ"sv, MUST(ProcROInode::create(process, &Process::proc_environ, fs, 0755, 0, 0))));
|
||||
|
||||
return inode;
|
||||
}
|
||||
|
@ -23,36 +25,30 @@ namespace Kernel
|
|||
{
|
||||
}
|
||||
|
||||
BAN::ErrorOr<BAN::RefPtr<ProcMemInode>> ProcMemInode::create(Process& process, RamFileSystem& fs, mode_t mode, uid_t uid, gid_t gid)
|
||||
BAN::ErrorOr<BAN::RefPtr<ProcROInode>> ProcROInode::create(Process& process, size_t (Process::*callback)(off_t, void*, size_t) const, RamFileSystem& fs, mode_t mode, uid_t uid, gid_t gid)
|
||||
{
|
||||
FullInodeInfo inode_info(fs, mode, uid, gid);
|
||||
|
||||
auto* inode_ptr = new ProcMemInode(process, fs, inode_info);
|
||||
auto* inode_ptr = new ProcROInode(process, callback, fs, inode_info);
|
||||
if (inode_ptr == nullptr)
|
||||
return BAN::Error::from_errno(ENOMEM);
|
||||
return BAN::RefPtr<ProcMemInode>::adopt(inode_ptr);
|
||||
return BAN::RefPtr<ProcROInode>::adopt(inode_ptr);
|
||||
}
|
||||
|
||||
ProcMemInode::ProcMemInode(Process& process, RamFileSystem& fs, const FullInodeInfo& inode_info)
|
||||
ProcROInode::ProcROInode(Process& process, size_t (Process::*callback)(off_t, void*, size_t) const, RamFileSystem& fs, const FullInodeInfo& inode_info)
|
||||
: RamInode(fs, inode_info)
|
||||
, m_process(process)
|
||||
, m_callback(callback)
|
||||
{
|
||||
m_inode_info.mode |= Inode::Mode::IFREG;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<size_t> ProcMemInode::read_impl(off_t offset, void* buffer, size_t buffer_size)
|
||||
BAN::ErrorOr<size_t> ProcROInode::read_impl(off_t offset, void* buffer, size_t buffer_size)
|
||||
{
|
||||
ASSERT(offset >= 0);
|
||||
if ((size_t)offset >= sizeof(proc_meminfo_t))
|
||||
return 0;
|
||||
|
||||
proc_meminfo_t meminfo;
|
||||
m_process.get_meminfo(&meminfo);
|
||||
|
||||
size_t bytes = BAN::Math::min<size_t>(buffer_size, sizeof(meminfo) - offset);
|
||||
memcpy(buffer, &meminfo, bytes);
|
||||
|
||||
return bytes;
|
||||
return (m_process.*m_callback)(offset, buffer, buffer_size);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ namespace Kernel
|
|||
}
|
||||
}
|
||||
|
||||
BAN::ErrorOr<bool> FileBackedRegion::allocate_page_containing(vaddr_t address)
|
||||
BAN::ErrorOr<bool> FileBackedRegion::allocate_page_containing_impl(vaddr_t address)
|
||||
{
|
||||
ASSERT(contains(address));
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace Kernel
|
|||
}
|
||||
}
|
||||
|
||||
BAN::ErrorOr<bool> MemoryBackedRegion::allocate_page_containing(vaddr_t address)
|
||||
BAN::ErrorOr<bool> MemoryBackedRegion::allocate_page_containing_impl(vaddr_t address)
|
||||
{
|
||||
ASSERT(m_type == Type::PRIVATE);
|
||||
|
||||
|
|
|
@ -47,4 +47,12 @@ namespace Kernel
|
|||
return true;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<bool> MemoryRegion::allocate_page_containing(vaddr_t address)
|
||||
{
|
||||
auto ret = allocate_page_containing_impl(address);
|
||||
if (!ret.is_error() && ret.value())
|
||||
m_physical_page_count++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -119,6 +119,9 @@ namespace Kernel
|
|||
MUST(process->m_working_directory.push_back('/'));
|
||||
process->m_page_table = BAN::UniqPtr<PageTable>::adopt(MUST(PageTable::create_userspace()));
|
||||
|
||||
TRY(process->m_cmdline.push_back({}));
|
||||
TRY(process->m_cmdline.back().append(path));
|
||||
|
||||
process->m_loadable_elf = TRY(load_elf_for_exec(credentials, path, "/"sv, process->page_table()));
|
||||
process->m_loadable_elf->reserve_address_space();
|
||||
|
||||
|
@ -252,19 +255,75 @@ namespace Kernel
|
|||
thread->set_terminating();
|
||||
}
|
||||
|
||||
void Process::get_meminfo(proc_meminfo_t* out) const
|
||||
size_t Process::proc_meminfo(off_t offset, void* buffer, size_t buffer_size) const
|
||||
{
|
||||
ASSERT(offset >= 0);
|
||||
if ((size_t)offset >= sizeof(proc_meminfo_t))
|
||||
return 0;
|
||||
|
||||
proc_meminfo_t meminfo;
|
||||
meminfo.page_size = PAGE_SIZE;
|
||||
meminfo.virt_pages = 0;
|
||||
meminfo.phys_pages = 0;
|
||||
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
|
||||
out->page_size = PAGE_SIZE;
|
||||
|
||||
out->virt_pages = 0;
|
||||
for (auto* thread : m_threads)
|
||||
out->virt_pages += thread->virtual_page_count();
|
||||
{
|
||||
meminfo.virt_pages += thread->virtual_page_count();
|
||||
meminfo.phys_pages += thread->physical_page_count();
|
||||
}
|
||||
for (auto& region : m_mapped_regions)
|
||||
out->virt_pages += region->virtual_page_count();
|
||||
{
|
||||
meminfo.virt_pages += region->virtual_page_count();
|
||||
meminfo.phys_pages += region->physical_page_count();
|
||||
}
|
||||
if (m_loadable_elf)
|
||||
out->virt_pages += m_loadable_elf->virtual_page_count();
|
||||
{
|
||||
meminfo.virt_pages += m_loadable_elf->virtual_page_count();
|
||||
meminfo.phys_pages += m_loadable_elf->physical_page_count();
|
||||
}
|
||||
}
|
||||
|
||||
size_t bytes = BAN::Math::min<size_t>(sizeof(proc_meminfo_t) - offset, buffer_size);
|
||||
memcpy(buffer, (uint8_t*)&meminfo + offset, bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static size_t read_from_vec_of_str(const BAN::Vector<BAN::String>& container, size_t start, void* buffer, size_t buffer_size)
|
||||
{
|
||||
size_t offset = 0;
|
||||
size_t written = 0;
|
||||
for (const auto& elem : container)
|
||||
{
|
||||
if (start < offset + elem.size() + 1)
|
||||
{
|
||||
size_t elem_offset = 0;
|
||||
if (offset < start)
|
||||
elem_offset = start - offset;
|
||||
|
||||
size_t bytes = BAN::Math::min<size_t>(elem.size() + 1 - elem_offset, buffer_size - written);
|
||||
memcpy((uint8_t*)buffer + written, elem.data() + elem_offset, bytes);
|
||||
|
||||
written += bytes;
|
||||
if (written >= buffer_size)
|
||||
break;
|
||||
}
|
||||
offset += elem.size() + 1;
|
||||
}
|
||||
return written;
|
||||
}
|
||||
|
||||
size_t Process::proc_cmdline(off_t offset, void* buffer, size_t buffer_size) const
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
return read_from_vec_of_str(m_cmdline, offset, buffer, buffer_size);
|
||||
}
|
||||
|
||||
size_t Process::proc_environ(off_t offset, void* buffer, size_t buffer_size) const
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
return read_from_vec_of_str(m_environ, offset, buffer, buffer_size);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> Process::sys_exit(int status)
|
||||
|
@ -454,6 +513,9 @@ namespace Kernel
|
|||
|
||||
m_userspace_info.argc = str_argv.size();
|
||||
|
||||
m_cmdline = BAN::move(str_argv);
|
||||
m_environ = BAN::move(str_envp);
|
||||
|
||||
asm volatile("cli");
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ struct proc_meminfo_t
|
|||
{
|
||||
size_t page_size;
|
||||
size_t virt_pages;
|
||||
size_t phys_pages;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -30,6 +30,43 @@ int main()
|
|||
if (!is_only_digits(proc_ent->d_name))
|
||||
continue;
|
||||
|
||||
printf("process: ");
|
||||
|
||||
{
|
||||
strcpy(path_buffer, proc_ent->d_name);
|
||||
strcat(path_buffer, "/cmdline");
|
||||
|
||||
int fd = openat(dirfd(proc), path_buffer, O_RDONLY);
|
||||
if (fd == -1)
|
||||
{
|
||||
perror("openat");
|
||||
continue;
|
||||
}
|
||||
|
||||
while (ssize_t nread = read(fd, path_buffer, sizeof(path_buffer) - 1))
|
||||
{
|
||||
if (nread == -1)
|
||||
{
|
||||
perror("read");
|
||||
break;
|
||||
}
|
||||
for (int i = 0; i < nread; i++)
|
||||
if (path_buffer[i] == '\0')
|
||||
path_buffer[i] = ' ';
|
||||
|
||||
path_buffer[nread] = '\0';
|
||||
|
||||
int written = 0;
|
||||
while (written < nread)
|
||||
written += printf("%s ", path_buffer + written);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
printf("\n pid: %s\n", proc_ent->d_name);
|
||||
|
||||
{
|
||||
strcpy(path_buffer, proc_ent->d_name);
|
||||
strcat(path_buffer, "/meminfo");
|
||||
|
||||
|
@ -45,13 +82,13 @@ int main()
|
|||
perror("read");
|
||||
else
|
||||
{
|
||||
printf("process:\n");
|
||||
printf(" pid: %s\n", proc_ent->d_name);
|
||||
printf(" vmem: %zu pages (%zu bytes)\n", meminfo.virt_pages, meminfo.page_size * meminfo.virt_pages);
|
||||
printf(" pmem: %zu pages (%zu bytes)\n", meminfo.phys_pages, meminfo.page_size * meminfo.phys_pages);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
closedir(proc);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue