diff --git a/kernel/amd64/bootmain.c b/kernel/amd64/bootmain.c index 56c9bf6..d1ca37c 100644 --- a/kernel/amd64/bootmain.c +++ b/kernel/amd64/bootmain.c @@ -57,6 +57,11 @@ void bootmain (void) { ioapic_init (); hpet_init (); + proc_pid_alloc_init (); + procgroup_pgid_alloc_init (); + + bsp_cpu->kproc = kproc_create (); + devices_init (); vfs_init (); @@ -66,9 +71,6 @@ void bootmain (void) { struct device* temp0 = device_find ("TEMP0"); vfs_create_volume ("TEMP", FS_FAT16, temp0, true); - proc_pid_alloc_init (); - procgroup_pgid_alloc_init (); - smp_init (); proc_init (); diff --git a/kernel/amd64/smp.c b/kernel/amd64/smp.c index eb47975..bb8d149 100644 --- a/kernel/amd64/smp.c +++ b/kernel/amd64/smp.c @@ -102,10 +102,12 @@ static void smp_bootstrap (struct limine_mp_info* mp_info) { atomic_fetch_sub (&cpu_counter, 1); + cpu->kproc = kproc_create (); + struct reschedule_ctx rctx; memset (&rctx, 0, sizeof (rctx)); - struct proc* spin_proc = proc_from_file (VFS_KERNEL, "RD", "/spin", &rctx); + struct proc* spin_proc = proc_from_file (thiscpu->kproc, "RD", "/spin", &rctx); proc_register (spin_proc, thiscpu, &rctx); spin_lock (&spin_proc->cpu->lock); diff --git a/kernel/amd64/smp.h b/kernel/amd64/smp.h index 1f45130..4b9770b 100644 --- a/kernel/amd64/smp.h +++ b/kernel/amd64/smp.h @@ -33,6 +33,7 @@ struct cpu { struct list_node_link* proc_run_q; struct proc* proc_current; int proc_run_q_count; + struct proc* kproc; }; struct cpu* cpu_make (uint64_t lapic_id, uint64_t acpi_id); diff --git a/kernel/fs/vfs.c b/kernel/fs/vfs.c index 657e08a..effae47 100644 --- a/kernel/fs/vfs.c +++ b/kernel/fs/vfs.c @@ -125,13 +125,8 @@ int vfs_volume_open (struct proc* proc, const char* volume_name, struct reschedu spin_unlock (&volume->lock); return ST_OK; } else { - if (proc == VFS_KERNEL) { - spin_unlock (&volume->lock); - return -ST_TRY_AGAIN; - } else { - proc_sq_suspend (proc, &volume->sq, &volume->lock, rctx); - return ST_OK; - } + proc_sq_suspend (proc, &volume->sq, &volume->lock, rctx); + return ST_OK; } } diff --git a/kernel/fs/vfs.h b/kernel/fs/vfs.h index a39ab67..d640a6b 100644 --- a/kernel/fs/vfs.h +++ b/kernel/fs/vfs.h @@ -16,8 +16,6 @@ #include #include -#define VFS_KERNEL ((struct proc*)0x123) - struct vfs_volume; struct vfs_volume { diff --git a/kernel/proc/proc.c b/kernel/proc/proc.c index b342dd7..68f320a 100644 --- a/kernel/proc/proc.c +++ b/kernel/proc/proc.c @@ -43,6 +43,27 @@ void proc_free_pid (int pid) { id_free (&pid_alloc, pid); } void proc_pid_alloc_init (void) { id_alloc_init (&pid_alloc, PIDS_MAX); } +struct proc* kproc_create (void) { + struct proc* kproc = malloc (sizeof (*kproc)); + + memset (kproc, 0, sizeof (*kproc)); + + kproc->lock = SPIN_LOCK_INIT; + kproc->flags |= PROC_KPROC; + kproc->pid = proc_alloc_pid (); + + kproc->procgroup = procgroup_create (); + procgroup_attach (kproc->procgroup, kproc); + + kproc->exec_pid = -1; + + struct reschedule_ctx rctx; + memset (&rctx, 0, sizeof (rctx)); + proc_register (kproc, NULL, &rctx); + + return kproc; +} + static bool proc_check_elf (uint8_t* elf) { if (!((elf[0] == 0x7F) && (elf[1] == 'E') && (elf[2] == 'L') && (elf[3] == 'F'))) return false; @@ -116,16 +137,35 @@ struct proc* proc_from_file (struct proc* proc1, const char* volume, const char* struct desc desc; int ret; - for (;;) { - ret = vfs_volume_open (proc1, volume, rctx); + spin_lock (&proc1->lock); + bool is_kproc = (proc1->flags & PROC_KPROC) != 0; + spin_unlock (&proc1->lock); - if (ret < 0) { - if (ret == -ST_TRY_AGAIN) - continue; - else + if (is_kproc) { + for (;;) { + ret = vfs_volume_open (proc1, volume, rctx); + + if (ret < 0) return NULL; - } else - break; + + spin_lock (&proc1->lock); + + if (ret == ST_OK && proc1->state != PROC_SUSPENDED) { + spin_unlock (&proc1->lock); + break; + } + + for (;;) { + spin_lock (&proc1->lock); + + if (proc1->state != PROC_SUSPENDED) { + spin_unlock (&proc1->lock); + break; + } + + spin_unlock (&proc1->lock); + } + } } if ((ret = vfs_describe (proc1, volume, path, &desc)) < 0) { @@ -221,7 +261,7 @@ static struct proc* proc_find_sched (struct cpu* cpu) { int state = proc->state; - if (state == PROC_READY) { + if (state == PROC_READY && !(proc->flags & PROC_KPROC)) { spin_unlock (&proc->lock); return proc; } @@ -256,6 +296,12 @@ void proc_sched (void) { void proc_kill (struct proc* proc, struct reschedule_ctx* rctx) { spin_lock (&proc->lock); + + if ((proc->flags & PROC_KPROC)) { + spin_unlock (&proc->lock); + return; + } + struct cpu* cpu = proc->cpu; spin_unlock (&proc->lock); @@ -313,10 +359,10 @@ void proc_init (void) { struct reschedule_ctx rctx; memset (&rctx, 0, sizeof (rctx)); - struct proc* spin_proc = proc_from_file (VFS_KERNEL, "RD", "/spin", &rctx); + struct proc* spin_proc = proc_from_file (thiscpu->kproc, "RD", "/spin", &rctx); proc_register (spin_proc, thiscpu, &rctx); - struct proc* init = proc_from_file (VFS_KERNEL, "RD", "/init", &rctx); + struct proc* init = proc_from_file (thiscpu->kproc, "RD", "/init", &rctx); init->procgroup->capabilities |= (PROC_CAP_TERMINAL | PROC_CAP_KB); proc_register (init, thiscpu, &rctx); diff --git a/kernel/proc/proc.h b/kernel/proc/proc.h index 9992388..20cfd13 100644 --- a/kernel/proc/proc.h +++ b/kernel/proc/proc.h @@ -25,6 +25,7 @@ /* process flags */ #define PROC_USTK_PREALLOC (1 << 0) +#define PROC_KPROC (1 << 1) struct cpu; struct reschedule_ctx; @@ -72,4 +73,6 @@ void proc_wait_for (struct proc* proc, struct reschedule_ctx* rctx, struct proc* void proc_init (void); +struct proc* kproc_create (void); + #endif // _KERNEL_PROC_PROC_H diff --git a/kernel/proc/suspension_q.c b/kernel/proc/suspension_q.c index 758de21..86ce64d 100644 --- a/kernel/proc/suspension_q.c +++ b/kernel/proc/suspension_q.c @@ -5,19 +5,20 @@ #include #include #include +#include #include #include #include -void proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock_t* resource_lock, - struct reschedule_ctx* rctx) { +int proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock_t* resource_lock, + struct reschedule_ctx* rctx) { struct cpu* cpu = proc->cpu; struct proc_sq_entry* sq_entry = malloc (sizeof (*sq_entry)); if (!sq_entry) { if (resource_lock != NULL) spin_unlock (resource_lock); - return; + return -ST_OOM_ERROR; } sq_entry->proc = proc; @@ -45,16 +46,19 @@ void proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock cpu->proc_current = NULL; proc->cpu = NULL; + int state = proc->state; spin_unlock (&sq->lock); spin_unlock (&proc->lock); spin_unlock (&cpu->lock); rctx_insert_cpu (rctx, cpu); + + return state; } -void proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry, - struct reschedule_ctx* rctx) { +int proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry, + struct reschedule_ctx* rctx) { struct cpu* cpu = cpu_find_lightest (); struct proc_suspension_q* sq = sq_entry->sq; @@ -76,6 +80,8 @@ void proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry, list_append (cpu->proc_run_q, &proc->cpu_run_q_link); cpu->proc_run_q_count++; + int state = proc->state; + spin_unlock (&sq->lock); spin_unlock (&proc->lock); spin_unlock (&cpu->lock); @@ -83,6 +89,8 @@ void proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry, free (sq_entry); rctx_insert_cpu (rctx, cpu); + + return state; } void proc_sqs_cleanup (struct proc* proc) { diff --git a/kernel/proc/suspension_q.h b/kernel/proc/suspension_q.h index 3a29e67..465c0b7 100644 --- a/kernel/proc/suspension_q.h +++ b/kernel/proc/suspension_q.h @@ -22,10 +22,9 @@ struct proc_sq_entry { void proc_sqs_cleanup (struct proc* proc); -void proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock_t* resource_lock, - struct reschedule_ctx* rctx); - -void proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry, +int proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock_t* resource_lock, struct reschedule_ctx* rctx); +int proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry, struct reschedule_ctx* rctx); + #endif // _KERNEL_PROC_SUSPENTION_Q_H diff --git a/libdebugconsole/debugconsole.h b/libdebugconsole/debugconsole.h index 9279baf..715d528 100644 --- a/libdebugconsole/debugconsole.h +++ b/libdebugconsole/debugconsole.h @@ -1,6 +1,8 @@ #ifndef _LIBDEBUGCONSOLE_DEBUGCONSOLE_H #define _LIBDEBUGCONSOLE_DEBUGCONSOLE_H +#include + #define DEBUG_PRINTF_MAX (16 * 1024) int debugconsole_print (const char* string, size_t len);