Compare commits

..

No commits in common. "df95126ccd09fc121b9737bb81201ed9f5155016" and "b7df596f8a2a71d25dd3df7c59ca1e301ca42e6b" have entirely different histories.

14 changed files with 50 additions and 46 deletions

View File

@ -1,6 +1,3 @@
target_compile_definitions(moon PRIVATE LOCKED_VALUE_DEBUG)
target_compile_definitions(moon PRIVATE DEBUG_MODE)
target_compile_definitions(moon PRIVATE ELF_DEBUG)
target_compile_definitions(moon PRIVATE MMU_DEBUG)
target_compile_definitions(moon PRIVATE MMAP_DEBUG)
target_compile_options(moon PRIVATE -fsanitize=undefined)

View File

@ -32,48 +32,48 @@ namespace ELFLoader
if (nread < sizeof elf_header)
{
kerrorln("Error while loading ELF: ELF header does not fit in file");
kdbgln("Error while loading ELF: ELF header does not fit in file");
return err(ENOEXEC);
}
if (memcmp(elf_header.e_ident, ELFMAG, SELFMAG) != 0)
{
kerrorln("Error while loading ELF: ELF header has no valid magic");
kdbgln("Error while loading ELF: ELF header has no valid magic");
return err(ENOEXEC);
}
if (elf_header.e_ident[EI_CLASS] != ELFCLASS64)
{
kerrorln("Error while loading ELF: ELF object is not 64-bit");
kdbgln("Error while loading ELF: ELF object is not 64-bit");
return err(ENOEXEC);
}
if (elf_header.e_ident[EI_DATA] != ELFDATA2LSB)
{
kerrorln("Error while loading ELF: ELF object is not 2's complement little-endian");
kdbgln("Error while loading ELF: ELF object is not 2's complement little-endian");
return err(ENOEXEC);
}
if (elf_header.e_type != ET_EXEC)
{
kerrorln("Error while loading ELF: ELF object is not an executable");
kdbgln("Error while loading ELF: ELF object is not an executable");
return err(ENOEXEC);
}
if (elf_header.e_machine != EM_MACH)
{
kerrorln("Error while loading ELF: ELF object's target architecture does not match the current one (%s)",
kdbgln("Error while loading ELF: ELF object's target architecture does not match the current one (%s)",
CPU::platform_string());
return err(ENOEXEC);
}
if (elf_header.e_phnum == 0)
{
kerrorln("Error while loading ELF: ELF object has no program headers");
kdbgln("Error while loading ELF: ELF object has no program headers");
return err(ENOEXEC);
}
kinfoln("ELF: Loading ELF with entry=%#.16lx", elf_header.e_entry);
kdbgln("ELF: Loading ELF with entry=%#.16lx", elf_header.e_entry);
usize i;
Elf64_Phdr program_header;
@ -85,11 +85,9 @@ namespace ELFLoader
{
if (program_header.p_type == PT_LOAD)
{
#ifdef ELF_DEBUG
kdbgln("ELF: Loading segment (offset=%zu, base=%#.16lx, filesize=%zu, memsize=%zu)",
program_header.p_offset, program_header.p_vaddr, program_header.p_filesz,
program_header.p_memsz);
#endif
u64 base_vaddr = align_down<ARCH_PAGE_SIZE>(program_header.p_vaddr);
u64 vaddr_diff = program_header.p_vaddr - base_vaddr;
@ -111,7 +109,7 @@ namespace ELFLoader
memset((void*)(program_header.p_vaddr + program_header.p_filesz), 0,
program_header.p_memsz - program_header.p_filesz);
}
else { kwarnln("ELF: Encountered non-loadable program header, skipping"); }
else { kdbgln("ELF: Encountered non-loadable program header, skipping"); }
}
return ELFData { elf_header.e_entry };

View File

@ -8,6 +8,9 @@
#include <luna/ScopeGuard.h>
#include <luna/SystemError.h>
#pragma GCC push_options
#pragma GCC diagnostic ignored "-Wconversion"
PageDirectory* g_kernel_directory;
u64 g_kernel_directory_virt;
@ -15,9 +18,6 @@ u64 g_kernel_directory_virt;
// physical memory at 0xFFFF800000000000.
u64 g_physical_mapping_base = 0;
#pragma GCC push_options
#pragma GCC diagnostic ignored "-Wconversion"
void PageTableEntry::set_address(u64 addr)
{
this->address = (addr >> 12);
@ -207,7 +207,7 @@ namespace MMU
if (flags & Flags::ReadWrite) l3.read_write = true;
if (flags & Flags::User) l3.user = true;
if (l3.larger_pages) return err(ENOMEM);
if (l3.larger_pages) return err(EEXIST);
auto& l2 = l2_entry(l3, virt);
if (!l2.present)
@ -225,7 +225,7 @@ namespace MMU
if (flags & Flags::ReadWrite) l2.read_write = true;
if (flags & Flags::User) l2.user = true;
if (l2.larger_pages) return err(ENOMEM);
if (l2.larger_pages) return err(EEXIST);
else if (use_huge_pages == UseHugePages::Yes)
{
l2.larger_pages = true;
@ -234,7 +234,7 @@ namespace MMU
}
auto& l1 = l1_entry(l2, virt);
if (l1.present) return err(ENOMEM);
if (l1.present) return err(EEXIST); // Please explicitly unmap the page before mapping it again.
set_page_table_entry_properties(l1, phys, flags);
return {};
}
@ -296,9 +296,7 @@ namespace MMU
g_kernel_directory_virt = translate_physical((u64)g_kernel_directory);
#ifdef MMU_DEBUG
kdbgln("MMU init page directory (ring0): virt %#.16lx, phys %p", g_kernel_directory_virt, g_kernel_directory);
#endif
}
Result<PageDirectory*> create_page_directory_for_userspace()
@ -314,9 +312,7 @@ namespace MMU
memcpy(offset_ptr(directory, HALF_PAGE), offset_ptr((PageDirectory*)g_kernel_directory_virt, HALF_PAGE),
HALF_PAGE);
#ifdef MMU_DEBUG
kdbgln("MMU init page directory (ring3): virt %p, phys %#.16lx", directory, directory_phys);
#endif
return (PageDirectory*)directory_phys;
}

