Kernel: Add basic fixed width allocator for userspace
We have to move process stacks to the general heap and maybe map kernel to higher half.
This commit is contained in:
		
							parent
							
								
									b65cd1d09b
								
							
						
					
					
						commit
						ff5bcd4416
					
				| 
						 | 
					@ -25,6 +25,7 @@ set(KERNEL_SOURCES
 | 
				
			||||||
	kernel/Input/PS2Keymap.cpp
 | 
						kernel/Input/PS2Keymap.cpp
 | 
				
			||||||
	kernel/InterruptController.cpp
 | 
						kernel/InterruptController.cpp
 | 
				
			||||||
	kernel/kernel.cpp
 | 
						kernel/kernel.cpp
 | 
				
			||||||
 | 
						kernel/Memory/FixedWidthAllocator.cpp
 | 
				
			||||||
	kernel/Memory/Heap.cpp
 | 
						kernel/Memory/Heap.cpp
 | 
				
			||||||
	kernel/Memory/kmalloc.cpp
 | 
						kernel/Memory/kmalloc.cpp
 | 
				
			||||||
	kernel/Panic.cpp
 | 
						kernel/Panic.cpp
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,48 @@
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <kernel/Memory/Heap.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Kernel
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						class Process;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						class FixedWidthAllocator
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							BAN_NON_COPYABLE(FixedWidthAllocator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public:
 | 
				
			||||||
 | 
							FixedWidthAllocator(Process*, uint32_t);
 | 
				
			||||||
 | 
							FixedWidthAllocator(FixedWidthAllocator&&);
 | 
				
			||||||
 | 
							~FixedWidthAllocator();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							vaddr_t allocate();
 | 
				
			||||||
 | 
							void deallocate(vaddr_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							uint32_t allocation_size() const { return m_allocation_size; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private:
 | 
				
			||||||
 | 
							struct node
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								node* prev { nullptr };
 | 
				
			||||||
 | 
								node* next { nullptr };
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
							vaddr_t address_of(const node*) const;
 | 
				
			||||||
 | 
							void allocate_page_for_node_if_needed(const node*);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private:
 | 
				
			||||||
 | 
							static constexpr uint32_t m_min_allocation_size = 16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Process* m_process;
 | 
				
			||||||
 | 
							const uint32_t m_allocation_size;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							vaddr_t m_nodes_page { 0 };
 | 
				
			||||||
 | 
							vaddr_t m_allocated_pages { 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							node* m_free_list { nullptr };
 | 
				
			||||||
 | 
							node* m_used_list { nullptr };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							uint32_t m_allocated { 0 };
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -4,6 +4,7 @@
 | 
				
			||||||
#include <BAN/StringView.h>
 | 
					#include <BAN/StringView.h>
 | 
				
			||||||
#include <BAN/Vector.h>
 | 
					#include <BAN/Vector.h>
 | 
				
			||||||
#include <kernel/FS/Inode.h>
 | 
					#include <kernel/FS/Inode.h>
 | 
				
			||||||
 | 
					#include <kernel/Memory/FixedWidthAllocator.h>
 | 
				
			||||||
#include <kernel/Memory/Heap.h>
 | 
					#include <kernel/Memory/Heap.h>
 | 
				
			||||||
#include <kernel/Memory/MMU.h>
 | 
					#include <kernel/Memory/MMU.h>
 | 
				
			||||||
#include <kernel/SpinLock.h>
 | 
					#include <kernel/SpinLock.h>
 | 
				
			||||||
| 
						 | 
					@ -55,6 +56,8 @@ namespace Kernel
 | 
				
			||||||
		BAN::ErrorOr<BAN::String> working_directory() const;
 | 
							BAN::ErrorOr<BAN::String> working_directory() const;
 | 
				
			||||||
		BAN::ErrorOr<void> set_working_directory(BAN::StringView);
 | 
							BAN::ErrorOr<void> set_working_directory(BAN::StringView);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							BAN::ErrorOr<void*> allocate(size_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void termid(char*) const;
 | 
							void termid(char*) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static Process& current() { return Thread::current().process(); }
 | 
							static Process& current() { return Thread::current().process(); }
 | 
				
			||||||
| 
						 | 
					@ -90,6 +93,8 @@ namespace Kernel
 | 
				
			||||||
		BAN::String m_working_directory;
 | 
							BAN::String m_working_directory;
 | 
				
			||||||
		BAN::Vector<Thread*> m_threads;
 | 
							BAN::Vector<Thread*> m_threads;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							BAN::Vector<FixedWidthAllocator> m_fixed_width_allocators;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		MMU* m_mmu { nullptr };
 | 
							MMU* m_mmu { nullptr };
 | 
				
			||||||
		TTY* m_tty { nullptr };
 | 
							TTY* m_tty { nullptr };
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,7 @@
 | 
				
			||||||
#define SYS_CLOSE 5
 | 
					#define SYS_CLOSE 5
 | 
				
			||||||
#define SYS_SEEK 6
 | 
					#define SYS_SEEK 6
 | 
				
			||||||
#define SYS_OPEN 7
 | 
					#define SYS_OPEN 7
 | 
				
			||||||
 | 
					#define SYS_ALLOC 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,145 @@
 | 
				
			||||||
 | 
					#include <kernel/CriticalScope.h>
 | 
				
			||||||
 | 
					#include <kernel/Memory/FixedWidthAllocator.h>
 | 
				
			||||||
 | 
					#include <kernel/Memory/MMU.h>
 | 
				
			||||||
 | 
					#include <kernel/Process.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Kernel
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FixedWidthAllocator::FixedWidthAllocator(Process* process, uint32_t allocation_size)
 | 
				
			||||||
 | 
							: m_process(process)
 | 
				
			||||||
 | 
							, m_allocation_size(BAN::Math::max(allocation_size, m_min_allocation_size))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							ASSERT(BAN::Math::is_power_of_two(allocation_size));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							paddr_t nodes_paddr = Heap::get().take_free_page();
 | 
				
			||||||
 | 
							m_nodes_page = m_process->mmu().get_free_page();
 | 
				
			||||||
 | 
							m_process->mmu().map_page_at(nodes_paddr, m_nodes_page, MMU::Flags::ReadWrite | MMU::Flags::Present);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							paddr_t allocated_pages_paddr = Heap::get().take_free_page();
 | 
				
			||||||
 | 
							m_allocated_pages = m_process->mmu().get_free_page();
 | 
				
			||||||
 | 
							m_process->mmu().map_page_at(allocated_pages_paddr, m_allocated_pages, MMU::Flags::ReadWrite | MMU::Flags::Present);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							CriticalScope _;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							m_process->mmu().load();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							memset((void*)m_nodes_page, 0, PAGE_SIZE);
 | 
				
			||||||
 | 
							memset((void*)m_allocated_pages, 0, PAGE_SIZE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							node* node_table = (node*)m_nodes_page;
 | 
				
			||||||
 | 
							for (uint32_t i = 0; i < PAGE_SIZE / sizeof(node); i++)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								node_table[i].next = &node_table[i + 1];
 | 
				
			||||||
 | 
								node_table[i].prev = &node_table[i - 1];
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							node_table[0].prev = nullptr;
 | 
				
			||||||
 | 
							node_table[PAGE_SIZE / sizeof(node) - 1].next = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							m_free_list = node_table;
 | 
				
			||||||
 | 
							m_used_list = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Process::current().mmu().load();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FixedWidthAllocator::FixedWidthAllocator(FixedWidthAllocator&& other)
 | 
				
			||||||
 | 
							: m_process(other.m_process)
 | 
				
			||||||
 | 
							, m_allocation_size(other.m_allocation_size)
 | 
				
			||||||
 | 
							, m_nodes_page(other.m_nodes_page)
 | 
				
			||||||
 | 
							, m_allocated_pages(other.m_allocated_pages)
 | 
				
			||||||
 | 
							, m_free_list(other.m_free_list)
 | 
				
			||||||
 | 
							, m_used_list(other.m_used_list)
 | 
				
			||||||
 | 
							, m_allocated(other.m_allocated)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							other.m_process = nullptr;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FixedWidthAllocator::~FixedWidthAllocator()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (m_process == nullptr)
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							Heap::get().release_page(m_process->mmu().physical_address_of(m_nodes_page));
 | 
				
			||||||
 | 
							m_process->mmu().unmap_page(m_nodes_page);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (uint32_t page_index = 0; page_index < PAGE_SIZE / sizeof(vaddr_t); page_index++)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								vaddr_t page_vaddr = ((vaddr_t*)m_allocated_pages)[page_index];
 | 
				
			||||||
 | 
								if (page_vaddr == 0)
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ASSERT(!m_process->mmu().is_page_free(page_vaddr));
 | 
				
			||||||
 | 
								paddr_t page_paddr = m_process->mmu().physical_address_of(page_vaddr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Heap::get().release_page(page_paddr);
 | 
				
			||||||
 | 
								m_process->mmu().unmap_page(page_vaddr);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Heap::get().release_page(m_process->mmu().physical_address_of(m_allocated_pages));
 | 
				
			||||||
 | 
							m_process->mmu().unmap_page(m_allocated_pages);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						paddr_t FixedWidthAllocator::allocate()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							// FIXME: We should get allocate more memory if we run out of
 | 
				
			||||||
 | 
							//        nodes in free list.
 | 
				
			||||||
 | 
							ASSERT(m_free_list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							node* node = m_free_list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							m_free_list = node->next;
 | 
				
			||||||
 | 
							if (m_free_list)
 | 
				
			||||||
 | 
								m_free_list->prev = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							node->next = m_used_list;
 | 
				
			||||||
 | 
							node->prev = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (m_used_list)
 | 
				
			||||||
 | 
								m_used_list->prev = node;
 | 
				
			||||||
 | 
							m_used_list = node;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							m_allocated++;
 | 
				
			||||||
 | 
							allocate_page_for_node_if_needed(node);
 | 
				
			||||||
 | 
							return address_of(node);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void FixedWidthAllocator::deallocate(paddr_t addr)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							(void)addr;
 | 
				
			||||||
 | 
							ASSERT_NOT_REACHED();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						vaddr_t FixedWidthAllocator::address_of(const node* node) const
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							uint32_t index = node - (struct node*)m_nodes_page;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							uint32_t page_index = index / (PAGE_SIZE / sizeof(struct node));
 | 
				
			||||||
 | 
							ASSERT(page_index < PAGE_SIZE / sizeof(vaddr_t));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							uint32_t offset = index % (PAGE_SIZE / sizeof(struct node));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							vaddr_t page_begin = ((vaddr_t*)m_allocated_pages)[page_index];
 | 
				
			||||||
 | 
							ASSERT(page_begin);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return page_begin + offset * m_allocation_size;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void FixedWidthAllocator::allocate_page_for_node_if_needed(const node* node)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							uint32_t index = node - (struct node*)m_nodes_page;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							uint32_t page_index = index / (PAGE_SIZE / sizeof(struct node));
 | 
				
			||||||
 | 
							ASSERT(page_index < PAGE_SIZE / sizeof(vaddr_t));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							vaddr_t& page_vaddr = ((vaddr_t*)m_allocated_pages)[page_index];
 | 
				
			||||||
 | 
							if (page_vaddr)
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							paddr_t page_paddr = Heap::get().take_free_page();
 | 
				
			||||||
 | 
							ASSERT(page_paddr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							page_vaddr = m_process->mmu().get_free_page();
 | 
				
			||||||
 | 
							m_process->mmu().map_page_at(page_paddr, page_vaddr, MMU::Flags::UserSupervisor | MMU::Flags::ReadWrite | MMU::Flags::Present);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,5 @@
 | 
				
			||||||
#include <BAN/StringView.h>
 | 
					#include <BAN/StringView.h>
 | 
				
			||||||
 | 
					#include <kernel/CriticalScope.h>
 | 
				
			||||||
#include <kernel/FS/VirtualFileSystem.h>
 | 
					#include <kernel/FS/VirtualFileSystem.h>
 | 
				
			||||||
#include <kernel/LockGuard.h>
 | 
					#include <kernel/LockGuard.h>
 | 
				
			||||||
#include <kernel/Memory/Heap.h>
 | 
					#include <kernel/Memory/Heap.h>
 | 
				
			||||||
| 
						 | 
					@ -69,10 +70,10 @@ namespace Kernel
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			case LibELF::PT_LOAD:
 | 
								case LibELF::PT_LOAD:
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				// TODO: Do some relocations?
 | 
									// TODO: Do some relocations or map kernel to higher half?
 | 
				
			||||||
				ASSERT(process->mmu().is_range_free(elf_program_header.p_vaddr, elf_program_header.p_memsz));
 | 
									ASSERT(process->mmu().is_range_free(elf_program_header.p_vaddr, elf_program_header.p_memsz));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				uint8_t flags = MMU::Flags::UserSupervisor | MMU::Flags::Present;
 | 
									MMU::flags_t flags = MMU::Flags::UserSupervisor | MMU::Flags::Present;
 | 
				
			||||||
				if (elf_program_header.p_flags & LibELF::PF_W)
 | 
									if (elf_program_header.p_flags & LibELF::PF_W)
 | 
				
			||||||
					flags |= MMU::Flags::ReadWrite;
 | 
										flags |= MMU::Flags::ReadWrite;
 | 
				
			||||||
				size_t page_start = elf_program_header.p_vaddr / PAGE_SIZE;
 | 
									size_t page_start = elf_program_header.p_vaddr / PAGE_SIZE;
 | 
				
			||||||
| 
						 | 
					@ -82,12 +83,16 @@ namespace Kernel
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					auto paddr = Heap::get().take_free_page();
 | 
										auto paddr = Heap::get().take_free_page();
 | 
				
			||||||
					MUST(process->m_allocated_pages.push_back(paddr));
 | 
										MUST(process->m_allocated_pages.push_back(paddr));
 | 
				
			||||||
					process->m_mmu->map_page_at(paddr, page * PAGE_SIZE, flags);
 | 
										process->mmu().map_page_at(paddr, page * PAGE_SIZE, flags);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				process->m_mmu->load();
 | 
					
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										CriticalScope _;
 | 
				
			||||||
 | 
										process->mmu().load();
 | 
				
			||||||
					memcpy((void*)elf_program_header.p_vaddr, elf->data() + elf_program_header.p_offset, elf_program_header.p_filesz);
 | 
										memcpy((void*)elf_program_header.p_vaddr, elf->data() + elf_program_header.p_offset, elf_program_header.p_filesz);
 | 
				
			||||||
					memset((void*)(elf_program_header.p_vaddr + elf_program_header.p_filesz), 0, elf_program_header.p_memsz - elf_program_header.p_filesz);
 | 
										memset((void*)(elf_program_header.p_vaddr + elf_program_header.p_filesz), 0, elf_program_header.p_memsz - elf_program_header.p_filesz);
 | 
				
			||||||
					Process::current().mmu().load();
 | 
										Process::current().mmu().load();
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			default:
 | 
								default:
 | 
				
			||||||
| 
						 | 
					@ -100,6 +105,11 @@ namespace Kernel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		delete elf;
 | 
							delete elf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							MUST(process->m_fixed_width_allocators.emplace_back(process, 64));
 | 
				
			||||||
 | 
							MUST(process->m_fixed_width_allocators.emplace_back(process, 256));
 | 
				
			||||||
 | 
							MUST(process->m_fixed_width_allocators.emplace_back(process, 1024));
 | 
				
			||||||
 | 
							MUST(process->m_fixed_width_allocators.emplace_back(process, 4096));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		register_process(process);
 | 
							register_process(process);
 | 
				
			||||||
		return process;
 | 
							return process;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -112,6 +122,7 @@ namespace Kernel
 | 
				
			||||||
	Process::~Process()
 | 
						Process::~Process()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		ASSERT(m_threads.empty());
 | 
							ASSERT(m_threads.empty());
 | 
				
			||||||
 | 
							ASSERT(m_fixed_width_allocators.empty());
 | 
				
			||||||
		if (m_mmu)
 | 
							if (m_mmu)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			MMU::get().load();
 | 
								MMU::get().load();
 | 
				
			||||||
| 
						 | 
					@ -144,6 +155,9 @@ namespace Kernel
 | 
				
			||||||
		for (auto& open_fd : m_open_files)
 | 
							for (auto& open_fd : m_open_files)
 | 
				
			||||||
			open_fd.inode = nullptr;
 | 
								open_fd.inode = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// NOTE: We must clear allocators while the mmu is still alive
 | 
				
			||||||
 | 
							m_fixed_width_allocators.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		dprintln("process {} exit", pid());
 | 
							dprintln("process {} exit", pid());
 | 
				
			||||||
		s_process_lock.lock();
 | 
							s_process_lock.lock();
 | 
				
			||||||
		for (size_t i = 0; i < s_processes.size(); i++)
 | 
							for (size_t i = 0; i < s_processes.size(); i++)
 | 
				
			||||||
| 
						 | 
					@ -364,6 +378,14 @@ namespace Kernel
 | 
				
			||||||
		return {};
 | 
							return {};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						BAN::ErrorOr<void*> Process::allocate(size_t bytes)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							for (auto& allocator : m_fixed_width_allocators)
 | 
				
			||||||
 | 
								if (bytes <= allocator.allocation_size())
 | 
				
			||||||
 | 
									return (void*)allocator.allocate();
 | 
				
			||||||
 | 
							return BAN::Error::from_errno(ENOMEM);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void Process::termid(char* buffer) const
 | 
						void Process::termid(char* buffer) const
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (m_tty == nullptr)
 | 
							if (m_tty == nullptr)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,6 +55,14 @@ namespace Kernel
 | 
				
			||||||
		return res.value();
 | 
							return res.value();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						long sys_alloc(size_t bytes)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							auto res = Process::current().allocate(bytes);
 | 
				
			||||||
 | 
							if (res.is_error())
 | 
				
			||||||
 | 
								return -res.error().get_error_code();
 | 
				
			||||||
 | 
							return (long)res.value();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	extern "C" long cpp_syscall_handler(int syscall, void* arg1, void* arg2, void* arg3)
 | 
						extern "C" long cpp_syscall_handler(int syscall, void* arg1, void* arg2, void* arg3)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Thread::current().set_in_syscall(true);
 | 
							Thread::current().set_in_syscall(true);
 | 
				
			||||||
| 
						 | 
					@ -85,6 +93,9 @@ namespace Kernel
 | 
				
			||||||
		case SYS_OPEN:
 | 
							case SYS_OPEN:
 | 
				
			||||||
			ret = sys_open((const char*)arg1, (int)(uintptr_t)arg2);
 | 
								ret = sys_open((const char*)arg1, (int)(uintptr_t)arg2);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
							case SYS_ALLOC:
 | 
				
			||||||
 | 
								ret = sys_alloc((size_t)arg1);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			Kernel::panic("Unknown syscall {}", syscall);
 | 
								Kernel::panic("Unknown syscall {}", syscall);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,10 @@
 | 
				
			||||||
#include <BAN/Assert.h>
 | 
					#include <BAN/Assert.h>
 | 
				
			||||||
#include <ctype.h>
 | 
					#include <ctype.h>
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <sys/syscall.h>
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern "C" void _fini();
 | 
					extern "C" void _fini();
 | 
				
			||||||
| 
						 | 
					@ -55,10 +57,16 @@ char* getenv(const char*)
 | 
				
			||||||
	return nullptr;
 | 
						return nullptr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void* malloc(size_t)
 | 
					void* malloc(size_t bytes)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						long ret = syscall(SYS_ALLOC, bytes);
 | 
				
			||||||
 | 
						if (ret < 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							errno = -ret;
 | 
				
			||||||
		return nullptr;
 | 
							return nullptr;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						return (void*)ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void* calloc(size_t nmemb, size_t size)
 | 
					void* calloc(size_t nmemb, size_t size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,6 +68,12 @@ long syscall(long syscall, ...)
 | 
				
			||||||
			ret = Kernel::syscall(SYS_OPEN, path, oflags);
 | 
								ret = Kernel::syscall(SYS_OPEN, path, oflags);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							case SYS_ALLOC:
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								size_t bytes = va_arg(args, size_t);
 | 
				
			||||||
 | 
								ret = Kernel::syscall(SYS_ALLOC, bytes);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			puts("LibC: Unhandeled syscall");
 | 
								puts("LibC: Unhandeled syscall");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,18 @@
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main()
 | 
					int main()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						void* ptr = malloc(10);
 | 
				
			||||||
 | 
						if (ptr == NULL)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							perror("malloc");
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						*(int*)ptr = 5;
 | 
				
			||||||
 | 
						putc('0' + *(int*)ptr, stdout);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	FILE* fp = fopen("/boot/grub/grub.cfg", "r");
 | 
						FILE* fp = fopen("/boot/grub/grub.cfg", "r");
 | 
				
			||||||
	if (fp == NULL)
 | 
						if (fp == NULL)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue