process #9
25
src/kmain.c
25
src/kmain.c
@@ -82,6 +82,21 @@ struct boot_context boot_ctx;
|
|||||||
extern struct process_t* processes_list;
|
extern struct process_t* processes_list;
|
||||||
extern struct process_t* current_process;
|
extern struct process_t* current_process;
|
||||||
|
|
||||||
|
void pedicel_main(void* arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void two_main(void* arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void three_main(void* arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// This is our entry point
|
// This is our entry point
|
||||||
void kmain()
|
void kmain()
|
||||||
{
|
{
|
||||||
@@ -118,13 +133,9 @@ void kmain()
|
|||||||
|
|
||||||
vmm_init();
|
vmm_init();
|
||||||
|
|
||||||
struct process_t* pedicel = process_create();
|
struct process_t* pedicel = process_create("pedicel", (void*)pedicel_main, 0);
|
||||||
struct process_t* two = process_create();
|
struct process_t* two = process_create("two", (void*)two_main, 0);
|
||||||
struct process_t* three = process_create();
|
struct process_t* three = process_create("three", (void*)three_main, 0);
|
||||||
|
|
||||||
process_add(&processes_list, pedicel);
|
|
||||||
process_add(&processes_list, two);
|
|
||||||
process_add(&processes_list, three);
|
|
||||||
process_display_list(processes_list);
|
process_display_list(processes_list);
|
||||||
|
|
||||||
scheduler_init();
|
scheduler_init();
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "mem/paging/pmm.h"
|
#include "mem/paging/pmm.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
|
#include "sched/process.h"
|
||||||
|
|
||||||
extern uint64_t kernel_phys_base;
|
extern uint64_t kernel_phys_base;
|
||||||
extern uint64_t kernel_virt_base;
|
extern uint64_t kernel_virt_base;
|
||||||
@@ -104,3 +105,11 @@ void kfree(void* ptr)
|
|||||||
struct heap_block_t* block = (struct heap_block_t*)((uintptr_t)ptr - sizeof(struct heap_block_t));
|
struct heap_block_t* block = (struct heap_block_t*)((uintptr_t)ptr - sizeof(struct heap_block_t));
|
||||||
block->free = true;
|
block->free = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Should alloc enough for a stack (at least 64kb) to be used for a process.
|
||||||
|
// Should return a pointer to top of the stack (as stack grows DOWNWARDS)
|
||||||
|
void* kalloc_stack()
|
||||||
|
{
|
||||||
|
void* ptr = kmalloc(PROCESS_STACK_SIZE);
|
||||||
|
return ptr+PROCESS_STACK_SIZE;
|
||||||
|
}
|
||||||
@@ -22,5 +22,6 @@ struct heap_block_t
|
|||||||
void kheap_init();
|
void kheap_init();
|
||||||
void* kmalloc(size_t size);
|
void* kmalloc(size_t size);
|
||||||
void kfree(void* ptr);
|
void kfree(void* ptr);
|
||||||
|
void* kalloc_stack();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -2,10 +2,14 @@
|
|||||||
#include "process.h"
|
#include "process.h"
|
||||||
#include "mem/heap/kheap.h"
|
#include "mem/heap/kheap.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
|
#include "string/string.h"
|
||||||
|
#include "mem/gdt/gdt.h"
|
||||||
|
|
||||||
struct process_t* processes_list;
|
struct process_t* processes_list;
|
||||||
struct process_t* current_process;
|
struct process_t* current_process;
|
||||||
|
|
||||||
|
size_t next_free_pid = 0;
|
||||||
|
|
||||||
void process_init()
|
void process_init()
|
||||||
{
|
{
|
||||||
processes_list = NULL;
|
processes_list = NULL;
|
||||||
@@ -26,16 +30,35 @@ void process_display_list(struct process_t* processes_list)
|
|||||||
DEBUG("NULL");
|
DEBUG("NULL");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct process_t* process_create()
|
struct process_t* process_create(char* name, void(*function)(void*), void* arg)
|
||||||
{
|
{
|
||||||
|
CLEAR_INTERRUPTS;
|
||||||
struct process_t* proc = (struct process_t*)kmalloc(sizeof(struct process_t));
|
struct process_t* proc = (struct process_t*)kmalloc(sizeof(struct process_t));
|
||||||
|
|
||||||
|
struct cpu_status_t* ctx = (struct cpu_status_t*)kmalloc(sizeof(struct cpu_status_t));
|
||||||
|
|
||||||
|
// No more memory?
|
||||||
if (!proc) return NULL;
|
if (!proc) return NULL;
|
||||||
|
if (!ctx) return NULL;
|
||||||
|
|
||||||
proc->context = NULL;
|
strncpy(proc->name, name, PROCESS_NAME_MAX);
|
||||||
|
proc->pid = next_free_pid++;
|
||||||
proc->status = READY;
|
proc->status = READY;
|
||||||
proc->next = NULL;
|
|
||||||
|
|
||||||
|
proc->context = ctx;
|
||||||
|
proc->context->iret_ss = KERNEL_DATA_SEGMENT; // process will live in kernel mode
|
||||||
|
proc->context->iret_rsp = (uint64_t)kalloc_stack();
|
||||||
|
proc->context->iret_flags = 0x202; //bit 2 and 9 set (Interrupt Flag)
|
||||||
|
proc->context->iret_cs = KERNEL_CODE_SEGMENT;
|
||||||
|
proc->context->iret_rip = (uint64_t)function; // beginning of executable code
|
||||||
|
proc->context->rdi = (uint64_t)arg; // 1st arg is in rdi (as per x64 calling convention)
|
||||||
|
proc->context->rbp = 0;
|
||||||
|
|
||||||
|
proc->next = 0;
|
||||||
|
|
||||||
|
process_add(&processes_list, proc);
|
||||||
|
|
||||||
|
SET_INTERRUPTS;
|
||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#ifndef PROCESS_H
|
#ifndef PROCESS_H
|
||||||
#define PROCESS_H
|
#define PROCESS_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
READY,
|
READY,
|
||||||
@@ -8,15 +10,21 @@ typedef enum
|
|||||||
DEAD
|
DEAD
|
||||||
} status_t;
|
} status_t;
|
||||||
|
|
||||||
|
#define PROCESS_NAME_MAX 64
|
||||||
|
#define PROCESS_STACK_SIZE 0x100 // 64kb
|
||||||
|
|
||||||
struct process_t
|
struct process_t
|
||||||
{
|
{
|
||||||
|
size_t pid;
|
||||||
|
char name[PROCESS_NAME_MAX];
|
||||||
|
|
||||||
status_t status;
|
status_t status;
|
||||||
struct cpu_status_t* context;
|
struct cpu_status_t* context;
|
||||||
struct process_t* next;
|
struct process_t* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
void process_init();
|
void process_init();
|
||||||
struct process_t* process_create();
|
struct process_t* process_create(char* name, void(*function)(void*), void* arg);
|
||||||
void process_add(struct process_t** processes_list, struct process_t* process);
|
void process_add(struct process_t** processes_list, struct process_t* process);
|
||||||
void process_delete(struct process_t** processes_list, struct process_t* process);
|
void process_delete(struct process_t** processes_list, struct process_t* process);
|
||||||
struct process_t* process_get_next(struct process_t* process);
|
struct process_t* process_get_next(struct process_t* process);
|
||||||
|
|||||||
@@ -4,18 +4,19 @@
|
|||||||
extern struct process_t* processes_list;
|
extern struct process_t* processes_list;
|
||||||
extern struct process_t* current_process;
|
extern struct process_t* current_process;
|
||||||
|
|
||||||
// DEBUG: how many times we did schedule
|
|
||||||
int scheduled = 0;
|
|
||||||
|
|
||||||
void scheduler_init()
|
void scheduler_init()
|
||||||
{
|
{
|
||||||
// Choose first process?
|
// Choose first process?
|
||||||
current_process = processes_list;
|
current_process = processes_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
void scheduler_schedule()
|
struct cpu_status_t* scheduler_schedule(struct cpu_status_t* context)
|
||||||
{
|
{
|
||||||
//DEBUG("Scheduler called!");
|
current_process->context = context;
|
||||||
|
current_process->status = READY;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
struct process_t* prev_process = current_process;
|
||||||
if (current_process->next != NULL)
|
if (current_process->next != NULL)
|
||||||
{
|
{
|
||||||
current_process = current_process->next;
|
current_process = current_process->next;
|
||||||
@@ -23,13 +24,17 @@ void scheduler_schedule()
|
|||||||
{
|
{
|
||||||
current_process = processes_list;
|
current_process = processes_list;
|
||||||
}
|
}
|
||||||
scheduled++;
|
|
||||||
DEBUG("SCHEDULER CALLED: current_process=%p", current_process);
|
|
||||||
|
|
||||||
// debug
|
if (current_process != NULL && current_process->status == DEAD)
|
||||||
/* if (scheduled == 5)
|
|
||||||
{
|
{
|
||||||
DEBUG("enough, halting");
|
process_delete(&prev_process, current_process);
|
||||||
hcf();
|
} else
|
||||||
} */
|
{
|
||||||
|
current_process->status = RUNNING;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG("SCHEDULER CALLED: current_process=%p", current_process);
|
||||||
|
return current_process->context;
|
||||||
}
|
}
|
||||||
@@ -17,3 +17,10 @@ char *strcat(char *dest, const char *src){
|
|||||||
dest[i+j] = '\0';
|
dest[i+j] = '\0';
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://stackoverflow.com/questions/14159625/implementation-of-strncpy
|
||||||
|
void strncpy(char* dst, const char* src, size_t n)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
while(i++ != n && (*dst++ = *src++));
|
||||||
|
}
|
||||||
@@ -3,5 +3,6 @@
|
|||||||
|
|
||||||
char *strcpy(char *dest, const char *src);
|
char *strcpy(char *dest, const char *src);
|
||||||
char *strcat(char *dest, const char *src);
|
char *strcat(char *dest, const char *src);
|
||||||
|
void strncpy(char* dst, const char* src, size_t n);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Reference in New Issue
Block a user