View File

@ -44,6 +44,8 @@ namespace VFS
auto child_name = TRY(parser.basename());
// kdbgln("vfs: creating directory '%s' in parent '%s'", child_name.chars(), parent_path.chars());
return parent_inode->create_subdirectory(child_name.chars());
}
@ -58,6 +60,8 @@ namespace VFS
auto child_name = TRY(parser.basename());
// kdbgln("vfs: creating file '%s' in parent '%s'", child_name.chars(), parent_path.chars());
return parent_inode->create_file(child_name.chars());
}

View File

@ -33,7 +33,7 @@ namespace DeviceRegistry
if (descriptor.major == major && descriptor.minor == minor) return err(EEXIST);
}
kdbgln("DeviceRegistry: registered new device type %u:%u", major, minor);
kdbgln("device manager: registered new device type %u:%u", major, minor);
return g_available_devices.try_append(
DeviceDescriptor { .initializer = initializer, .major = major, .minor = minor });

View File

@ -92,6 +92,7 @@ static u64 allocate_initial_kernel_stack()
// First page is a guard page, the rest is stack.
MMU::unmap(address); // Unmap (without deallocating VM) one guard page so that attempts to access it fail with a
// non-present page fault.
kdbgln("stack guard page: %p", (void*)address);
// The actual stack.
Stack stack { address + ARCH_PAGE_SIZE, BOOTSTRAP_STACK_PAGES * ARCH_PAGE_SIZE };

View File

@ -40,6 +40,7 @@ Result<OwnedPtr<UserVM>> UserVM::clone()
UserVM::UserVM(void* base, usize size)
{
kdbgln("user vm created with base=%p, size=%zu", base, size);
m_bitmap.initialize(base, size);
m_bitmap.clear(false);
}
@ -56,6 +57,8 @@ Result<bool> UserVM::try_expand(usize size)
m_bitmap.resize(new_size);
m_bitmap.clear_region(old_size * 8, (new_size - old_size) * 8, false);
kdbgln("user vm expanded to base=%p, size=%zu", m_bitmap.location(), new_size);
return true;
}
@ -118,5 +121,6 @@ Result<bool> UserVM::free_several_pages(u64 address, usize count)
UserVM::~UserVM()
{
kdbgln("user vm destroyed: base=%p, size=%zu", m_bitmap.location(), m_bitmap.size_in_bytes());
m_bitmap.deallocate();
}

View File

@ -51,9 +51,13 @@ Result<u64> sys_execve(Registers* regs, SyscallArgs args)
auto image = TRY(ThreadImage::try_load_from_elf(inode));
kdbgln("exec: copying argv to image memory (argc = %zu)", argv.size());
u64 user_argv = TRY(image->push_string_vector_on_stack(argv));
usize user_argc = argv.size();
kdbgln("exec: copying envp to image memory (envc = %zu)", envp.size());
u64 user_envp = TRY(image->push_string_vector_on_stack(envp));
usize user_envc = envp.size();
@ -85,6 +89,8 @@ Result<u64> sys_execve(Registers* regs, SyscallArgs args)
memcpy(regs, &current->regs, sizeof(*regs));
kinfoln("exec: done");
return 0;
}
@ -94,6 +100,8 @@ Result<u64> sys_fork(Registers* regs, SyscallArgs)
auto guard = make_scope_guard([current] { MMU::switch_page_directory(current->directory); });
kinfoln("fork: trying to duplicate process %lu", current->id);
memcpy(&current->regs, regs, sizeof(*regs));
auto current_directory_path = TRY(current->current_directory_path.clone());
@ -121,7 +129,5 @@ Result<u64> sys_fork(Registers* regs, SyscallArgs)
Scheduler::add_thread(thread);
kinfoln("fork: thread %lu forked into child %lu", current->id, thread->id);
return thread->id;
}

