aboutsummaryrefslogtreecommitdiff
path: root/src/page
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi92@disroot.org>2025-07-07 13:22:53 +0200
committerXavier Del Campo Romero <xavi92@disroot.org>2025-11-11 00:08:15 +0100
commit7861a52adf92a083bb2aed4c35f98d8035dce032 (patch)
tree28cd3c40e4c878f730f5df3c1d93bdf91af490c3 /src/page
parent7fc48e9216ff809da5f8055a50b0be17628ef1df (diff)
downloadwnix-7861a52adf92a083bb2aed4c35f98d8035dce032.tar.gz
Setup project skeleton
Diffstat (limited to 'src/page')
-rw-r--r--src/page/CMakeLists.txt20
-rw-r--r--src/page/include/page.h31
-rw-r--r--src/page/private_include/page/mem.h27
-rw-r--r--src/page/private_include/page/mem/ops.h30
-rw-r--r--src/page/private_include/page/mem/types.h27
-rw-r--r--src/page/private_include/page/routines.h29
-rw-r--r--src/page/private_include/page/types.h42
-rw-r--r--src/page/src/CMakeLists.txt26
-rw-r--r--src/page/src/add.c39
-rw-r--r--src/page/src/free.c35
-rw-r--r--src/page/src/from_addr.c30
-rw-r--r--src/page/src/mem/CMakeLists.txt23
-rw-r--r--src/page/src/mem/alloc.c50
-rw-r--r--src/page/src/mem/free.c31
-rw-r--r--src/page/src/mem/ops.c27
-rw-r--r--src/page/src/mem/read.c34
-rw-r--r--src/page/src/mem/write.c34
-rw-r--r--src/page/src/read.c37
-rw-r--r--src/page/src/shrink.c36
-rw-r--r--src/page/src/write.c38
20 files changed, 646 insertions, 0 deletions
diff --git a/src/page/CMakeLists.txt b/src/page/CMakeLists.txt
new file mode 100644
index 0000000..2aa2d4c
--- /dev/null
+++ b/src/page/CMakeLists.txt
@@ -0,0 +1,20 @@
+# wnix, a Unix-like operating system for WebAssembly applications.
+# Copyright (C) 2025 Xavier Del Campo Romero
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+add_library(page)
+add_subdirectory(src)
+target_include_directories(page PUBLIC include PRIVATE private_include)
+target_link_libraries(page PRIVATE kprintf)
diff --git a/src/page/include/page.h b/src/page/include/page.h
new file mode 100644
index 0000000..d5af4be
--- /dev/null
+++ b/src/page/include/page.h
@@ -0,0 +1,31 @@
+/*
+ * wnix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef PAGE_H
+#define PAGE_H
+
+#include <stddef.h>
+
+struct page;
+
+int page_read(struct page **head, unsigned long addr, void *buf, size_t n);
+int page_write(struct page **head, unsigned long addr, const void *buf,
+ size_t n);
+int page_shrink(struct page **head, unsigned long addr);
+
+#endif
diff --git a/src/page/private_include/page/mem.h b/src/page/private_include/page/mem.h
new file mode 100644
index 0000000..abb2c6d
--- /dev/null
+++ b/src/page/private_include/page/mem.h
@@ -0,0 +1,27 @@
+/*
+ * wnix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef PAGE_MEM_H
+#define PAGE_MEM_H
+
+#include <page/types.h>
+#include <stddef.h>
+
+struct page *page_mem_alloc(unsigned long addr);
+
+#endif
diff --git a/src/page/private_include/page/mem/ops.h b/src/page/private_include/page/mem/ops.h
new file mode 100644
index 0000000..5e50256
--- /dev/null
+++ b/src/page/private_include/page/mem/ops.h
@@ -0,0 +1,30 @@
+/*
+ * wnix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef PAGE_MEM_OPS_H
+#define PAGE_MEM_OPS_H
+
+#include <page/types.h>
+
+int page_mem_read(struct page *p, void *buf, size_t n, unsigned long addr);
+int page_mem_write(struct page *p, const void *buf, size_t n, unsigned long addr);
+void page_mem_free(struct page *p);
+
+extern const struct page_ops page_mem_ops;
+
+#endif
diff --git a/src/page/private_include/page/mem/types.h b/src/page/private_include/page/mem/types.h
new file mode 100644
index 0000000..fe0fc74
--- /dev/null
+++ b/src/page/private_include/page/mem/types.h
@@ -0,0 +1,27 @@
+/*
+ * wnix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef PAGE_MEM_TYPES_H
+#define PAGE_MEM_TYPES_H
+
+struct page_prv
+{
+ char buf[256];
+};
+
+#endif
diff --git a/src/page/private_include/page/routines.h b/src/page/private_include/page/routines.h
new file mode 100644
index 0000000..359ca6b
--- /dev/null
+++ b/src/page/private_include/page/routines.h
@@ -0,0 +1,29 @@
+/*
+ * wnix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef PAGE_ROUTINES_H
+#define PAGE_ROUTINES_H
+
+#include <page.h>
+
+void page_free(struct page *p);
+struct page *page_from_addr(struct page *head, unsigned long addr);
+int page_add(struct page *p, unsigned long addr,
+ struct page *(*alloc)(unsigned long));
+
+#endif
diff --git a/src/page/private_include/page/types.h b/src/page/private_include/page/types.h
new file mode 100644
index 0000000..ae1ff99
--- /dev/null
+++ b/src/page/private_include/page/types.h
@@ -0,0 +1,42 @@
+/*
+ * wnix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef PAGE_TYPES_H
+#define PAGE_TYPES_H
+
+#include <stddef.h>
+
+struct page;
+
+struct page_ops
+{
+ int (*read)(struct page *p, void *buf, size_t n, unsigned long addr);
+ int (*write)(struct page *p, const void *buf, size_t n, unsigned long addr);
+ void (*free)(struct page *p);
+};
+
+struct page
+{
+ const struct page_ops *ops;
+ unsigned long addr;
+ size_t sz;
+ struct page_prv *prv;
+ struct page *prev, *next;
+};
+
+#endif
diff --git a/src/page/src/CMakeLists.txt b/src/page/src/CMakeLists.txt
new file mode 100644
index 0000000..9f771b4
--- /dev/null
+++ b/src/page/src/CMakeLists.txt
@@ -0,0 +1,26 @@
+# wnix, a Unix-like operating system for WebAssembly applications.
+# Copyright (C) 2025 Xavier Del Campo Romero
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+target_sources(page PRIVATE
+ add.c
+ free.c
+ from_addr.c
+ read.c
+ shrink.c
+ write.c
+)
+
+add_subdirectory(mem)
diff --git a/src/page/src/add.c b/src/page/src/add.c
new file mode 100644
index 0000000..5ac3c37
--- /dev/null
+++ b/src/page/src/add.c
@@ -0,0 +1,39 @@
+/*
+ * wnix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <page/routines.h>
+#include <page/types.h>
+
+int page_add(struct page *const p, const unsigned long addr,
+ struct page *(*const alloc)(unsigned long))
+{
+ struct page *const np = alloc(addr);
+
+ if (!np)
+ return -1;
+
+ if (p->next)
+ {
+ p->next->prev = np;
+ np->next = p->next;
+ }
+
+ p->next = np;
+ np->prev = p;
+ return 0;
+}
diff --git a/src/page/src/free.c b/src/page/src/free.c
new file mode 100644
index 0000000..f9b72fb
--- /dev/null
+++ b/src/page/src/free.c
@@ -0,0 +1,35 @@
+/*
+ * wnix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <page/routines.h>
+#include <page/types.h>
+#include <stdlib.h>
+
+void page_free(struct page *const p)
+{
+ if (!p)
+ return;
+ else if (p->next)
+ p->next->prev = p->prev;
+
+ if (p->prev)
+ p->prev->next = p->next;
+
+ p->ops->free(p);
+ free(p);
+}
diff --git a/src/page/src/from_addr.c b/src/page/src/from_addr.c
new file mode 100644
index 0000000..8727db6
--- /dev/null
+++ b/src/page/src/from_addr.c
@@ -0,0 +1,30 @@
+/*
+ * wnix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <page/routines.h>
+#include <page/types.h>
+#include <stddef.h>
+
+struct page *page_from_addr(struct page *const head, const unsigned long addr)
+{
+ for (struct page *p = head; p; p = p->next)
+ if (addr >= p->addr && addr < p->addr + p->sz)
+ return p;
+
+ return NULL;
+}
diff --git a/src/page/src/mem/CMakeLists.txt b/src/page/src/mem/CMakeLists.txt
new file mode 100644
index 0000000..ea430c3
--- /dev/null
+++ b/src/page/src/mem/CMakeLists.txt
@@ -0,0 +1,23 @@
+# wnix, a Unix-like operating system for WebAssembly applications.
+# Copyright (C) 2025 Xavier Del Campo Romero
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+target_sources(page PRIVATE
+ alloc.c
+ free.c
+ ops.c
+ read.c
+ write.c
+)
diff --git a/src/page/src/mem/alloc.c b/src/page/src/mem/alloc.c
new file mode 100644
index 0000000..be9f43d
--- /dev/null
+++ b/src/page/src/mem/alloc.c
@@ -0,0 +1,50 @@
+/*
+ * wnix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <page/mem.h>
+#include <page/mem/ops.h>
+#include <page/mem/types.h>
+#include <page/types.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+struct page *page_mem_alloc(const unsigned long addr)
+{
+ struct page *const ret = malloc(sizeof *ret);
+ struct page_prv *const prv = malloc(sizeof *prv);
+ const unsigned long start = addr - (addr % sizeof prv->buf);
+
+ if (!ret || !prv)
+ goto failure;
+
+ *prv = (const struct page_prv){0};
+ *ret = (const struct page)
+ {
+ .sz = sizeof prv->buf,
+ .ops = &page_mem_ops,
+ .addr = start,
+ .prv = prv
+ };
+
+ return ret;
+
+failure:
+ free(prv);
+ free(ret);
+ return NULL;
+}
diff --git a/src/page/src/mem/free.c b/src/page/src/mem/free.c
new file mode 100644
index 0000000..6834288
--- /dev/null
+++ b/src/page/src/mem/free.c
@@ -0,0 +1,31 @@
+/*
+ * wnix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <page/types.h>
+#include <page/mem/ops.h>
+#include <page/mem/types.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+void page_mem_free(struct page *const p)
+{
+ if (!p->prv)
+ return;
+
+ free(p->prv);
+}
diff --git a/src/page/src/mem/ops.c b/src/page/src/mem/ops.c
new file mode 100644
index 0000000..843b82a
--- /dev/null
+++ b/src/page/src/mem/ops.c
@@ -0,0 +1,27 @@
+/*
+ * wnix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <page/mem/ops.h>
+#include <page/types.h>
+
+const struct page_ops page_mem_ops =
+{
+ .read = page_mem_read,
+ .write = page_mem_write,
+ .free = page_mem_free
+};
diff --git a/src/page/src/mem/read.c b/src/page/src/mem/read.c
new file mode 100644
index 0000000..67d5594
--- /dev/null
+++ b/src/page/src/mem/read.c
@@ -0,0 +1,34 @@
+/*
+ * wnix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <page/types.h>
+#include <page/mem/ops.h>
+#include <page/mem/types.h>
+#include <stddef.h>
+#include <string.h>
+
+int page_mem_read(struct page *const p, void *const buf, const size_t n,
+ const unsigned long addr)
+{
+ const unsigned long offset = addr - p->addr;
+ const char *const src = &p->prv->buf[offset];
+ const size_t rem = p->sz - offset, w = rem < n ? rem : n;
+
+ memcpy(buf, src, w);
+ return w;
+}
diff --git a/src/page/src/mem/write.c b/src/page/src/mem/write.c
new file mode 100644
index 0000000..7cf8f40
--- /dev/null
+++ b/src/page/src/mem/write.c
@@ -0,0 +1,34 @@
+/*
+ * wnix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <page/types.h>
+#include <page/mem/ops.h>
+#include <page/mem/types.h>
+#include <stddef.h>
+#include <string.h>
+
+int page_mem_write(struct page *const p, const void *const buf, const size_t n,
+ const unsigned long addr)
+{
+ const unsigned long offset = addr - p->addr;
+ char *const dst = &p->prv->buf[offset];
+ const size_t rem = p->sz - offset, w = rem < n ? rem : n;
+
+ memcpy(dst, buf, w);
+ return w;
+}
diff --git a/src/page/src/read.c b/src/page/src/read.c
new file mode 100644
index 0000000..9c50711
--- /dev/null
+++ b/src/page/src/read.c
@@ -0,0 +1,37 @@
+/*
+ * wnix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <page.h>
+#include <page/routines.h>
+#include <page/types.h>
+#include <page/mem.h>
+
+int page_read(struct page **const head, const unsigned long addr,
+ void *const buf, const size_t n)
+{
+ if (!*head)
+ return (*head = page_mem_alloc(addr)) ? 0 : -1;
+
+ struct page *const p = page_from_addr(*head, addr);
+
+ if (!p)
+ /* TODO: decide best strategy (fs, mem, etc.) */
+ return page_add(*head, addr, page_mem_alloc);
+
+ return p->ops->read(p, buf, n, addr);
+}
diff --git a/src/page/src/shrink.c b/src/page/src/shrink.c
new file mode 100644
index 0000000..53873f6
--- /dev/null
+++ b/src/page/src/shrink.c
@@ -0,0 +1,36 @@
+/*
+ * wnix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <page.h>
+#include <page/routines.h>
+#include <page/types.h>
+
+int page_shrink(struct page **const head, const unsigned long addr)
+{
+ for (struct page *p = *head; p;)
+ {
+ struct page *const next = p->next;
+
+ if (p->addr > addr)
+ page_free(p);
+
+ p = next;
+ }
+
+ return 0;
+}
diff --git a/src/page/src/write.c b/src/page/src/write.c
new file mode 100644
index 0000000..a28ed2b
--- /dev/null
+++ b/src/page/src/write.c
@@ -0,0 +1,38 @@
+/*
+ * wnix, a Unix-like operating system for WebAssembly applications.
+ * Copyright (C) 2025 Xavier Del Campo Romero
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <page.h>
+#include <page/mem.h>
+#include <page/routines.h>
+#include <page/types.h>
+#include <stddef.h>
+
+int page_write(struct page **const head, const unsigned long addr,
+ const void *const buf, const size_t n)
+{
+ if (!*head)
+ return (*head = page_mem_alloc(addr)) ? 0 : -1;
+
+ struct page *const p = page_from_addr(*head, addr);
+
+ if (!p)
+ /* TODO: decide best strategy (fs, mem, etc.) */
+ return page_add(*head, addr, page_mem_alloc);
+
+ return p->ops->write(p, buf, n, addr);
+}