From 218557a7af5b281c871ba29690daa7873d0877fa Mon Sep 17 00:00:00 2001 From: Piotr Podusowski Date: Mon, 23 Dec 2013 23:53:37 +0100 Subject: [PATCH] import last known source tree --- include/drax.h | 43 ++++ include/libc.h | 16 ++ include/limits.h | 56 +++++ include/stdarg.h | 15 ++ include/syscall.h | 53 ++++ include/system.h | 30 +++ src/crt0/Makefile | 2 + src/crt0/compile.log | 0 src/crt0/crt0.asm | 6 + src/floppyd/Makefile | 10 + src/floppyd/compile.log | 11 + src/floppyd/floppyd.c | 313 +++++++++++++++++++++++ src/floppyd/floppyd.h | 52 ++++ src/floppyd/link.ld | 29 +++ src/floppyd/map.txt | 166 +++++++++++++ src/idle/Makefile | 8 + src/idle/compile.log | 3 + src/idle/idle.c | 4 + src/idle/link.ld | 29 +++ src/kernel/Makefile | 31 +++ src/kernel/console.c | 96 ++++++++ src/kernel/elf.c | 118 +++++++++ src/kernel/entry.asm | 121 +++++++++ src/kernel/exception.c | 51 ++++ src/kernel/gdt.c | 65 +++++ src/kernel/include/console.h | 12 + src/kernel/include/draco.h | 41 ++++ src/kernel/include/elf.h | 394 +++++++++++++++++++++++++++++ src/kernel/include/exception.h | 7 + src/kernel/include/gdt.h | 14 ++ src/kernel/include/inlines.h | 198 +++++++++++++++ src/kernel/include/ints.h | 68 +++++ src/kernel/include/ipc.h | 7 + src/kernel/include/kernel.h | 6 + src/kernel/include/keyboard.h | 6 + src/kernel/include/paging.h | 11 + src/kernel/include/proc.h | 11 + src/kernel/include/types.h | 139 +++++++++++ src/kernel/ints.c | 150 +++++++++++ src/kernel/ipc.c | 48 ++++ src/kernel/isr.asm | 209 ++++++++++++++++ src/kernel/kernel.c | 32 +++ src/kernel/link.ld | 0 src/kernel/modules.c | 32 +++ src/kernel/paging.c | 115 +++++++++ src/kernel/paging.c~ | 115 +++++++++ src/kernel/proc.c | 437 +++++++++++++++++++++++++++++++++ src/kernel/syscall.c | 244 ++++++++++++++++++ src/keybd/Makefile | 10 + src/keybd/compile.log | 8 + src/keybd/keybd.c | 119 +++++++++ src/keybd/link.ld | 29 +++ src/libc/Makefile | 25 ++ src/libc/compile.log | 0 src/libc/memcpy.c | 13 + src/libc/memset.c | 12 + src/libc/printf.c | 64 +++++ src/libc/sprintf.c | 72 ++++++ src/libc/strchr.c | 13 + src/libc/strcmp.c | 12 + src/libc/strlen.c | 10 + src/libc/ultoa.c | 90 +++++++ src/libsys/Makefile | 18 ++ src/libsys/compile.log | 0 src/libsys/system.c | 122 +++++++++ src/libsys/systemcall.asm | 25 ++ src/mon/Makefile | 10 + src/mon/compile.log | 3 + src/mon/link.ld | 29 +++ src/mon/map.txt | 148 +++++++++++ src/mon/mon.c | 63 +++++ src/moused/Makefile | 10 + src/moused/compile.log | 3 + src/moused/link.ld | 29 +++ src/moused/map.txt | 148 +++++++++++ src/moused/moused.c | 117 +++++++++ src/moused/moused.h | 52 ++++ src/sh/Makefile | 10 + src/sh/compile.log | 8 + src/sh/link.ld | 29 +++ src/sh/sh.c | 55 +++++ src/storaged/Makefile | 10 + src/storaged/compile.log | 5 + src/storaged/link.ld | 29 +++ src/storaged/storaged.c | 90 +++++++ src/storaged/storaged.h | 27 ++ src/test/Makefile | 19 ++ src/test/link.ld | 29 +++ src/test/map.txt | 152 ++++++++++++ src/test/test.c | 58 +++++ 90 files changed, 5399 insertions(+) create mode 100755 include/drax.h create mode 100755 include/libc.h create mode 100755 include/limits.h create mode 100755 include/stdarg.h create mode 100755 include/syscall.h create mode 100755 include/system.h create mode 100755 src/crt0/Makefile create mode 100755 src/crt0/compile.log create mode 100755 src/crt0/crt0.asm create mode 100755 src/floppyd/Makefile create mode 100755 src/floppyd/compile.log create mode 100755 src/floppyd/floppyd.c create mode 100755 src/floppyd/floppyd.h create mode 100755 src/floppyd/link.ld create mode 100755 src/floppyd/map.txt create mode 100755 src/idle/Makefile create mode 100755 src/idle/compile.log create mode 100755 src/idle/idle.c create mode 100755 src/idle/link.ld create mode 100755 src/kernel/Makefile create mode 100755 src/kernel/console.c create mode 100755 src/kernel/elf.c create mode 100755 src/kernel/entry.asm create mode 100755 src/kernel/exception.c create mode 100755 src/kernel/gdt.c create mode 100755 src/kernel/include/console.h create mode 100755 src/kernel/include/draco.h create mode 100755 src/kernel/include/elf.h create mode 100755 src/kernel/include/exception.h create mode 100755 src/kernel/include/gdt.h create mode 100755 src/kernel/include/inlines.h create mode 100755 src/kernel/include/ints.h create mode 100755 src/kernel/include/ipc.h create mode 100755 src/kernel/include/kernel.h create mode 100755 src/kernel/include/keyboard.h create mode 100755 src/kernel/include/paging.h create mode 100755 src/kernel/include/proc.h create mode 100755 src/kernel/include/types.h create mode 100755 src/kernel/ints.c create mode 100755 src/kernel/ipc.c create mode 100755 src/kernel/isr.asm create mode 100755 src/kernel/kernel.c create mode 100755 src/kernel/link.ld create mode 100755 src/kernel/modules.c create mode 100755 src/kernel/paging.c create mode 100755 src/kernel/paging.c~ create mode 100755 src/kernel/proc.c create mode 100755 src/kernel/syscall.c create mode 100755 src/keybd/Makefile create mode 100755 src/keybd/compile.log create mode 100755 src/keybd/keybd.c create mode 100755 src/keybd/link.ld create mode 100755 src/libc/Makefile create mode 100755 src/libc/compile.log create mode 100755 src/libc/memcpy.c create mode 100755 src/libc/memset.c create mode 100755 src/libc/printf.c create mode 100755 src/libc/sprintf.c create mode 100755 src/libc/strchr.c create mode 100755 src/libc/strcmp.c create mode 100755 src/libc/strlen.c create mode 100755 src/libc/ultoa.c create mode 100755 src/libsys/Makefile create mode 100755 src/libsys/compile.log create mode 100755 src/libsys/system.c create mode 100755 src/libsys/systemcall.asm create mode 100755 src/mon/Makefile create mode 100755 src/mon/compile.log create mode 100755 src/mon/link.ld create mode 100755 src/mon/map.txt create mode 100755 src/mon/mon.c create mode 100755 src/moused/Makefile create mode 100755 src/moused/compile.log create mode 100755 src/moused/link.ld create mode 100755 src/moused/map.txt create mode 100755 src/moused/moused.c create mode 100755 src/moused/moused.h create mode 100755 src/sh/Makefile create mode 100755 src/sh/compile.log create mode 100755 src/sh/link.ld create mode 100755 src/sh/sh.c create mode 100755 src/storaged/Makefile create mode 100755 src/storaged/compile.log create mode 100755 src/storaged/link.ld create mode 100755 src/storaged/storaged.c create mode 100755 src/storaged/storaged.h create mode 100755 src/test/Makefile create mode 100755 src/test/link.ld create mode 100755 src/test/map.txt create mode 100755 src/test/test.c diff --git a/include/drax.h b/include/drax.h new file mode 100755 index 0000000..de85b11 --- /dev/null +++ b/include/drax.h @@ -0,0 +1,43 @@ +#ifndef __DRAX__H__ +#define __DRAX__H__ + +typedef struct { + unsigned long + type, + lparam, + hparam, + from; +} message_t; + +typedef int bool; + +#define PROC_CLASS_A 1 +#define PROC_CLASS_B 2 + +#define PROC_STATE_READY 1 +#define PROC_STATE_SLEEPING 2 +#define PROC_STATE_SLAVE 4 +#define PROC_STATE_KILLED 5 + +/* te wartosci musza byc stale */ +#define SLEEP_IRQ1 (1 << 1) +#define SLEEP_IRQ2 (1 << 2) +#define SLEEP_IRQ3 (1 << 3) +#define SLEEP_IRQ4 (1 << 4) +#define SLEEP_IRQ5 (1 << 5) +#define SLEEP_IRQ6 (1 << 6) +#define SLEEP_IRQ7 (1 << 7) +#define SLEEP_IRQ8 (1 << 8) +#define SLEEP_IRQ9 (1 << 9) +#define SLEEP_IRQ10 (1 << 10) +#define SLEEP_IRQ11 (1 << 11) +#define SLEEP_IRQ12 (1 << 12) +#define SLEEP_IRQ13 (1 << 13) +#define SLEEP_IRQ14 (1 << 14) +#define SLEEP_IRQ15 (1 << 15) +#define SLEEP_IRQ16 (1 << 16) + +#define SLEEP_MESSAGE (1 << 17) +#define SLEEP_SLAVE (1 << 18) + +#endif // __DRAX__H__ diff --git a/include/libc.h b/include/libc.h new file mode 100755 index 0000000..0620a0e --- /dev/null +++ b/include/libc.h @@ -0,0 +1,16 @@ +#ifndef __LIBC__H +#define __LIBC__H + +#include "limits.h" + +char * ultoa( unsigned long val , int base ); +int strlen( char * str ); +void * memcpy( void * dest , const void * src , unsigned long num ); +int sprintf( char * dest , const char * fmt , ... ); +void printf(const char * fmt, ...); +void * memset( void * buffer , int c , unsigned long num ); +int strcmp( const char * s1, const char * s2 ); +char * strchr( const char * s, char c ); + +#endif + diff --git a/include/limits.h b/include/limits.h new file mode 100755 index 0000000..9c6cccf --- /dev/null +++ b/include/limits.h @@ -0,0 +1,56 @@ +#ifndef _LIMITS_H +#define _LIMITS_H + +/* Number of bits in a `char'. */ +#define CHAR_BIT 8 + +/* Maximum length of any multibyte character in any locale. + Locale-writers should change this as necessary. */ +#define MB_LEN_MAX 1 + +/* Minimum and maximum values a `signed char' can hold. */ +#define SCHAR_MIN (-128) +#define SCHAR_MAX 127 + +/* Maximum value an `unsigned char' can hold. (Minimum is 0.) */ +#ifdef __STDC__ +#define UCHAR_MAX 255U +#else +#define UCHAR_MAX 255 +#endif + +/* Minimum and maximum values a `char' can hold. */ +#ifdef __CHAR_UNSIGNED__ +#define CHAR_MIN 0 +#define CHAR_MAX UCHAR_MAX +#else +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX +#endif + +/* Minimum and maximum values a `signed short int' can hold. */ +#define SHRT_MIN (-32768) +#define SHRT_MAX 32767 + +/* Maximum value an `unsigned short int' can hold. (Minimum is 0.) */ +#define USHRT_MAX 65535 + +/* Minimum and maximum values a `signed int' can hold. */ +#define INT_MIN (- INT_MAX - 1) +#define INT_MAX 2147483647 + +/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */ +#ifdef __STDC__ +#define UINT_MAX 4294967295U +#else +#define UINT_MAX 4294967295 +#endif + +/* Minimum and maximum values a `signed long int' can hold. */ +#define LONG_MIN INT_MIN +#define LONG_MAX INT_MAX + +/* Maximum value an `unsigned long int' can hold. (Minimum is 0.) */ +#define ULONG_MAX UINT_MAX + +#endif /* limits.h */ diff --git a/include/stdarg.h b/include/stdarg.h new file mode 100755 index 0000000..d562d6d --- /dev/null +++ b/include/stdarg.h @@ -0,0 +1,15 @@ +#ifndef _STDARG_H +#define _STDARG_H + +typedef char *va_list; + +/* only correct for i386 */ +#define va_start(ap,last) ap = ((char *)&(last)) + ((sizeof(last)+3)&~3) +#define va_arg(ap,type) (ap += (sizeof(type)+3)&~3, *(type *)(ap - ((sizeof(type)+3)&~3))) +#define va_end(ap) + +/* fix a buggy dependency on GCC in libio.h */ +typedef va_list __gnuc_va_list; +#define _VA_LIST_DEFINED + +#endif diff --git a/include/syscall.h b/include/syscall.h new file mode 100755 index 0000000..0d05355 --- /dev/null +++ b/include/syscall.h @@ -0,0 +1,53 @@ +#ifndef __SYSCALL__H +#define __SYSCALL__H + +#define SYSCALL_EXIT 0x00000000 + +#define SYSCALL_GET_HEAP_SIZE 0x00000001 +#define SYSCALL_SET_HEAP_SIZE 0x00000002 + +#define SYSCALL_GET_PID 0x00000003 +#define SYSCALL_GET_PROCESS_NAME 0x00000007 +#define SYSCALL_GET_PROCESS_COUNT 0x00000100 +#define SYSCALL_GET_MEMORY_USAGE 0x00000101 +#define SYSCALL_IS_PROCESS 0x00000102 +#define SYSCALL_GET_TICKS 0x00000103 +#define SYSCALL_FIND_PROCESS 0x00000104 +#define SYSCALL_SET_MY_NAME 0x00000105 +#define SYSCALL_GET_PROCESS_STATE 0x00000106 + +#define SYSCALL_STI 0x00000106 +#define SYSCALL_CLI 0x00000107 + +#define SYSCALL_PUTS 0x00000005 +#define SYSCALL_PUTC 0x00000006 +#define SYSCALL_SET_CARRET_POS 0x00000200 +#define SYSCALL_GET_CARRET_POS 0x00000201 +#define SYSCALL_SET_CONSOLE_ATTRIBUTE 0x00000202 +#define SYSCALL_GET_CONSOLE_ATTRIBUTE 0x00000203 + +#define SYSCALL_SEND_MESSAGE 0x00000010 +#define SYSCALL_GET_MESSAGE 0x00000011 + +#define SYSCALL_CREATE_SHARED_FRAME 0x00000012 +#define SYSCALL_FREE_SHARED_FRAME 0x00000013 + +#define SYSCALL_REGISTER_CALLBACK 0x00000014 +#define SYSCALL_FREE_CALLBACK 0x00000015 + +/* kontrola IRQ */ +#define SYSCALL_CLEAR_IRQ_STATUS 0xA0000001 +#define SYSCALL_GET_IRQ_STATUS 0xA0000002 + +#define SYSCALL_IRQ_ENABLE 0xA0000003 +#define SYSCALL_IRQ_DISABLE 0xA0000004 + +#define SYSCALL_SLEEP 0xA0000005 +#define SYSCALL_SET_PROCESS_STATE 0xA0000006 + +#define SYSCALL_UNAME 0xA0000007 +#define SYSCALL_GET_BOOT_DEVICE 0xA0000008 + +unsigned long do_syscall(unsigned long eax, unsigned long ebx, unsigned long ecx, unsigned long edx); + +#endif diff --git a/include/system.h b/include/system.h new file mode 100755 index 0000000..8eb1916 --- /dev/null +++ b/include/system.h @@ -0,0 +1,30 @@ +#ifndef __SYSTEM__H +#define __SYSTEM__H + +#include "drax.h" + +void uname(char * s); +void * createsharedframe(int pid); +bool freesharedframe(); +int findprocess(char * name); +bool getmessage(message_t * msg); +int getpid(); +int getprocesscount(); +bool getprocessname(int pid, char * buf); +void setprocessstate(int pid, int state); +int getprocessstate(int pid); +unsigned long gettickcount(); +bool isprocess(int pid); +bool sendmessage(int pid, message_t * msg); +void setmyname(char * name); +void puts(char * s); +void putc(char c); +void gets(char * s); +void sleep(unsigned long flags); +void enableirq(int irq); +void disableirq(int irq); +unsigned int getirqstatus(int irq); +void clearirqstatus(int irq); +int getbootdevice(); + +#endif /* __SYSTEM__H */ diff --git a/src/crt0/Makefile b/src/crt0/Makefile new file mode 100755 index 0000000..991856c --- /dev/null +++ b/src/crt0/Makefile @@ -0,0 +1,2 @@ +all: + nasm crt0.asm -o crt0.o -f elf diff --git a/src/crt0/compile.log b/src/crt0/compile.log new file mode 100755 index 0000000..e69de29 diff --git a/src/crt0/crt0.asm b/src/crt0/crt0.asm new file mode 100755 index 0000000..ec79edd --- /dev/null +++ b/src/crt0/crt0.asm @@ -0,0 +1,6 @@ +section .text +extern main +call main +xor eax, eax +int 0x80 +jmp $ diff --git a/src/floppyd/Makefile b/src/floppyd/Makefile new file mode 100755 index 0000000..5ea622e --- /dev/null +++ b/src/floppyd/Makefile @@ -0,0 +1,10 @@ +NAME = floppyd + +OBJS = ../../lib/libc.o \ + ../../lib/libsys.o \ + +CFLAGS = -O2 -fomit-frame-pointer -I ../kernel/include -I ../../include -nostdinc -fno-builtin -DDEBUG + +all: + /usr/cross/i586-elf/bin/gcc -c $(CFLAGS) -o $(NAME).o $(NAME).c + ld -T /usr/cross/i586-elf/lib/ldscripts/elf_i386.x -o ../../bin/$(NAME).dri ../crt0/crt0.o $(NAME).o $(OBJS) diff --git a/src/floppyd/compile.log b/src/floppyd/compile.log new file mode 100755 index 0000000..be4f246 --- /dev/null +++ b/src/floppyd/compile.log @@ -0,0 +1,11 @@ +floppyd.c: In function `fdc_init': +floppyd.c:247: warning: assignment makes integer from pointer without a cast +floppyd.c:249: warning: assignment makes integer from pointer without a cast +floppyd.c:251: warning: assignment makes integer from pointer without a cast +floppyd.c: In function `main': +floppyd.c:282: warning: passing arg 1 of `memcpy' makes pointer from integer without a cast +floppyd.c:282: warning: passing arg 2 of `memcpy' makes pointer from integer without a cast +floppyd.c:296: warning: passing arg 1 of `memcpy' makes pointer from integer without a cast +floppyd.c:296: warning: passing arg 2 of `memcpy' makes pointer from integer without a cast +floppyd.c:262: warning: return type of 'main' is not `int' +ld: warning: cannot find entry symbol _start; defaulting to 0000000001000080 diff --git a/src/floppyd/floppyd.c b/src/floppyd/floppyd.c new file mode 100755 index 0000000..b5a3d45 --- /dev/null +++ b/src/floppyd/floppyd.c @@ -0,0 +1,313 @@ +#include "draco.h" +#include "drax.h" +#include "libc.h" +#include "floppyd.h" +#include "../storaged/storaged.h" + +uint8 MaskReg[8] = { 0x0A, 0x0A, 0x0A, 0x0A, 0xD4, 0xD4, 0xD4, 0xD4 }; +uint8 ModeReg[8] = { 0x0B, 0x0B, 0x0B, 0x0B, 0xD6, 0xD6, 0xD6, 0xD6 }; +uint8 ClearReg[8] = { 0x0C, 0x0C, 0x0C, 0x0C, 0xD8, 0xD8, 0xD8, 0xD8 }; + +uint8 PagePort[8] = { 0x87, 0x83, 0x81, 0x82, 0x8F, 0x8B, 0x89, 0x8A }; +uint8 AddrPort[8] = { 0x00, 0x02, 0x04, 0x06, 0xC0, 0xC4, 0xC8, 0xCC }; +uint8 CountPort[8] = { 0x01, 0x03, 0x05, 0x07, 0xC2, 0xC6, 0xCA, 0xCE }; + +void dma_xfer(uint8 channel, uint8 page, uint16 length, int read) +{ + outb(MaskReg[channel], 0x04 | channel); // setup DMA channel + outb(ClearReg[channel], 0x00); // reset channel (if sometn is transfered) + + if (read) + outb(ModeReg[channel], 0x46); + else + outb(ModeReg[channel], 0x4A); + + outb(AddrPort[channel], 0); // send offset (low, next high byte) + outb(AddrPort[channel], 0); + outb(PagePort[channel], page); // send the physical page that the data lies on. + outb(CountPort[channel], length & 0x00FF); // data length (low, high byte) + outb(CountPort[channel], length >> 8); + outb(MaskReg[channel], channel); // enable DMA channel +} + +char fdc_drive = 0; +volatile char fdc_sr0; +volatile char fdc_track; +volatile char fdc_status[7] = { 0 }; +volatile char fdc_statsz = 0; + +void fdc_block2hts(uint16 block, uint16 *head, uint16 *track, uint16 *sector) +{ + *head = (block % (18 * 2)) / (18); + *track = block / (18 * 2); + *sector = block % 18 + 1; +} + +uint8 fdc_wait(uint8 send_sensei) +{ + uint32 i = 0; + + while (!systemcall(SYSCALL_GET_IRQ_STATUS, 6) && (i < 40000)) + i++; + + if (systemcall(SYSCALL_GET_IRQ_STATUS, 6)) + { + systemcall(SYSCALL_CLEAR_IRQ_STATUS, 6); + } + + fdc_statsz = 0; + while ((fdc_statsz < 7) && (inb(FDC_MSR) & (1<<4))) + fdc_status[fdc_statsz++] = fdc_getbyte(); + + if (send_sensei) + { + fdc_sendbyte(FDC_CMD_SENSEI); + fdc_sr0 = fdc_getbyte(); + fdc_track = fdc_getbyte(); + } + + systemcall(SYSCALL_CLEAR_IRQ_STATUS, 6); + + if (i >= 40000) + { + printf("floppyd: operation timeout\n", 7); + return 0; + } + return 1; +} + +/* wg intela */ +void fdc_sendbyte(uint8 byte) +{ + volatile int msr; + int tmo; + + for (tmo = 0; tmo < 128; tmo++) + { + msr = inb(FDC_MSR); + if ((msr & 0xc0) == 0x80) + { + outb(FDC_DATA,byte); + return; + } + inb(0x80); /* delay */ + } +} + +uint8 fdc_getbyte() +{ + volatile int msr; + int tmo; + + for (tmo = 0; tmo < 128; tmo++) + { + msr = inb(FDC_MSR); + if ((msr & 0xd0) == 0xd0) + return inb(FDC_DATA); + inb(0x80); /* delay */ + } + + return -1; /* read timeout */ +} + +void fdc_start_motor() +{ + outb(FDC_DOR, 0x1C); + int i = 0; for(; i < 10000; i++); +} + +void fdc_stop_motor() { outb(FDC_DOR, 0x0C); } + +void fdc_seek(uint16 track) +{ + if (fdc_track == track) return; + + /* send actual command bytes */ + fdc_sendbyte(FDC_CMD_SEEK); + fdc_sendbyte(0); + fdc_sendbyte(track); + + /* wait until seek finished */ + fdc_wait(1); + + /* now let head settle for 15ms */ + int i = 0; for(; i < 10000; i++); +} + +void fdc_recalibrate() +{ + fdc_sendbyte(FDC_CMD_RECAL); + fdc_sendbyte(0); + fdc_wait(1); +} + +void fdc_reset() +{ + /* stop the motor and disable IRQ/DMA */ + outb(FDC_DOR,0); + + /* program data rate (500K/s) */ + outb(FDC_DRS,0); + + /* re-enable interrupts */ + outb(FDC_DOR,0x0C); + + /* resetting triggered an interrupt - handle it */ + fdc_wait(1); + + /* specify drive timings (got these off the BIOS) */ + fdc_sendbyte(FDC_CMD_SPECIFY); + fdc_sendbyte(0xDF); /* SRT = 3ms, HUT = 240ms */ + fdc_sendbyte(0x02); /* HLT = 16ms, ND = 0 */ + + /* clear "disk change" status */ + fdc_start_motor(); + fdc_seek(1); + fdc_recalibrate(); + fdc_stop_motor(); +} + +void fdc_readwrite(uint16 block, int read) +{ + systemcall(SYSCALL_CLEAR_IRQ_STATUS, 6); + + uint16 head, track, sector; + uint32 i; + + fdc_block2hts(block, &head, &track, §or); + fdc_start_motor(); + + for (i = 1; i <= 3; i ++) + { + fdc_seek(track); + outb(FDC_CCR,0); + + dma_xfer(2, KERNEL_DMA_BUFFER >> 16, 511, read); + + fdc_sendbyte(read? FDC_CMD_READ : FDC_CMD_WRITE); + fdc_sendbyte(0); // drive 0, head 0 + fdc_sendbyte(track); // cylinder + fdc_sendbyte(head); // head + fdc_sendbyte(sector); // sector + fdc_sendbyte(2); // sector size 2 - 512 + fdc_sendbyte(18); // sectors per cylinder + fdc_sendbyte(DG144_GAP3RW); // narazie tylko 1.44 + fdc_sendbyte(0xFF); // length? (podobno nieuzywane) + + fdc_wait(0); //nie wymaga SENSEI + + if ( (fdc_status[0] & 0xC0) == 0 ) + break; + + if ( (fdc_status[0] & 0xC0) == 0xC0 ) + printf("floppyd: abnormal termination by polling (%d retries left)\n", 3-i); + } + + fdc_stop_motor(); +} + + +/* + 1 - 360kb 5.25in + 2 - 1.2mb 5.25in + 3 - 720kb 3.5in + 4 - 1.44mb 3.5in + 5 - 2.88mb 3.5in + 0 - No drive +*/ +void fdc_init() +{ + /* obslugujemy jednego flopa (narazie) */ + uint8 cmos; + + /* info o stacji wezmiemy sobie z cmos'a */ + outb(0x70, 0x10); + cmos = inb(0x71); + fdc_drive = cmos >> 4; + + static request_t request; + static message_t msg; + static uint32 result; + uint32 storaged_pid = 0; + + /* przyda tez sie wersja FDC */ + /* uint8 i = 0; + fdc_sendbyte(FDC_CMD_VERSION); + i = fdc_getbyte(); */ + + /* narazie bawimy sie tylko flopami 1.44 */ + if (fdc_drive == 4) + { + printf("floppyd: detected 1.44 floppy drive\n"); + enableirq(6); + fdc_reset(); + + /* zarejestruj urzadzenie */ + request.type = STORAGED_REGISTER; + request.a = "fd0"; + request.b = 0; + request.result = &result; + + msg.lparam = &request; + + while (!storaged_pid) storaged_pid = findprocess("storaged"); + sendmessage(storaged_pid, &msg); + //sleep(SLEEP_SLAVE); + } + else + printf("floppyd: no devices i can handle, sorry\n"); +} + +void main() +{ + static message_t msg; + unsigned long sharedframe; + + fdc_init(); + + setmyname("floppyd"); + + while(1) + { + sleep(SLEEP_MESSAGE); + if (getmessage(&msg)) + { + switch (msg.type) + { + case FLOPPYD_READ: + { + fdc_readwrite(msg.lparam, 1); + sharedframe = createsharedframe(msg.from); + //printf("buf == %x\n", msg.hparam); + memcpy(sharedframe + msg.hparam, KERNEL_DMA_BUFFER, 512); + + /* powiadamiamy, ze skonczylismy */ + msg.type = FLOPPYD_DONE; + sendmessage(msg.from, &msg); + + freesharedframe(); + + break; + } + case FLOPPYD_WRITE: + { + sharedframe = createsharedframe(msg.from); + //printf("buf == %x\n", msg.hparam); + memcpy(KERNEL_DMA_BUFFER, sharedframe + msg.hparam, 512); + + + fdc_readwrite(msg.lparam, 0); + + freesharedframe(); + + /* powiadamiamy, ze skonczylismy */ + msg.type = FLOPPYD_DONE; + sendmessage(msg.from, &msg); + + break; + } + } + } + } +} + diff --git a/src/floppyd/floppyd.h b/src/floppyd/floppyd.h new file mode 100755 index 0000000..7eacf4b --- /dev/null +++ b/src/floppyd/floppyd.h @@ -0,0 +1,52 @@ +#ifndef __FLOPPY__H +#define __FLOPPY__H + +/* io ports */ +#define FDC_DOR (0x3f2) /* Digital Output Register */ +#define FDC_MSR (0x3f4) /* Main Status Register (input) */ +#define FDC_DRS (0x3f4) /* Data Rate Select Register (output) */ +#define FDC_DATA (0x3f5) /* Data Register */ +#define FDC_DIR (0x3f7) /* Digital Input Register (input) */ +#define FDC_CCR (0x3f7) /* Configuration Control Register (output) */ + +/* command bytes (these are 765 commands + options such as MFM, etc) */ +#define FDC_CMD_RESET (0x00) +#define FDC_CMD_SPECIFY (0x03) /* specify drive timings */ +#define FDC_CMD_WRITE (0xc5) /* write data (+ MT,MFM) */ +#define FDC_CMD_READ (0xe6) /* read data (+ MT,MFM,SK) */ +#define FDC_CMD_RECAL (0x07) /* recalibrate */ +#define FDC_CMD_SENSEI (0x08) /* sense interrupt status */ +#define FDC_CMD_FORMAT (0x4d) /* format track (+ MFM) */ +#define FDC_CMD_SEEK (0x0f) /* seek track */ +#define FDC_CMD_VERSION (0x10) /* FDC version */ + +/* drive geometries */ +#define DG144_HEADS 2 /* heads per drive (1.44M) */ +#define DG144_TRACKS 80 /* number of tracks (1.44M) */ +#define DG144_SPT 18 /* sectors per track (1.44M) */ +#define DG144_GAP3FMT 0x54 /* gap3 while formatting (1.44M) */ +#define DG144_GAP3RW 0x1b /* gap3 while reading/writing (1.44M) */ + +#define DG168_HEADS 2 /* heads per drive (1.68M) */ +#define DG168_TRACKS 80 /* number of tracks (1.68M) */ +#define DG168_SPT 21 /* sectors per track (1.68M) */ +#define DG168_GAP3FMT 0x0c /* gap3 while formatting (1.68M) */ +#define DG168_GAP3RW 0x1c /* gap3 while reading/writing (1.68M) */ + +#define FLOPPYD_READ 1 +#define FLOPPYD_WRITE 2 +#define FLOPPYD_DONE 0xFFFF + +void fdc_block2hts(uint16 block, uint16 *head, uint16 *track, uint16 *sector); +uint8 fdc_wait(uint8 send_sensei); +void fdc_sendbyte(uint8 byte); +uint8 fdc_getbyte(); +void fdc_start_motor(); +void fdc_stop_motor(); +void fdc_seek(uint16 track); +void fdc_recalibrate(); +void fdc_reset(); +void fdc_readwrite(uint16 block, int read); +void fdc_init(); + +#endif diff --git a/src/floppyd/link.ld b/src/floppyd/link.ld new file mode 100755 index 0000000..f4fe914 --- /dev/null +++ b/src/floppyd/link.ld @@ -0,0 +1,29 @@ +OUTPUT_FORMAT("binary") +SECTIONS { + .text 0x1000000 : { + code = . ; _code = . ; + *(.text) + } + .rodata : { + rodata = .; + *(.rodata) + } + .rodata.str1.4 : { + rodata.str1.4 = .; + *(.rodata.str1.4) + } + .rodata.str1.1 : { + rodata.str1.1 = .; + *(.rodata.str1.1) + } + .data : { + *(.data) + edata = . ; + } + .bss : { + bss = . ; _bss = . ; + *(.bss) + *(.COMMON) + } + end = . ; _end = . ; +} diff --git a/src/floppyd/map.txt b/src/floppyd/map.txt new file mode 100755 index 0000000..be48584 --- /dev/null +++ b/src/floppyd/map.txt @@ -0,0 +1,166 @@ + +Allocating common symbols +Common symbol size file + +ultoabuf 0x9 ../../libc/ultoa.o +fdc_track 0x1 floppyd.o +fdc_sr0 0x1 floppyd.o + +Memory Configuration + +Name Origin Length Attributes +*default* 0x0000000000000000 0xffffffffffffffff + +Linker script and memory map + + +.text 0x0000000001000000 0xc6d + 0x0000000001000000 code = . + 0x0000000001000000 _code = . + *(.text) + .text 0x0000000001000000 0xb ../entry/entry.o + *fill* 0x000000000100000b 0x100000b00000001 00 + .text 0x000000000100000c 0x642 floppyd.o + 0x00000000010001b4 fdc_wait + 0x0000000001000334 fdc_reset + 0x0000000001000498 fdc_init + 0x0000000001000384 fdc_readwrite + 0x0000000001000314 fdc_recalibrate + 0x00000000010002c0 fdc_stop_motor + 0x0000000001000160 fdc_sendbyte + 0x0000000001000540 main + 0x00000000010002ac fdc_start_motor + 0x000000000100000c dma_xfer + 0x00000000010002cc fdc_seek + 0x0000000001000090 fdc_block2hts + 0x0000000001000110 fdc_getbyte + *fill* 0x000000000100064e 0x100064e00000002 00 + .text 0x0000000001000650 0x24 ../../libc/memcpy.o + 0x0000000001000650 memcpy + .text 0x0000000001000674 0x1e ../../libc/memset.o + 0x0000000001000674 memset + *fill* 0x0000000001000692 0x100069200000002 00 + .text 0x0000000001000694 0xd3 ../../libc/sprintf.o + 0x0000000001000694 sprintf + *fill* 0x0000000001000767 0x100076700000001 00 + .text 0x0000000001000768 0x8c ../../libc/printf.o + 0x0000000001000768 printf + .text 0x00000000010007f4 0x62 ../../libc/strlen.o + 0x00000000010007f4 strlen + *fill* 0x0000000001000856 0x100085600000002 00 + .text 0x0000000001000858 0x184 ../../libc/ultoa.o + 0x0000000001000858 __ultoa + 0x00000000010009a8 ultoa + .text 0x00000000010009dc 0x16 ../../libc/strchr.o + 0x00000000010009dc strchr + *fill* 0x00000000010009f2 0x10009f200000002 00 + .text 0x00000000010009f4 0x29 ../../libc/strcmp.o + 0x00000000010009f4 strcmp + *fill* 0x0000000001000a1d 0x1000a1d00000003 00 + .text 0x0000000001000a20 0x225 ../../libc/system.o + 0x0000000001000aac getprocessname + 0x0000000001000a74 getmessage + 0x0000000001000b94 gets + 0x0000000001000a5c findprocess + 0x0000000001000a88 getpid + 0x0000000001000b54 puts + 0x0000000001000b7c sleep + 0x0000000001000b3c setmyname + 0x0000000001000bd4 enableirq + 0x0000000001000ae0 getprocessstate + 0x0000000001000b24 sendmessage + 0x0000000001000a20 uname + 0x0000000001000a38 createsharedframe + 0x0000000001000c1c clearirqstatus + 0x0000000001000c04 getirqstatus + 0x0000000001000b68 putc + 0x0000000001000b0c isprocess + 0x0000000001000bec disableirq + 0x0000000001000a98 getprocesscount + 0x0000000001000a4c freesharedframe + 0x0000000001000c34 getbootdevice + 0x0000000001000af8 gettickcount + 0x0000000001000ac4 setprocessstate + *fill* 0x0000000001000c45 0x1000c450000000b 00 + .text 0x0000000001000c50 0x1d ../../libc/systemcall.o + 0x0000000001000c50 systemcall + +.rodata 0x0000000001000c70 0x108 + 0x0000000001000c70 rodata = . + *(.rodata) + .rodata 0x0000000001000c70 0x84 ../../libc/sprintf.o + .rodata 0x0000000001000cf4 0x84 ../../libc/printf.o + +.rodata.str1.4 0x0000000001000d78 0x8d + 0x0000000001000d78 rodata.str1.4 = . + *(.rodata.str1.4) + .rodata.str1.4 + 0x0000000001000d78 0x8d floppyd.o + +.rodata.str1.1 0x0000000001000e05 0x48 + 0x0000000001000e05 rodata.str1.1 = . + *(.rodata.str1.1) + .rodata.str1.1 + 0x0000000001000e05 0x31 floppyd.o + .rodata.str1.1 + 0x0000000001000e36 0x11 ../../libc/ultoa.o + .rodata.str1.1 + 0x0000000001000e47 0x6 ../../libc/system.o + +.data 0x0000000001000e50 0x30 + *(.data) + .data 0x0000000001000e50 0x30 floppyd.o + 0x0000000001000e50 CountPort + 0x0000000001000e58 AddrPort + 0x0000000001000e68 ClearReg + 0x0000000001000e70 ModeReg + 0x0000000001000e78 MaskReg + 0x0000000001000e60 PagePort + 0x0000000001000e80 edata = . + +.bss 0x0000000001000e80 0x5f + 0x0000000001000e80 bss = . + 0x0000000001000e80 _bss = . + *(.bss) + .bss 0x0000000001000e80 0x44 floppyd.o + 0x0000000001000e80 fdc_statsz + 0x0000000001000e81 fdc_status + 0x0000000001000e88 fdc_drive + .bss 0x0000000001000ec4 0x10 ../../libc/system.o + *(.COMMON) + COMMON 0x0000000001000ed4 0x2 floppyd.o + 0x0 (size before relaxing) + 0x0000000001000ed4 fdc_track + 0x0000000001000ed5 fdc_sr0 + COMMON 0x0000000001000ed6 0x9 ../../libc/ultoa.o + 0x0 (size before relaxing) + 0x0000000001000ed6 ultoabuf + 0x0000000001000edf end = . + 0x0000000001000edf _end = . +LOAD ../entry/entry.o +LOAD floppyd.o +LOAD ../../libc/memcpy.o +LOAD ../../libc/memset.o +LOAD ../../libc/sprintf.o +LOAD ../../libc/printf.o +LOAD ../../libc/strlen.o +LOAD ../../libc/ultoa.o +LOAD ../../libc/strchr.o +LOAD ../../libc/strcmp.o +LOAD ../../libc/system.o +LOAD ../../libc/systemcall.o +OUTPUT(../../bin/floppyd.dri binary) + +.comment 0x0000000000000000 0x1b0 + .comment 0x0000000000000000 0x1f ../entry/entry.o + .comment 0x000000000000001f 0x25 floppyd.o + .comment 0x0000000000000044 0x25 ../../libc/memcpy.o + .comment 0x0000000000000069 0x25 ../../libc/memset.o + .comment 0x000000000000008e 0x25 ../../libc/sprintf.o + .comment 0x00000000000000b3 0x25 ../../libc/printf.o + .comment 0x00000000000000d8 0x25 ../../libc/strlen.o + .comment 0x00000000000000fd 0x25 ../../libc/ultoa.o + .comment 0x0000000000000122 0x25 ../../libc/strchr.o + .comment 0x0000000000000147 0x25 ../../libc/strcmp.o + .comment 0x000000000000016c 0x25 ../../libc/system.o + .comment 0x0000000000000191 0x1f ../../libc/systemcall.o diff --git a/src/idle/Makefile b/src/idle/Makefile new file mode 100755 index 0000000..a0ae074 --- /dev/null +++ b/src/idle/Makefile @@ -0,0 +1,8 @@ +NAME = idle + +CFLAGS = -O2 -fomit-frame-pointer -I ../kernel/include -I ../../include -nostdinc -fno-builtin -DDEBUG + +all: + /usr/cross/i586-elf/bin/gcc -c $(CFLAGS) -o $(NAME).o $(NAME).c + ld -T /usr/cross/i586-elf/lib/ldscripts/elf_i386.x -o ../../bin/$(NAME).dri ../crt0/crt0.o $(NAME).o $(OBJS) + diff --git a/src/idle/compile.log b/src/idle/compile.log new file mode 100755 index 0000000..0d63498 --- /dev/null +++ b/src/idle/compile.log @@ -0,0 +1,3 @@ +idle.c: In function `main': +idle.c:2: warning: return type of 'main' is not `int' +ld: warning: cannot find entry symbol _start; defaulting to 0000000001000080 diff --git a/src/idle/idle.c b/src/idle/idle.c new file mode 100755 index 0000000..845d082 --- /dev/null +++ b/src/idle/idle.c @@ -0,0 +1,4 @@ +void main() +{ + while(1); +} diff --git a/src/idle/link.ld b/src/idle/link.ld new file mode 100755 index 0000000..f4fe914 --- /dev/null +++ b/src/idle/link.ld @@ -0,0 +1,29 @@ +OUTPUT_FORMAT("binary") +SECTIONS { + .text 0x1000000 : { + code = . ; _code = . ; + *(.text) + } + .rodata : { + rodata = .; + *(.rodata) + } + .rodata.str1.4 : { + rodata.str1.4 = .; + *(.rodata.str1.4) + } + .rodata.str1.1 : { + rodata.str1.1 = .; + *(.rodata.str1.1) + } + .data : { + *(.data) + edata = . ; + } + .bss : { + bss = . ; _bss = . ; + *(.bss) + *(.COMMON) + } + end = . ; _end = . ; +} diff --git a/src/kernel/Makefile b/src/kernel/Makefile new file mode 100755 index 0000000..77ced36 --- /dev/null +++ b/src/kernel/Makefile @@ -0,0 +1,31 @@ +.SUFFIXES: .asm .c; + +OUTFILE = ../../bin/kernel + +OBJS = entry.o \ + kernel.o \ + gdt.o \ + ints.o \ + isr.o \ + paging.o \ + proc.o \ + syscall.o \ + modules.o \ + console.o \ + exception.o \ + ipc.o \ + elf.o \ + ../../lib/libc.o + + +CFLAGS = -O2 -fomit-frame-pointer -I include -I ../../include -nostdinc -fno-builtin -DDEBUG + +$(OUTFILE): $(OBJS) + ld -T link.ld -o $(OUTFILE) $(OBJS) + +.asm.o: + nasm $*.asm -o $*.o -f elf + +.c.o: + gcc -c $(CFLAGS) -o $*.o $*.c + diff --git a/src/kernel/console.c b/src/kernel/console.c new file mode 100755 index 0000000..c1b61bb --- /dev/null +++ b/src/kernel/console.c @@ -0,0 +1,96 @@ +#include +#include "draco.h" + +#define MODULE_NAME "console" + +uint32 cons_carret = 0; +uint8 cons_attribute = 8; + +void clrscr() +{ + uint8 *vga = (uint8*)0xB8000; + for (; vga <= (uint8*)0xB8000 + 4000; vga ++) + { + *vga = 0; + } +} + +void putc(uint8 c) +{ + uint8 *vga = 0xB8000; + + vga += cons_carret * 2; + + if (c == 27) + { + vga -= 2; + *vga = 0; + *(vga + 1) = cons_attribute; + cons_carret --; + } + else + if (c == 10) + { + cons_carret += 80 - ( cons_carret % 80 ); + } + else + { + *vga = c; + *(vga + 1) = cons_attribute; + cons_carret ++; + } + + vga += 2; + *vga = ' '; + *(vga + 1) = cons_attribute; + + + if (cons_carret / 80 > 24) + { + cons_carret = 24 * 80; + memcpy((uint8 *)0xB8000, (uint8 *)0xB8000 + 160, 160 * 24); + + uint8 i; + for (i = 0; i <= 160; i ++) + { + *(uint8*)(0xB8000 + 3840 + i) = 0; + } + } + console_updatecursor(); +} + +void puts(int8 *str) +{ + while(*str != 0) + { + putc(*str); + str++; + } +} + +void print(int8 *str, int8 attribute) +{ + cons_attribute = attribute; + while(*str != 0) + { + putc(*str); + str++; + } + putc('\n'); +} + +void console_updatecursor() +{ + outb(0x3D4, 0x0F); + outb(0x3D5, (uint8)(cons_carret & 0xFF)); + + outb(0x3D4, 0x0E); + outb(0x3D5, (uint8)((cons_carret >> 8) & 0xFF)); +} + +void set_carret(uint32 x, uint32 y) +{ + cons_carret = (y * 80) + x; + console_updatecursor(); +} + diff --git a/src/kernel/elf.c b/src/kernel/elf.c new file mode 100755 index 0000000..a3ef021 --- /dev/null +++ b/src/kernel/elf.c @@ -0,0 +1,118 @@ +#include "draco.h" + + +char * elf_sectionName(void * image, int section) +{ + Elf32_Ehdr * header = image; + Elf32_Shdr * sections = image + header->e_shoff; + return image + sections[header->e_shstrndx].sh_offset + sections[section].sh_name; +} + +int elf_findSection(void * image, char * name) +{ + Elf32_Ehdr * header = image; + Elf32_Shdr * sections = image + header->e_shoff; + int i; + + for (i = 0; i < header->e_shnum; i++) + if (strcmp(elf_sectionName(image, i), name) == 0) + return i; + + return -1; +} + +Elf32_Sym * elf_findSymbol(void * image, char * name) +{ + +} + +uint32 elf_imageSize(void * image) +{ + Elf32_Ehdr * header = image; + Elf32_Shdr * sections = image + header->e_shoff; + uint32 result = 0; + int i; + + for (i = 0; i < header->e_shnum; i++) + if (sections[i].sh_addr > 0) + result += sections[i].sh_size; + + return result; +} + +/** zwraca eip, jak NULL to jakis blad */ +void * elf_relocate(void * image) +{ + return 0; +} + +void elf_exec(char * name, void * image, uint32 size) +{ + int i, t, reloc_size; + void * proc_mem = proc_createenv(elf_imageSize(image)); + void * proc_offset = KERNEL_MEMORY; + Elf32_Ehdr * header = image; + Elf32_Shdr * sections = image + header->e_shoff; + + + memcpy(get_physical_address(proc_mem, PROCESS_MEMORY), image, elf_imageSize(image)); + + + for (i = 1; i < header->e_shnum; i++) + { + printf("%s ", elf_sectionName(image, i)); + + if (sections[i].sh_type == SHT_RELA) /* RELA */ + { + for (t = 0; t < sections[i].sh_size / sizeof(Elf32_Rela); t++); + /* do_reloc */ + } + else if(sections[i].sh_type == SHT_REL) /* REL */ + { + for (t = 0; t < sections[i].sh_size / sizeof(Elf32_Rel); t++); + /* do_reloc */ + } + else continue; + } + + //memcpy(get_physical_address(proc_mem, KERNEL_MEMORY), image, size); + proc_add(name, PROC_CLASS_A, proc_mem, size, header->e_entry); +} + + +void elf_dump(void * image) +{ + int i; + + printf("\nelfinfo:\n"); + + Elf32_Ehdr * header = image; + + printf("e_ident[EI_CLASS]: %s\n", header->e_ident[EI_CLASS] == ELFCLASS32 ? "ELFCLASS32" : "ELFCLASS64"); + printf("e_entry: 0x%x\n", header->e_entry); + printf("e_type: %s\n", header->e_type == ET_EXEC ? "EXEC" : "NON-EXEC"); + printf("e_phoff: 0x%x\n", header->e_phoff); + printf("e_phnum: %d\n", header->e_phnum); + printf("e_shoff: 0x%x\n", header->e_shoff); + printf("e_shnum: %d\n", header->e_shnum); + printf("e_shstrndx: %d\n", header->e_shstrndx); + + + Elf32_Shdr * sections = image + header->e_shoff; + + printf("Sections dump (sh_offset:sh_size:sh_addr):\n"); + for (i = 0; i < header->e_shnum; i++) + { + printf(" %s (0x%x:0x%x:0x%x)\n", elf_sectionName(image, i), sections[i].sh_offset, sections[i].sh_size, sections[i].sh_addr); + } +/* + Elf32_Phdr * p_headers = image + header->e_phoff; + + printf("Program header dump:\n"); + for (i = 0; i < header->e_phnum; i++) + { + printf(" %s\n", elf_sectionName(image, i)); + printf(" p_offset: 0x%x\n", p_headers[i].p_offset); + } + */ +} diff --git a/src/kernel/entry.asm b/src/kernel/entry.asm new file mode 100755 index 0000000..fc83ac2 --- /dev/null +++ b/src/kernel/entry.asm @@ -0,0 +1,121 @@ +[BITS 32] + +[SECTION .text] + +MULTIBOOT_PAGE_ALIGN equ 1<<0 +MULTIBOOT_MEMORY_INFO equ 1<<1 +MULTIBOOT_AOUT_KLUDGE equ 1<<16 +MULTIBOOT_HEADER_MAGIC equ 0x1BADB002 +MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_AOUT_KLUDGE +CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) + +align 4 + +; wartosci z linkera +[extern code] +[extern edata] +[extern end] + +mboot: + dd MULTIBOOT_HEADER_MAGIC + dd MULTIBOOT_HEADER_FLAGS + dd CHECKSUM + ;MULTIBOOT_AOUT_KLUDGE + dd mboot ; these are PHYSICAL addresses + dd code ; start of kernel .text (code) section + dd edata ; end of kernel .data section + dd end ; end of kernel BSS + dd start ; kernel entry point (initial EIP) + +[GLOBAL start] +start: + ; niewiadmo co bootloader ustawi + push dword 0x2 + popf + + + ; w ebx jest wskaznik do strukture w ktorej + ; GRUB zapisal dla nas ciekawe informacje ;) + push ebx + + [EXTERN k_main] + call k_main + + cli + hlt + +start_paging: + mov eax, cr3 + or eax, 0x80000000 + mov cr3, eax + ret + +[GLOBAL read_cr0] +read_cr0: + mov eax, cr0 + ret + +[GLOBAL write_cr0] +write_cr0: + push ebp + mov ebp, esp + mov eax, [ebp+8] + mov cr0, eax + pop ebp + ret + +[GLOBAL read_cr3] +read_cr3: + mov eax, cr3 + ret + +[GLOBAL write_cr3] +write_cr3: + push ebp + mov ebp, esp + mov eax, [ebp+8] + mov cr3, eax + pop ebp + ret + +[GLOBAL move_to_user_mode] +move_to_user_mode: + mov eax, esp + push (8*4)|3 + push eax ;esp + pushf + push (8*3)|3 + push user_mode + iret + user_mode: + mov ax, (8*4)|3 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + ret + + +[GLOBAL load_gdt] +load_gdt: + lgdt [gdt_descr] + ret + +[GLOBAL load_idt] +load_idt: + lidt [idt_descr] + ret + +[SECTION .data] + +cpu_vendor: times 12 db 0 + db ' detected.' + +gdt_descr: + .size: dw 2048 + .addr: dd 0x400000 + +idt_descr: + .size: dw 2048 + .addr: dd 0x400400 + diff --git a/src/kernel/exception.c b/src/kernel/exception.c new file mode 100755 index 0000000..ca94c34 --- /dev/null +++ b/src/kernel/exception.c @@ -0,0 +1,51 @@ +#include "draco.h" + +#define MODULE_NAME "EXCEPTION" + +extern process_t proctab[]; +extern uint32 current_task; + +char * hardware_exceptions[] = +{ + "Divide Error", + "Debug", + "NMI Interrupt", + "Breakpoint", + "Overflow", + "BOUND Range Exceeded", + "Invalid Opcode", + "Device Not Available", + "Double Fault", + "Coprocessor Segment Overrun", + "Invalid TSS", + "Segment Not Present", + "Stack Fault", + "General Protection Fault", + "Page Fault", + "x87 FPU Floating-Point Error", + "Alignment Check", + "Machine-Check", + "SIMD Floating-Point" +}; + +char * software_exceptions[] = +{ + "Invalid Pointer", + "Some process already mapped while createsharedframe()", + "Trying to call class A function" +}; + +void exception_hardware(uint32 nr, uint32 cr2) +{ + if (nr == 14) + printf("page fault while accessing %x by %s (PID %d)\n", cr2, &proctab[current_task].name, current_task); + else + printf("%s (PID %d) raised an exception \"%s\"\n", &proctab[current_task].name, current_task, hardware_exceptions[nr]); + + proc_kill(current_task); +} + +void exception_software(uint32 nr) +{ + printf("%s (PID %d) raised an exception \"%s\"\n", &proctab[current_task].name, current_task, software_exceptions[nr]); +} diff --git a/src/kernel/gdt.c b/src/kernel/gdt.c new file mode 100755 index 0000000..918beb2 --- /dev/null +++ b/src/kernel/gdt.c @@ -0,0 +1,65 @@ +#include "draco.h" + +#define MODULE_NAME "gdt" + +/* + Nalezy tutaj zapamietac, ze rejestry segmentowe zaaladowane + sa wg GDT bootloadera i nie ma sensu ich zmieniac, w tej + chwili mozemy modyfikowac (dodawac/usuwac) deskryptory. + Nie czyszcze tego miejsca bo jesli nie zaladujemy blednego + selektora do rejestrow to nic zlego nie powinno sie stac - W. +*/ +void init_gdt() +{ + sys_desc *desc = (sys_desc*)KERNEL_GDT; + + /* + NULLa nie da sie ustawic z setup_seg, wiec trzeba to + zrobic tutaj (defaultowo ustawia G) + */ + desc[0].limit = 0; + desc[0].base_0_15 = 0; + desc[0].base_16_23 = 0; + desc[0].dpl_type = 0; + desc[0].gav_lim = 0; + desc[0].base_24_31 = 0; + + setup_seg(1, 0, 0x000FFFFF, SEGMENT_EXE | SEGMENT_RING0); + setup_seg(2, 0, 0x000FFFFF, SEGMENT_RW | SEGMENT_RING0); + + // dwa segmenty dla aplikacji + setup_seg(3, 0, 0x000FFFFF, SEGMENT_EXE | SEGMENT_RING3); + setup_seg(4, 0, 0x000FFFFF, SEGMENT_RW | SEGMENT_RING3); + + load_gdt(); +} + +/* + Na limit mamy 20 bitow, wiec trzeba to uwzglednic przy wywolywaniu + funkcji, starsze bity zostana usuniete (granularity jest zapalony) + wiec adres jest mnozony przez 4KB (lub jak kto woli podajemy ilosc + stron w segmencie). - W. +*/ +void setup_seg(uint8 index, uint32 base, uint32 limit, uint8 type) +{ + sys_desc *desc = (sys_desc*)KERNEL_GDT; + +/* + ; CODE, BASE:0, LIMIT: 4GB, DPL:0 + dw 0xFFFF ; low word of limit + dw 0 ; low word of base + db 0 ; low byte of high word of base + db 10011010b ; code exec-read + db 11001111b ; flags and 4 bits of limit + db 0 ; highest byte of base +*/ + + desc[index].limit = limit & 0xFFFF; + desc[index].base_0_15 = base << 16; + desc[index].base_16_23 = (base & 0xFF0000) >> 16; + desc[index].dpl_type = type; + desc[index].gav_lim = ((limit & 0xF0000) >> 16) | 0xC0; + desc[index].base_24_31 = 0; +} + + diff --git a/src/kernel/include/console.h b/src/kernel/include/console.h new file mode 100755 index 0000000..54a6f72 --- /dev/null +++ b/src/kernel/include/console.h @@ -0,0 +1,12 @@ +#ifndef __CONSOLE__H +#define __CONSOLE__H + +void clrscr(); +void putc(uint8 c); +void puts(int8 *str); +void print(int8 *str, int8 attribute); +void console_updatecursor(); +void set_carret(uint32 x, uint32 y); + +#endif + diff --git a/src/kernel/include/draco.h b/src/kernel/include/draco.h new file mode 100755 index 0000000..9006b65 --- /dev/null +++ b/src/kernel/include/draco.h @@ -0,0 +1,41 @@ +#ifndef __DRACO__H +#define __DRACO__H + +#define KERNEL_ADDRESS 0x100000 //1mb +#define KERNEL_MEMORY 0x1000000 //16mb +#define PROCESS_MEMORY 0x1000000 +#define KERNEL_PAGEDIR 0x200000 //2mb +/* nie wiemy ile bedzie pagetabow wiec musimy + zalozyc, ze 1024 (1mb?) */ +#define KERNEL_PAGETABS 0x300000 //3mb +#define KERNEL_GDT 0x400000 //4mb +#define KERNEL_IDT 0x400400 //4mb 1kb +#define KERNEL_PAGEBMP 0x500000 /* 5mb */ +#define KERNEL_PROCTAB 0x600000 /* 6mb-16mb */ + +#define KERNEL_DMA_BUFFER 0x80000 + +#define SHARED_MEMORY_ADDRESS 0xC0000000 + +/* Prcoesses def's */ +#define DEFAULT_STACK_SIZE 2 +#define DEFAULT_MSGBOX_SIZE 1 + +#include "drax.h" + +#include "libc.h" +#include "types.h" +#include "inlines.h" +#include "kernel.h" +#include "gdt.h" +#include "ints.h" +#include "paging.h" +#include "proc.h" +#include "syscall.h" +#include "console.h" +#include "exception.h" +#include "ipc.h" +#include "elf.h" + + +#endif diff --git a/src/kernel/include/elf.h b/src/kernel/include/elf.h new file mode 100755 index 0000000..e3b272d --- /dev/null +++ b/src/kernel/include/elf.h @@ -0,0 +1,394 @@ +#ifndef __ELF__H +#define __ELF__H + +/* + * ELF definitions that are independent of architecture or word size. + */ + +/* + * Note header. The ".note" section contains an array of notes. Each + * begins with this header, aligned to a word boundary. Immediately + * following the note header is n_namesz bytes of name, padded to the + * next word boundary. Then comes n_descsz bytes of descriptor, again + * padded to a word boundary. The values of n_namesz and n_descsz do + * not include the padding. + */ + +typedef struct { + uint32 n_namesz; /* Length of name. */ + uint32 n_descsz; /* Length of descriptor. */ + uint32 n_type; /* Type of this note. */ +} Elf_Note; + +/* Indexes into the e_ident array. Keep synced with + http://www.sco.com/developer/gabi/ch4.eheader.html */ +#define EI_MAG0 0 /* Magic number, byte 0. */ +#define EI_MAG1 1 /* Magic number, byte 1. */ +#define EI_MAG2 2 /* Magic number, byte 2. */ +#define EI_MAG3 3 /* Magic number, byte 3. */ +#define EI_CLASS 4 /* Class of machine. */ +#define EI_DATA 5 /* Data format. */ +#define EI_VERSION 6 /* ELF format version. */ +#define EI_OSABI 7 /* Operating system / ABI identification */ +#define EI_ABIVERSION 8 /* ABI version */ +#define OLD_EI_BRAND 8 /* Start of architecture identification. */ +#define EI_PAD 9 /* Start of padding (per SVR4 ABI). */ +#define EI_NIDENT 16 /* Size of e_ident array. */ + +/* Values for the magic number bytes. */ +#define ELFMAG0 0x7f +#define ELFMAG1 'E' +#define ELFMAG2 'L' +#define ELFMAG3 'F' +#define ELFMAG "\177ELF" /* magic string */ +#define SELFMAG 4 /* magic string size */ + +/* Values for e_ident[EI_VERSION] and e_version. */ +#define EV_NONE 0 +#define EV_CURRENT 1 + +/* Values for e_ident[EI_CLASS]. */ +#define ELFCLASSNONE 0 /* Unknown class. */ +#define ELFCLASS32 1 /* 32-bit architecture. */ +#define ELFCLASS64 2 /* 64-bit architecture. */ + +/* Values for e_ident[EI_DATA]. */ +#define ELFDATANONE 0 /* Unknown data format. */ +#define ELFDATA2LSB 1 /* 2's complement little-endian. */ +#define ELFDATA2MSB 2 /* 2's complement big-endian. */ + +/* Values for e_ident[EI_OSABI]. */ +#define ELFOSABI_SYSV 0 /* UNIX System V ABI */ +#define ELFOSABI_NONE ELFOSABI_SYSV /* symbol used in old spec */ +#define ELFOSABI_HPUX 1 /* HP-UX operating system */ +#define ELFOSABI_NETBSD 2 /* NetBSD */ +#define ELFOSABI_LINUX 3 /* GNU/Linux */ +#define ELFOSABI_HURD 4 /* GNU/Hurd */ +#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */ +#define ELFOSABI_SOLARIS 6 /* Solaris */ +#define ELFOSABI_MONTEREY 7 /* Monterey */ +#define ELFOSABI_IRIX 8 /* IRIX */ +#define ELFOSABI_FREEBSD 9 /* FreeBSD */ +#define ELFOSABI_TRU64 10 /* TRU64 UNIX */ +#define ELFOSABI_MODESTO 11 /* Novell Modesto */ +#define ELFOSABI_OPENBSD 12 /* OpenBSD */ +#define ELFOSABI_ARM 97 /* ARM */ +#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ + +/* e_ident */ +#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \ + (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \ + (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \ + (ehdr).e_ident[EI_MAG3] == ELFMAG3) + +/* Values for e_type. */ +#define ET_NONE 0 /* Unknown type. */ +#define ET_REL 1 /* Relocatable. */ +#define ET_EXEC 2 /* Executable. */ +#define ET_DYN 3 /* Shared object. */ +#define ET_CORE 4 /* Core file. */ + +/* Values for e_machine. */ +#define EM_NONE 0 /* Unknown machine. */ +#define EM_M32 1 /* AT&T WE32100. */ +#define EM_SPARC 2 /* Sun SPARC. */ +#define EM_386 3 /* Intel i386. */ +#define EM_68K 4 /* Motorola 68000. */ +#define EM_88K 5 /* Motorola 88000. */ +#define EM_486 6 /* Intel i486. */ +#define EM_860 7 /* Intel i860. */ +#define EM_MIPS 8 /* MIPS R3000 Big-Endian only */ + +/* Extensions. This list is not complete. */ +#define EM_S370 9 /* IBM System/370 */ +#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */ /* Depreciated */ +#define EM_PARISC 15 /* HPPA */ +#define EM_SPARC32PLUS 18 /* SPARC v8plus */ +#define EM_PPC 20 /* PowerPC 32-bit */ +#define EM_PPC64 21 /* PowerPC 64-bit */ +#define EM_ARM 40 /* ARM */ +#define EM_SPARCV9 43 /* SPARC v9 64-bit */ +#define EM_IA_64 50 /* Intel IA-64 Processor */ +#define EM_X86_64 62 /* Advanced Micro Devices x86-64 */ +#define EM_ALPHA 0x9026 /* Alpha (written in the absence of an ABI */ + +/* Special section indexes. */ +#define SHN_UNDEF 0 /* Undefined, missing, irrelevant. */ +#define SHN_LORESERVE 0xff00 /* First of reserved range. */ +#define SHN_LOPROC 0xff00 /* First processor-specific. */ +#define SHN_HIPROC 0xff1f /* Last processor-specific. */ +#define SHN_ABS 0xfff1 /* Absolute values. */ +#define SHN_COMMON 0xfff2 /* Common data. */ +#define SHN_HIRESERVE 0xffff /* Last of reserved range. */ + +/* sh_type */ +#define SHT_NULL 0 /* inactive */ +#define SHT_PROGBITS 1 /* program defined information */ +#define SHT_SYMTAB 2 /* symbol table section */ +#define SHT_STRTAB 3 /* string table section */ +#define SHT_RELA 4 /* relocation section with addends */ +#define SHT_HASH 5 /* symbol hash table section */ +#define SHT_DYNAMIC 6 /* dynamic section */ +#define SHT_NOTE 7 /* note section */ +#define SHT_NOBITS 8 /* no space section */ +#define SHT_REL 9 /* relocation section - no addends */ +#define SHT_SHLIB 10 /* reserved - purpose unknown */ +#define SHT_DYNSYM 11 /* dynamic symbol table section */ +#define SHT_NUM 12 /* number of section types */ +#define SHT_LOOS 0x60000000 /* First of OS specific semantics */ +#define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */ +#define SHT_LOPROC 0x70000000 /* reserved range for processor */ +#define SHT_HIPROC 0x7fffffff /* specific section header types */ +#define SHT_LOUSER 0x80000000 /* reserved range for application */ +#define SHT_HIUSER 0xffffffff /* specific indexes */ + +/* Flags for sh_flags. */ +#define SHF_WRITE 0x1 /* Section contains writable data. */ +#define SHF_ALLOC 0x2 /* Section occupies memory. */ +#define SHF_EXECINSTR 0x4 /* Section contains instructions. */ +#define SHF_TLS 0x400 /* Section contains TLS data. */ +#define SHF_MASKPROC 0xf0000000 /* Reserved for processor-specific. */ + +/* Values for p_type. */ +#define PT_NULL 0 /* Unused entry. */ +#define PT_LOAD 1 /* Loadable segment. */ +#define PT_DYNAMIC 2 /* Dynamic linking information segment. */ +#define PT_INTERP 3 /* Pathname of interpreter. */ +#define PT_NOTE 4 /* Auxiliary information. */ +#define PT_SHLIB 5 /* Reserved (not used). */ +#define PT_PHDR 6 /* Location of program header itself. */ +#define PT_TLS 7 /* Thread local storage segment */ + +#define PT_COUNT 8 /* Number of defined p_type values. */ + +#define PT_LOOS 0x60000000 /* OS-specific */ +#define PT_HIOS 0x6fffffff /* OS-specific */ +#define PT_LOPROC 0x70000000 /* First processor-specific type. */ +#define PT_HIPROC 0x7fffffff /* Last processor-specific type. */ + +/* Values for p_flags. */ +#define PF_X 0x1 /* Executable. */ +#define PF_W 0x2 /* Writable. */ +#define PF_R 0x4 /* Readable. */ + +/* Values for d_tag. */ +#define DT_NULL 0 /* Terminating entry. */ +#define DT_NEEDED 1 /* String table offset of a needed shared + library. */ +#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */ +#define DT_PLTGOT 3 /* Processor-dependent address. */ +#define DT_HASH 4 /* Address of symbol hash table. */ +#define DT_STRTAB 5 /* Address of string table. */ +#define DT_SYMTAB 6 /* Address of symbol table. */ +#define DT_RELA 7 /* Address of ElfNN_Rela relocations. */ +#define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */ +#define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */ +#define DT_STRSZ 10 /* Size of string table. */ +#define DT_SYMENT 11 /* Size of each symbol table entry. */ +#define DT_INIT 12 /* Address of initialization function. */ +#define DT_FINI 13 /* Address of finalization function. */ +#define DT_SONAME 14 /* String table offset of shared object + name. */ +#define DT_RPATH 15 /* String table offset of library path. [sup] */ +#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. [sup] */ +#define DT_REL 17 /* Address of ElfNN_Rel relocations. */ +#define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */ +#define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */ +#define DT_PLTREL 20 /* Type of relocation used for PLT. */ +#define DT_DEBUG 21 /* Reserved (not used). */ +#define DT_TEXTREL 22 /* Indicates there may be relocations in + non-writable segments. [sup] */ +#define DT_JMPREL 23 /* Address of PLT relocations. */ +#define DT_BIND_NOW 24 /* [sup] */ +#define DT_INIT_ARRAY 25 /* Address of the array of pointers to + initialization functions */ +#define DT_FINI_ARRAY 26 /* Address of the array of pointers to + termination functions */ +#define DT_INIT_ARRAYSZ 27 /* Size in bytes of the array of + initialization functions. */ +#define DT_FINI_ARRAYSZ 28 /* Size in bytes of the array of + terminationfunctions. */ +#define DT_RUNPATH 29 /* String table offset of a null-terminated + library search path string. */ +#define DT_FLAGS 30 /* Object specific flag values. */ +#define DT_ENCODING 32 /* Values greater than or equal to DT_ENCODING + and less than DT_LOOS follow the rules for + the interpretation of the d_un union + as follows: even == 'd_ptr', even == 'd_val' + or none */ +#define DT_PREINIT_ARRAY 32 /* Address of the array of pointers to + pre-initialization functions. */ +#define DT_PREINIT_ARRAYSZ 33 /* Size in bytes of the array of + pre-initialization functions. */ + +#define DT_COUNT 33 /* Number of defined d_tag values. */ + +#define DT_LOOS 0x6000000d /* First OS-specific */ +#define DT_HIOS 0x6fff0000 /* Last OS-specific */ +#define DT_LOPROC 0x70000000 /* First processor-specific type. */ +#define DT_HIPROC 0x7fffffff /* Last processor-specific type. */ + +/* Values for DT_FLAGS */ +#define DF_ORIGIN 0x0001 /* Indicates that the object being loaded may + make reference to the $ORIGIN substitution + string */ +#define DF_SYMBOLIC 0x0002 /* Indicates "symbolic" linking. */ +#define DF_TEXTREL 0x0004 /* Indicates there may be relocations in + non-writable segments. */ +#define DF_BIND_NOW 0x0008 /* Indicates that the dynamic linker should + process all relocations for the object + containing this entry before transferring + control to the program. */ +#define DF_STATIC_TLS 0x0010 /* Indicates that the shared object or + executable contains code using a static + thread-local storage scheme. */ + +/* Values for n_type. Used in core files. */ +#define NT_PRSTATUS 1 /* Process status. */ +#define NT_FPREGSET 2 /* Floating point registers. */ +#define NT_PRPSINFO 3 /* Process state info. */ + +/* Symbol Binding - ELFNN_ST_BIND - st_info */ +#define STB_LOCAL 0 /* Local symbol */ +#define STB_GLOBAL 1 /* Global symbol */ +#define STB_WEAK 2 /* like global - lower precedence */ +#define STB_LOPROC 13 /* reserved range for processor */ +#define STB_HIPROC 15 /* specific symbol bindings */ + +/* Symbol type - ELFNN_ST_TYPE - st_info */ +#define STT_NOTYPE 0 /* Unspecified type. */ +#define STT_OBJECT 1 /* Data object. */ +#define STT_FUNC 2 /* Function. */ +#define STT_SECTION 3 /* Section. */ +#define STT_FILE 4 /* Source file. */ +#define STT_TLS 6 /* TLS object. */ +#define STT_LOPROC 13 /* reserved range for processor */ +#define STT_HIPROC 15 /* specific symbol types */ + +/* Special symbol table indexes. */ +#define STN_UNDEF 0 /* Undefined symbol index. */ + +/* + * ELF definitions common to all 32-bit architectures. + */ + +typedef uint32 Elf32_Addr; +typedef uint16 Elf32_Half; +typedef uint32 Elf32_Off; +typedef int32 Elf32_Sword; +typedef uint32 Elf32_Word; +typedef uint32 Elf32_Size; +typedef uint32 Elf32_Hashelt; +//typedef Elf32_Off Elf32_Hashelt; + +/* + * ELF header. + */ + +typedef struct { + unsigned char e_ident[EI_NIDENT]; /* File identification. */ + Elf32_Half e_type; /* File type. */ + Elf32_Half e_machine; /* Machine architecture. */ + Elf32_Word e_version; /* ELF format version. */ + Elf32_Addr e_entry; /* Entry point. */ + Elf32_Off e_phoff; /* Program header file offset. */ + Elf32_Off e_shoff; /* Section header file offset. */ + Elf32_Word e_flags; /* Architecture-specific flags. */ + Elf32_Half e_ehsize; /* Size of ELF header in bytes. */ + Elf32_Half e_phentsize; /* Size of program header entry. */ + Elf32_Half e_phnum; /* Number of program header entries. */ + Elf32_Half e_shentsize; /* Size of section header entry. */ + Elf32_Half e_shnum; /* Number of section header entries. */ + Elf32_Half e_shstrndx; /* Section name strings section. */ +} Elf32_Ehdr; + +/* + * Section header. + */ + +typedef struct { + Elf32_Word sh_name; /* Section name (index into the + section header string table). */ + Elf32_Word sh_type; /* Section type. */ + Elf32_Word sh_flags; /* Section flags. */ + Elf32_Addr sh_addr; /* Address in memory image. */ + Elf32_Off sh_offset; /* Offset in file. */ + Elf32_Size sh_size; /* Size in bytes. */ + Elf32_Word sh_link; /* Index of a related section. */ + Elf32_Word sh_info; /* Depends on section type. */ + Elf32_Size sh_addralign; /* Alignment in bytes. */ + Elf32_Size sh_entsize; /* Size of each entry in section. */ +} Elf32_Shdr; + +/* + * Program header. + */ + +typedef struct { + Elf32_Word p_type; /* Entry type. */ + Elf32_Off p_offset; /* File offset of contents. */ + Elf32_Addr p_vaddr; /* Virtual address in memory image. */ + Elf32_Addr p_paddr; /* Physical address (not used). */ + Elf32_Size p_filesz; /* Size of contents in file. */ + Elf32_Size p_memsz; /* Size of contents in memory. */ + Elf32_Word p_flags; /* Access permission flags. */ + Elf32_Size p_align; /* Alignment in memory and file. */ +} Elf32_Phdr; + +/* + * Dynamic structure. The ".dynamic" section contains an array of them. + */ + +typedef struct { + Elf32_Sword d_tag; /* Entry type. */ + union { + Elf32_Size d_val; /* Integer value. */ + Elf32_Addr d_ptr; /* Address value. */ + } d_un; +} Elf32_Dyn; + +/* + * Relocation entries. + */ + +/* Relocations that don't need an addend field. */ +typedef struct { + Elf32_Addr r_offset; /* Location to be relocated. */ + Elf32_Word r_info; /* Relocation type and symbol index. */ +} Elf32_Rel; + +/* Relocations that need an addend field. */ +typedef struct { + Elf32_Addr r_offset; /* Location to be relocated. */ + Elf32_Word r_info; /* Relocation type and symbol index. */ + Elf32_Sword r_addend; /* Addend. */ +} Elf32_Rela; + +/* Macros for accessing the fields of r_info. */ +#define ELF32_R_SYM(info) ((info) >> 8) +#define ELF32_R_TYPE(info) ((unsigned char)(info)) + +/* Macro for constructing r_info from field values. */ +#define ELF32_R_INFO(sym, type) (((sym) << 8) + (unsigned char)(type)) + +/* + * Symbol table entries. + */ + +typedef struct { + Elf32_Word st_name; /* String table index of name. */ + Elf32_Addr st_value; /* Symbol value. */ + Elf32_Size st_size; /* Size of associated object. */ + unsigned char st_info; /* Type and binding information. */ + unsigned char st_other; /* Reserved (not used). */ + Elf32_Half st_shndx; /* Section index of symbol. */ +} Elf32_Sym; + +/* Macros for accessing the fields of st_info. */ +#define ELF32_ST_BIND(info) ((info) >> 4) +#define ELF32_ST_TYPE(info) ((info) & 0xf) + +/* Macro for constructing st_info from field values. */ +#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) + +#endif //__ELF__H diff --git a/src/kernel/include/exception.h b/src/kernel/include/exception.h new file mode 100755 index 0000000..4910111 --- /dev/null +++ b/src/kernel/include/exception.h @@ -0,0 +1,7 @@ +#ifndef __EXCEPTION__H +#define __EXCEPTION__H + +void exception_hardware(uint32 nr, uint32 cr2); +void exception_software(uint32 nr); + +#endif diff --git a/src/kernel/include/gdt.h b/src/kernel/include/gdt.h new file mode 100755 index 0000000..ba263b5 --- /dev/null +++ b/src/kernel/include/gdt.h @@ -0,0 +1,14 @@ +#ifndef __GDT__H +#define __GDT__H + +#define SEGMENT_R 0x00 //0000 data read-only +#define SEGMENT_RW 0x02 //0010 data read/write +#define SEGMENT_EXE 0x0A //1010 code exec/read +#define SEGMENT_RING0 0x90 +#define SEGMENT_RING3 0xF0 + +void init_gdt(); +void setup_seg(uint8 index, uint32 base, uint32 limit, uint8 type); +extern void load_gdt(); + +#endif diff --git a/src/kernel/include/inlines.h b/src/kernel/include/inlines.h new file mode 100755 index 0000000..dc5ba92 --- /dev/null +++ b/src/kernel/include/inlines.h @@ -0,0 +1,198 @@ +#ifndef __INLINES__H +#define __INLINES__H + +inline static unsigned char inb(int port) +{ + register unsigned char r; + + __asm__ __volatile__( "inb %%dx,%%al\n\t" : "=a" (r) : "d" (port)); + return(r); +} + +inline static void outb(int port, unsigned char data) +{ + __asm__ __volatile__("outb %%al,%%dx\n\t" :: "a" (data), "d" (port)); +} + +inline static unsigned short inw(int port) +{ + register unsigned short r; + + __asm__ __volatile__("inw %%dx,%%ax\n\t" : "=a" (r) : "d" (port)); + return(r); +} + +inline static void outw(int port, unsigned short data) +{ + __asm__ __volatile__("outw %%ax,%%dx\n\t" :: "a" (data), "d" (port)); +} + +inline static void repinsw(int port, void* va, int count) +{ + __asm__ __volatile__ ("rep\n\t" \ + "insw" :: "d" (port), "D" (va), "c" (count)); +} + +inline static void repoutsw(int port, void* va, int count) +{ + __asm__ __volatile__ ("rep\n\t" \ + "outsw" :: "d" (port), "D" (va), "c" (count)); +} + +inline static void sti() +{ + __asm__ __volatile__ ("sti"::); +} + +inline static void cli() +{ + __asm__ __volatile__ ("cli"::); +} + +inline static void fast_copy(void* src, void* dest, int count) +{ + __asm__ __volatile__ ("rep\n\t" \ + "movsl" \ + :: "S" (src), "D" (dest), "c" (count)); +} + +inline static void ldcr3(unsigned long val) +{ + __asm__ __volatile__ ("movl %0, %%cr3\n\t" : : "r" (val)); +} + +inline static unsigned long get_cr3(void) +{ + register unsigned long res; + + __asm__ __volatile__( "movl %%cr3, %0\n\t" : "=r" (res) :); + return(res); +} + +inline static void ldcr0(unsigned long val) +{ + __asm__ __volatile__ ("movl %0, %%cr0\n\t" : : "r" (val)); +} + +inline static unsigned long get_cr0(void) +{ + register unsigned long res; + + __asm__ __volatile__( "movl %%cr0, %0\n\t" : "=r" (res) :); + return(res); +} + +inline static unsigned long get_esp() +{ + unsigned long __ret; + __asm__ __volatile__("movl %%esp, %0":"=r"(__ret)); + return __ret; +} + +inline static void ldesp(unsigned long val) +{ + __asm__ __volatile__ ("movl %0, %%esp\n\t" : : "r" (val)); +} + +static inline unsigned short get_ss() +{ + unsigned short __ret; + __asm__ __volatile__("mov %%ss,%w0":"=r"(__ret)); + return __ret; +} + +static inline unsigned short get_gs() +{ + unsigned short __ret; + __asm__ __volatile__("mov %%gs,%w0":"=r"(__ret)); + return __ret; +} + +static inline unsigned short get_fs() +{ + unsigned short __ret; + __asm__ __volatile__("mov %%fs,%w0":"=r"(__ret)); + return __ret; +} + +static inline unsigned short get_es() +{ + unsigned short __ret; + __asm__ __volatile__("mov %%es,%w0":"=r"(__ret)); + return __ret; +} + + +static inline unsigned short get_cs() +{ + unsigned short __ret; + __asm__ __volatile__("mov %%cs,%w0":"=r"(__ret)); + return __ret; +} + +static inline unsigned short get_ds() +{ + unsigned short __ret; + __asm__ __volatile__("mov %%ds,%w0":"=r"(__ret)); + return __ret; +} + +inline static unsigned long get_eax() +{ + unsigned long __ret; + __asm__ __volatile__("movl %%eax,%0":"=r"(__ret)); + return __ret; +} + +inline static void ldeax(unsigned long val) +{ + __asm__ __volatile__ ("movl %0, %%eax\n\t" : : "r" (val)); +} + +inline static unsigned long get_ebx() +{ + unsigned long __ret; + __asm__ __volatile__("movl %%ebx,%0":"=r"(__ret)); + return __ret; +} + +inline static unsigned long get_ecx() +{ + unsigned long __ret; + __asm__ __volatile__("movl %%ecx,%0":"=r"(__ret)); + return __ret; +} + +inline static unsigned long get_edx() +{ + unsigned long __ret; + __asm__ __volatile__("movl %%edx,%0":"=r"(__ret)); + return __ret; +} + +inline static unsigned long get_ebp() +{ + unsigned long __ret; + __asm__ __volatile__("movl %%ebx,%0":"=r"(__ret)); + return __ret; +} + +inline static unsigned long get_esi() +{ + unsigned long __ret; + __asm__ __volatile__("movl %%esi,%0":"=r"(__ret)); + return __ret; +} + +inline static unsigned long get_edi() +{ + unsigned long __ret; + __asm__ __volatile__("movl %%edi,%0":"=r"(__ret)); + return __ret; +} + + + + +#endif + diff --git a/src/kernel/include/ints.h b/src/kernel/include/ints.h new file mode 100755 index 0000000..729d187 --- /dev/null +++ b/src/kernel/include/ints.h @@ -0,0 +1,68 @@ +#ifndef __INTS__H +#define __INTS__H + +extern gate_desc idt[256]; + +void unknown_interrupt_isr(); +void int80_isr(); +void timer_isr(); +void floppy_isr(); +void keyb_isr(); + +void exception_isr0(); +void exception_isr1(); +void exception_isr2(); +void exception_isr3(); +void exception_isr4(); +void exception_isr5(); +void exception_isr6(); +void exception_isr7(); +void exception_isr8(); +void exception_isr9(); +void exception_isr10(); +void exception_isr11(); +void exception_isr12(); +void exception_isr13(); +void exception_isr14(); +void exception_isr15(); +void exception_isr16(); + +//void irq_isr0(); +void irq_isr1(); +void irq_isr2(); +void irq_isr3(); +void irq_isr4(); +void irq_isr5(); +void irq_isr6(); +void irq_isr7(); +void irq_isr8(); +void irq_isr9(); +void irq_isr10(); +void irq_isr11(); +void irq_isr12(); +void irq_isr13(); +void irq_isr14(); +void irq_isr15(); +void irq_isr16(); + +#define PIC1 0x20 +#define PIC2 0xA0 +#define ICW1 0x11 +#define ICW4 0x01 + +#define TRAP_GATE 0x8F00 +#define IRQ_GATE 0x8E00 +#define CALL_GATE 0x8C00 +#define USER_CALL_GATE 0xEE00 + +void init_irq(uint32 pic1, uint32 pic2); +void setup_int(int i, unsigned long p_hand, unsigned short type, uint32 selector); +void load_idt(); + +void irq_handler(uint32 irq); +void irq_clear_status(uint32 irq); +uint32 irq_get_status(uint32 irq); +void irq_disable(uint8 irq); +void irq_enable(uint8 irq); + +#endif diff --git a/src/kernel/include/ipc.h b/src/kernel/include/ipc.h new file mode 100755 index 0000000..5e4ec80 --- /dev/null +++ b/src/kernel/include/ipc.h @@ -0,0 +1,7 @@ +#ifndef __IPC__H +#define __IPC__H + +void ipc_sendmessage(uint32 pid, message_t * msg); +void ipc_getmessage(message_t * buf); + +#endif diff --git a/src/kernel/include/kernel.h b/src/kernel/include/kernel.h new file mode 100755 index 0000000..e4d98fa --- /dev/null +++ b/src/kernel/include/kernel.h @@ -0,0 +1,6 @@ +#ifndef __KERNEL__H +#define __KERNEL__H + +void k_main(multiboot_info_t *multiboot_info); + +#endif diff --git a/src/kernel/include/keyboard.h b/src/kernel/include/keyboard.h new file mode 100755 index 0000000..4970dd2 --- /dev/null +++ b/src/kernel/include/keyboard.h @@ -0,0 +1,6 @@ +#ifndef __KEYBOARD__H +#define __KEYBOARD__H + +void keyb(); + +#endif diff --git a/src/kernel/include/paging.h b/src/kernel/include/paging.h new file mode 100755 index 0000000..1b8040c --- /dev/null +++ b/src/kernel/include/paging.h @@ -0,0 +1,11 @@ +#ifndef __PAGING__H +#define __PAGING__H + +void paging_init(); +void paging_map(const void *physical_address, const void *virtual_address); +uint32 paging_new(); +void paging_free(uint32 index); +uint32 get_physical_address(uint32 * PD, uint32 address); + +#endif + diff --git a/src/kernel/include/proc.h b/src/kernel/include/proc.h new file mode 100755 index 0000000..d052176 --- /dev/null +++ b/src/kernel/include/proc.h @@ -0,0 +1,11 @@ +#ifndef __PROC__H +#define __PROC__H + +void proc_init(); +uint32 proc_add(char * name, uint8 class, uint32 address, uint32 image_size, uint32 e_entry); +uint32 proc_kill(uint32 pid); +uint32 proc_process_env(uint32 image_size); +uint32 proc_setheapsize(uint32 pid, uint32 size); +uint32 proc_createsharedframe(uint32 pid); + +#endif diff --git a/src/kernel/include/types.h b/src/kernel/include/types.h new file mode 100755 index 0000000..cdaf497 --- /dev/null +++ b/src/kernel/include/types.h @@ -0,0 +1,139 @@ +#ifndef __TYPES__H +#define __TYPES__H + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned long uint32; + +typedef char int8; +typedef short int16; +typedef long int32; + +typedef uint32 PTE; +typedef uint32 PDE; + +typedef struct { + uint32 flags; + uint32 mem_lower; + uint32 mem_upper; + uint32 boot_device; + uint32 cmdline; + uint32 mods_count; + uint32 mods_addr; + uint32 syms[4]; + uint32 mmap_length; + uint32 mmap_addr; + +/* Drive Info buffer */ + uint32 drives_length; + uint32 drives_addr; + + /* ROM configuration table */ + uint32 config_table; + + /* Boot Loader Name */ + uint32 boot_loader_name; + + /* APM table */ + uint32 apm_table; +} multiboot_info_t; + +typedef struct module +{ + uint32 mod_start; + uint32 mod_end; + uint32 string; + uint32 reserved; +} module_t; + +typedef struct { + uint16 offset_0; + uint16 selector; + uint16 type; + uint16 offset_16; +} gate_desc; + +typedef struct { + uint16 limit; + uint16 base_0_15; + uint8 base_16_23; + uint8 dpl_type; + uint8 gav_lim; + uint8 base_24_31; +} sys_desc; + +typedef struct { + uint32 backlink; + uint32 esp0; + uint32 ss0; + uint32 esp1; + uint32 ss1; + uint32 esp2; + uint32 ss2; + uint32 cr3; + uint32 eip; + uint32 eflags; + uint32 eax; + uint32 ecx; + uint32 edx; + uint32 ebx; + uint32 esp; + uint32 ebp; + uint32 esi; + uint32 edi; + uint32 es; + uint32 cs; + uint32 ss; + uint32 ds; + uint32 fs; + uint32 gs; + uint32 ldt; + uint32 bmoffset; +} tss_t; + +typedef struct { + uint8 used; + + char name[32]; + uint8 class; + uint32 *stack; + uint32 *stack3; + void * ipc_buffer; + uint32 queue_begin, queue_end, queue_size; + + /*uint32 message_to; + message_t message; + callbacks_t callbacks;*/ + + uint32 cr3; + uint8 state; + uint32 sleep_flags; + uint32 sleep_status; + uint32 image_size; // rozmiar aplikacji (dane+kod) + uint32 stack_size; + uint32 heap_size; + uint8 irq; + + /* rozmiar srodowiska w stronach (bez PD i PT) */ + uint32 size; +} process_t; + +typedef struct { + void *next; + uint8 used; + uint32 size; + uint8 data; +} heap_block_t; + +typedef struct { + heap_block_t *first_block; + uint32 size; +} heap_info_t; + +typedef struct { + uint32 total_memory; + uint32 used_memory; + uint32 boot_device; +} system_info_t; + +#endif diff --git a/src/kernel/ints.c b/src/kernel/ints.c new file mode 100755 index 0000000..dc34b28 --- /dev/null +++ b/src/kernel/ints.c @@ -0,0 +1,150 @@ +#include "draco.h" + +#define MODULE_NAME "ints" + +extern process_t proctab[255]; +extern uint32 current_task; +extern uint32 highest_task; + +/* tutaj zapiszemy sobie informacje ktory irq zostal wywolany, + procesy z odpowiednim uprawnieniem beda mogly sobie to sprawdzic + bajt 0 zawsze bedzie zgaszony bo to zegar */ +uint32 irq_status[17]; + +void init_irq(uint32 pic1, uint32 pic2) +{ + /* send ICW1 */ + outb(PIC1, ICW1); + outb(PIC2, ICW1); + + /* send ICW2 */ + outb(PIC1 + 1, pic1); /* remap */ + outb(PIC2 + 1, pic2); /* pics */ + + /* send ICW3 */ + outb(PIC1 + 1, 4); /* IRQ2 -> connection to slave */ + outb(PIC2 + 1, 2); + + /* send ICW4 */ + outb(PIC1 + 1, ICW4); + outb(PIC2 + 1, ICW4); + + /* disable all IRQs */ + //outb(PIC1 + 1, 0xFF); + outb(0x21, 0xFF); + outb(0xA1, 0xFF); + + /* enable all IRQs */ + //outb(0x21, 0); + //outb(0xA1, 0); +} + +static uint16 irq_mask = 0xFFFF; + + +void irq_enable(uint8 irq) +{ + irq_mask &= ~(1 << irq); + if (irq >= 8) irq_mask &= ~(1 << 2); + + outb(0x21, irq_mask & 0xFF); + outb(0xA1, (irq_mask >> 8) & 0xFF); +} + +void irq_disable(uint8 irq) +{ + irq_mask |= (1 << irq); + if ((irq_mask & 0xFF00) == 0xFF00) irq_mask |= (1 << 2); + + outb(0x21, irq_mask & 0xFF); + outb(0xA1, (irq_mask >> 8) & 0xFF); +} + +#define IDT_DPL3 0x6000 + +void setup_int(int i, unsigned long p_hand, unsigned short type, uint32 selector) +{ + gate_desc *idt = (gate_desc *)KERNEL_IDT; + idt[i].offset_0 = p_hand; + idt[i].selector = selector; + idt[i].type = type; + idt[i].offset_16 = (p_hand >> 16); +} + +void init_idt() +{ + int c; + for(c = 17; c < 256; c++) + { + setup_int(c, (uint32)(void*)&unknown_interrupt_isr, IRQ_GATE, 0x08); + } + + setup_int(0, (uint32)(void*)&exception_isr0, TRAP_GATE, 0x08); + setup_int(1, (uint32)(void*)&exception_isr1, TRAP_GATE, 0x08); + setup_int(2, (uint32)(void*)&exception_isr2, TRAP_GATE, 0x08); + setup_int(3, (uint32)(void*)&exception_isr3, TRAP_GATE, 0x08); + setup_int(4, (uint32)(void*)&exception_isr4, TRAP_GATE, 0x08); + setup_int(5, (uint32)(void*)&exception_isr5, TRAP_GATE, 0x08); + setup_int(6, (uint32)(void*)&exception_isr6, TRAP_GATE, 0x08); + setup_int(7, (uint32)(void*)&exception_isr7, TRAP_GATE, 0x08); + setup_int(8, (uint32)(void*)&exception_isr8, TRAP_GATE, 0x08); + setup_int(9, (uint32)(void*)&exception_isr9, TRAP_GATE, 0x08); + setup_int(10, (uint32)(void*)&exception_isr10, TRAP_GATE, 0x08); + setup_int(11, (uint32)(void*)&exception_isr11, TRAP_GATE, 0x08); + setup_int(12, (uint32)(void*)&exception_isr12, TRAP_GATE, 0x08); + setup_int(13, (uint32)(void*)&exception_isr13, TRAP_GATE, 0x08); + setup_int(14, (uint32)(void*)&exception_isr14, TRAP_GATE, 0x08); + setup_int(15, (uint32)(void*)&exception_isr15, TRAP_GATE, 0x08); + setup_int(16, (uint32)(void*)&exception_isr16, TRAP_GATE, 0x08); + + setup_int(0x21, (uint32)(void*)&irq_isr1, IRQ_GATE, 0x08); + setup_int(0x22, (uint32)(void*)&irq_isr2, IRQ_GATE, 0x08); + setup_int(0x23, (uint32)(void*)&irq_isr3, IRQ_GATE, 0x08); + setup_int(0x24, (uint32)(void*)&irq_isr4, IRQ_GATE, 0x08); + setup_int(0x25, (uint32)(void*)&irq_isr5, IRQ_GATE, 0x08); + setup_int(0x26, (uint32)(void*)&irq_isr6, IRQ_GATE, 0x08); + setup_int(0x27, (uint32)(void*)&irq_isr7, IRQ_GATE, 0x08); + setup_int(0x28, (uint32)(void*)&irq_isr8, IRQ_GATE, 0x08); + setup_int(0x29, (uint32)(void*)&irq_isr9, IRQ_GATE, 0x08); + setup_int(0x2A, (uint32)(void*)&irq_isr10, IRQ_GATE, 0x08); + setup_int(0x2B, (uint32)(void*)&irq_isr11, IRQ_GATE, 0x08); + setup_int(0x2C, (uint32)(void*)&irq_isr12, IRQ_GATE, 0x08); + setup_int(0x2D, (uint32)(void*)&irq_isr13, IRQ_GATE, 0x08); + setup_int(0x2E, (uint32)(void*)&irq_isr14, IRQ_GATE, 0x08); + setup_int(0x2F, (uint32)(void*)&irq_isr15, IRQ_GATE, 0x08); + setup_int(0x30, (uint32)(void*)&irq_isr16, IRQ_GATE, 0x08); + + setup_int(0x80, (uint32)(void*)&int80_isr, USER_CALL_GATE, 0x08); + setup_int(0x20, (uint32)(void*)&timer_isr, IRQ_GATE, 0x08); + + load_idt(); +} + +void irq_handler(uint32 irq) +{ + uint32 i; + + for (i = 0; i <= highest_task; i++) + if (proctab[i].used && proctab[i].state == PROC_STATE_SLEEPING && (proctab[i].sleep_flags & (1 << irq)) == (1 << irq)) + { + proctab[i].sleep_status = (1 << irq); + proctab[i].state = PROC_STATE_READY; + } + + irq_status[irq] ++; + outb(0x20, 0x20); + if (irq >= 8) + outb(0xA0, 0x20); +} + +void irq_clear_status(uint32 irq) +{ + irq_status[irq] = 0; +} + +uint32 irq_get_status(uint32 irq) +{ + return irq_status[irq]; +} + + diff --git a/src/kernel/ipc.c b/src/kernel/ipc.c new file mode 100755 index 0000000..dbc7dfb --- /dev/null +++ b/src/kernel/ipc.c @@ -0,0 +1,48 @@ +#include "draco.h" + +#define QUEUE_SIZE (4096/sizeof(message_t)) + +extern process_t proctab[]; +extern current_task; + +void ipc_sendmessage(uint32 pid, message_t * msg) +{ + ldcr3(KERNEL_PAGEDIR); + if( proctab[pid].queue_size < QUEUE_SIZE ) + { + memcpy(proctab[pid].ipc_buffer + (proctab[pid].queue_begin * sizeof(message_t)), get_physical_address(proctab[current_task].cr3, msg), sizeof(message_t)); + + if (proctab[pid].queue_begin == QUEUE_SIZE-1) + proctab[pid].queue_begin = 0; + else + proctab[pid].queue_begin ++; + + proctab[pid].queue_size ++; + } + + if (proctab[pid].state == PROC_STATE_SLEEPING && (proctab[pid].sleep_flags & SLEEP_MESSAGE) == SLEEP_MESSAGE) + { + proctab[pid].sleep_status = SLEEP_MESSAGE; + proctab[pid].state = PROC_STATE_READY; + } + + ldcr3(proctab[current_task].cr3); +} + + +void ipc_getmessage(message_t * buf) +{ + ldcr3(KERNEL_PAGEDIR); + if (proctab[current_task].queue_size > 0) + { + memcpy(get_physical_address(proctab[current_task].cr3, buf), proctab[current_task].ipc_buffer + (proctab[current_task].queue_end * sizeof(message_t)), sizeof(message_t)); + + if (proctab[current_task].queue_end == QUEUE_SIZE - 1) + proctab[current_task].queue_end = 0; + else + proctab[current_task].queue_end ++; + + proctab[current_task].queue_size --; + } + ldcr3(proctab[current_task].cr3); +} diff --git a/src/kernel/isr.asm b/src/kernel/isr.asm new file mode 100755 index 0000000..ee74adc --- /dev/null +++ b/src/kernel/isr.asm @@ -0,0 +1,209 @@ +[BITS 32] + +[SECTION .text] + +extern kernel_esp +extern tss +extern user_ring0_esp +extern timer_handler + +global timer_isr +timer_isr: + ;tu mamy esp z tssa + cli + + pushad + push ds + push es + push fs + push gs + + mov ax, 16 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + mov [user_ring0_esp], esp + mov esp, [kernel_esp] + + call timer_handler + ;nie czyscimy stosu bo i tak jest w kernel_esp + + global timer_isr_part2 + timer_isr_part2: + + mov esp, [user_ring0_esp] + + mov al , 0x20 + out 0x20 , al + + pop gs + pop fs + pop es + pop ds + popad + + ;czyli esp nie liczac zapisanego stanu + mov [tss+4], esp + add long [tss+4], 20 + + sti + iret + +[GLOBAL int80_isr] +int80_isr: + cli + + ;tu mamy esp z tssa + + pushad + push ds + push es + push fs + push gs + + push ax + mov ax, 16 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + pop ax + + ;potrzebny! + mov [user_ring0_esp], esp + mov esp, [kernel_esp] + + push edx + push ecx + push ebx + push eax + + extern do_syscall + call do_syscall + + add esp, 16 + + mov esp, [user_ring0_esp] + + pop gs + pop fs + pop es + pop ds + + add esp, 32 + ;popad + + mov [tss+4], esp + add long [tss+4], 20 + + sti + iret + +extern irq_handler + +%macro IRQ_ISR 1 +global irq_isr%1 +irq_isr%1: + cli + + pusha + push gs + push fs + push es + push ds + + push ax + mov ax, 16 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + pop ax + + ;uzywamy stosu aplikacji/kernela + + push %1 + call irq_handler + add esp, 4 + + pop ds + pop es + pop fs + pop gs + popa + + sti + iret +%endmacro + +IRQ_ISR 1 +IRQ_ISR 2 +IRQ_ISR 3 +IRQ_ISR 4 +IRQ_ISR 5 +IRQ_ISR 6 +IRQ_ISR 7 +IRQ_ISR 8 +IRQ_ISR 9 +IRQ_ISR 10 +IRQ_ISR 11 +IRQ_ISR 12 +IRQ_ISR 13 +IRQ_ISR 14 +IRQ_ISR 15 +IRQ_ISR 16 + +extern exception_hardware + +%macro EXCEPTION_ISR 1 +[GLOBAL exception_isr%1] +exception_isr%1: + cli + + pusha + push gs + push fs + push es + push ds + + mov eax, cr2 + push eax + push %1 + call exception_hardware + add esp, 8 + + pop ds + pop es + pop fs + pop gs + popa + + sti + + iret +%endmacro + +EXCEPTION_ISR 0 +EXCEPTION_ISR 1 +EXCEPTION_ISR 2 +EXCEPTION_ISR 3 +EXCEPTION_ISR 4 +EXCEPTION_ISR 5 +EXCEPTION_ISR 6 +EXCEPTION_ISR 7 +EXCEPTION_ISR 8 +EXCEPTION_ISR 9 +EXCEPTION_ISR 10 +EXCEPTION_ISR 11 +EXCEPTION_ISR 12 +EXCEPTION_ISR 13 +EXCEPTION_ISR 14 +EXCEPTION_ISR 15 +EXCEPTION_ISR 16 + + +[GLOBAL unknown_interrupt_isr] +unknown_interrupt_isr: + iret diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c new file mode 100755 index 0000000..10039f7 --- /dev/null +++ b/src/kernel/kernel.c @@ -0,0 +1,32 @@ +#include "draco.h" + +char uname[] = "DRACO compilation "__DATE__" "__TIME__; +system_info_t system_info; +extern char cons_attribute; + +void k_main(multiboot_info_t * multiboot_info) +{ + system_info.total_memory = multiboot_info->mem_upper; + + clrscr(); + + printf("%s\n", &uname); + printf(" Copyright 2005-2006 Draco Project\n"); + printf("%dM of extended memory.\n", multiboot_info->mem_upper >> 10); + + cons_attribute = 7; + + init_gdt(); + init_idt(); + init_irq(0x20, 0x28); + paging_kernel_env(system_info.total_memory / 4); + paging_init(); + proc_init(); + modules_init(multiboot_info); + + printf("Kernel is initialized.\n"); + + sti(); + + while(1); +} diff --git a/src/kernel/link.ld b/src/kernel/link.ld new file mode 100755 index 0000000..e69de29 diff --git a/src/kernel/modules.c b/src/kernel/modules.c new file mode 100755 index 0000000..22fed87 --- /dev/null +++ b/src/kernel/modules.c @@ -0,0 +1,32 @@ +#include "draco.h" + +#define MODULE_NAME "modules" + +void modules_init(multiboot_info_t * multiboot_info) +{ + printf("[ "MODULE_NAME" ] loading: "); + + uint32 i; + void * proc_mem; + + module_t *modules = (module_t *)multiboot_info->mods_addr; + for (i = 0; i < multiboot_info->mods_count; i++) + { + + /** ELF EXEC */ + if (*((char *)(modules[i].mod_start)) == 0x7f) + { + elf_dump(modules[i].mod_start); + printf("%s ", modules[i].string); + elf_exec(modules[i].string, modules[i].mod_start, modules[i].mod_end - modules[i].mod_start); + continue; + } + + printf("%s ", modules[i].string); + + proc_mem = proc_createenv(modules[i].mod_end - modules[i].mod_start); + memcpy(get_physical_address(proc_mem, KERNEL_MEMORY), modules[i].mod_start, modules[i].mod_end - modules[i].mod_start); + proc_add(modules[i].string, PROC_CLASS_A, proc_mem, modules[i].mod_end - modules[i].mod_start, KERNEL_MEMORY); + } + printf("\n"); +} diff --git a/src/kernel/paging.c b/src/kernel/paging.c new file mode 100755 index 0000000..437cfc1 --- /dev/null +++ b/src/kernel/paging.c @@ -0,0 +1,115 @@ +#include "draco.h" + +#define MODULE_NAME "paging" + +extern system_info_t system_info; + +/* + wlacza stronicowanie i zeruje pagebmp, przed wywolaniem + powinnismy zmapowac pamiec dla jadra +*/ +void paging_init() +{ + uint8 *PB = (uint8*)KERNEL_PAGEBMP; + + ldcr3(KERNEL_PAGEDIR); + ldcr0(get_cr0() | 0x80000000); + + /* pewnie na prawdziwym kompie bedzie wyczyszczona ale dla pewnosci + mozemy ja wyczyscic sami, zwlaszcza, ze dlugo to nie potrwa */ + memset(KERNEL_PAGEBMP, 0, 1024*128); + + /* ustawiamy strony kernela (16MB) jako zajete */ + memset(KERNEL_PAGEBMP, 0xFF, 512); + + system_info.used_memory = 16 << 10; +} + +/* mapuje cala pamiec dla jadra, ilosc pamieci podawana + w parametrze pages */ +void paging_kernel_env(uint32 pages) +{ + uint32 address = 0; //aktualny adres do zmapowania + uint32 i, k; + uint32 pts; //ilosc tabel stron + uint32 *PT = (uint32*)KERNEL_PAGETABS; //page table + uint32 *PD = (uint32*)KERNEL_PAGEDIR; //page directory + + pts = pages >> 10; + + /* tworzymy page directory */ + for (i = 0; i < pts; i ++) + { + PT = (uint32*)KERNEL_PAGETABS + (i << 12); + for (k = 0; k < 1024; k ++) + { + PT[k] = address | 7; // user mode, read/write, present + address += 4096; // nastepna strona ... + } + //wypelniamy page dir + PD[i] = (uint32)PT | 7; //user mode, read/write, present + } + + /* nie wiem czy nie powinnismy wypelnic calego page dir, zobaczymy + w koncu prostota rlz */ +} + +/* + Funkcja wyszukuje wolna strone, zwraca jej _numer_ i zapala jej bit - W. + + DOTO: w tej wersji bitmapa jest na sztyno ustawiona na milion stron (4GB) + bootloader powinien dostarczyc nam informacje o pamieci i wg tego + ew wywalac 'out of memory' +*/ +uint32 paging_new() +{ + uint8 *pagebmp = (uint8 *)KERNEL_PAGEBMP; + uint32 i, p; + for (i = 0; i <= 1024*128; i ++, pagebmp ++) + { + /* nie jestem pewien czy to ma sens, chociaz + mysle, ze asmowe cmp jest szybsze niz moja + petelka */ + if (*pagebmp < 0xFF) + { + for (p = 0; p <= 7; p ++) + { + if (((*pagebmp >> p) & 1) == 0) + { + system_info.used_memory += 4; + *pagebmp |= 1 << p; + return (i*8) + p; + } + } + } + } + /* coz, to zadziala <=> gdy user bedzie mial 4GB ramu i caly sie + wyczerpie, czyli mozna uznac, ze nigdy */ + printf("out of memory\n"); + return 0; +} + +/* + Gasi bit strony o _numerze_ index. - W. + + NOTKA: funkcja nie jest odporna na zwalnianie wolnych stron :P +*/ +void paging_free(uint32 index) +{ + uint8 *pagebmp = (uint8 *)KERNEL_PAGEBMP; + pagebmp += index >> 3; + *pagebmp &= ~(1 << (index & 7)); + system_info.used_memory -= 4; +} + +/* + konwertuje wirtualny adres na podstawie pgdir i adresu + na fizyczny +*/ +uint32 get_physical_address(uint32 * PD, uint32 address) +{ + uint32 * PT; + + PT = (uint32)PD[address >> 22] & 0xFFFFF000; + return ( PT[(address >> 12) & 0x3FF] & 0xFFFFF000 ) | ( address & 0xFFF ); +} diff --git a/src/kernel/paging.c~ b/src/kernel/paging.c~ new file mode 100755 index 0000000..16310ac --- /dev/null +++ b/src/kernel/paging.c~ @@ -0,0 +1,115 @@ +#include "draco.h" + +#define MODULE_NAME "paging" + +extern system_info_t system_info; + +/* + wlacza stronicowanie i zeruje pagebmp, przed wywolaniem + powinnismy zmapowac pamiec dla jadra +*/ +void paging_init() +{ + uint8 *PB = (uint8*)KERNEL_PAGEBMP; + + ldcr3(KERNEL_PAGEDIR); + ldcr0(get_cr0() | 0x80000000); + + /* pewnie na prawdziwym kompie bedzie wyczyszczona ale dla pewnosci + mozemy ja wyczyscic sami, zwlaszcza, ze dlugo to nie potrwa */ + memset(KERNEL_PAGEBMP, 0, 1024*128); + + /* ustawiamy strony kernela (16MB) jako zajete */ + memset(KERNEL_PAGEBMP, 0xFF, 512); + + system_info.used_memory = 16 << 10; +} + +/* mapuje cala pamiec dla jadra, ilosc pamieci podawana + w parametrze pages */ +void paging_kernel_env(uint32 pages) +{ + uint32 address = 0; //aktualny adres do zmapowania + uint32 i, k; + uint32 pts; //ilosc tabel stron + uint32 *PT = (uint32*)KERNEL_PAGETABS; //page table + uint32 *PD = (uint32*)KERNEL_PAGEDIR; //page directory + + pts = pages >> 10; + + /* tworzymy page directory */ + for (i = 0; i < pts; i ++) + { + PT = (uint32*)KERNEL_PAGETABS + (i << 12); + for (k = 0; k < 1024; k ++) + { + PT[k] = address | 7; // user mode, read/write, present + address += 4096; // nastepna strona ... + } + //wypelniamy page dir + PD[i] = (uint32)PT | 7; //user mode, read/write, present + } + + /* nie wiem czy nie powinnismy wypelnic calego page dir, zobaczymy + w koncu prostota rlz */ +} + +/* + Funkcja wyszukuje wolna strone, zwraca jej _numer_ i zapala jej bit - W. + + DOTO: w tej wersji bitmapa jest na sztyno ustawiona na milion stron (4GB) + bootloader powinien dostarczyc nam informacje o pamieci i wg tego + ew wywalac 'out of memory' +*/ +uint32 paging_new() +{ + uint8 *pagebmp = (uint8 *)KERNEL_PAGEBMP; + uint32 i, p; + for (i = 0; i <= 1024*128; i ++, pagebmp ++) + { + /* nie jestem pewien czy to ma sens, chociaz + mysle, ze asmowe cmp jest szybsze niz moja + pentelka */ + if (*pagebmp < 0xFF) + { + for (p = 0; p <= 7; p ++) + { + if (((*pagebmp >> p) & 1) == 0) + { + system_info.used_memory += 4; + *pagebmp |= 1 << p; + return (i*8) + p; + } + } + } + } + /* coz, to zadziala <=> gdy user bedzie mial 4GB ramu i caly sie + wyczerpie, czyli mozna uznac, ze nigdy */ + printf("out of memory\n"); + return 0; +} + +/* + Gasi bit strony o _numerze_ index. - W. + + NOTKA: funkcja nie jest odporna na zwalnianie wolnych stron :P +*/ +void paging_free(uint32 index) +{ + uint8 *pagebmp = (uint8 *)KERNEL_PAGEBMP; + pagebmp += index >> 3; + *pagebmp &= ~(1 << (index & 7)); + system_info.used_memory -= 4; +} + +/* + konwertuje wirtualny adres na podstawie pgdir i adresu + na fizyczny +*/ +uint32 get_physical_address(uint32 * PD, uint32 address) +{ + uint32 * PT; + + PT = (uint32)PD[address >> 22] & 0xFFFFF000; + return ( PT[(address >> 12) & 0x3FF] & 0xFFFFF000 ) | ( address & 0xFFF ); +} diff --git a/src/kernel/proc.c b/src/kernel/proc.c new file mode 100755 index 0000000..8aabbbe --- /dev/null +++ b/src/kernel/proc.c @@ -0,0 +1,437 @@ +#include "draco.h" + +#define MODULE_NAME "tasks" + +extern system_info_t system_info; + +process_t proctab[255];// = (process_t*)KERNEL_PROCTAB; na bssie jest ;] +uint32 current_task = 0; +uint32 highest_task = 0; +uint32 tasks_running = 0; +uint32 ticks = 0; +uint32 max_processes = (KERNEL_MEMORY - KERNEL_PROCTAB) / sizeof(process_t); + +tss_t tss; + +sys_desc * sys_gdt = (sys_desc*)KERNEL_GDT; + +uint32 * kernel_esp, + * user_ring0_esp; + + +void set_clock(uint16 hz) +{ + uint16 val = 1193180 / hz; + outb(0x36, 0x43); + outb(val & 0xff, 0x40); + outb((val >> 8) & 0xff, 0x40); +} + +void proc_init() +{ + tss.esp0 = get_esp(); + tss.ss0 = get_ss(); + + sys_gdt[5].base_0_15 = (uint32)(&tss)&0x0000FFFF; + sys_gdt[5].limit = sizeof(tss); + sys_gdt[5].base_16_23 = ((uint32)(&tss)&0x00FF0000)>>16; + sys_gdt[5].dpl_type = 0x89; + sys_gdt[5].gav_lim = 0x90; + sys_gdt[5].base_24_31 = ((uint32)(&tss)&0xFF000000)>>24; + + __asm__ __volatile__ ("ltr %w0"::"r"(5*8)); + + /* stos kernela - w kernel-mode pracujemy na swoim stosie */ + kernel_esp = (uint32*)get_esp(); + + //memset(proctab, 0, KERNEL_MEMORY - KERNEL_PROCTAB); + + set_clock(100); + irq_enable(0); +} + + +/* musimy miec przynajmniej jeden proces gotowy */ +void schedule() +{ + uint32 i; + + while (1) + { + current_task ++; + if (current_task > highest_task) + current_task = 0; + if (proctab[current_task].used && proctab[current_task].state == PROC_STATE_READY) + return; + } +} + +/* jesli tak, to nie zapisujemy do tabproc stosu */ +uint8 scheduler_first_run = 1; + +void timer_handler() +{ + ticks ++; + + //zapisujemy stary stos + if (!scheduler_first_run) + proctab[current_task].stack = user_ring0_esp; + else + scheduler_first_run = 0; + + //wybieramy nowy watek + schedule(); + + write_cr3(proctab[current_task].cr3); + + //zapisujemy jego stos dla r0 w tssie + user_ring0_esp = proctab[current_task].stack; +} + +uint32 temp; +uint32 proc_kill(uint32 pid) +{ +#ifdef DEBUG + printf("[ "MODULE_NAME" ] %s (PID %d) killed\n", &proctab[pid].name, pid); +#endif + temp = pid; + + /* mam nadzieje, ze zmienna pid dalej bedzie obowiazywala jak + zmienimy esp, w koncu gcc to do ebp kopiuje */ + ldesp(kernel_esp); + write_cr3(KERNEL_PAGEDIR); + + proctab[temp].used = 0; + tasks_running--; + + uint32 i; + for (i = 0; i < proctab[temp].size; i++) + paging_free(get_physical_address(proctab[temp].cr3, (i << 12) + KERNEL_MEMORY) >> 12); + + uint32 *PD = (uint32*)proctab[temp].cr3 + 4; + while (1) + { + if (*PD == 0) break; + paging_free((*PD & 0xFFFFF000) >> 12); + PD++; + } + paging_free((uint32)PD >> 12); + + schedule(); + + write_cr3(proctab[current_task].cr3); + + //zapisujemy jego stos dla r0 w tssie + user_ring0_esp = proctab[current_task].stack; + + /* nie jest to moze sliczne ale skaczac do konca isra + timera po prostu skoczymy do nastepnego watku */ + __asm__ __volatile__ ("jmp timer_isr_part2"); +} + +/* wyszukuje wolny wpis w proctab */ +uint32 get_free_pid() +{ + uint32 i; + /* 0 sux */ + for (i = 1; i < max_processes; i ++) + if (!proctab[i].used) + return i; + return 0; +} + +/* + Pamiec musi byc zmapowana dla procesu, kod zaladowany itp. + + Funkcja nadaje PID procesowi, wstawia strukture PROCESS do + tablicy procesow, ustawia stos itp +*/ +uint32 proc_add(char * name, uint8 class, uint32 address, uint32 image_size, uint32 e_entry) +{ + uint32 pid = get_free_pid(); + + memcpy(&proctab[pid].name, name, strlen(name)); + proctab[pid].name[strlen(name)] = '\0'; + + proctab[pid].ipc_buffer = paging_new() << 12; + proctab[pid].class = class; + proctab[pid].state = PROC_STATE_READY; + proctab[pid].cr3 = address; + //pierw potrzebujemy prawdziwego (fizycznego) wskaznika, potem zmienimy na wirtualny + proctab[pid].stack = (uint32*)(get_physical_address(proctab[pid].cr3, KERNEL_MEMORY + (((image_size >> 12)+1)<<12) + 0x100)); + proctab[pid].stack3 = (uint32*)(KERNEL_MEMORY + (((image_size >> 12)+1)<<12) + (DEFAULT_STACK_SIZE << 12)); //na koncu strony ze stosami + //proctab[pid].message_box = (void*)(KERNEL_MEMORY + (((image_size >> 12)+1)<<12) + (DEFAULT_STACK_SIZE << 12)); + proctab[pid].size = (image_size >> 12) + 1 + DEFAULT_STACK_SIZE; + + proctab[pid].stack -- ; *proctab[pid].stack = (8*4)|3; //ss dla r3 + proctab[pid].stack -- ; *proctab[pid].stack = (uint32)proctab[pid].stack3; //esp dla r3 + + proctab[pid].stack -- ; + if (class == PROC_CLASS_A) + *proctab[pid].stack = 0x3202; //flagi + else + *proctab[pid].stack = 0x0202; //flagi + + proctab[pid].stack -- ; *proctab[pid].stack = (8*3)|3; //cs dla r3 + proctab[pid].stack -- ; *proctab[pid].stack = e_entry; //eip (kernel+start kodu) + proctab[pid].stack -- ; *proctab[pid].stack = 0; + proctab[pid].stack -- ; *proctab[pid].stack = 0; + proctab[pid].stack -- ; *proctab[pid].stack = 0; + proctab[pid].stack -- ; *proctab[pid].stack = 0; + proctab[pid].stack -- ; *proctab[pid].stack = 0; + proctab[pid].stack -- ; *proctab[pid].stack = 0; + proctab[pid].stack -- ; *proctab[pid].stack = 0; + proctab[pid].stack -- ; *proctab[pid].stack = 0; + proctab[pid].stack -- ; *proctab[pid].stack = (8*4)|3; + proctab[pid].stack -- ; *proctab[pid].stack = (8*4)|3; + proctab[pid].stack -- ; *proctab[pid].stack = (8*4)|3; + proctab[pid].stack -- ; *proctab[pid].stack = (8*4)|3; + + proctab[pid].stack = (uint32*)(KERNEL_MEMORY + (((image_size >> 12)+1)<<12) + 0x100) - 17; + + proctab[pid].used = 1; + proctab[pid].heap_size = 0; + + //uaktualniamy liczniki + tasks_running ++; + if (pid > highest_task) + highest_task = pid; + + return pid; +} + +/* + podajemy rozmiar aplikacji, funkcja zwraca adres + PD z ktorego cala reszte mozemy odczytac + + aplikacja widzi swoj stos dla kernela ale nie ma to + znaczenia bo te dane sa wazne tylko wtedy kiedy + proces spi +*/ +uint32 proc_createenv(uint32 image_size) +{ + uint32 application_address; + uint32 application_env_size; + uint32 page_tables; + + /* rozmiar obrazu aplikacji bedzie staly, po prostu wrzucamy kod i juz */ + image_size = (image_size >> 12) + 1; + + //rozmiar srodowiska aplikacji W STRONACH + application_env_size = image_size + DEFAULT_STACK_SIZE; + + //dodajemy miejsce dla PD i PTki + page_tables = (application_env_size >> 10) + 1; + + /* zmienna page_tables jest liczona BEZ miejsca dla samych + PTkow bo te nie musza byc zmapowane */ + application_env_size += page_tables + 1; //1 dla PD + + //uint32 address; //aktualny adres do zmapowania + uint32 i, k, t = 0; + uint32 *PD = (uint32*)(paging_new() << 12); //page directory + uint32 *PT = (uint32*)(paging_new() << 12); //pierwsza page table + uint32 *kernel_PD = (uint32*)KERNEL_PAGEDIR; //page directory kernela + + /* potrzebne do *sharedframe() */ + memset(PD, 0, 4096); + + /* mapujemy kernela (4 PTki, co daje 4*1024 strony - 16MiB) */ + for (k = 0; k < 4; k ++) + PD[k] = kernel_PD[k]; + + /* pierwszy PT do PD */ + PD[k] = (uint32)PT | 7; + for (i = 0; i < application_env_size; i++) + { + PT[t] = (uint32)(paging_new() << 12) | 7; // user mode, read/write, present + //printf("PT[%d] == %x\n", t, PT[t]); + t++; + /* jesli wypelnilismy PTka to robimy nastepny */ + if (t == 1024) + { + k++; + t = 0; + PT = (uint32*)(paging_new() << 12); + PD[k] = (uint32)PT | 7; //user mode, read/write, present + } + } + + //printf("k==%d, t==%d\n", k, t); + + return (uint32)PD; +} + +/** + funkcja odpala proces zakladajac, ze jestesmy juz w sti, + w parametrze podajemy adres do obrazu w przestrzeni + aktualnego procesu, musimy tu pracowac na roznych + przestrzeniach - to bedzie hardkor ;] +*/ +uint32 proc_exec(char * name, void * image, uint32 size) +{ + /* przesrzen adresowa */ + /** TODO: tu trzeba cr3 kernela */ + void * proc_env = proc_createenv(size); /** TODO: dokladny rozmiar (BSS itp) */ + /** TODO: zaladuj nowy cr3 */ + void * frame = proc_createsharedframe(current_task); /* mam nadzieje, ze zadziala */ + + memcpy(frame + image, PROCESS_MEMORY, size); /* kopiujemy obraz do nowej przestrzeni */ + uint32 e_entry = elf_relocate(PROCESS_MEMORY); + uint32 result = proc_add(name, PROC_CLASS_A, frame, size, e_entry); + /** TODO: przywroc cr3 */ + return result; +} + +uint32 proc_find(char * name) +{ + uint32 i; + for (i = 1; i <= highest_task; i ++) + if (proctab[i].used && strcmp(&proctab[i].name, name) == 0) + return i; + return 0; +} + +void proc_setname(uint32 pid, char * name) +{ + memcpy(&proctab[pid].name, name, strlen(name)); + proctab[pid].name[strlen(name)] = '\0'; +} + +uint32 proc_setheapsize(uint32 pid, uint32 size) +{ + //printf("Setting heap size for %d from %d to %d pages\n", pid, proctab[pid].heap_size, size); + + /* no potrzeba, co zrobic? :P */ + ldcr3(KERNEL_PAGEDIR); + + uint32 *PT, + *PD, + k, t; + + PD = proctab[pid].cr3; + + if (proctab[pid].heap_size == size) + { + ldcr3(proctab[pid].cr3); + return 0; + } + + k = (proctab[pid].size + (KERNEL_MEMORY >> 12) + DEFAULT_STACK_SIZE) / 1024; + t = (proctab[pid].size + DEFAULT_STACK_SIZE) % 1024; + + //printf("k==%d, t==%d, proctab[pid].size==%d\n", k, t, proctab[pid].size); + + if (proctab[pid].heap_size < size) + { + if (t == 0) + { + PT = (uint32*)(paging_new() << 12); + PD[k + 1] = (uint32)PT | 7; + t = 0; + } + else + { + PT = PD[k] & 0xFFFFF000; + t++; + } + + while (size > proctab[pid].heap_size) + { + proctab[pid].heap_size ++; + proctab[pid].size ++; + PT[t] = (uint32)(paging_new() << 12) | 7; // user mode, read/write, present + t++; + /* jesli wypelnilismy PTka to robimy nastepny */ + if (t == 1024) + { + k++; + t = 0; + PT = (uint32*)(paging_new() << 12); + PD[k] = (uint32)PT | 7; //user mode, read/write, present + } + } + } + else + { + while (size < proctab[pid].heap_size) + { + proctab[pid].heap_size --; + proctab[pid].size --; + + PT = PD[k] & 0xFFFFF000; + paging_free((PT[t] & 0xFFFFF000) >> 12); + //printf("PT[%d] = %x, %x\n", t, PT[t], PT[t] & 0xFFFFF000); + //printf("paging_free(%d, %x)\n", (PD[t] & 0xFFFFF000) >> 12, PD[t] & 0xFFFFF000); + + PT[t] = 0; + + + if (t == 0) + { + t = 1024; + k --; + paging_free((PD[k] & 0xFFFFF000) >> 12); + PD[k] = 0; + } + t --; + } + } + + ldcr3(proctab[pid].cr3); +} + +/** TODO: proces ma byc mapowany do AKTUALNEGO cr3 */ +uint32 proc_createsharedframe(uint32 pid) +{ + //printf("proc_createsharedframe(%d)\n", pid); + + ldcr3(KERNEL_PAGEDIR); + + uint32 * PD = proctab[current_task].cr3; + uint32 * aPD = proctab[pid].cr3; + uint32 k, ak, i; + + ak = (KERNEL_MEMORY >> 12) / 1024; + k = (SHARED_MEMORY_ADDRESS >> 12) / 1024; + k += ak; + + + /* jakis proces juz jest zmapowany * + if (PD[k] != 0) + { + exception_software(1); + ldcr3(proctab[current_task].cr3); + return 0; + }*/ + + for (i = 0; i < (proctab[pid].size / 1024) + 1; i++) + { + //printf("proc_createsharedframe(%d): PD[%d] = aPD[%d] = %x\n", pid, k, ak, aPD[ak]); + PD[k] = aPD[ak]; + k++; + ak++; + } + + ldcr3(proctab[current_task].cr3); + + //printf("%x\n", SHARED_MEMORY_ADDRESS); + return SHARED_MEMORY_ADDRESS; +} + +void proc_freesharedframe() +{ + ldcr3(KERNEL_PAGEDIR); + + uint32 * PD = proctab[current_task].cr3; + uint32 k = (SHARED_MEMORY_ADDRESS >> 12) / 1024; + k += (KERNEL_MEMORY >> 12) / 1024; + + while (PD[k] != 0) + { + PD[k] = 0; + k++; + } + + ldcr3(proctab[current_task].cr3); +} diff --git a/src/kernel/syscall.c b/src/kernel/syscall.c new file mode 100755 index 0000000..10a1ede --- /dev/null +++ b/src/kernel/syscall.c @@ -0,0 +1,244 @@ +#include "draco.h" + +#define MODULE_NAME "syscall" + +extern process_t proctab[255]; +extern uint32 current_task; +extern tasks_running; +extern cons_carret; +extern uint8 cons_attribute; +extern system_info_t system_info; +extern uint32 highest_task; +extern uint32 ticks; +extern uint32 user_ring0_esp; +extern char uname[]; + +uint32 do_syscall(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx) +{ + uint32 i; + uint32 *PD, *PT; + + //printf("SYSCALL, eax=%x, ebx=%x, ecx=%x, edx=%x\n", eax, ebx, ecx, edx); + + switch (eax) + { + case SYSCALL_UNAME: + { + //printf("%s\n", uname); + memcpy(ebx, uname, strlen(uname)); + *((char*)ebx + strlen(uname)) = '\0'; + break; + } + case SYSCALL_GET_IRQ_STATUS: + { + return irq_get_status(ebx); + } + case SYSCALL_CLEAR_IRQ_STATUS: + { + irq_clear_status(ebx); + break; + } + case SYSCALL_SET_HEAP_SIZE: + { + proc_setheapsize(current_task, ebx); + break; + } + case SYSCALL_GET_HEAP_SIZE: + { + return proctab[current_task].heap_size; + } + case SYSCALL_GET_PID: + { + return current_task; + } + case SYSCALL_GET_PROCESS_NAME: + { + /* nie mozemy dopuscic kazdego adresu */ + if (ecx > KERNEL_MEMORY) + { + memcpy(ecx, &proctab[ebx].name, strlen(&proctab[ebx].name)); + *((char*)ecx + strlen(&proctab[ebx].name)) = '\0'; + } + break; + } + case SYSCALL_GET_PROCESS_COUNT: + { + return tasks_running; + } + case SYSCALL_GET_PROCESS_STATE: + { + return proctab[ebx].state; + } + case SYSCALL_SET_PROCESS_STATE: + { + proctab[ebx].state = ecx; + break; + } + case SYSCALL_EXIT: + { + proc_kill(current_task); + break; + } + case SYSCALL_PUTS: + { + puts(ebx); + break; + } + case SYSCALL_PUTC: + { + putc(ebx); + break; + } + case SYSCALL_SET_CARRET_POS: + { + cons_carret = ebx; + break; + } + case SYSCALL_GET_CARRET_POS: + { + return cons_carret; + } + case SYSCALL_SET_CONSOLE_ATTRIBUTE: + { + cons_attribute = ebx; + break; + } + case SYSCALL_GET_CONSOLE_ATTRIBUTE: + { + return cons_attribute; + } + case SYSCALL_GET_MEMORY_USAGE: + { + return system_info.used_memory; + } + case SYSCALL_SEND_MESSAGE: + { + /* asynchronicznie mozna + if (ebx == current_task) + return 0;*/ + + ((message_t*)ecx)->from = current_task; + ipc_sendmessage(ebx, ecx); +/* + if (ecx > KERNEL_MEMORY) + { + if (proctab[ebx].state == PROC_STATE_WAITING_FOR_MESSAGE) + proctab[ebx].state = PROC_STATE_READY; + + proctab[current_task].state = PROC_STATE_WORKING; + memcpy(&proctab[current_task].message, ecx, sizeof(message_t)); + proctab[current_task].message.from = current_task; + proctab[current_task].message_to = ebx; + + /* ten watek spi, wiec nie mozemy do niego wrocic * + proctab[current_task].stack = user_ring0_esp; + schedule(); + write_cr3(proctab[current_task].cr3); + + //zapisujemy jego stos dla r0 w tssie + user_ring0_esp = proctab[current_task].stack; + __asm__ __volatile__ ("jmp timer_isr_part2"); + + return 1; + } + else + { + exception_software(0); + return 0; + } +*/ + return 1; + } + case SYSCALL_GET_MESSAGE: + { + if (proctab[current_task].queue_size > 0) + { + //printf("getmessage(): %d, %d, %x\n", current_task, proctab[current_task].queue_size, ebx); + ipc_getmessage(ebx); + return 1; + } + else + return 0; +/* + for (i = 0; i < highest_task; i++) + { + if (proctab[i].used && proctab[i].state == PROC_STATE_WORKING && proctab[i].message_to == current_task) + { + proctab[i].state = PROC_STATE_READY; + if (ebx > KERNEL_MEMORY) + { + memcpy(ebx, &proctab[i].message, sizeof(message_t)); + return 1; + } + else + { + exception_software(0); + return 0; + } + } + } +*/ + return 0; + } + case SYSCALL_CREATE_SHARED_FRAME: + { + return proc_createsharedframe(ebx); + } + case SYSCALL_FREE_SHARED_FRAME: + { + proc_freesharedframe(); + break; + } + case SYSCALL_IS_PROCESS: + { + return proctab[ebx].used; + } + case SYSCALL_GET_TICKS: + { + return ticks; + } + case SYSCALL_FIND_PROCESS: + { + return proc_find(ebx); + } + case SYSCALL_SET_MY_NAME: + { + proc_setname(current_task, ebx); + break; + } + case SYSCALL_IRQ_ENABLE: + { + irq_enable(ebx); + break; + } + case SYSCALL_IRQ_DISABLE: + { + irq_disable(ebx); + break; + } + case SYSCALL_SLEEP: + { + if (ebx == SLEEP_SLAVE) + proctab[current_task].state = PROC_STATE_SLAVE; + else + proctab[current_task].state = PROC_STATE_SLEEPING; + + proctab[current_task].sleep_flags = ebx; + + /* ten watek spi, wiec nie mozemy do niego wrocic */ + proctab[current_task].stack = user_ring0_esp; + schedule(); + write_cr3(proctab[current_task].cr3); + + //zapisujemy jego stos dla r0 w tssie + user_ring0_esp = proctab[current_task].stack; + __asm__ __volatile__ ("jmp timer_isr_part2"); + + break; + } + case SYSCALL_GET_BOOT_DEVICE: + { + return system_info.boot_device; + } + } +} diff --git a/src/keybd/Makefile b/src/keybd/Makefile new file mode 100755 index 0000000..beb6256 --- /dev/null +++ b/src/keybd/Makefile @@ -0,0 +1,10 @@ +NAME = keybd + +OBJS = ../../lib/libc.o \ + ../../lib/libsys.o \ + +CFLAGS = -O2 -fomit-frame-pointer -I ../kernel/include -I ../../include -nostdinc -fno-builtin -DDEBUG + +all: + /usr/cross/i586-elf/bin/gcc -c $(CFLAGS) -o $(NAME).o $(NAME).c + ld -T /usr/cross/i586-elf/lib/ldscripts/elf_i386.x -o ../../bin/$(NAME).dri ../crt0/crt0.o $(NAME).o $(OBJS) diff --git a/src/keybd/compile.log b/src/keybd/compile.log new file mode 100755 index 0000000..a24a9eb --- /dev/null +++ b/src/keybd/compile.log @@ -0,0 +1,8 @@ +keybd.c: In function `do_gets': +keybd.c:64: warning: initialization makes pointer from integer without a cast +keybd.c:68: warning: use of cast expressions as lvalues is deprecated +keybd.c:68: warning: use of cast expressions as lvalues is deprecated +keybd.c: In function `main': +keybd.c:115: warning: passing arg 2 of `do_gets' makes pointer from integer without a cast +keybd.c:102: warning: return type of 'main' is not `int' +ld: warning: cannot find entry symbol _start; defaulting to 0000000001000080 diff --git a/src/keybd/keybd.c b/src/keybd/keybd.c new file mode 100755 index 0000000..5ba3131 --- /dev/null +++ b/src/keybd/keybd.c @@ -0,0 +1,119 @@ +#include "draco.h" +#include "libc.h" + +#define KBD_SPECIAL 200 +#define ENTER 10 +#define F1 201 +#define F2 202 +#define F3 203 +#define F4 204 +#define F5 205 +#define F6 206 +#define F7 207 +#define F8 208 +#define F9 209 +#define F10 210 +#define F11 211 +#define F12 212 +#define PAUSE 213 + +char scancode_ascii[0x100] = { + KBD_SPECIAL, KBD_SPECIAL, + '1','2','3','4','5','6','7','8','9','0','-','=', + 27, KBD_SPECIAL, + 'q','w','e','r','t','y','u','i','o','p','[',']','\n',KBD_SPECIAL, + 'a','s','d','f','g','h','j','k','l',';','\'',KBD_SPECIAL,'\\', + '<','z','x','c','v','b','n','m',',','.','/',KBD_SPECIAL,KBD_SPECIAL,KBD_SPECIAL, + ' ',KBD_SPECIAL,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12,PAUSE,KBD_SPECIAL,KBD_SPECIAL, +}; + +int shift = 0; +int escaped = 0; + +int buffering = 0; +char * buffer; + +message_t msg; + +char readkey() +{ + char key; + char kbd_scancode = inb(0x60); + if (escaped) kbd_scancode += 256; + + switch (kbd_scancode) + { + case 0x2a: shift = 1; break; + case 0xaa: shift = 0; break; + case 0xe0: escaped = 1; break; + default: + if (kbd_scancode & 0x80) + { + return 0; + } + else + { + return scancode_ascii[kbd_scancode]; + } + break; + } +} + +void do_gets(int pid, char * buffer) +{ + void * frame = createsharedframe(pid); + char key = 0; + static int i, k; + + (unsigned long)buffer += (unsigned long)frame; + + i = 0; + while (key != '\n') + { + sleep(SLEEP_IRQ1); + for (k = getirqstatus(1); k > 0; k --) + { + key = readkey(); + if (key == 0) continue; + if (key == 27) + { + buffer[i] = 0; + i --; + } + if (i < 0) + { + i = 0; + continue; + } + putc(key); + buffer[i] = key; + i ++; + } + clearirqstatus(1); + } + buffer[i == 0 ? i : i - 1] = 0; + + setprocessstate(pid, PROC_STATE_READY); + + freesharedframe(); +} + +void main() +{ + enableirq(1); + + printf("keybd: standard keyboard driver\n"); + setmyname("keybd"); + + while(1) + { + sleep(SLEEP_MESSAGE); + + getmessage(&msg); + if (msg.type == 1) + { + do_gets(msg.from, msg.lparam); + } + } +} + diff --git a/src/keybd/link.ld b/src/keybd/link.ld new file mode 100755 index 0000000..f4fe914 --- /dev/null +++ b/src/keybd/link.ld @@ -0,0 +1,29 @@ +OUTPUT_FORMAT("binary") +SECTIONS { + .text 0x1000000 : { + code = . ; _code = . ; + *(.text) + } + .rodata : { + rodata = .; + *(.rodata) + } + .rodata.str1.4 : { + rodata.str1.4 = .; + *(.rodata.str1.4) + } + .rodata.str1.1 : { + rodata.str1.1 = .; + *(.rodata.str1.1) + } + .data : { + *(.data) + edata = . ; + } + .bss : { + bss = . ; _bss = . ; + *(.bss) + *(.COMMON) + } + end = . ; _end = . ; +} diff --git a/src/libc/Makefile b/src/libc/Makefile new file mode 100755 index 0000000..d3d20e5 --- /dev/null +++ b/src/libc/Makefile @@ -0,0 +1,25 @@ +.SUFFIXES: .asm .c; + +OUTFILE = ../../lib/libc.o + +OBJS = memcpy.o \ + memset.o \ + sprintf.o \ + printf.o \ + strlen.o \ + ultoa.o \ + strchr.o \ + strcmp.o + + +CFLAGS = -O2 -fomit-frame-pointer -I include -I ../../include -nostdinc -fno-builtin -DDEBUG + +$(OUTFILE): $(OBJS) + ld -r -o $(OUTFILE) $(OBJS) + +.asm.o: + nasm $*.asm -o $*.o -f elf + +.c.o: + gcc -c $(CFLAGS) -o $*.o $*.c + diff --git a/src/libc/compile.log b/src/libc/compile.log new file mode 100755 index 0000000..e69de29 diff --git a/src/libc/memcpy.c b/src/libc/memcpy.c new file mode 100755 index 0000000..d963026 --- /dev/null +++ b/src/libc/memcpy.c @@ -0,0 +1,13 @@ +#include "libc.h" + +void * memcpy( void * dest , const void * src , unsigned long num ) +{ + unsigned long i; + unsigned char * uc_dest = (unsigned char*)dest; + const unsigned char * uc_src = (const unsigned char *)src; + + for( i = 0; i < num; i ++ ) + uc_dest[i] = uc_src[i]; + + return dest; +} diff --git a/src/libc/memset.c b/src/libc/memset.c new file mode 100755 index 0000000..01963a1 --- /dev/null +++ b/src/libc/memset.c @@ -0,0 +1,12 @@ +#include "libc.h" + +void * memset( void * buffer , int c , unsigned long num ) +{ + unsigned long i; + unsigned char * uc_dest = (unsigned char*)buffer; + + for( i = 0; i < num ; i ++ ) + uc_dest[i] = c; + + return buffer; +} diff --git a/src/libc/printf.c b/src/libc/printf.c new file mode 100755 index 0000000..e838c3e --- /dev/null +++ b/src/libc/printf.c @@ -0,0 +1,64 @@ +#include "libc.h" +#include "stdarg.h" + +void printf(const char * fmt, ...) +{ + va_list ap; + int i_fmt; + + va_start(ap, fmt); + + for (i_fmt = 0; i_fmt < INT_MAX;) + { + if (fmt[i_fmt] == '%') + { + i_fmt++; + + char *argchptr; + unsigned long argul; + unsigned char argch; + + switch (fmt[i_fmt]) + { + case 's': + argchptr = va_arg( ap, char* ); + puts(argchptr); + i_fmt++; + break; + + case 'X': + case 'x': + argul = va_arg( ap , unsigned long ); + argchptr = ultoa( argul , 16 ); + puts(argchptr); + i_fmt++; + break; + + case 'c': + argch = va_arg( ap , char ); + putc(argch); + i_fmt++; + break; + + case 'd': + argul = va_arg( ap , unsigned long ); + argchptr = ultoa( argul , 10 ); + puts(argchptr); + i_fmt++; + break; + + default: + break; + } + } + else if( fmt[i_fmt] == '\0' ) + { + break; + } + else + { + putc(fmt[i_fmt]); + i_fmt++; + } + } +} diff --git a/src/libc/sprintf.c b/src/libc/sprintf.c new file mode 100755 index 0000000..2ebfdb2 --- /dev/null +++ b/src/libc/sprintf.c @@ -0,0 +1,72 @@ +#include +#include "libc.h" + +int sprintf( char * dest , const char * fmt , ... ) +{ + va_list ap; + int i_dest, i_fmt, i; + + va_start( ap , fmt ); + + for( i_dest = 0, i_fmt = 0; i_fmt < INT_MAX; ) + { + if( fmt[i_fmt] == '%' ) + { + i_fmt++; + + char *argchptr; + unsigned long argul; + unsigned char argch; + + switch( fmt[i_fmt] ) + { + case 's': + argchptr = va_arg( ap, char* ); + memcpy( &dest[i_dest], argchptr, strlen( argchptr ) ); + i_dest += strlen( argchptr ); + i_fmt++; + break; + + case 'X': + case 'x': + argul = va_arg( ap , unsigned long ); + argchptr = ultoa( argul , 16 ); + memcpy( &dest[i_dest], argchptr, strlen( argchptr ) ); + i_dest += strlen( argchptr ); + i_fmt++; + break; + + case 'c': + argch = va_arg( ap , int ); + dest[i_dest] = argch; + i_dest++; + i_fmt++; + break; + + case 'd': + argul = va_arg( ap , unsigned long ); + argchptr = ultoa( argul , 10 ); + memcpy( &dest[i_dest], argchptr, strlen( argchptr ) ); + i_dest += strlen( argchptr ); + i_fmt++; + break; + + default: + break; + } + + } else if( fmt[i_fmt] == '\0' ) + { + dest[i_dest] = '\0'; + break; + } else + { + dest[i_dest] = fmt[i_fmt]; + i_fmt ++; + i_dest ++; + } + } + + return i_dest; +} + diff --git a/src/libc/strchr.c b/src/libc/strchr.c new file mode 100755 index 0000000..51128db --- /dev/null +++ b/src/libc/strchr.c @@ -0,0 +1,13 @@ +#include "libc.h" + +char * strchr( const char * s, char c ) +{ + do + { + if ( *s == c ) + { + return (char *) s; + } + } while ( *s++ ); + return 0; +} diff --git a/src/libc/strcmp.c b/src/libc/strcmp.c new file mode 100755 index 0000000..05ceb8d --- /dev/null +++ b/src/libc/strcmp.c @@ -0,0 +1,12 @@ +#include "libc.h" + +int strcmp( const char * s1, const char * s2 ) +{ + while ( ( *s1 ) && ( *s1 == *s2 ) ) + { + ++s1; + ++s2; + } + return ( *s1 - *s2 ); +} + diff --git a/src/libc/strlen.c b/src/libc/strlen.c new file mode 100755 index 0000000..661577e --- /dev/null +++ b/src/libc/strlen.c @@ -0,0 +1,10 @@ +#include "libc.h" + +int strlen( char * str ) +{ + int len; + for( len = 0; len < INT_MAX; len ++ ) + if( str[len] == '\0' ) + return len; +} + diff --git a/src/libc/ultoa.c b/src/libc/ultoa.c new file mode 100755 index 0000000..f01fb76 --- /dev/null +++ b/src/libc/ultoa.c @@ -0,0 +1,90 @@ +#include "libc.h" + +#define to_digit(c) ((c) - '0') +#define is_digit(c) ((unsigned)to_digit(c) <= 9) +#define to_char(n) ((n) + '0') + +char * +__ultoa(unsigned long val, char *endp, int base, int octzero, const char *xdigs, + int needgrp, char thousep, const char *grp) +{ + char *cp = endp; + long sval; + int ndig; + + /* + * Handle the three cases separately, in the hope of getting + * better/faster code. + */ + switch (base) { + case 10: + if (val < 10) { /* many numbers are 1 digit */ + *--cp = to_char(val); + return (cp); + } + ndig = 0; + /* + * On many machines, unsigned arithmetic is harder than + * signed arithmetic, so we do at most one unsigned mod and + * divide; this is sufficient to reduce the range of + * the incoming value to where signed arithmetic works. + */ + if (val > LONG_MAX) { + *--cp = to_char(val % 10); + ndig++; + sval = val / 10; + } else + sval = val; + do { + *--cp = to_char(sval % 10); + ndig++; + /* + * If (*grp == CHAR_MAX) then no more grouping + * should be performed. + */ + if (needgrp && ndig == *grp && *grp != CHAR_MAX + && sval > 9) { + *--cp = thousep; + ndig = 0; + /* + * If (*(grp+1) == '\0') then we have to + * use *grp character (last grouping rule) + * for all next cases + */ + if (*(grp+1) != '\0') + grp++; + } + sval /= 10; + } while (sval != 0); + break; + + case 8: + do { + *--cp = to_char(val & 7); + val >>= 3; + } while (val); + if (octzero && *cp != '0') + *--cp = '0'; + break; + + case 16: + do { + *--cp = xdigs[val & 15]; + val >>= 4; + } while (val); + break; + + default: /* oops */ + return (char*)0; + } + return (cp); +} + +char ultoabuf[9]; +char * ultoa( unsigned long val , int base ) +{ + register int i; + for(i = 0; i < 9; i ++ ) ultoabuf[i] = 0; + return __ultoa( val , ultoabuf+8, base, 0, "0123456789ABCDEF", 0, 0, 0 ); +} + diff --git a/src/libsys/Makefile b/src/libsys/Makefile new file mode 100755 index 0000000..278365d --- /dev/null +++ b/src/libsys/Makefile @@ -0,0 +1,18 @@ +.SUFFIXES: .asm .c; + +OUTFILE = ../../lib/libsys.o + +OBJS = system.o \ + systemcall.o + +CFLAGS = -O2 -fomit-frame-pointer -I include -I ../../include -nostdinc -fno-builtin -DDEBUG + +$(OUTFILE): $(OBJS) + ld -r -o $(OUTFILE) $(OBJS) + +.asm.o: + nasm $*.asm -o $*.o -f elf + +.c.o: + gcc -c $(CFLAGS) -o $*.o $*.c + diff --git a/src/libsys/compile.log b/src/libsys/compile.log new file mode 100755 index 0000000..e69de29 diff --git a/src/libsys/system.c b/src/libsys/system.c new file mode 100755 index 0000000..4441b01 --- /dev/null +++ b/src/libsys/system.c @@ -0,0 +1,122 @@ +#include "system.h" +#include "syscall.h" +#include "drax.h" + +void uname(char * s) +{ + systemcall(SYSCALL_UNAME, s); +} + +void * createsharedframe(int pid) +{ + return systemcall(SYSCALL_CREATE_SHARED_FRAME, pid); +} + +bool freesharedframe() +{ + return systemcall(SYSCALL_FREE_SHARED_FRAME); +} + +int findprocess(char * name) +{ + return systemcall(SYSCALL_FIND_PROCESS, name); +} + +bool getmessage(message_t * msg) +{ + return systemcall(SYSCALL_GET_MESSAGE, msg); +} + +int getpid() +{ + return systemcall(SYSCALL_GET_PID); +} + +int getprocesscount() +{ + return systemcall(SYSCALL_GET_PROCESS_COUNT); +} + +bool getprocessname(int pid, char * buf) +{ + return systemcall(SYSCALL_GET_PROCESS_NAME, pid, buf); +} + +void setprocessstate(int pid, int state) +{ + systemcall(SYSCALL_SET_PROCESS_STATE, pid, state); +} + +int getprocessstate(int pid) +{ + systemcall(SYSCALL_GET_PROCESS_STATE, pid); +} + +unsigned long gettickcount() +{ + return systemcall(SYSCALL_GET_TICKS); +} + +bool isprocess(int pid) +{ + return systemcall(SYSCALL_IS_PROCESS, pid); +} + +bool sendmessage(int pid, message_t * msg) +{ + return systemcall(SYSCALL_SEND_MESSAGE, pid, msg); +} + +void setmyname(char * name) +{ + systemcall(SYSCALL_SET_MY_NAME, name); +} + +void puts(char * s) +{ + systemcall(SYSCALL_PUTS, s); +} + +void putc(char c) +{ + systemcall(SYSCALL_PUTC, c); +} + +void gets(char * s) +{ + static message_t msg; + msg.type = 1; + msg.lparam = s; + sendmessage(findprocess("keybd"), &msg); + sleep(SLEEP_SLAVE); +} + +void sleep(unsigned long flags) +{ + systemcall(SYSCALL_SLEEP, flags); +} + +void enableirq(int irq) +{ + systemcall(SYSCALL_IRQ_ENABLE, irq); +} + +void disableirq(int irq) +{ + systemcall(SYSCALL_IRQ_DISABLE, irq); +} + +unsigned int getirqstatus(int irq) +{ + return systemcall(SYSCALL_GET_IRQ_STATUS, irq); +} + +void clearirqstatus(int irq) +{ + systemcall(SYSCALL_CLEAR_IRQ_STATUS, irq); +} + +int getbootdevice() +{ + return systemcall(SYSCALL_GET_BOOT_DEVICE); +} diff --git a/src/libsys/systemcall.asm b/src/libsys/systemcall.asm new file mode 100755 index 0000000..0c32cfa --- /dev/null +++ b/src/libsys/systemcall.asm @@ -0,0 +1,25 @@ +global systemcall +systemcall: + mov ebp, esp + + push ecx + push edx + push ebx + push ebp + push esi + push edi + + mov eax, [ebp + 4] + mov ebx, [ebp + 8] + mov ecx, [ebp + 12] + mov edx, [ebp + 16] + int 0x80 + + pop edi + pop esi + pop ebp + pop ebx + pop edx + pop ecx + + ret diff --git a/src/mon/Makefile b/src/mon/Makefile new file mode 100755 index 0000000..5e1b494 --- /dev/null +++ b/src/mon/Makefile @@ -0,0 +1,10 @@ +NAME = mon + +OBJS = ../../lib/libc.o \ + ../../lib/libsys.o \ + +CFLAGS = -O2 -fomit-frame-pointer -I ../kernel/include -I ../../include -nostdinc -fno-builtin -DDEBUG + +all: + /usr/cross/i586-elf/bin/gcc -c $(CFLAGS) -o $(NAME).o $(NAME).c + ld -T /usr/cross/i586-elf/lib/ldscripts/elf_i386.x -o ../../bin/$(NAME).dri ../crt0/crt0.o $(NAME).o $(OBJS) diff --git a/src/mon/compile.log b/src/mon/compile.log new file mode 100755 index 0000000..5402cc1 --- /dev/null +++ b/src/mon/compile.log @@ -0,0 +1,3 @@ +mon.c: In function `main': +mon.c:26: warning: return type of 'main' is not `int' +ld: warning: cannot find entry symbol _start; defaulting to 0000000001000080 diff --git a/src/mon/link.ld b/src/mon/link.ld new file mode 100755 index 0000000..f4fe914 --- /dev/null +++ b/src/mon/link.ld @@ -0,0 +1,29 @@ +OUTPUT_FORMAT("binary") +SECTIONS { + .text 0x1000000 : { + code = . ; _code = . ; + *(.text) + } + .rodata : { + rodata = .; + *(.rodata) + } + .rodata.str1.4 : { + rodata.str1.4 = .; + *(.rodata.str1.4) + } + .rodata.str1.1 : { + rodata.str1.1 = .; + *(.rodata.str1.1) + } + .data : { + *(.data) + edata = . ; + } + .bss : { + bss = . ; _bss = . ; + *(.bss) + *(.COMMON) + } + end = . ; _end = . ; +} diff --git a/src/mon/map.txt b/src/mon/map.txt new file mode 100755 index 0000000..0dce7c1 --- /dev/null +++ b/src/mon/map.txt @@ -0,0 +1,148 @@ + +Allocating common symbols +Common symbol size file + +cons_attr 0x1 mon.o +ultoabuf 0x9 ../../libc/ultoa.o +cons_carret 0x4 mon.o +buf 0x80 mon.o + +Memory Configuration + +Name Origin Length Attributes +*default* 0x0000000000000000 0xffffffffffffffff + +Linker script and memory map + + +.text 0x0000000001000000 0x7cd + 0x0000000001000000 code = . + 0x0000000001000000 _code = . + *(.text) + .text 0x0000000001000000 0xb ../entry/entry.o + *fill* 0x000000000100000b 0x100000b00000001 00 + .text 0x000000000100000c 0x1a5 mon.o + 0x000000000100000c _wait + 0x0000000001000028 clear_rect + 0x0000000001000070 main + *fill* 0x00000000010001b1 0x10001b100000003 00 + .text 0x00000000010001b4 0x24 ../../libc/memcpy.o + 0x00000000010001b4 memcpy + .text 0x00000000010001d8 0x1e ../../libc/memset.o + 0x00000000010001d8 memset + *fill* 0x00000000010001f6 0x10001f600000002 00 + .text 0x00000000010001f8 0xd3 ../../libc/sprintf.o + 0x00000000010001f8 sprintf + *fill* 0x00000000010002cb 0x10002cb00000001 00 + .text 0x00000000010002cc 0x8c ../../libc/printf.o + 0x00000000010002cc printf + .text 0x0000000001000358 0x62 ../../libc/strlen.o + 0x0000000001000358 strlen + *fill* 0x00000000010003ba 0x10003ba00000002 00 + .text 0x00000000010003bc 0x184 ../../libc/ultoa.o + 0x00000000010003bc __ultoa + 0x000000000100050c ultoa + .text 0x0000000001000540 0x16 ../../libc/strchr.o + 0x0000000001000540 strchr + *fill* 0x0000000001000556 0x100055600000002 00 + .text 0x0000000001000558 0x29 ../../libc/strcmp.o + 0x0000000001000558 strcmp + *fill* 0x0000000001000581 0x100058100000003 00 + .text 0x0000000001000584 0x225 ../../libc/system.o + 0x0000000001000610 getprocessname + 0x00000000010005d8 getmessage + 0x00000000010006f8 gets + 0x00000000010005c0 findprocess + 0x00000000010005ec getpid + 0x00000000010006b8 puts + 0x00000000010006e0 sleep + 0x00000000010006a0 setmyname + 0x0000000001000738 enableirq + 0x0000000001000644 getprocessstate + 0x0000000001000688 sendmessage + 0x0000000001000584 uname + 0x000000000100059c createsharedframe + 0x0000000001000780 clearirqstatus + 0x0000000001000768 getirqstatus + 0x00000000010006cc putc + 0x0000000001000670 isprocess + 0x0000000001000750 disableirq + 0x00000000010005fc getprocesscount + 0x00000000010005b0 freesharedframe + 0x0000000001000798 getbootdevice + 0x000000000100065c gettickcount + 0x0000000001000628 setprocessstate + *fill* 0x00000000010007a9 0x10007a900000007 00 + .text 0x00000000010007b0 0x1d ../../libc/systemcall.o + 0x00000000010007b0 systemcall + +.rodata 0x00000000010007d0 0x108 + 0x00000000010007d0 rodata = . + *(.rodata) + .rodata 0x00000000010007d0 0x84 ../../libc/sprintf.o + .rodata 0x0000000001000854 0x84 ../../libc/printf.o + +.rodata.str1.4 0x00000000010008d8 0x27 + 0x00000000010008d8 rodata.str1.4 = . + *(.rodata.str1.4) + .rodata.str1.4 + 0x00000000010008d8 0x27 mon.o + +.rodata.str1.1 0x00000000010008ff 0x3c + 0x00000000010008ff rodata.str1.1 = . + *(.rodata.str1.1) + .rodata.str1.1 + 0x00000000010008ff 0x25 mon.o + .rodata.str1.1 + 0x0000000001000924 0x11 ../../libc/ultoa.o + .rodata.str1.1 + 0x0000000001000935 0x6 ../../libc/system.o + +.data 0x000000000100093c 0x0 + *(.data) + 0x000000000100093c edata = . + +.bss 0x0000000001000940 0xc9 + 0x0000000001000940 bss = . + 0x0000000001000940 _bss = . + *(.bss) + .bss 0x0000000001000940 0x10 ../../libc/system.o + *(.COMMON) + *fill* 0x0000000001000950 0x100095000000010 00 + COMMON 0x0000000001000960 0xa0 mon.o + 0x0 (size before relaxing) + 0x0000000001000960 cons_attr + 0x0000000001000964 cons_carret + 0x0000000001000980 buf + COMMON 0x0000000001000a00 0x9 ../../libc/ultoa.o + 0x0 (size before relaxing) + 0x0000000001000a00 ultoabuf + 0x0000000001000a09 end = . + 0x0000000001000a09 _end = . +LOAD ../entry/entry.o +LOAD mon.o +LOAD ../../libc/memcpy.o +LOAD ../../libc/memset.o +LOAD ../../libc/sprintf.o +LOAD ../../libc/printf.o +LOAD ../../libc/strlen.o +LOAD ../../libc/ultoa.o +LOAD ../../libc/strchr.o +LOAD ../../libc/strcmp.o +LOAD ../../libc/system.o +LOAD ../../libc/systemcall.o +OUTPUT(../../bin/mon.dri binary) + +.comment 0x0000000000000000 0x1b0 + .comment 0x0000000000000000 0x1f ../entry/entry.o + .comment 0x000000000000001f 0x25 mon.o + .comment 0x0000000000000044 0x25 ../../libc/memcpy.o + .comment 0x0000000000000069 0x25 ../../libc/memset.o + .comment 0x000000000000008e 0x25 ../../libc/sprintf.o + .comment 0x00000000000000b3 0x25 ../../libc/printf.o + .comment 0x00000000000000d8 0x25 ../../libc/strlen.o + .comment 0x00000000000000fd 0x25 ../../libc/ultoa.o + .comment 0x0000000000000122 0x25 ../../libc/strchr.o + .comment 0x0000000000000147 0x25 ../../libc/strcmp.o + .comment 0x000000000000016c 0x25 ../../libc/system.o + .comment 0x0000000000000191 0x1f ../../libc/systemcall.o diff --git a/src/mon/mon.c b/src/mon/mon.c new file mode 100755 index 0000000..5bfb7d0 --- /dev/null +++ b/src/mon/mon.c @@ -0,0 +1,63 @@ +#include "libc.h" +#include "syscall.h" +#include "types.h" + +void _wait(int i) +{ + i *= 1000; + while (i > 0) + i--; +} + +void clear_rect(int lines) +{ + int i; + systemcall(SYSCALL_SET_CARRET_POS, 0); + for (i = 0; i < 80 * lines; i++) + putc(' '); + systemcall(SYSCALL_SET_CARRET_POS, 0); +} + +char buf[128]; +char cons_attr; +long cons_carret; + +void main() +{ + int i, t, l; + + while(1) + { + l++; + + cons_attr = systemcall(SYSCALL_GET_CONSOLE_ATTRIBUTE); + cons_carret = systemcall(SYSCALL_GET_CARRET_POS); + + systemcall(SYSCALL_SET_CONSOLE_ATTRIBUTE, 25); + clear_rect(3); + printf("DracMon system monitor v0.1\n"); + printf("Processes: %d | Mem: %dKB | Ticks: %d\n", + systemcall(SYSCALL_GET_PROCESS_COUNT), + systemcall(SYSCALL_GET_MEMORY_USAGE), + systemcall(SYSCALL_GET_TICKS) + ); + + i = 0; + t = 0; + while (t < systemcall(SYSCALL_GET_PROCESS_COUNT)) + { + if (systemcall(SYSCALL_IS_PROCESS, i)) + { + systemcall(SYSCALL_GET_PROCESS_NAME, i, &buf); + printf("%s(%d) ", &buf, systemcall(SYSCALL_GET_PROCESS_STATE, i)); + t++; + } + i++; + } + + systemcall(SYSCALL_SET_CONSOLE_ATTRIBUTE, cons_attr); + systemcall(SYSCALL_SET_CARRET_POS, cons_carret); + + _wait(100); + } +} diff --git a/src/moused/Makefile b/src/moused/Makefile new file mode 100755 index 0000000..db59d5d --- /dev/null +++ b/src/moused/Makefile @@ -0,0 +1,10 @@ +NAME = moused + +OBJS = ../../lib/libc.o \ + ../../lib/libsys.o \ + +CFLAGS = -O2 -fomit-frame-pointer -I ../kernel/include -I ../../include -nostdinc -fno-builtin -DDEBUG + +all: + /usr/cross/i586-elf/bin/gcc -c $(CFLAGS) -o $(NAME).o $(NAME).c + ld -T /usr/cross/i586-elf/lib/ldscripts/elf_i386.x -o ../../bin/$(NAME).dri ../crt0/crt0.o $(NAME).o $(OBJS) diff --git a/src/moused/compile.log b/src/moused/compile.log new file mode 100755 index 0000000..bb6a6e2 --- /dev/null +++ b/src/moused/compile.log @@ -0,0 +1,3 @@ +moused.c: In function `main': +moused.c:82: warning: return type of 'main' is not `int' +ld: warning: cannot find entry symbol _start; defaulting to 0000000001000080 diff --git a/src/moused/link.ld b/src/moused/link.ld new file mode 100755 index 0000000..f4fe914 --- /dev/null +++ b/src/moused/link.ld @@ -0,0 +1,29 @@ +OUTPUT_FORMAT("binary") +SECTIONS { + .text 0x1000000 : { + code = . ; _code = . ; + *(.text) + } + .rodata : { + rodata = .; + *(.rodata) + } + .rodata.str1.4 : { + rodata.str1.4 = .; + *(.rodata.str1.4) + } + .rodata.str1.1 : { + rodata.str1.1 = .; + *(.rodata.str1.1) + } + .data : { + *(.data) + edata = . ; + } + .bss : { + bss = . ; _bss = . ; + *(.bss) + *(.COMMON) + } + end = . ; _end = . ; +} diff --git a/src/moused/map.txt b/src/moused/map.txt new file mode 100755 index 0000000..3fbe0ab --- /dev/null +++ b/src/moused/map.txt @@ -0,0 +1,148 @@ + +Allocating common symbols +Common symbol size file + +ultoabuf 0x9 ../../libc/ultoa.o +mouse_byte 0x3 moused.o + +Memory Configuration + +Name Origin Length Attributes +*default* 0x0000000000000000 0xffffffffffffffff + +Linker script and memory map + + +.text 0x0000000001000000 0x97d + 0x0000000001000000 code = . + 0x0000000001000000 _code = . + *(.text) + .text 0x0000000001000000 0xb ../entry/entry.o + *fill* 0x000000000100000b 0x100000b00000001 00 + .text 0x000000000100000c 0x352 moused.o + 0x000000000100004c mouse_write + 0x000000000100009c mouse_read + 0x00000000010000c4 init + 0x0000000001000228 main + 0x000000000100000c mouse_wait + *fill* 0x000000000100035e 0x100035e00000002 00 + .text 0x0000000001000360 0x24 ../../libc/memcpy.o + 0x0000000001000360 memcpy + .text 0x0000000001000384 0x1e ../../libc/memset.o + 0x0000000001000384 memset + *fill* 0x00000000010003a2 0x10003a200000002 00 + .text 0x00000000010003a4 0xd3 ../../libc/sprintf.o + 0x00000000010003a4 sprintf + *fill* 0x0000000001000477 0x100047700000001 00 + .text 0x0000000001000478 0x8c ../../libc/printf.o + 0x0000000001000478 printf + .text 0x0000000001000504 0x62 ../../libc/strlen.o + 0x0000000001000504 strlen + *fill* 0x0000000001000566 0x100056600000002 00 + .text 0x0000000001000568 0x184 ../../libc/ultoa.o + 0x0000000001000568 __ultoa + 0x00000000010006b8 ultoa + .text 0x00000000010006ec 0x16 ../../libc/strchr.o + 0x00000000010006ec strchr + *fill* 0x0000000001000702 0x100070200000002 00 + .text 0x0000000001000704 0x29 ../../libc/strcmp.o + 0x0000000001000704 strcmp + *fill* 0x000000000100072d 0x100072d00000003 00 + .text 0x0000000001000730 0x225 ../../libc/system.o + 0x00000000010007bc getprocessname + 0x0000000001000784 getmessage + 0x00000000010008a4 gets + 0x000000000100076c findprocess + 0x0000000001000798 getpid + 0x0000000001000864 puts + 0x000000000100088c sleep + 0x000000000100084c setmyname + 0x00000000010008e4 enableirq + 0x00000000010007f0 getprocessstate + 0x0000000001000834 sendmessage + 0x0000000001000730 uname + 0x0000000001000748 createsharedframe + 0x000000000100092c clearirqstatus + 0x0000000001000914 getirqstatus + 0x0000000001000878 putc + 0x000000000100081c isprocess + 0x00000000010008fc disableirq + 0x00000000010007a8 getprocesscount + 0x000000000100075c freesharedframe + 0x0000000001000944 getbootdevice + 0x0000000001000808 gettickcount + 0x00000000010007d4 setprocessstate + *fill* 0x0000000001000955 0x10009550000000b 00 + .text 0x0000000001000960 0x1d ../../libc/systemcall.o + 0x0000000001000960 systemcall + +.rodata 0x0000000001000980 0x108 + 0x0000000001000980 rodata = . + *(.rodata) + .rodata 0x0000000001000980 0x84 ../../libc/sprintf.o + .rodata 0x0000000001000a04 0x84 ../../libc/printf.o + +.rodata.str1.4 0x0000000001000a88 0x0 + 0x0000000001000a88 rodata.str1.4 = . + *(.rodata.str1.4) + +.rodata.str1.1 0x0000000001000a88 0x33 + 0x0000000001000a88 rodata.str1.1 = . + *(.rodata.str1.1) + .rodata.str1.1 + 0x0000000001000a88 0x1c moused.o + .rodata.str1.1 + 0x0000000001000aa4 0x11 ../../libc/ultoa.o + .rodata.str1.1 + 0x0000000001000ab5 0x6 ../../libc/system.o + +.data 0x0000000001000abc 0x0 + *(.data) + 0x0000000001000abc edata = . + +.bss 0x0000000001000abc 0x20 + 0x0000000001000abc bss = . + 0x0000000001000abc _bss = . + *(.bss) + .bss 0x0000000001000abc 0x3 moused.o + 0x0000000001000abd mouse_x + 0x0000000001000abe mouse_cycle + 0x0000000001000abc mouse_y + *fill* 0x0000000001000abf 0x1000abf00000001 00 + .bss 0x0000000001000ac0 0x10 ../../libc/system.o + *(.COMMON) + COMMON 0x0000000001000ad0 0x3 moused.o + 0x0 (size before relaxing) + 0x0000000001000ad0 mouse_byte + COMMON 0x0000000001000ad3 0x9 ../../libc/ultoa.o + 0x0 (size before relaxing) + 0x0000000001000ad3 ultoabuf + 0x0000000001000adc end = . + 0x0000000001000adc _end = . +LOAD ../entry/entry.o +LOAD moused.o +LOAD ../../libc/memcpy.o +LOAD ../../libc/memset.o +LOAD ../../libc/sprintf.o +LOAD ../../libc/printf.o +LOAD ../../libc/strlen.o +LOAD ../../libc/ultoa.o +LOAD ../../libc/strchr.o +LOAD ../../libc/strcmp.o +LOAD ../../libc/system.o +LOAD ../../libc/systemcall.o +OUTPUT(../../bin/moused.dri binary) + +.comment 0x0000000000000000 0x1b0 + .comment 0x0000000000000000 0x1f ../entry/entry.o + .comment 0x000000000000001f 0x25 moused.o + .comment 0x0000000000000044 0x25 ../../libc/memcpy.o + .comment 0x0000000000000069 0x25 ../../libc/memset.o + .comment 0x000000000000008e 0x25 ../../libc/sprintf.o + .comment 0x00000000000000b3 0x25 ../../libc/printf.o + .comment 0x00000000000000d8 0x25 ../../libc/strlen.o + .comment 0x00000000000000fd 0x25 ../../libc/ultoa.o + .comment 0x0000000000000122 0x25 ../../libc/strchr.o + .comment 0x0000000000000147 0x25 ../../libc/strcmp.o + .comment 0x000000000000016c 0x25 ../../libc/system.o + .comment 0x0000000000000191 0x1f ../../libc/systemcall.o diff --git a/src/moused/moused.c b/src/moused/moused.c new file mode 100755 index 0000000..ff9bb81 --- /dev/null +++ b/src/moused/moused.c @@ -0,0 +1,117 @@ +#include "draco.h" +#include "libc.h" +#include "moused.h" + +uint8 mouse_cycle=0; //unsigned char +int8 mouse_byte[3]; //signed char +int8 mouse_x=0; //signed char +int8 mouse_y=0; //signed char + +inline void mouse_wait(uint8 a_type) //unsigned char +{ + uint32 _time_out = 100000; + if(a_type==0) + { + while(_time_out--) //Data + { + if((inb(0x64) & 1)==1) + { + return; + } + } + return; + } + else + { + while(_time_out--) //Signal + { + if((inb(0x64) & 2)==0) + { + return; + } + } + return; + } +} + +inline void mouse_write(uint8 a_write) +{ + mouse_wait(1); + outb(0x64, 0xD4); + mouse_wait(1); + outb(0x60, a_write); +} + +uint8 mouse_read() +{ + //Get's response from mouse + mouse_wait(0); + return inb(0x60); +} + +void init() +{ + printf("moused: init\n"); + + uint8 _status; //unsigned char + + //Enable the auxiliary mouse device + mouse_wait(1); + outb(0x64, 0xA8); + + //Enable the interrupts + mouse_wait(1); + outb(0x64, 0x20); + mouse_wait(0); + _status=(inb(0x60) | 2); + mouse_wait(1); + outb(0x64, 0x60); + mouse_wait(1); + outb(0x60, _status); + + //Tell the mouse to use default settings + mouse_write(0xF6); + mouse_read(); //Acknowledge + + //Enable the mouse + mouse_write(0xF4); + mouse_read(); //Acknowledge +} + +void main() +{ + //while(1); + systemcall(SYSCALL_CLEAR_IRQ_STATUS, 12); + systemcall(SYSCALL_IRQ_ENABLE, 12); + init(); + + setmyname("moused"); + + while(1) + { + sleep(1 << 12); + if (systemcall(SYSCALL_GET_IRQ_STATUS, 12)) + { + switch(mouse_cycle) + { + case 0: + mouse_byte[0] = inb(0x60); + mouse_cycle++; + break; + case 1: + mouse_byte[1] = inb(0x60); + mouse_cycle++; + break; + case 2: + mouse_byte[2] = inb(0x60); + mouse_x += mouse_byte[1]; + mouse_y += mouse_byte[2]; + mouse_cycle=0; + break; + } + printf("%dx%d\n", mouse_x, mouse_y); + systemcall(SYSCALL_CLEAR_IRQ_STATUS, 12); + } + } +} + diff --git a/src/moused/moused.h b/src/moused/moused.h new file mode 100755 index 0000000..7eacf4b --- /dev/null +++ b/src/moused/moused.h @@ -0,0 +1,52 @@ +#ifndef __FLOPPY__H +#define __FLOPPY__H + +/* io ports */ +#define FDC_DOR (0x3f2) /* Digital Output Register */ +#define FDC_MSR (0x3f4) /* Main Status Register (input) */ +#define FDC_DRS (0x3f4) /* Data Rate Select Register (output) */ +#define FDC_DATA (0x3f5) /* Data Register */ +#define FDC_DIR (0x3f7) /* Digital Input Register (input) */ +#define FDC_CCR (0x3f7) /* Configuration Control Register (output) */ + +/* command bytes (these are 765 commands + options such as MFM, etc) */ +#define FDC_CMD_RESET (0x00) +#define FDC_CMD_SPECIFY (0x03) /* specify drive timings */ +#define FDC_CMD_WRITE (0xc5) /* write data (+ MT,MFM) */ +#define FDC_CMD_READ (0xe6) /* read data (+ MT,MFM,SK) */ +#define FDC_CMD_RECAL (0x07) /* recalibrate */ +#define FDC_CMD_SENSEI (0x08) /* sense interrupt status */ +#define FDC_CMD_FORMAT (0x4d) /* format track (+ MFM) */ +#define FDC_CMD_SEEK (0x0f) /* seek track */ +#define FDC_CMD_VERSION (0x10) /* FDC version */ + +/* drive geometries */ +#define DG144_HEADS 2 /* heads per drive (1.44M) */ +#define DG144_TRACKS 80 /* number of tracks (1.44M) */ +#define DG144_SPT 18 /* sectors per track (1.44M) */ +#define DG144_GAP3FMT 0x54 /* gap3 while formatting (1.44M) */ +#define DG144_GAP3RW 0x1b /* gap3 while reading/writing (1.44M) */ + +#define DG168_HEADS 2 /* heads per drive (1.68M) */ +#define DG168_TRACKS 80 /* number of tracks (1.68M) */ +#define DG168_SPT 21 /* sectors per track (1.68M) */ +#define DG168_GAP3FMT 0x0c /* gap3 while formatting (1.68M) */ +#define DG168_GAP3RW 0x1c /* gap3 while reading/writing (1.68M) */ + +#define FLOPPYD_READ 1 +#define FLOPPYD_WRITE 2 +#define FLOPPYD_DONE 0xFFFF + +void fdc_block2hts(uint16 block, uint16 *head, uint16 *track, uint16 *sector); +uint8 fdc_wait(uint8 send_sensei); +void fdc_sendbyte(uint8 byte); +uint8 fdc_getbyte(); +void fdc_start_motor(); +void fdc_stop_motor(); +void fdc_seek(uint16 track); +void fdc_recalibrate(); +void fdc_reset(); +void fdc_readwrite(uint16 block, int read); +void fdc_init(); + +#endif diff --git a/src/sh/Makefile b/src/sh/Makefile new file mode 100755 index 0000000..51eb371 --- /dev/null +++ b/src/sh/Makefile @@ -0,0 +1,10 @@ +NAME = sh + +OBJS = ../../lib/libc.o \ + ../../lib/libsys.o \ + +CFLAGS = -O2 -fomit-frame-pointer -I ../kernel/include -I ../../include -nostdinc -fno-builtin -DDEBUG + +all: + /usr/cross/i586-elf/bin/gcc -c $(CFLAGS) -o $(NAME).o $(NAME).c + ld -T /usr/cross/i586-elf/lib/ldscripts/elf_i386.x -o ../../bin/$(NAME) ../crt0/crt0.o $(NAME).o $(OBJS) diff --git a/src/sh/compile.log b/src/sh/compile.log new file mode 100755 index 0000000..96b4a89 --- /dev/null +++ b/src/sh/compile.log @@ -0,0 +1,8 @@ +sh.c: In function `main': +sh.c:17: warning: passing arg 1 of `strcmp' from incompatible pointer type +sh.c:22: warning: passing arg 1 of `strcmp' from incompatible pointer type +sh.c:27: warning: passing arg 1 of `strcmp' from incompatible pointer type +sh.c:31: warning: passing arg 1 of `strcmp' from incompatible pointer type +sh.c:48: warning: passing arg 1 of `strlen' from incompatible pointer type +sh.c:8: warning: return type of 'main' is not `int' +ld: warning: cannot find entry symbol _start; defaulting to 0000000001000080 diff --git a/src/sh/link.ld b/src/sh/link.ld new file mode 100755 index 0000000..f4fe914 --- /dev/null +++ b/src/sh/link.ld @@ -0,0 +1,29 @@ +OUTPUT_FORMAT("binary") +SECTIONS { + .text 0x1000000 : { + code = . ; _code = . ; + *(.text) + } + .rodata : { + rodata = .; + *(.rodata) + } + .rodata.str1.4 : { + rodata.str1.4 = .; + *(.rodata.str1.4) + } + .rodata.str1.1 : { + rodata.str1.1 = .; + *(.rodata.str1.1) + } + .data : { + *(.data) + edata = . ; + } + .bss : { + bss = . ; _bss = . ; + *(.bss) + *(.COMMON) + } + end = . ; _end = . ; +} diff --git a/src/sh/sh.c b/src/sh/sh.c new file mode 100755 index 0000000..d7cc3b0 --- /dev/null +++ b/src/sh/sh.c @@ -0,0 +1,55 @@ +#include "draco.h" +#include "libc.h" + +char cmd[256]; +char buf[256]; + +void main() +{ + int i, t; + for (i = 0; i < 100000; i++); + + while (1) + { + printf("# "); + gets(&cmd); + + if (strcmp(&cmd, "uname") == 0) + { + uname(&buf); + printf("%s\n", &buf); + } + else if (strcmp(&cmd, "ticks") == 0) + { + int tick_count = gettickcount(); + printf("%d ticks\n", tick_count); + } + else if (strcmp(&cmd, "boot") == 0) + { + printf("system booted from %d\n", getbootdevice()); + } + else if (strcmp(&cmd, "ps") == 0) + { + printf("%d processes:\n", getprocesscount()); + + i = 0; + t = 0; + while (t < getprocesscount()) + { + if (isprocess(i)) + { + getprocessname(i, &buf); + printf("%s (%d)\n", &buf, getprocessstate(i)); + t++; + } + i++; + } + } + else if (strlen(&cmd) == 0); + else + printf("%s: command not found\n", &cmd); + } + + while(1); +} + diff --git a/src/storaged/Makefile b/src/storaged/Makefile new file mode 100755 index 0000000..ac27c22 --- /dev/null +++ b/src/storaged/Makefile @@ -0,0 +1,10 @@ +NAME = storaged + +OBJS = ../../lib/libc.o \ + ../../lib/libsys.o \ + +CFLAGS = -O2 -fomit-frame-pointer -I ../kernel/include -I ../../include -nostdinc -fno-builtin -DDEBUG + +all: + /usr/cross/i586-elf/bin/gcc -c $(CFLAGS) -o $(NAME).o $(NAME).c + ld -T /usr/cross/i586-elf/lib/ldscripts/elf_i386.x -o ../../bin/$(NAME).dri ../crt0/crt0.o $(NAME).o $(OBJS) diff --git a/src/storaged/compile.log b/src/storaged/compile.log new file mode 100755 index 0000000..200acbd --- /dev/null +++ b/src/storaged/compile.log @@ -0,0 +1,5 @@ +storaged.c: In function `main': +storaged.c:72: warning: assignment makes pointer from integer without a cast +storaged.c:83: warning: passing arg 1 of `dev_register' makes pointer from integer without a cast +storaged.c:58: warning: return type of 'main' is not `int' +ld: warning: cannot find entry symbol _start; defaulting to 0000000001000080 diff --git a/src/storaged/link.ld b/src/storaged/link.ld new file mode 100755 index 0000000..f4fe914 --- /dev/null +++ b/src/storaged/link.ld @@ -0,0 +1,29 @@ +OUTPUT_FORMAT("binary") +SECTIONS { + .text 0x1000000 : { + code = . ; _code = . ; + *(.text) + } + .rodata : { + rodata = .; + *(.rodata) + } + .rodata.str1.4 : { + rodata.str1.4 = .; + *(.rodata.str1.4) + } + .rodata.str1.1 : { + rodata.str1.1 = .; + *(.rodata.str1.1) + } + .data : { + *(.data) + edata = . ; + } + .bss : { + bss = . ; _bss = . ; + *(.bss) + *(.COMMON) + } + end = . ; _end = . ; +} diff --git a/src/storaged/storaged.c b/src/storaged/storaged.c new file mode 100755 index 0000000..a51d9b8 --- /dev/null +++ b/src/storaged/storaged.c @@ -0,0 +1,90 @@ +#include "draco.h" +#include "drax.h" +#include "libc.h" +#include "storaged.h" + +#define MAX_DEVS 50000 + +static dev_t devs[MAX_DEVS]; +int highest_device; +int devices_count; + +int dev_freeslot() +{ + int i; + for (i = 0; i < MAX_DEVS; i++) + if (!devs[i].used) + return i; + return -1; +} + +void dev_register(char * name, unsigned int did, unsigned int pid) +{ + int i = dev_freeslot(); + char driver_name[32]; + + getprocessname(pid, &driver_name); + + printf("storaged: mouting /%s handled by %s\n", name, &driver_name); + + devs[i].used = 1; + devs[i].did = did; + devs[i].pid = pid; + memcpy(&devs[i].name, name, strlen(name)); + *((char*)&devs[i].name + strlen(name)) = '\0'; +} + +int dev_find(char * path) +{ + +} + +FILE * dev_fopen(char * name, char * mode) +{ + +} + +void dev_fclose(FILE * f) +{ + +} + +void init() +{ + setmyname("storaged"); +} + +void main() +{ + static message_t msg; + unsigned long frame; + request_t * request; + + init(); + + while(1) + { + sleep(SLEEP_MESSAGE); + getmessage(&msg); + + /* odczytaj request */ + frame = createsharedframe(msg.from); + request = frame + msg.lparam; + setprocessstate(msg.from, PROC_STATE_READY); + + switch (request->type) + { + case STORAGED_FOPEN: + { + break; + } + case STORAGED_REGISTER: + { + dev_register(frame + request->a, request->b, msg.from); + break; + } + } + freesharedframe(); + } +} + diff --git a/src/storaged/storaged.h b/src/storaged/storaged.h new file mode 100755 index 0000000..8d3627b --- /dev/null +++ b/src/storaged/storaged.h @@ -0,0 +1,27 @@ +#ifndef __STORAGED__H__ +#define __STORAGED__H__ + +#define STORAGED_FOPEN 1 +#define STORAGED_FCLOSE 2 +#define STORAGED_REGISTER 3 + +typedef struct +{ + char used; + char name[12]; + unsigned long did; + unsigned long pid; +} dev_t; + +typedef struct +{ + unsigned long type; + unsigned long a; + unsigned long b; + unsigned long c; + unsigned long result; +} request_t; + +typedef int FILE; + +#endif //__STORAGED__H__ diff --git a/src/test/Makefile b/src/test/Makefile new file mode 100755 index 0000000..d20e7b5 --- /dev/null +++ b/src/test/Makefile @@ -0,0 +1,19 @@ +NAME = test + +OBJS = ../../libc/memcpy.o \ + ../../libc/memset.o \ + ../../libc/sprintf.o \ + ../../libc/printf.o \ + ../../libc/strlen.o \ + ../../libc/ultoa.o \ + ../../libc/strchr.o \ + ../../libc/strcmp.o \ + ../../libc/system.o \ + ../../libc/systemcall.o + +CFLAGS = -O2 -fomit-frame-pointer -I ../../kernel/include -I ../../libc/include -nostdinc -fno-builtin -DDEBUG + +all: + gcc -c $(CFLAGS) -o $(NAME).o $(NAME).c + #gcc -S $(CFLAGS) -o $(NAME).s $(NAME).c + ld -Map map.txt -T link.ld -o ../../bin/$(NAME).dri --start-group ../entry/entry.o $(NAME).o $(OBJS) --end-group diff --git a/src/test/link.ld b/src/test/link.ld new file mode 100755 index 0000000..f4fe914 --- /dev/null +++ b/src/test/link.ld @@ -0,0 +1,29 @@ +OUTPUT_FORMAT("binary") +SECTIONS { + .text 0x1000000 : { + code = . ; _code = . ; + *(.text) + } + .rodata : { + rodata = .; + *(.rodata) + } + .rodata.str1.4 : { + rodata.str1.4 = .; + *(.rodata.str1.4) + } + .rodata.str1.1 : { + rodata.str1.1 = .; + *(.rodata.str1.1) + } + .data : { + *(.data) + edata = . ; + } + .bss : { + bss = . ; _bss = . ; + *(.bss) + *(.COMMON) + } + end = . ; _end = . ; +} diff --git a/src/test/map.txt b/src/test/map.txt new file mode 100755 index 0000000..a9f7fc9 --- /dev/null +++ b/src/test/map.txt @@ -0,0 +1,152 @@ + +Allocating common symbols +Common symbol size file + +ultoabuf 0x9 ../../libc/ultoa.o +msg 0x10 test.o +addr 0x4 test.o +buf 0x200 test.o +name 0x20 test.o + +Memory Configuration + +Name Origin Length Attributes +*default* 0x0000000000000000 0xffffffffffffffff + +Linker script and memory map + + +.text 0x0000000001000000 0x71d + 0x0000000001000000 code = . + 0x0000000001000000 _code = . + *(.text) + .text 0x0000000001000000 0xb ../entry/entry.o + *fill* 0x000000000100000b 0x100000b00000001 00 + .text 0x000000000100000c 0x153 test.o + 0x000000000100000c _wait + 0x0000000001000028 main + *fill* 0x000000000100015f 0x100015f00000001 00 + .text 0x0000000001000160 0x24 ../../libc/memcpy.o + 0x0000000001000160 memcpy + .text 0x0000000001000184 0x1e ../../libc/memset.o + 0x0000000001000184 memset + *fill* 0x00000000010001a2 0x10001a200000002 00 + .text 0x00000000010001a4 0xd3 ../../libc/sprintf.o + 0x00000000010001a4 sprintf + *fill* 0x0000000001000277 0x100027700000001 00 + .text 0x0000000001000278 0x8c ../../libc/printf.o + 0x0000000001000278 printf + .text 0x0000000001000304 0x62 ../../libc/strlen.o + 0x0000000001000304 strlen + *fill* 0x0000000001000366 0x100036600000002 00 + .text 0x0000000001000368 0x184 ../../libc/ultoa.o + 0x0000000001000368 __ultoa + 0x00000000010004b8 ultoa + .text 0x00000000010004ec 0x16 ../../libc/strchr.o + 0x00000000010004ec strchr + *fill* 0x0000000001000502 0x100050200000002 00 + .text 0x0000000001000504 0x29 ../../libc/strcmp.o + 0x0000000001000504 strcmp + *fill* 0x000000000100052d 0x100052d00000003 00 + .text 0x0000000001000530 0x1c9 ../../libc/system.o + 0x00000000010005bc getprocessname + 0x0000000001000584 getmessage + 0x000000000100068c gets + 0x000000000100056c findprocess + 0x0000000001000598 getpid + 0x000000000100064c puts + 0x0000000001000674 sleep + 0x0000000001000634 setmyname + 0x00000000010006cc enableirq + 0x000000000100061c sendmessage + 0x0000000001000530 uname + 0x0000000001000548 createsharedframe + 0x0000000001000660 putc + 0x0000000001000604 isprocess + 0x00000000010006e4 disableirq + 0x00000000010005a8 getprocesscount + 0x000000000100055c freesharedframe + 0x00000000010005f0 gettickcount + 0x00000000010005d4 setprocessstate + *fill* 0x00000000010006f9 0x10006f900000007 00 + .text 0x0000000001000700 0x1d ../../libc/systemcall.o + 0x0000000001000700 systemcall + +.rodata 0x0000000001000720 0x108 + 0x0000000001000720 rodata = . + *(.rodata) + .rodata 0x0000000001000720 0x84 ../../libc/sprintf.o + .rodata 0x00000000010007a4 0x84 ../../libc/printf.o + +.rodata.str1.4 0x0000000001000828 0x40 + 0x0000000001000828 rodata.str1.4 = . + *(.rodata.str1.4) + .rodata.str1.4 + 0x0000000001000828 0x40 test.o + +.rodata.str1.1 0x0000000001000868 0x36 + 0x0000000001000868 rodata.str1.1 = . + *(.rodata.str1.1) + .rodata.str1.1 + 0x0000000001000868 0x1f test.o + .rodata.str1.1 + 0x0000000001000887 0x11 ../../libc/ultoa.o + .rodata.str1.1 + 0x0000000001000898 0x6 ../../libc/system.o + +.data 0x00000000010008a0 0x28 + *(.data) + .data 0x00000000010008a0 0x26 test.o + 0x00000000010008a0 str + *fill* 0x00000000010008c6 0x10008c600000002 00 + 0x00000000010008c8 edata = . + +.bss 0x00000000010008e0 0x269 + 0x00000000010008e0 bss = . + 0x00000000010008e0 _bss = . + *(.bss) + .bss 0x00000000010008e0 0x4 test.o + 0x00000000010008e0 floppyd + .bss 0x00000000010008e4 0x10 ../../libc/system.o + *(.COMMON) + *fill* 0x00000000010008f4 0x10008f40000000c 00 + COMMON 0x0000000001000900 0x240 test.o + 0x0 (size before relaxing) + 0x0000000001000900 msg + 0x0000000001000910 addr + 0x0000000001000920 buf + 0x0000000001000b20 name + COMMON 0x0000000001000b40 0x9 ../../libc/ultoa.o + 0x0 (size before relaxing) + 0x0000000001000b40 ultoabuf + 0x0000000001000b49 end = . + 0x0000000001000b49 _end = . +START GROUP +LOAD ../entry/entry.o +LOAD test.o +LOAD ../../libc/memcpy.o +LOAD ../../libc/memset.o +LOAD ../../libc/sprintf.o +LOAD ../../libc/printf.o +LOAD ../../libc/strlen.o +LOAD ../../libc/ultoa.o +LOAD ../../libc/strchr.o +LOAD ../../libc/strcmp.o +LOAD ../../libc/system.o +LOAD ../../libc/systemcall.o +END GROUP +OUTPUT(../../bin/test.dri binary) + +.comment 0x0000000000000000 0x1b0 + .comment 0x0000000000000000 0x1f ../entry/entry.o + .comment 0x000000000000001f 0x25 test.o + .comment 0x0000000000000044 0x25 ../../libc/memcpy.o + .comment 0x0000000000000069 0x25 ../../libc/memset.o + .comment 0x000000000000008e 0x25 ../../libc/sprintf.o + .comment 0x00000000000000b3 0x25 ../../libc/printf.o + .comment 0x00000000000000d8 0x25 ../../libc/strlen.o + .comment 0x00000000000000fd 0x25 ../../libc/ultoa.o + .comment 0x0000000000000122 0x25 ../../libc/strchr.o + .comment 0x0000000000000147 0x25 ../../libc/strcmp.o + .comment 0x000000000000016c 0x25 ../../libc/system.o + .comment 0x0000000000000191 0x1f ../../libc/systemcall.o diff --git a/src/test/test.c b/src/test/test.c new file mode 100755 index 0000000..afc19f6 --- /dev/null +++ b/src/test/test.c @@ -0,0 +1,58 @@ +#include "libc.h" +#include "syscall.h" +#include +#include "types.h" + +message_t msg; +char name[32]; +int addr; +int floppyd = 0; +char buf[512]; +char str[] = "Cos co zostanie zapisane na dyskietke"; +void _wait(int i) +{ + i *= 1000; + while (i > 0) + i--; +} + +void main() +{ + printf("Test Module for Draco\n"); + getprocessname(getpid(), &name); + printf("My name is %s and my PID is %d\n", &name, getpid()); + + if (getpid() == 3) + { + while(floppyd < 1) + floppyd = findprocess("floppyd"); + + + /* zapisujemy cos */ + msg.type = 2; + msg.lparam = 0; + msg.hparam = &str; + sendmessage(floppyd, &msg); + + //musimy odebrac wiadomosc bo sie zablokuje + while(!getmessage(&msg)); + + /* odczytujemy */ + msg.type = 1; + msg.lparam = 0; + msg.hparam = &buf; + sendmessage(floppyd, &msg); + + //puts(&buf); + } + + while(1) + { + sleep(SLEEP_MESSAGE); + if (getmessage(&msg)) + { + printf("Floppy buffer from floppyd: %s\n", &buf); + } + _wait(100); + } +}