Skip to content

Commit

Permalink
Shell. Apparently buggy context switch.
Browse files Browse the repository at this point in the history
  • Loading branch information
pykello committed Jun 4, 2015
1 parent 429e77b commit f6b19e2
Show file tree
Hide file tree
Showing 14 changed files with 69 additions and 26 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ CFLAGS = -mcpu=$(CPU) -gstabs -I include -I arch/$(arch)/include -marm \
-fno-builtin-printf -fno-builtin-strcpy -Wno-overlength-strings \
-fno-builtin-exit
ASFLAGS = -mcpu=$(CPU) -g -I include -I arch/$(arch)/include
QEMU_FLAGS = $(ARCH_QEMU_FLAGS) -nographic
QEMU_FLAGS = $(ARCH_QEMU_FLAGS) -nographic -d in_asm

all: $(OS).bin

Expand Down
4 changes: 3 additions & 1 deletion include/lib/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ enum SystemCallCode {
SYSCALL_GETPID,
SYSCALL_FORK,
SYSCALL_EXEC,
SYSCALL_YIELD
SYSCALL_YIELD,
SYSCALL_WAIT
};

int syscall0(enum SystemCallCode code);
Expand All @@ -30,5 +31,6 @@ int getpid(void);
int fork(void);
void exec(int id);
void yield(void);
void wait(int id);

#endif
4 changes: 4 additions & 0 deletions include/proc.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ struct Process {
char *user_stack;
char *kernel_stack;
int context[17];

int wait_pid;
int child_return_value;
};

#define ELF_MAGIC 0x464C457FU
Expand Down Expand Up @@ -115,6 +118,7 @@ int syscall_getpid(void);
int syscall_fork(void);
int syscall_exec(int id);
int syscall_yield(void);
int syscall_wait(int id);

#endif
#endif
2 changes: 1 addition & 1 deletion kernel/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ void c_entry(void)
console_init();
kalloc_init(KERNEL_BASE + INITIAL_MEMORY_SIZE,
KERNEL_BASE + TOTAL_MEMORY_SIZE);
scheduler_init();

/* start the first program */
{
struct Process *proc = proc_create();
proc_load_program(proc, 0);
scheduler_init();
schedule();
}
}
3 changes: 2 additions & 1 deletion kernel/ksyscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ static int (*const syscall_handler[])() = {
[SYSCALL_GETPID] = syscall_getpid,
[SYSCALL_FORK] = syscall_fork,
[SYSCALL_EXEC] = syscall_exec,
[SYSCALL_YIELD] = syscall_yield
[SYSCALL_YIELD] = syscall_yield,
[SYSCALL_WAIT] = syscall_wait
};

/* kernel side of system calls. */
Expand Down
1 change: 1 addition & 0 deletions kernel/proc/build.mk
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ OBJS += $(PROC_DIR)/syscall_getpid.o
OBJS += $(PROC_DIR)/syscall_fork.o
OBJS += $(PROC_DIR)/syscall_exec.o
OBJS += $(PROC_DIR)/syscall_yield.o
OBJS += $(PROC_DIR)/syscall_wait.o
1 change: 1 addition & 0 deletions kernel/proc/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ struct Process *proc_create(void)
proc->heap_size = 0;
proc->kernel_stack = kernel_stack;
proc->user_stack = user_stack;
proc->wait_pid = -1;

return proc;
}
Expand Down
7 changes: 6 additions & 1 deletion kernel/proc/scheduler.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ void handle_timer(void)
void scheduler_init(void)
{
round_robin_index = 0;
timer_set_interval(100000);
timer_set_interval(10000);
register_interrupt_handler(0x5, handle_timer);
}

Expand All @@ -36,12 +36,17 @@ void schedule(void)
proc = &process_table[round_robin_index];

if (proc->state == READY) {
//kprintf("scheduling %d\n", round_robin_index);
current_process = proc;
proc_start(proc);
}
}

/* no process? panic */
mon_status(0, 0);
kprintf("round_robin_index = %d\n", round_robin_index);
for (i = 0; i < PROCESS_COUNT_MAX; i++)
kprintf("[%d] = %d\n", i, process_table[i].state);
kprintf("PANIC");
while(1);
}
13 changes: 13 additions & 0 deletions kernel/proc/syscall_exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,26 @@

int syscall_exit(int arg1)
{
int pid;

(void) arg1;
if (current_process == NULL)
return -1;

set_translation_table_base((uint32_t) V2P(kernel_vm));
__asm__ volatile("ldr sp, =kernel_stack_start");

for (pid = 0; pid < PROCESS_COUNT_MAX; pid++) {
struct Process *proc = &process_table[pid];

if (proc->state == SLEEPING &&
proc->wait_pid == current_process->pid) {

proc->wait_pid = -1;
proc->state = READY;
}
}

proc_free(current_process);
current_process = NULL;

Expand Down
12 changes: 12 additions & 0 deletions kernel/proc/syscall_wait.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <ksyscall.h>
#include <proc.h>
#include <system.h>

int syscall_wait(int arg1)
{
current_process->wait_pid = arg1;
current_process->state = SLEEPING;
schedule();

return 0;
}
11 changes: 0 additions & 11 deletions kernel/startup.S
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ entry:
bl copy_interrupt_table
bl use_high_interrupts
bl enable_interrupts
bl setup_irq_stack_pointer

bl jump_to_high_mem
bl c_entry
Expand Down Expand Up @@ -45,16 +44,6 @@ copy_interrupt_table:

mov pc, lr

setup_irq_stack_pointer:
mrs r0, cpsr
bic r1, r0, #0x1F
orr r1, r1, #0x12
msr cpsr, r1
ldr sp, =irq_stack_start
msr cpsr, r0

mov pc, lr

interrupt_table_start:
nop
subs pc, lr, #4
Expand Down
7 changes: 6 additions & 1 deletion lib/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,9 @@ void exec(int id)
void yield(void)
{
syscall0(SYSCALL_YIELD);
}
}

void wait(int id)
{
syscall1(SYSCALL_WAIT, id);
}
4 changes: 2 additions & 2 deletions user/exec_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
void _start()
{
if (fork() == 0) {
printf("starting program 0 ...\n");
exec(0);
printf("starting program 1 ...\n");
exec(1);
}
else {
printf("message from parent.\n");
Expand Down
24 changes: 17 additions & 7 deletions user/shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,25 @@

void _start()
{
int i = 0, j = 0;
fork();
fork();
fork();
char command[128];
int program_idx = 0;
int child_pid = 0;

while (1) {
printf("step %d at pid %d\n", i, getpid());
yield();
i++;
printf("$ ");
gets(command);
if (command[0] < '0' || command[0] > '9')
continue;

program_idx = command[0] - '0';
child_pid = fork();
printf("child_pid = %d\n", child_pid);
if (child_pid == 0) {
exec(program_idx);
}
else {
wait(child_pid);
}
}

exit(0);
Expand Down

0 comments on commit f6b19e2

Please sign in to comment.