summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Idziorek <m.i@gmx.at>2014-10-21 19:08:03 +0200
committerMichal Idziorek <m.i@gmx.at>2014-10-21 19:08:03 +0200
commitd25834310293c8a30b4a31418ff4ffd8fad8ef24 (patch)
tree97ae696211f7709002d80ecbfb8595123611d3c1
parent5b9ea685dfd12415774e4e97ad387c601dd2b43b (diff)
started implementing our first fool-shell.
-rw-r--r--Makefile3
-rw-r--r--asm/int_syscall_handler.asm39
-rw-r--r--kernel/kernel.c9
-rw-r--r--kernel/keyboard.c67
-rw-r--r--kernel/spinlock.c4
-rw-r--r--kernel/syscalls.c32
-rw-r--r--lib/buffer/ringbuffer.c96
-rw-r--r--lib/logger/log.c1
-rw-r--r--userspace/Makefile4
-rw-r--r--userspace/foolshell.c34
-rw-r--r--userspace/syscalls.c60
11 files changed, 260 insertions, 89 deletions
diff --git a/Makefile b/Makefile
index 9dac9b0..04d468d 100644
--- a/Makefile
+++ b/Makefile
@@ -26,6 +26,7 @@ CC=i686-elf-gcc
CFLAGS=-ffreestanding -nostdlib -lgcc -std=gnu11
CFLAGS+= -I.
CFLAGS+= -Wno-implicit-function-declaration
+#CFLAGS+= -O0
#CFLAGS+=-fdata-sections -ffunction-sections
#CFLAGS+= -Werror
@@ -81,7 +82,7 @@ newrun: clean run
# the kernel_entry.o needs to be FIRST!!
kernel.bin: $(KERNEL_ENTRY) $(ASMOBJECTS) $(OBJECTS)
- $(CC) $(CFLAGS) -o $@ -Wl,-Ttext,$(KERNEL_START),--oformat,binary $^
+ $(CC) $(CFLAGS) -o $@ -Wl,-Ttext,$(KERNEL_START),--oformat,binary $^
#ld -o $@ -Ttext $(KERNEL_START) --oformat binary -melf_i386 $^ -O0 # --gc-sections --entry=kernel_main -v
diff --git a/asm/int_syscall_handler.asm b/asm/int_syscall_handler.asm
index 37bc71a..bd787de 100644
--- a/asm/int_syscall_handler.asm
+++ b/asm/int_syscall_handler.asm
@@ -3,7 +3,8 @@ global int_syscall_handler
[extern example_syscall]
[extern example_syscall_2]
-[extern syscall_outbyte]
+[extern syscall_write]
+[extern syscall_read]
[bits 32]
int_syscall_handler:
@@ -21,31 +22,53 @@ int_syscall_handler:
je call_example_syscall_2
cmp eax, 61
- je call_outbyte
+ je call_write
+
+ cmp eax, 62
+ je call_read
done:
+ mov ebx,eax
+
+ mov al, 0x20 ;Port number AND command number to Acknowledge IRQ
+ out 0x20, al ;Acknowledge IRQ, so we keep getting interrupts
+
+ mov eax,ebx
+
+ sti
+
+done_blocking:
+
pop ebx
pop ecx
pop edx
mov ebx,eax
- mov al, 0x20 ;Port number AND command number to Acknowledge IRQ
- out 0x20, al ;Acknowledge IRQ, so we keep getting interrupts
- sti
iret ;Interrupt-Return
+
call_example_syscall:
call example_syscall
jmp done
-call_example_syscall_2
+call_example_syscall_2:
call example_syscall_2
jmp done
-call_outbyte
- call syscall_outbyte
+call_write:
+ call syscall_write
jmp done
+call_read:
+
+ mov al, 0x20 ;Port number AND command number to Acknowledge IRQ
+ out 0x20, al ;Acknowledge IRQ, so we keep getting interrupts
+ sti
+
+ call syscall_read
+
+ jmp done_blocking
+
diff --git a/kernel/kernel.c b/kernel/kernel.c
index 34f3d69..dd5cc15 100644
--- a/kernel/kernel.c
+++ b/kernel/kernel.c
@@ -98,6 +98,7 @@ void kernel_main(uint32_t initial_stack, int mp)
// self-log message of logger :P
log_log();
+
//
// Print initial address of the esp stack pointer
//
@@ -147,6 +148,10 @@ void kernel_main(uint32_t initial_stack, int mp)
// init spinlocks
init_spinlocks();
+
+ // ringbuffer for stdin!
+ ringbuffer_init();
+
//
// Start the other Processors (also before paging for some reason!)
//
@@ -185,7 +190,7 @@ void kernel_main(uint32_t initial_stack, int mp)
// Will process input from the keyboard but will be completely
// redesigned soon. TODO!!
//
- shell_init();
+ //shell_init();
//
// Initialize Multitasking
@@ -206,8 +211,10 @@ void kernel_main(uint32_t initial_stack, int mp)
// autorun "user-space" prog
asm("push $0x80800");
asm("ret");
+
while(1)
{
+
}
diff --git a/kernel/keyboard.c b/kernel/keyboard.c
index c70a03f..083e553 100644
--- a/kernel/keyboard.c
+++ b/kernel/keyboard.c
@@ -8,19 +8,15 @@
/// keyboard driver ////
+
void keyboard_handle(uint8_t in)
{
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"scancode 0x%x",in);
-
- int i=0;
- //
- //print_hex(int_count);
uint8_t make_codes[]={
0x1e, // A
0x30, // B
0x2e, // C
- 0x20, // s/OSDev19.htmlD
+ 0x20, // D
0x12, // E
0x21, // F
0x22, // G
@@ -78,51 +74,32 @@ void keyboard_handle(uint8_t in)
uint8_t break_key_space=0xb9;
uint8_t break_key_backspace=0x8e;
- //if(last_code==*int_count)return;
-/*
- for(i=0;i<26;i++)
- {
- if(make_codes[i]==in)
- {
-// print_char_col(cursor,20,'A'+i,0xf);
-// scr_put_char('A'+i);
- }
- }
- */
+ char ascii;
- if(break_key_space==in)
- {
- scr_put_char(' ');
- shell_put(' ');
- return;
- }
+ // optimize this!
+ if(break_key_space==in)ascii=' ';
+ else if(break_key_backspace==in)ascii='x';
+ else if(break_key_enter==in)ascii='\n';
- if(break_key_backspace==in)
+ else for(int i=0;i<26;i++)
{
- scr_backspace();
- shell_backspace();
- return;
- }
-
- if(break_key_enter==in)
- {
- scr_nextline();
- shell_execute();
- return;
- }
-
- for(i=0;i<26;i++)
- {
- if(break_alpha[i]==in)
+ if(break_alpha[i]==in)
{
- //print_char_col(cursor++,20,'a'+i,SCR_RED);
- scr_put_char('A'+i);
- shell_put('A'+i);
- return;
+ ascii=('A'+i);
+ break;
+ }
+ if(i==25)
+ {
+ return;
}
}
-// last_code=in;
+
+ PutConsoleChar(ascii,0b1111100000011111);
+
+
+ if(!ringbuffer_put(ascii))
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"ringbuffer full..");
}
@@ -134,6 +111,8 @@ void int_kb_handler()
static uint8_t kb_in;
__asm__("in $0x60, %al");
__asm__("mov %%al, %0"::"m" (kb_in));
+
+ //log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"scancode 0x%x",kb_in);
keyboard_handle(kb_in);
X86_IRQ_END
diff --git a/kernel/spinlock.c b/kernel/spinlock.c
index c7f5062..975de68 100644
--- a/kernel/spinlock.c
+++ b/kernel/spinlock.c
@@ -18,7 +18,7 @@ volatile void lock_spin(int i)
{
spinlock *addr=spinlocks+i;
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"locking %d (0x%08X)",i,addr);
+// log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"locking %d (0x%08X)",i,addr);
while(x86_xchg(addr,1));
}
@@ -26,7 +26,7 @@ volatile void lock_spin(int i)
void lock_release(int i)
{
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"unlocking %d",i);
+// log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"unlocking %d",i);
spinlock *addr=spinlocks+i;
asm("movb $0,%0"::"m"(*addr));
diff --git a/kernel/syscalls.c b/kernel/syscalls.c
index bf875fd..470939c 100644
--- a/kernel/syscalls.c
+++ b/kernel/syscalls.c
@@ -1,11 +1,39 @@
#define FOOLOS_MODULE_NAME "syscalls"
#include "lib/logger/log.h"
+#include "lib/bool/bool.h"
//
-void syscall_outbyte(char c)
+int syscall_write(int file, char *buf, int len)
{
- PutConsoleChar(c,0b1111111111000000);
+ for(int i=0;i<len;i++)
+ PutConsoleChar(buf[i],0b1111111111000000);
+
+ return len;
+}
+
+int syscall_read(int file, char *buf, int len)
+{
+
+ char c;
+
+ while(1)
+ {
+ asm("cli");
+ bool ret=ringbuffer_get(&c);
+ asm("sti");
+
+ if(ret)
+ {
+ *buf=c;
+ return 1;
+ }
+
+// if(ret) log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"read kb buffer: %d",c);
+ }
+
+
}
+//
int example_syscall(int x,int y)
{
diff --git a/lib/buffer/ringbuffer.c b/lib/buffer/ringbuffer.c
new file mode 100644
index 0000000..cdb5fed
--- /dev/null
+++ b/lib/buffer/ringbuffer.c
@@ -0,0 +1,96 @@
+// can handle one buffer for a start.
+// later make it reentrant and manage multiple buffers!
+// todo: syncing access to buffer.
+
+#define FOOLOS_MODULE_NAME "ringbuffer"
+#include "lib/bool/bool.h"
+#include "lib/logger/log.h"
+
+static volatile int front;
+static volatile int back;
+static volatile int size;
+
+#define RINGBUFFER_SIZE 10
+static volatile char buf[RINGBUFFER_SIZE];
+
+bool ringbuffer_selftest();
+
+void ringbuffer_init()
+{
+ size=RINGBUFFER_SIZE;
+ front=size-1;
+ back=size-1;
+
+// ringbuffer_selftest();
+// while(1);
+}
+
+bool ringbuffer_put(char c)
+{
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"put wants lock)");
+ lock_spin(3);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"locked by put)");
+ if((back-1+size)%size==front)
+ {
+ lock_release(3);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"unlocked by put)");
+ return false;
+ }
+ buf[back]=c;
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"put %d %d (%c)", back, front,c);
+ back--;
+ back+=size;
+ back%=size;
+ lock_release(3);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"unlocked by put)");
+
+ return true;
+}
+
+bool ringbuffer_get(char *c)
+{
+
+
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"get wants lock)");
+ lock_spin(3);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"locked by get)");
+ if(front==back)
+ {
+ lock_release(3);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"unlocked by get)");
+ return false;
+ }
+
+ *c=buf[front];
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"get %d %d (%c)", back, front,*c);
+
+ front--;
+ front+=size;
+ front%=size;
+
+ lock_release(3);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"unlocked by get)");
+
+ return true;
+}
+
+bool ringbuffer_selftest()
+{
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"ringbuffer selftest");
+ char c;
+
+ ringbuffer_put('a');
+ ringbuffer_put('b');
+ ringbuffer_put('c');
+ ringbuffer_put('d');
+ ringbuffer_put('e');
+
+ ringbuffer_get(&c);
+ ringbuffer_get(&c);
+ ringbuffer_get(&c);
+ ringbuffer_get(&c);
+ ringbuffer_get(&c);
+ ringbuffer_get(&c);
+ ringbuffer_get(&c);
+
+}
diff --git a/lib/logger/log.c b/lib/logger/log.c
index 331726f..6d107f8 100644
--- a/lib/logger/log.c
+++ b/lib/logger/log.c
@@ -21,7 +21,6 @@ void log(char *module_name, int log_level, char *format_string, ...)
if(log_level<FOOLOS_LOG_INFO)return;
-
char buf_info[256];
char buf_log[256];
char buf_time[20];
diff --git a/userspace/Makefile b/userspace/Makefile
index 21c4560..fc5e2dd 100644
--- a/userspace/Makefile
+++ b/userspace/Makefile
@@ -8,7 +8,7 @@ LDFLAGS=-L/home/miguel/temp/fool-os-stuff/newlib-build-clean/i686-elf/newlib/ \
-L/home/miguel/temp/fool-os-stuff/newlib-build-clean/i686-elf/libgloss/libnosys/ \
-lnosys
-all: brainfuck.o crt0.o
- ${CC} -T linker.ld ${LDFLAGS} brainfuck.o -Wl,--oformat,binary -o userprog
+all: foolshell.o crt0.o
+ ${CC} -T linker.ld ${LDFLAGS} $< -Wl,--oformat,binary -o userprog
clean:
-rm *.o *.out userprog
diff --git a/userspace/foolshell.c b/userspace/foolshell.c
new file mode 100644
index 0000000..bc02102
--- /dev/null
+++ b/userspace/foolshell.c
@@ -0,0 +1,34 @@
+#include <stdio.h>
+#include "syscalls.c"
+
+void hello() {
+ puts(
+ "Welcome to FoolShell v0.1"
+ );
+}
+
+void prompt() {
+ printf(
+ "$ "
+ );
+}
+int main(int argc, char **argv)
+{
+ syscalls_init();
+ hello();
+
+ FILE *input;
+ input=fopen(1,"r");
+ char *buf=malloc(256);
+
+ while(1)
+ {
+ prompt();
+ fgets(buf,255,input);
+ buf[strlen(buf)-1]=0;
+ puts(buf);
+ }
+
+
+ return 0;
+}
diff --git a/userspace/syscalls.c b/userspace/syscalls.c
index 7b0f563..f4e77a1 100644
--- a/userspace/syscalls.c
+++ b/userspace/syscalls.c
@@ -45,23 +45,27 @@ int lseek(int file, int ptr, int dir)
int read(int file, char *ptr, int len)
{
-// easywrite("syscall: read\n");
+ int ebx; // will hold return value;
+
+ asm("pusha");
+
+ // select syscall
+ asm("mov $62,%eax");
- int i;
- char buf[]="++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.";
+ // pass params
+ asm("mov %0,%%edx"::"m"(file));
+ asm("mov %0,%%ecx"::"m"(ptr));
+ asm("mov %0,%%ebx"::"m"(len));
- if(preread>=strlen(buf)){
-// easywrite("syscall: read = EOF\n");
- return 0; //EOF
- }
+ // interrrupt
+ asm("int $0x80");
- for(i=0;i<len;i++)
- {
- if(preread>=strlen(buf))return i;
- ptr[i]=buf[preread++];
- }
+ // get return value
+ asm("mov %%ebx, %0": "=b" (ebx));
+
+ asm("popa");
- return len;
+ return ebx;
}
int open(const char *name, int flags, int mode)
@@ -73,28 +77,28 @@ int open(const char *name, int flags, int mode)
int write(int file, char *ptr, int len)
{
- int todo;
- for (todo = 0; todo < len; todo++)
- {
-
- char byte=(*ptr++);
- int byt=byte;
int ebx; // will hold return value;
- // system call
+
asm("pusha");
- asm("mov $61,%eax"); // select syscall)
+
+ // select syscall
+ asm("mov $61,%eax");
- asm("mov %0,%%edx"::"m"(byt));
- //asm("mov $88,%edx");
+ // pass params
+ asm("mov %0,%%edx"::"m"(file));
+ asm("mov %0,%%ecx"::"m"(ptr));
+ asm("mov %0,%%ebx"::"m"(len));
+
+ // interrupt
+ asm("int $0x80");
+
+ // get return value
+ asm("mov %%ebx, %0": "=b" (ebx));
- asm("int $0x80"); // actual syscall ! interrupt
- asm("mov %%ebx, %0": "=b" (ebx));
asm("popa");
- //
- }
- return len;
+ return ebx;
}