View File

@ -11,6 +11,8 @@ Result<u64> sys_mkdir(Registers*, SyscallArgs args)
Thread* current = Scheduler::current();
kinfoln("mkdir: attempting to create %s", path.chars());
auto inode = TRY(VFS::create_directory(path.chars(), current->auth, current->current_directory));
inode->chmod(mode);
inode->chown(current->auth.euid, current->auth.egid);

View File

@ -17,6 +17,8 @@ Result<u64> sys_mknod(Registers*, SyscallArgs args)
u32 maj = luna_dev_major(dev);
u32 min = luna_dev_minor(dev);
kdbgln("mknod: attempting to create device %u:%u in path %s", maj, min, path.chars());
auto parser = TRY(PathParser::create(path.chars()));
auto dirname = TRY(parser.dirname());

View File

@ -49,9 +49,7 @@ Result<u64> sys_mmap(Registers*, SyscallArgs args)
if (prot & PROT_EXEC) mmu_flags &= ~MMU::NoExecute;
if (prot == PROT_NONE) mmu_flags = MMU::NoExecute;
#ifdef MMAP_DEBUG
kdbgln("mmap: mapping memory at %#lx, size=%zu", address, len);
#endif
return MemoryManager::alloc_at(address, get_blocks_from_size(len, ARCH_PAGE_SIZE), mmu_flags);
}
@ -71,9 +69,7 @@ Result<u64> sys_munmap(Registers*, SyscallArgs args)
// POSIX says munmap should silently do nothing if the memory was not already mapped.
if (!ok) return 0;
#ifdef MMAP_DEBUG
kdbgln("munmap: unmapping memory at %#lx, size=%zu", address, size);
#endif
TRY(MemoryManager::unmap_owned(address, get_blocks_from_size(size, ARCH_PAGE_SIZE)));

View File

@ -17,6 +17,8 @@ Result<u64> sys_open(Registers*, SyscallArgs args)
Thread* current = Scheduler::current();
kinfoln("open: trying to open file %s, flags %d", path.chars(), flags);
SharedPtr<VFS::Inode> inode;
// Caller did not pass either O_RDONLY, O_WRONLY or O_RDWR
@ -52,7 +54,7 @@ Result<u64> sys_open(Registers*, SyscallArgs args)
current->fd_table[fd] = FileDescriptor { inode, 0, flags & FLAGS_TO_KEEP };
kinfoln("open: opening file %s, flags %d, mode %#o = fd %d", path.chars(), flags, mode, fd);
kinfoln("open: allocated file descriptor %d for inode %zu", fd, inode->inode_number());
return (u64)fd;
}
@ -68,6 +70,8 @@ Result<u64> sys_close(Registers*, SyscallArgs args)
if (!descriptor.has_value()) return err(EBADF);
kinfoln("close: closing file descriptor %d (was referencing inode %zu)", fd, descriptor->inode->inode_number());
descriptor = {};
return 0;

View File

@ -157,11 +157,15 @@ namespace Scheduler
if (thread->is_kernel)
{
auto stack = thread->stack;
// FIXME: Propagate errors I guess?
kinfoln("deleting stack @ %#lx", stack.bottom());
MemoryManager::unmap_owned_and_free_vm(stack.bottom(), stack.bytes() / ARCH_PAGE_SIZE).release_value();
}
else
{
auto stack = thread->kernel_stack;
kinfoln("deleting kstack @ %#lx", stack.bottom());
// FIXME: Propagate errors I guess?
MemoryManager::unmap_owned_and_free_vm(stack.bottom(), stack.bytes() / ARCH_PAGE_SIZE).release_value();
}

View File

@ -84,12 +84,7 @@ extern "C"
case 'B':
if (!try_put_string(state, mon_names[tm->tm_mon])) return 0;
break;
case 'c':
if (!try_format(state, "%s %s %.2d %.2d:%.2d:%.2d %d", abday_names[tm->tm_wday],
abmon_names[tm->tm_mon], tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec,
tm->tm_year + 1900))
return 0;
break;
case 'c': todo();
case 'd':
if (!try_format(state, "%.2d", tm->tm_mday)) return 0;
break;
@ -122,13 +117,8 @@ extern "C"
case 'S':
if (!try_format(state, "%.2d", tm->tm_sec)) return 0;
break;
case 'x':
// Sorry, Americans, but I ain't doing m/d/y.
if (!try_format(state, "%.2d/%.2d/%.2d", tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900)) return 0;
break;
case 'X':
if (!try_format(state, "%.2d:%.2d:%.2d", tm->tm_hour, tm->tm_min, tm->tm_sec)) return 0;
break;
case 'x': todo();
case 'X': todo();
case 'y':
if (!try_format(state, "%.2d", (tm->tm_year + 1900) % 100)) return 0;
break;