Commit 8e6d9b19 by triazo

Merge branch 'trapframe' into 'master'

Trapframe

Process control blocks, trapframes, syscalls, and more

See merge request !19
parents 38e27c54 70c0f742
#include "PCB.h"
#include "serial.h"
#include "term.h"
#define NUM_SYSCALLS 256
#define NUM_PROCS 16
process* procs[NUM_PROCS];
int curproc=0;
int firstfree=0;
//process* curproc;
//process* otherproc;
void addproc(process* proc)
{
procs[firstfree]=proc;
firstfree++;
//curproc=proc;
}
void settf(trapframe* tf)
{
procs[curproc]->tf = tf;
}
void schedule()
{
int old = curproc;
curproc++;
while(procs[curproc]==0 || procs[curproc]->state!=RUNNABLE)
{
curproc=(curproc<NUM_PROCS-1)?curproc+1:0;
}
context_switch(&procs[old]->ctxt, procs[curproc]->ctxt);
//procs[old]->state=RUNNABLE;
procs[curproc]->state=RUNNING;
//process* t = curproc;
//curproc = otherproc;
//otherproc = t;
}
int yield()
{
//lock mutex
procs[curproc]->state = RUNNABLE;
schedule();
//unlock mutex
return 1;
}
int print1()
{
terminal_writestring("1\n");
return 1;
}
int print2()
{
terminal_writestring("2\n");
return 2;
}
int(*syscalls[NUM_SYSCALLS])()={0,0,0, yield, print1, print2};
/*NOPE, exit, fork, yield, test, test*/
void syscall()
{
int num = procs[curproc]->tf->eax;
serial_hexword(num);
serial_writestring(" SYSCALLED\n");
if(num>0 && num<NUM_SYSCALLS && syscalls[num])
{
procs[curproc]->tf->eax = syscalls[num]();
}
else
{
serial_writestring("UNKNOWN SYSCALL CALLED ");
serial_hexword(num);
serial_writestring("\n");
procs[curproc]->tf->eax = -1;
}
}
void proc_setup()
{
for(int i=0;i<NUM_PROCS;i++)
{
procs[i]=NULL;
}
}
#ifndef _PCB_INC
#define _PCB_INC
#include <stdint.h>
#include "mem.h"
typedef struct//all regs in proc
{
uint32_t edi;
uint32_t esi;
uint32_t ebp;
uint32_t oesp; //what is this
uint32_t ebx;
uint32_t edx;
uint32_t ecx;
uint32_t eax;
uint16_t gs;
uint16_t gspad;
uint16_t fs;
uint16_t fspad;
uint16_t es;
uint16_t espad;
uint16_t ds;
uint16_t dspad;
uint32_t trap;
uint32_t err;
uint32_t eip;
uint16_t cs;
uint16_t cspad;
uint32_t eflags;
//ring changing, for user mode stuff. not used yet
//uint32_t esp;
//uint16_t ss;
//uint16_t sspad;
}__attribute__((packed)) trapframe;
typedef struct//regs needed for context
{
uint32_t edi;
uint32_t esi;
uint32_t ebx;
uint32_t ebp;
uint32_t eip;
}__attribute__((packed)) context;
enum procstate {KILLED, RUNNABLE, RUNNING};
typedef struct
{
page_directory_entry* mem;
volatile int pid;
struct process* parent;
char* kstack;//apparently we need this. idk why
trapframe* tf;
context* ctxt;
char name[32];
enum procstate state;
}__attribute__((packed)) process;
extern void context_switch(context** old, context* new);
void syscall();
void addproc(process* proc);
void settf(trapframe* tf);
void proc_setup();
#endif
......@@ -35,14 +35,23 @@ inline uint32_t inl(uint16_t port)
return ret;
}
uint32_t __int_depth;
inline void disable_int()
{
asm volatile ("cli");
__int_depth++;
}
inline void enable_int()
{
asm volatile ("sti");
if(__int_depth>0)
{
if(--__int_depth == 0)
{
asm volatile ("sti");
}
}
}
#endif
......@@ -59,7 +59,14 @@ void int_general_protection_fault(uint32_t __attribute__((unused))error)
}
void int_page_fault(uint32_t __attribute__((unused))error)
{
serial_writestring("PAGE FAULT ERROR\n");
serial_writestring("PAGE FAULT ERROR ");
serial_hexword(error);
uint32_t cr2;
asm volatile("movl %%cr2, %0" : "=r" (cr2) : );
//register uint32_t cr2 asm("%%cr2");
serial_writestring(" ");
serial_hexword(cr2);
serial_writestring("\n");
}
void int_reserved(uint32_t __attribute__((unused))error)
{
......
......@@ -2,6 +2,7 @@
#include "string.h"
#include "serial.h"
#include "exceptions.h"
#include "PCB.h"
#pragma GCC push_options
#pragma GCC optimize ("0")
......@@ -31,27 +32,26 @@ void idt_install()
void load_error_handlers()
{
void(*errors[])(uint32_t)={int_div_by_zero,int_debug,int_non_maskable_interrupt,int_breakpoint,int_overflow,
int_bound_range_exceeded,int_invalid_opcode,int_device_not_available,int_double_fault,
int_coprocessor_segment_overrun,int_invalid_tss,int_segment_not_present,
int_stack_segment_fault,int_general_protection_fault,int_page_fault,int_reserved,
int_x87_floating_point,int_alignment_check,int_machine_check,int_simd_floating_point,
int_virtualization,int_reserved,int_reserved,int_reserved,int_reserved,int_reserved,
int_reserved,int_reserved,int_reserved,int_reserved,int_security,int_reserved};
int_bound_range_exceeded,int_invalid_opcode,int_device_not_available,int_double_fault,
int_coprocessor_segment_overrun,int_invalid_tss,int_segment_not_present,
int_stack_segment_fault,int_general_protection_fault,int_page_fault,int_reserved,
int_x87_floating_point,int_alignment_check,int_machine_check,int_simd_floating_point,
int_virtualization,int_reserved,int_reserved,int_reserved,int_reserved,int_reserved,
int_reserved,int_reserved,int_reserved,int_reserved,int_security,int_reserved};
for(int i=0;i<32;i++)
{
handlers[i]=errors[i];
}
}
void default_handler(struct reg_state __attribute__((unused))reg, uint32_t interrupt, uint32_t error, struct stack_state stack)
void default_handler(trapframe reg)
{
if(interrupt<32)
stack.eip+=2;
//char f[20];
//serial_val(interrupt);
if(handlers[interrupt]!=NULL)
settf(&reg);
if(reg.trap<32)
reg.eip+=2;
if(handlers[reg.trap]!=NULL)
{
handlers[interrupt](error);
handlers[reg.trap](reg.err);
}
return;
}
......@@ -107,6 +107,7 @@ int idt_init(uint16_t code_sel)
idtsetup();
idt_install();
load_error_handlers();
handlers[0x80] = syscall;
return 0;
}
#pragma GCC pop_options
#ifndef _IDT_INC
#define _IDT_INC
#include "PCB.h"
#include <stdint.h>
#define MAX_IDT_INT 256
......@@ -24,7 +25,7 @@ typedef struct
}__attribute__((packed)) idt_desc;
struct reg_state
/*struct reg_state
{
uint32_t eax;
uint32_t ecx;
......@@ -34,17 +35,17 @@ struct reg_state
uint32_t ebp;
uint32_t esi;
uint32_t edi;
}__attribute__((packed));
}__attribute__((packed));*/
struct stack_state
{
/*struct stack_state
{
uint32_t eip;
uint32_t cd;
uint32_t eflags;
}__attribute__((packed));
}__attribute__((packed));*/
extern void default_handler(struct reg_state reg,uint32_t interrupt, uint32_t error, struct stack_state stack);
extern void default_handler(trapframe reg);
extern idt_desc* get_ir(uint32_t i);
extern int install_ir(uint32_t i, uint16_t flags, uint16_t code_sel, IRQ_HANDLER);
extern void install_c_ir(uint32_t interrupt, void (*handler) (uint32_t));
......
......@@ -17,9 +17,18 @@ interrupt_handler_%1:
%endmacro
common_handler:
push dword ds
push dword es
push dword fs
push dword gs
pusha
call default_handler
popa
pop dword gs
pop dword fs
pop dword es
pop dword ds
add esp, 8
iret
......
......@@ -20,6 +20,7 @@
#include "pit.h"
#include "io.h"
#include "elf.h"
#include "PCB.h"
// The parameters passed here ultimately come through the bootloader
void kernel_main(multiboot_info* mbt, uint32_t magic)
......@@ -39,6 +40,7 @@ void kernel_main(multiboot_info* mbt, uint32_t magic)
pic_init(0x20,0x28);
pit_init();
io_init();
proc_setup();
pit_start_counter(100, PIT_OCW_CONT_0, PIT_OCW_MODE_SQWVGEN);
enable_int();
......
......@@ -4,6 +4,7 @@ all:
/usr/bin/nasm -felf32 head.asm -o boot.o
/usr/bin/nasm -felf32 paging.asm
/usr/bin/nasm -felf32 idta.asm
/usr/bin/nasm -felf32 switch.asm
$C *.c -std=gnu99 -ffreestanding -O2 -Wall -Wextra -c
$C -Wl,--format=binary -Wl,hello.elf -Wl,--format=default -T linker.ld -o myos.bin -ffreestanding -O2 -nostdlib *.o -lgcc
......
#include "queue.h"
#define NULL 0
struct node
{
process* proc;
struct node *next;
};
struct node* node_create(process *proc)
{
struct node* n = malloc(sizeof(struct node));
n->next = NULL;
n->proc = proc;
return n;
}
void queue_push(queue q, process *proc)
{
struct node* n = node_create(proc);
if(q.rear!=NULL)
{
q.rear->next = n;
q.rear = n;
}
else
{
q.rear = q.front = n;
}
}
void queue_pop(queue q)
{
if(q.front!=NULL)
{
struct node* f =q.front->next;
//free(q.front)
q.front = f;
if(q.front==NULL)
{
q.rear=NULL;
}
}
}
process* queue_front(queue q)
{
return q.front->proc;
}
void create(queue q)
{
q.front = q.rear = NULL;
}
#ifndef _QUEUE_INC
#define _QUEUE_INC
#include "PCB.h"
struct node;
typedef struct
{
struct node *front,*rear;
} queue;
void queue_push(queue q, process *proc);
void queue_pop(queue q);
process* queue_front(queue q);
void create(queue q);
#endif
global context_switch
context_switch:
mov eax, [esp+4]
mov edx, [esp+8]
push ebp
push ebx
push esi
push edi
mov [eax], esp
mov esp, edx
pop edi
pop esi
pop ebx
pop ebp
ret
......@@ -6,8 +6,8 @@
void test_idt()
{
asm ("int $0x80");
asm ("int $0x90");
asm volatile("mov $4, %eax; int $0x80");
asm volatile("int $0x90");
}
void test_mem()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment