summaryrefslogtreecommitdiff
path: root/src/kernel/proc
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/proc')
-rw-r--r--src/kernel/proc/exec.cc260
-rw-r--r--src/kernel/proc/proc.cc654
-rw-r--r--src/kernel/proc/swtch.S37
3 files changed, 0 insertions, 951 deletions
diff --git a/src/kernel/proc/exec.cc b/src/kernel/proc/exec.cc
deleted file mode 100644
index 8d8c467..0000000
--- a/src/kernel/proc/exec.cc
+++ /dev/null
@@ -1,260 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (C) 2026 Richard QIn
- */
-#include "common/types.h"
-#include "kernel/riscv.h"
-#include "kernel/proc.h"
-#include "kernel/mm.h"
-#include "kernel/elf.h"
-#include "fs/fs.h"
-#include "lib/string.h"
-#include "drivers/uart.h"
-#include "kernel/trap.h"
-
-extern char trampoline[];
-
-// RAII: Page Table Resource Management
-class VmGuard
-{
-public:
- uint64 *pagetable = nullptr;
- uint64 sz = 0;
-
- VmGuard() : pagetable(VM::uvmcreate()) {}
-
- ~VmGuard()
- {
- if (pagetable)
- {
- VM::uvmfree(pagetable, sz);
- }
- }
-
- // Copying is prohibited
- VmGuard(const VmGuard &) = delete;
- VmGuard &operator=(const VmGuard &) = delete;
-
- // Submit resources: Ownership transfer, destructor no longer releases
- uint64 *commit()
- {
- uint64 *pt = pagetable;
- pagetable = nullptr;
- return pt;
- }
-};
-
-// RAII: Inode Lock Management
-class InodeGuard
-{
-public:
- Inode *ip;
- InodeGuard(Inode *i) : ip(i)
- {
- if (ip)
- VFS::ilock(ip);
- }
- ~InodeGuard()
- {
- if (ip)
- {
- VFS::iunlockput(ip); // Automatically unlock and release references
- }
- }
- // Copying is prohibited
- InodeGuard(const InodeGuard &) = delete;
- InodeGuard &operator=(const InodeGuard &) = delete;
-};
-
-// laod segment
-static int loadseg(uint64 *pagetable, uint64 va, Inode *ip, uint64 offset, uint64 sz)
-{
- for (uint64 i = 0; i < sz; i += PGSIZE)
- {
- uint64 pa = VM::walkaddr(pagetable, va + i);
- if (pa == 0)
- {
- Drivers::uart_puts("[Exec Debug] loadseg: walkaddr failed\n");
- return -1;
- }
-
- uint64 n = PGSIZE - (va + i) % PGSIZE;
- if (i + n > sz)
- n = sz - i;
-
- // Read physical address (isUser=0)
- if (ip->read((char *)(pa + (va + i) % PGSIZE), offset + i, n, 0) != (int)n)
- {
- Drivers::uart_puts("[Exec Debug] loadseg: read failed\n");
- return -1;
- }
- }
- return 0;
-}
-
-namespace Exec
-{
- int exec(char *path, char **argv)
- {
- // 1. Get Inode
- Inode *raw_ip = VFS::namei(path);
- if (!raw_ip)
- {
- Drivers::uart_puts("[Exec Debug] namei failed for path: ");
- Drivers::uart_puts(path);
- Drivers::uart_puts("\n");
- return -1;
- }
- InodeGuard iguard(raw_ip);
-
- // Get ELF head
- struct elfhdr elf;
- if (raw_ip->read((char *)&elf, 0, sizeof(elf), 0) != sizeof(elf))
- {
- Drivers::uart_puts("[Exec Debug] read elf header failed\n");
- return -1;
- }
- if (elf.magic != ELF_MAGIC)
- {
- Drivers::uart_puts("[Exec Debug] invalid elf magic\n");
- return -1;
- }
-
- // Create new pagetable
- VmGuard vm_guard;
- if (!vm_guard.pagetable)
- {
- Drivers::uart_puts("[Exec Debug] uvmcreate failed\n");
- return -1;
- }
-
- // Load Program Segment
- struct proghdr ph;
- for (int i = 0; i < elf.phnum; i++)
- {
- uint64 off = elf.phoff + i * sizeof(ph);
- if (raw_ip->read((char *)&ph, off, sizeof(ph), 0) != sizeof(ph))
- {
- Drivers::uart_puts("[Exec Debug] read proghdr failed\n");
- return -1;
- }
-
- if (ph.type != ELF_PROG_LOAD)
- continue;
- if (ph.memsz < ph.filesz)
- return -1;
- if (ph.vaddr + ph.memsz < ph.vaddr)
- return -1;
-
- uint64 sz1 = VM::uvmalloc(vm_guard.pagetable, vm_guard.sz, ph.vaddr + ph.memsz, PTE_W | PTE_X | PTE_R | PTE_U);
- if (sz1 == 0)
- {
- Drivers::uart_puts("[Exec Debug] uvmalloc failed (segment)\n");
- return -1;
- }
- vm_guard.sz = sz1;
-
- if (loadseg(vm_guard.pagetable, ph.vaddr, raw_ip, ph.off, ph.filesz) < 0)
- return -1;
- }
-
- // Prepare user stack
- uint64 sz = PGROUNDUP(vm_guard.sz);
-
- const int stack_data_pages = 16;
- const int stack_total_pages = stack_data_pages + 1;
-
- uint64 sz1 = VM::uvmalloc(vm_guard.pagetable, sz, sz + stack_total_pages * PGSIZE, PTE_W | PTE_R | PTE_U);
- if (sz1 == 0)
- {
- Drivers::uart_puts("[Exec Debug] uvmalloc failed (stack)\n");
- return -1;
- }
- vm_guard.sz = sz1;
-
- VM::uvmunmap(vm_guard.pagetable, sz, 1, 0);
-
- uint64 sp = sz1;
- uint64 stackbase = sp - stack_data_pages * PGSIZE;
- uint64 ustack[32];
- uint64 argc = 0;
-
- // Push parameter string
- for (; argv[argc]; argc++)
- {
- if (argc >= 31)
- return -1;
- sp -= strlen(argv[argc]) + 1;
- sp -= sp % 16;
- if (sp < stackbase)
- {
- Drivers::uart_puts("[Exec Debug] stack overflow (args)\n");
- return -1;
- }
-
- if (VM::copyout(vm_guard.pagetable, sp, argv[argc], strlen(argv[argc]) + 1) < 0)
- {
- Drivers::uart_puts("[Exec Debug] copyout arg string failed\n");
- return -1;
- }
- ustack[argc] = sp;
- }
- ustack[argc] = 0;
-
- // Push into parameter array
- sp -= (argc + 1) * sizeof(uint64);
- sp -= sp % 16;
- if (sp < stackbase)
- {
- Drivers::uart_puts("[Exec Debug] stack overflow (argv array)\n");
- return -1;
- }
- if (VM::copyout(vm_guard.pagetable, sp, (char *)ustack, (argc + 1) * sizeof(uint64)) < 0)
- {
- Drivers::uart_puts("[Exec Debug] copyout argv array failed\n");
- return -1;
- }
-
- // Commit Changes
- struct Proc *p = myproc();
- if (VM::mappages(vm_guard.pagetable, TRAPFRAME, PGSIZE, (uint64)p->tf, PTE_R | PTE_W) < 0)
- {
- Drivers::uart_puts("[Exec Debug] mappages TRAPFRAME failed\n");
- return -1;
- }
-
- uint64 oldsz = p->sz;
- uint64 *oldpagetable = p->pagetable;
-
- p->tf->a0 = argc;
- p->tf->a1 = sp;
- p->tf->sp = sp;
- p->tf->epc = elf.entry;
-
- char *s = path, *last = path;
- while (*s)
- {
- if (*s == '/')
- last = s + 1;
- s++;
- }
-
- size_t len = 0;
- while (last[len] && len < sizeof(p->name) - 1)
- {
- p->name[len] = last[len];
- len++;
- }
- p->name[len] = '\0';
-
- // change pagetable
- p->pagetable = vm_guard.commit();
- p->sz = vm_guard.sz;
-
- // release old pagetable
- VM::uvmfree(oldpagetable, oldsz);
- asm volatile("fence.i");
-
- return 0; // iguard unlocks and releases IP upon destruction
- }
-} \ No newline at end of file
diff --git a/src/kernel/proc/proc.cc b/src/kernel/proc/proc.cc
deleted file mode 100644
index 3923fe8..0000000
--- a/src/kernel/proc/proc.cc
+++ /dev/null
@@ -1,654 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (C) 2026 Richard QIn
- */
-#include "kernel/proc.h"
-#include "kernel/proc_def.h"
-#include "kernel/runqueue.h"
-#include "kernel/cpu.h"
-#include "kernel/spinlock.h"
-#include "kernel/pmm.h"
-#include "kernel/mm.h"
-#include "kernel/trap.h"
-#include "kernel/riscv.h"
-#include "kernel/slab.h"
-#include "drivers/uart.h"
-#include "fs/fs.h"
-#include "fs/file.h"
-#include "lib/string.h"
-
-// #define NPROC 64
-#define NCPU 8
-
-extern "C" void swtch(struct Context *old_ctx, struct Context *new_ctx);
-extern char uservec[], trampoline[];
-extern "C" void usertrap();
-extern "C" void userret(uint64, uint64);
-extern char initcode_start[], initcode_end[];
-
-// struct Proc procs[NPROC];
-struct Proc *proc_list_head = nullptr;
-struct Proc *initproc = nullptr;
-struct Spinlock proc_mem_lock;
-struct cpu cpus[NCPU];
-struct RunQueue runqueues[NCPU];
-
-
-static int nextpid = 1;
-
-
-struct cpu *mycpu()
-{
- int id = r_tp();
- return &cpus[id];
-}
-
-
-void RunQueue::init(const char *name)
-{
- lock.init(name);
- count = 0;
- for (int i = 0; i < N_PRIO; i++)
- {
- heads[i] = nullptr;
- tails[i] = nullptr;
- }
-}
-
-void RunQueue::enqueue(struct Proc *p)
-{
- if (p->priority < 0 || p->priority >= N_PRIO)
- p->priority = PRIO_MIN;
- p->next = nullptr;
- if (heads[p->priority] == nullptr)
- {
- heads[p->priority] = p;
- tails[p->priority] = p;
- }
- else
- {
- tails[p->priority]->next = p;
- tails[p->priority] = p;
- }
- count++;
-}
-
-struct Proc *RunQueue::dequeue()
-{
- for (int i = 0; i < N_PRIO; i++)
- {
- if (heads[i])
- {
- struct Proc *p = heads[i];
- heads[i] = p->next;
- if (!heads[i])
- tails[i] = nullptr;
- p->next = nullptr;
- count--;
- return p;
- }
- }
- return nullptr;
-}
-
-struct Proc *RunQueue::steal()
-{
- for (int i = N_PRIO - 1; i >= 0; i--)
- {
- if (heads[i])
- {
- struct Proc *p = heads[i];
- heads[i] = p->next;
- if (!heads[i])
- tails[i] = nullptr;
- p->next = nullptr;
- count--;
- return p;
- }
- }
- return nullptr;
-}
-
-// Trap Return Functions
-
-void usertrapret()
-{
- struct Proc *p = myproc();
-
- intr_off();
-
- // Set stvec to point to uservec in the trampoline
- // When an interrupt occurs in user mode, the CPU will jump here
- uint64 trampoline_uservec = TRAMPOLINE + (uservec - trampoline);
- w_stvec(trampoline_uservec);
-
- // Fill in the Trapframe, used when uservec saves the kernel state
- p->tf->kernel_satp = r_satp();
- p->tf->kernel_sp = (uint64)p->kstack + PGSIZE;
- p->tf->kernel_trap = (uint64)usertrap;
- p->tf->kernel_hartid = r_tp();
-
- // Set SSTATUS
- // SPP = 0 (return to User Mode)
- // SPIE = 1 (enable interrupts)
- unsigned long x = r_sstatus();
- x &= ~SSTATUS_SPP;
- x |= SSTATUS_SPIE;
- w_sstatus(x);
-
- // Set SEPC to the user program counter
- w_sepc(p->tf->epc);
-
- // Prepare user page table SATP
- uint64 satp = MAKE_SATP(p->pagetable);
-
- // Calculate the virtual address of userret in the trampoline
- uint64 fn = TRAMPOLINE + ((uint64)userret - (uint64)trampoline);
-
- // Jump to userret, with parameters being the TRAPFRAME address and the user page table SATP
- ((void (*)(uint64, uint64))fn)(TRAPFRAME, satp);
-}
-
-
-void forkret()
-{
-
- struct cpu *c = mycpu();
- c->runqueue->lock.release();
-
- // Debug
- // Drivers::uart_puts("[Proc] forkret: jumping to user.\n");
-
- // Enter user mode
- usertrapret();
-}
-
-// ProcManager Implementation
-
-static Proc *allocproc()
-{
- struct Proc *p;
- proc_mem_lock.acquire();
-
- p = (struct Proc *)Slab::kmalloc(sizeof(struct Proc));
-
- if (!p)
- {
- proc_mem_lock.release();
- return 0;
- }
-
- memset(p, 0, sizeof(struct Proc));
-
- p->all_next = proc_list_head;
- p->all_prev = nullptr;
- if (proc_list_head)
- proc_list_head->all_prev = p;
- proc_list_head = p;
-
-
- p->state = USED;
- p->pid = nextpid++;
- p->priority = 0;
- p->killed = 0;
- p->cpu = mycpu();
- p->cwd = nullptr;
- for (int i = 0; i < NOFILE; i++)
- p->ofile[i] = nullptr;
-
- if ((p->tf = (struct Trapframe *)PMM::alloc_page()) == 0)
- {
- p->state = UNUSED;
- if (p->all_next)
- p->all_next->all_prev = p->all_prev;
- if (p->all_prev)
- p->all_prev->all_next = p->all_next;
- if (p == proc_list_head)
- proc_list_head = p->all_next;
- Slab::kfree(p);
- proc_mem_lock.release();
- return 0;
- }
-
- if ((p->kstack = PMM::alloc_page()) == 0)
- {
- PMM::free_page(p->tf);
- p->state = UNUSED;
- if (p->all_next)
- p->all_next->all_prev = p->all_prev;
- if (p->all_prev)
- p->all_prev->all_next = p->all_next;
- if (p == proc_list_head)
- proc_list_head = p->all_next;
- Slab::kfree(p);
-
- proc_mem_lock.release();
- return 0;
- }
- memset(p->kstack, 0, PGSIZE);
-
- memset(&p->context, 0, sizeof(p->context));
-
- // Set the context so that the next time this process is scheduled, it starts executing directly from forkret
- p->context.ra = (uint64)forkret;
- p->context.sp = (uint64)p->kstack + PGSIZE;
- return p;
-}
-
-static void freeproc(struct Proc *p)
-{
- if (p->tf)
- PMM::free_page(p->tf);
- p->tf = 0;
- if (p->kstack)
- PMM::free_page(p->kstack);
- p->kstack = 0;
- if (p->pagetable)
- VM::uvmfree(p->pagetable, p->sz);
- for (int i = 0; i < NOFILE; i++)
- {
- if (p->ofile[i])
- {
- FileTable::close(p->ofile[i]);
- p->ofile[i] = nullptr;
- }
- }
- if (p->cwd)
- {
- VFS::iput(p->cwd);
- p->cwd = nullptr;
- }
-
- if (p->all_prev)
- p->all_prev->all_next = p->all_next;
- else
- proc_list_head = p->all_next;
-
- if (p->all_next)
- p->all_next->all_prev = p->all_prev;
-
- Slab::kfree(p);
-}
-
-int fork()
-{
- struct Proc *np;
- struct Proc *p = myproc();
-
- if ((np = allocproc()) == 0)
- return -1;
-
- np->pagetable = VM::uvmcreate();
- np->sz = p->sz;
- if (VM::uvmcopy(p->pagetable, np->pagetable, p->sz) < 0)
- {
- freeproc(np);
- proc_mem_lock.release();
- return -1;
- }
-
-
- if (VM::mappages(np->pagetable, TRAPFRAME, PGSIZE, (uint64)np->tf, PTE_R | PTE_W) < 0)
- {
- freeproc(np);
- proc_mem_lock.release();
- return -1;
- }
-
- *(np->tf) = *(p->tf);
- np->tf->a0 = 0;
- strcpy(np->name, p->name);
- np->parent = p;
- np->priority = p->priority;
-
- for (int i = 0; i < NOFILE; i++)
- {
- if (p->ofile[i])
- {
- np->ofile[i] = FileTable::dup(p->ofile[i]);
- }
- }
-
- if (p->cwd)
- {
- np->cwd = VFS::idup(p->cwd);
- }
-
- proc_mem_lock.release();
-
- struct cpu *c = mycpu();
- c->runqueue->lock.acquire();
- np->state = RUNNABLE;
- c->runqueue->enqueue(np);
- c->runqueue->lock.release();
-
- return np->pid;
-}
-
-namespace ProcManager
-{
-
- void init()
- {
- proc_mem_lock.init("proc_mem");
-
- proc_list_head = nullptr;
-
- for (int i = 0; i < NCPU; i++)
- {
- cpus[i].runqueue = &runqueues[i];
- cpus[i].runqueue->init("runqueue");
- }
- }
-
- void scheduler()
- {
- struct Proc *p;
- struct cpu *c = mycpu();
- c->proc = 0;
- Drivers::uart_puts("[Proc] Scheduler started (Per-CPU).\n");
-
- for (;;)
- {
- intr_on();
-
- // Get from the local queue
- c->runqueue->lock.acquire();
- p = c->runqueue->dequeue();
- c->runqueue->lock.release();
-
- // Work Stealing
- if (!p)
- {
- for (int i = 0; i < NCPU; i++)
- {
- if ((uint64)i == r_tp())
- continue;
-
- struct cpu *victim = &cpus[i];
- victim->runqueue->lock.acquire();
- if (victim->runqueue->count > 0)
- p = victim->runqueue->steal();
- victim->runqueue->lock.release();
- if (p)
- break;
- }
- }
-
- if (p)
- {
- p->state = RUNNING;
- c->proc = p;
-
- c->runqueue->lock.acquire();
- swtch(&c->context, &p->context);
- c->runqueue->lock.release();
-
- c->proc = 0;
- }
- }
- }
-
- void yield()
- {
- struct Proc *p = myproc();
- struct cpu *c = mycpu();
- c->runqueue->lock.acquire();
- if (p && p->state == RUNNING)
- {
- p->state = RUNNABLE;
- if (p->priority < PRIO_MIN)
- p->priority++;
- c->runqueue->enqueue(p);
- swtch(&p->context, &c->context);
- }
- c->runqueue->lock.release();
- }
-
- void user_init()
- {
- struct Proc *p = allocproc();
- if (!p)
- return;
-
- initproc = p;
-
- p->pagetable = VM::uvmcreate();
-
- uint64 initcode_sz = initcode_end - initcode_start;
- Drivers::uart_puts("[Proc] initcode size: ");
- Drivers::uart_put_int(initcode_sz);
- Drivers::uart_puts(" bytes\n");
-
- uint64 code_pages = PGROUNDUP(initcode_sz) / PGSIZE;
-
- for (uint64 i = 0; i < code_pages; i++)
- {
- void *mem = PMM::alloc_page();
- if (!mem)
- {
- Drivers::uart_puts("user_init: out of memory for code\n");
- return;
- }
- memset(mem, 0, PGSIZE);
-
- uint64 src_offset = i * PGSIZE;
- uint64 copy_len = PGSIZE;
- if (src_offset + copy_len > initcode_sz)
- {
- copy_len = initcode_sz - src_offset;
- }
- memmove(mem, (void *)(initcode_start + src_offset), copy_len);
-
- if (VM::mappages(p->pagetable, i * PGSIZE, PGSIZE, (uint64)mem, PTE_R | PTE_W | PTE_X | PTE_U) < 0)
- {
- Drivers::uart_puts("user_init: mappages code failed\n");
- return;
- }
- }
-
- uint64 stack_va = (code_pages + 1) * PGSIZE;
-
- void *stack = PMM::alloc_page();
- if (!stack)
- return;
- memset(stack, 0, PGSIZE);
-
- if (VM::mappages(p->pagetable, stack_va, PGSIZE, (uint64)stack, PTE_R | PTE_W | PTE_U) < 0)
- return;
-
- if (VM::mappages(p->pagetable, TRAPFRAME, PGSIZE, (uint64)p->tf, PTE_R | PTE_W) < 0)
- return;
-
- p->tf->epc = 0;
- p->tf->sp = stack_va + PGSIZE;
- p->sz = stack_va + PGSIZE;
- strcpy(p->name, "initcode");
-
- p->cwd = nullptr;
-
- proc_mem_lock.release();
-
- struct cpu *c = &cpus[0];
- c->runqueue->lock.acquire();
- p->state = RUNNABLE;
- c->runqueue->enqueue(p);
- c->runqueue->lock.release();
-
- Drivers::uart_puts("[Proc] user_init success. PID: 1\n");
- asm volatile("fence.i");
- }
-
- void sleep(void *chan, Spinlock *lk)
- {
- struct Proc *p = myproc();
- struct cpu *c = mycpu();
-
- if (lk && lk != &proc_mem_lock)
- lk->release();
-
- c->runqueue->lock.acquire();
- p->chan = chan;
- p->state = SLEEPING;
- swtch(&p->context, &c->context);
- p->chan = 0;
- c->runqueue->lock.release();
-
- if (lk && lk != &proc_mem_lock)
- lk->acquire();
- }
-
- void wakeup(void *chan)
- {
- for (struct Proc *p = proc_list_head; p != nullptr; p = p->all_next)
- {
- if (p->state == SLEEPING && p->chan == chan)
- {
- struct cpu *c = mycpu();
- c->runqueue->lock.acquire();
- p->state = RUNNABLE;
- c->runqueue->enqueue(p);
- c->runqueue->lock.release();
- }
- }
- }
-
- void exit(int status)
- {
- struct Proc *p = myproc();
- if (p == initproc)
- while (1)
- ;
-
- wakeup(p->parent);
-
- proc_mem_lock.acquire();
-
- for (struct Proc *pp = proc_list_head; pp != nullptr; pp = pp->all_next)
- {
- if (pp->parent == p)
- {
- pp->parent = initproc;
- wakeup(initproc);
- }
- }
-
- proc_mem_lock.release();
-
- p->xstate = status;
-
- struct cpu *c = mycpu();
- c->runqueue->lock.acquire();
- p->state = ZOMBIE;
- swtch(&p->context, &c->context);
- while (1)
- ;
- }
-
- int wait(uint64 addr)
- {
-
- struct Proc *np;
- int havekids, pid;
- struct Proc *p = myproc();
- for (;;)
- {
- havekids = 0;
- proc_mem_lock.acquire();
-
- for (np = proc_list_head; np != nullptr; np = np->all_next)
- {
- if (np->parent == p)
- {
- havekids = 1;
- if (np->state == ZOMBIE)
- {
-
- struct cpu *child_cpu = np->cpu;
- if (child_cpu)
- {
- proc_mem_lock.release();
- child_cpu->runqueue->lock.acquire();
- child_cpu->runqueue->lock.release();
- proc_mem_lock.acquire();
- }
-
- pid = np->pid;
- if (addr != 0 && VM::copyout(p->pagetable, addr, (char *)&np->xstate, sizeof(np->xstate)) < 0)
- {
- proc_mem_lock.release();
- return -1;
- }
- freeproc(np);
- proc_mem_lock.release();
- return pid;
- }
- }
- }
- proc_mem_lock.release();
-
- if (!havekids || p->state == ZOMBIE)
- return -1;
- sleep(p, &proc_mem_lock);
- }
- }
-
- int kill(int pid)
- {
- Proc* p;
- proc_mem_lock.acquire();
- for (p = proc_list_head; p != nullptr; p = p->all_next)
- {
- if (p->pid == pid)
- {
- p->killed = 1;
-
- if (p->state == SLEEPING)
- {
- p->state = RUNNABLE;
-
- struct cpu *c = mycpu();
- c->runqueue->lock.acquire();
- c->runqueue->enqueue(p);
- c->runqueue->lock.release();
- }
-
- proc_mem_lock.release();
- return 0;
- }
- }
- proc_mem_lock.release();
- return -1;
- }
-
- int growproc(int n)
- {
- uint64 sz;
- struct Proc *p = myproc();
-
- sz = p->sz;
-
- if (n > 0)
- {
- // Call VM::uvmalloc to allocate memory
- // Parameters: page table, old size, new size, permissions (PTE_W)
- if ((sz = VM::uvmalloc(p->pagetable, sz, sz + n, PTE_W | PTE_R | PTE_U)) == 0)
- {
- return -1;
- }
- }
- else if (n < 0)
- {
- sz = VM::uvmdealloc(p->pagetable, sz, sz + n);
- }
-
- p->sz = sz;
- return 0;
- }
-
- void create_kernel_thread(void (*func)(), const char *name)
- {
- (void)func;
- (void)name;
- }
-} \ No newline at end of file
diff --git a/src/kernel/proc/swtch.S b/src/kernel/proc/swtch.S
deleted file mode 100644
index d55c03e..0000000
--- a/src/kernel/proc/swtch.S
+++ /dev/null
@@ -1,37 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-or-later
-# Copyright (C) 2026 Richard Qin
-
-.global swtch
-
-swtch:
- sd ra, 0(a0)
- sd sp, 8(a0)
- sd s0, 16(a0)
- sd s1, 24(a0)
- sd s2, 32(a0)
- sd s3, 40(a0)
- sd s4, 48(a0)
- sd s5, 56(a0)
- sd s6, 64(a0)
- sd s7, 72(a0)
- sd s8, 80(a0)
- sd s9, 88(a0)
- sd s10, 96(a0)
- sd s11, 104(a0)
-
- ld ra, 0(a1)
- ld sp, 8(a1)
- ld s0, 16(a1)
- ld s1, 24(a1)
- ld s2, 32(a1)
- ld s3, 40(a1)
- ld s4, 48(a1)
- ld s5, 56(a1)
- ld s6, 64(a1)
- ld s7, 72(a1)
- ld s8, 80(a1)
- ld s9, 88(a1)
- ld s10, 96(a1)
- ld s11, 104(a1)
-
- ret