diff options
| author | Michal Idziorek <m.i@gmx.at> | 2014-10-21 19:08:03 +0200 |
|---|---|---|
| committer | Michal Idziorek <m.i@gmx.at> | 2014-10-21 19:08:03 +0200 |
| commit | d25834310293c8a30b4a31418ff4ffd8fad8ef24 (patch) | |
| tree | 97ae696211f7709002d80ecbfb8595123611d3c1 | |
| parent | 5b9ea685dfd12415774e4e97ad387c601dd2b43b (diff) | |
started implementing our first fool-shell.
| -rw-r--r-- | Makefile | 3 | ||||
| -rw-r--r-- | asm/int_syscall_handler.asm | 39 | ||||
| -rw-r--r-- | kernel/kernel.c | 9 | ||||
| -rw-r--r-- | kernel/keyboard.c | 67 | ||||
| -rw-r--r-- | kernel/spinlock.c | 4 | ||||
| -rw-r--r-- | kernel/syscalls.c | 32 | ||||
| -rw-r--r-- | lib/buffer/ringbuffer.c | 96 | ||||
| -rw-r--r-- | lib/logger/log.c | 1 | ||||
| -rw-r--r-- | userspace/Makefile | 4 | ||||
| -rw-r--r-- | userspace/foolshell.c | 34 | ||||
| -rw-r--r-- | userspace/syscalls.c | 60 |
11 files changed, 260 insertions, 89 deletions
@@ -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; } |
