This commit is contained in:
2026-10-06 01:34:24 +02:00
parent 134343d2a8
commit f8eb4f4e54
28 changed files with 166 additions and 36 deletions
+1 -1
View File
@@ -2,8 +2,8 @@
#include <zinnia/cmdline.h>
#include <zinnia/init.h>
#include <zinnia/print.h>
#include <zinnia/utils.h>
#include <zinnia/string.h>
#include <zinnia/utils.h>
#include "limine.h"
[[__initdata_sorted("limine.0")]]
+3
View File
@@ -0,0 +1,3 @@
#include <zinnia/dpc.h>
// TODO
+1 -2
View File
@@ -1,5 +1,4 @@
// Compiler runtime support like libgcc or compiler-rt.
// Extend as required.
// Compiler runtime support.
#include <stdint.h>
+1 -1
View File
@@ -2,9 +2,9 @@
#include <zinnia/errno.h>
#include <zinnia/pmap.h>
#include <zinnia/spin.h>
#include <zinnia/string.h>
#include <zinnia/vma.h>
#include <config.h>
#include <zinnia/string.h>
// TODO: For now, we assume that we can do generic PTE lookups on every arch that has a MMU.
static_assert(CONFIG_HAVE_MMU_GENERIC);
+1 -1
View File
@@ -3,9 +3,9 @@
#include <zinnia/panic.h>
#include <zinnia/print.h>
#include <zinnia/spin.h>
#include <zinnia/string.h>
#include <zinnia/virt.h>
#include <stdint.h>
#include <zinnia/string.h>
uintptr_t mem_hhdm_base = 0;
+3 -4
View File
@@ -60,7 +60,7 @@ static struct vma_mapping* find_mapping(struct vma* v, size_t page) {
return nullptr;
}
static bool access_allowed(enum prot_flags prot, const struct vma_fault_info* info) {
static bool can_access(enum prot_flags prot, const struct vma_fault_info* info) {
if (info->caused_by_write)
return prot & PROT_WRITE;
if (info->caused_by_fetch)
@@ -87,7 +87,7 @@ bool vma_page_fault(struct vma* v, const struct vma_fault_info* info) {
spin_lock(&v->lock);
struct vma_mapping* mapping = find_mapping(v, faulty_page);
if (!mapping || !access_allowed(mapping->prot, info)) {
if (!mapping || !can_access(mapping->prot, info)) {
spin_unlock(&v->lock);
return false;
}
@@ -107,8 +107,7 @@ bool vma_page_fault(struct vma* v, const struct vma_fault_info* info) {
spin_lock(&v->lock);
mapping = find_mapping(v, faulty_page);
const bool still_valid = mapping && mapping->object == object &&
(faulty_page - mapping->start_page) + mapping->offset_page == object_page &&
access_allowed(mapping->prot, info);
(faulty_page - mapping->start_page) + mapping->offset_page == object_page && can_access(mapping->prot, info);
if (still_valid) {
errno_t status =
+20 -1
View File
@@ -1,9 +1,9 @@
#include <zinnia/alloc.h>
#include <zinnia/errno.h>
#include <zinnia/list.h>
#include <zinnia/string.h>
#include <zinnia/utils.h>
#include <zinnia/vmo.h>
#include <zinnia/string.h>
void vmo_ref(struct vmo* obj) {
refcount_inc(&obj->rc);
@@ -211,6 +211,25 @@ errno_t vmo_new_phys(struct paged_vmo** out) {
return vmo_new_paged(phys_pager, out);
}
void vmo_truncate_paged(struct paged_vmo* paged, size_t length) {
const size_t page_size = arch_mem_page_size();
const size_t keep_pages = ROUND_UP(length, page_size) / page_size;
spin_lock(&paged->lock);
struct page_list** pp = &list_first(&paged->cache);
while (*pp) {
struct page_list* entry = *pp;
if (entry->offset >= keep_pages) {
*pp = list_next(entry, next);
paged->source.put_page(&paged->source, entry->offset, entry->value);
mem_free(entry);
} else {
pp = &list_next(entry, next);
}
}
spin_unlock(&paged->lock);
}
struct phys_range_vmo {
struct vmo object;
uintptr_t start;
-1
View File
@@ -1,7 +1,6 @@
kernel_sources += files(
'clock.c',
'console.c',
'elf.c',
'irq.c',
'module.c',
'panic.c',
+3
View File
@@ -29,6 +29,9 @@ struct percpu* percpu_new() {
const size_t size = __ld_percpu_end - __ld_percpu_start;
const size_t num_pages = ALIGN_UP(size, arch_mem_page_size()) / arch_mem_page_size();
// TODO: Map pages past the end of the kernel.
// TODO: Document how allocations work.
phys_t mem;
if (mem_phys_alloc(num_pages, 0, &mem))
return nullptr;
+5
View File
@@ -1,6 +1,11 @@
#include <zinnia/spin.h>
#include <stdatomic.h>
void spin_init(struct spinlock* spin) {
spin->next = 0;
spin->owner = 0;
}
void spin_lock(struct spinlock* spin) {
uint32_t my = atomic_fetch_add_explicit(&spin->next, 1, memory_order_relaxed);
+1 -4
View File
@@ -1,12 +1,9 @@
subdir('common')
subdir('block')
subdir('dt')
if kconfig.get('CONFIG_ACPI', 'n') == 'y'
subdir('acpi')
endif
if kconfig.get('CONFIG_DT', 'n') == 'y'
subdir('dt')
endif
module_lds = meson.current_source_dir() / 'module.ld'
+1
View File
@@ -9,6 +9,7 @@
#include <zinnia/sched.h>
#include <zinnia/string.h>
#include <zinnia/utils.h>
#include <zinnia/vfs.h>
#include <zinnia/vma.h>
#include <zinnia/vmo.h>
#include <bits/elf.h>
+3
View File
@@ -0,0 +1,3 @@
kernel_sources += files(
'elf.c',
)
+1 -1
View File
@@ -1 +1 @@
subdir('tmpfs')
subdir('exec')
-1
View File
@@ -1 +0,0 @@
kernel_sources += files('tmpfs.c')
-1
View File
@@ -1 +0,0 @@
// TODO
+7
View File
@@ -0,0 +1,7 @@
#include <zinnia/ident.h>
static const struct ident kernel_identity = {0};
const struct ident* ident_kernel() {
return &kernel_identity;
}
+3
View File
@@ -0,0 +1,3 @@
kernel_sources += files(
'ident.c',
)
+2 -2
View File
@@ -17,12 +17,12 @@ struct __timeval {
__suseconds_t tv_usec;
};
struct itimerval {
struct __itimerval {
struct __timeval it_interval;
struct __timeval it_value;
};
struct itimerspec {
struct __itimerspec {
struct __timespec it_interval;
struct __timespec it_value;
};
+4 -1
View File
@@ -26,7 +26,10 @@ struct phys_mem {
// Base address of the HHDM.
extern uintptr_t mem_hhdm_base;
#define HHDM_PTR(paddr) (void*)(mem_hhdm_base + (paddr))
static inline void* HHDM_PTR(phys_t paddr) {
return (void*)(mem_hhdm_base + paddr);
}
// Allocates a region of memory which can be smaller than the page size.
// Returns `nullptr` if the allocator cannot provide an allocation for the given `length` + `flags`.
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include <zinnia/list.h>
#include <zinnia/percpu.h>
#include <stdatomic.h>
struct dpc {
void (*const callback)(struct dpc* dpc, void* data);
void* data;
atomic_bool inserted;
list_link(struct dpc*) link;
};
void dpc_dispatch();
struct dpc_percpu {};
extern struct dpc_percpu dpc_percpu_data;
+1 -11
View File
@@ -1,6 +1,7 @@
#pragma once
#include <zinnia/errno.h>
#include <zinnia/vfs.h>
#include <bits/elf.h>
#include <stdint.h>
@@ -341,15 +342,4 @@ static inline uint32_t ELF64_R_TYPE(uint64_t info) {
return info & 0xFFFFFFFF;
}
struct vma;
struct vmo;
struct task;
struct exec_info {
struct vma* space;
struct vmo* file_obj;
const char** argv;
const char** envp;
};
errno_t elf_load(struct exec_info* info, struct task** out);
+45
View File
@@ -0,0 +1,45 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
struct fdt_header {
uint32_t magic;
uint32_t total_size;
uint32_t structs_offset;
uint32_t strings_offset;
uint32_t reserved_offset;
uint32_t version;
uint32_t compat_version;
uint32_t boot_cpuid;
uint32_t strings_size;
uint32_t structs_size;
};
constexpr uint32_t FDT_BEGIN_NODE = 0x00000001;
constexpr uint32_t FDT_END_NODE = 0x00000002;
constexpr uint32_t FDT_PROP = 0x00000003;
constexpr uint32_t FDT_NOP = 0x00000004;
constexpr uint32_t FDT_END = 0x00000009;
struct fdt {
uint32_t version;
uint32_t compat_version;
uint32_t boot_cpuid;
const uint8_t* structs;
size_t structs_len;
const uint8_t* strings;
size_t strings_len;
};
struct fdt_node {
struct fdt* tree;
};
struct fdt_prop {
struct fdt* tree;
};
// Root of the device tree.
struct fdt_node fdt_root(struct fdt* tree);
+9 -1
View File
@@ -1,5 +1,13 @@
#pragma once
#include <zinnia/types.h>
#include <zinnia/vec.h>
struct ident {
// TODO
uid_t uid, euid, suid;
gid_t gid, egid, sgid;
vec(gid_t) groups;
};
const struct ident* ident_kernel(void);
+26 -1
View File
@@ -1,12 +1,37 @@
#pragma once
#include <zinnia/errno.h>
#include <zinnia/string.h>
#include <zinnia/usercopy.h>
#include <zinnia/utils.h>
#include <stddef.h>
#include <uapi/uio.h>
struct iovec_iter {
struct iovec* iovecs;
struct __iovec* iovecs;
size_t iovecs_len;
size_t total_len;
size_t total_offset;
size_t current_idx;
size_t current_offset;
};
static inline size_t iovec_iter_len(struct iovec_iter* iter) {
return iter->total_len - iter->total_offset;
}
// Creates an iovec iterator over kernel memory.
static inline struct iovec_iter iovec_iter_kernel(struct __iovec* iovecs, size_t count) {
size_t total = 0;
for (size_t i = 0; i < count; i++)
total += iovecs[i].len;
return (struct iovec_iter){
.iovecs = iovecs,
.iovecs_len = count,
.total_len = total,
.total_offset = 0,
.current_idx = 0,
.current_offset = 0,
};
}
+2
View File
@@ -10,6 +10,8 @@ struct spinlock {
_Atomic(uint32_t) next;
};
void spin_init(struct spinlock* spin);
// Attempts to lock a spinlock. If it's already locked, waits until it's freed.
void spin_lock(struct spinlock* spin);
+4 -1
View File
@@ -33,7 +33,7 @@ struct pager_ops {
errno_t (*put_page)(struct pager_ops* pager, uintptr_t offset_idx, struct page* page);
};
// TODO: change to btree
// TODO: change to rbtree
struct page_list {
uintptr_t offset;
struct page* value;
@@ -50,5 +50,8 @@ struct paged_vmo {
errno_t vmo_new_paged(struct pager_ops ops, struct paged_vmo** out);
errno_t vmo_new_phys(struct paged_vmo** out);
// Drops all cached pages past `length` bytes.
void vmo_truncate_paged(struct paged_vmo* paged, size_t length);
// Creates a VMO backed by a specific physical address range (e.g. for MMIO).
errno_t vmo_new_phys_range(uintptr_t addr, size_t length, struct vmo** out);
+1 -1
View File
@@ -13,7 +13,7 @@ static struct __utsname uname_buf = {
.version = CONFIG_KERNEL_FLAVOR,
.nodename = "localhost",
.machine = ZINNIA_ARCH,
.domainname = "none",
.domainname = "(none)",
};
struct syscall_ret sys_setuname(const __user struct __utsname* ptr) {