diff --git a/src/include/list.h b/src/include/list.h new file mode 100644 index 0000000..fe8c91f --- /dev/null +++ b/src/include/list.h @@ -0,0 +1,16 @@ +#ifndef LIST_H +#define LIST_H + +#define NULL (void *)0 + +typedef struct ListElement { + struct ListElement *next; + void *data; +} ListElement; + +extern void listAdd(ListElement **list, void *data); +extern void listAddSet(ListElement **list, void *data); + +extern void *popBeginning(ListElement **list); + +#endif diff --git a/src/include/list.h b/src/include/list.h new file mode 100644 index 0000000..fe8c91f --- /dev/null +++ b/src/include/list.h @@ -0,0 +1,16 @@ +#ifndef LIST_H +#define LIST_H + +#define NULL (void *)0 + +typedef struct ListElement { + struct ListElement *next; + void *data; +} ListElement; + +extern void listAdd(ListElement **list, void *data); +extern void listAddSet(ListElement **list, void *data); + +extern void *popBeginning(ListElement **list); + +#endif diff --git a/src/include/message.h b/src/include/message.h index 12e3a85..ece324e 100644 --- a/src/include/message.h +++ b/src/include/message.h @@ -3,10 +3,16 @@ #include +enum MessageTypes { + KEYBOARD_CHAR, + KEYBOARD_STRING, + TIMER_UPDATE, +}; + typedef struct { - void *data; - uint32_t size; - struct Message *next; + void *data; + uint8_t type; + uint32_t size; } Message; #endif diff --git a/src/include/list.h b/src/include/list.h new file mode 100644 index 0000000..fe8c91f --- /dev/null +++ b/src/include/list.h @@ -0,0 +1,16 @@ +#ifndef LIST_H +#define LIST_H + +#define NULL (void *)0 + +typedef struct ListElement { + struct ListElement *next; + void *data; +} ListElement; + +extern void listAdd(ListElement **list, void *data); +extern void listAddSet(ListElement **list, void *data); + +extern void *popBeginning(ListElement **list); + +#endif diff --git a/src/include/message.h b/src/include/message.h index 12e3a85..ece324e 100644 --- a/src/include/message.h +++ b/src/include/message.h @@ -3,10 +3,16 @@ #include +enum MessageTypes { + KEYBOARD_CHAR, + KEYBOARD_STRING, + TIMER_UPDATE, +}; + typedef struct { - void *data; - uint32_t size; - struct Message *next; + void *data; + uint8_t type; + uint32_t size; } Message; #endif diff --git a/src/include/osTasks.h b/src/include/osTasks.h index 2865863..ef8c0bf 100644 --- a/src/include/osTasks.h +++ b/src/include/osTasks.h @@ -5,6 +5,8 @@ extern void initOSTasks(); -extern Task* getPrinterTask(); +extern Task *getPrinterTask(); -#endif \ No newline at end of file +extern Task *getKeyboardConsumer(); + +#endif diff --git a/src/include/list.h b/src/include/list.h new file mode 100644 index 0000000..fe8c91f --- /dev/null +++ b/src/include/list.h @@ -0,0 +1,16 @@ +#ifndef LIST_H +#define LIST_H + +#define NULL (void *)0 + +typedef struct ListElement { + struct ListElement *next; + void *data; +} ListElement; + +extern void listAdd(ListElement **list, void *data); +extern void listAddSet(ListElement **list, void *data); + +extern void *popBeginning(ListElement **list); + +#endif diff --git a/src/include/message.h b/src/include/message.h index 12e3a85..ece324e 100644 --- a/src/include/message.h +++ b/src/include/message.h @@ -3,10 +3,16 @@ #include +enum MessageTypes { + KEYBOARD_CHAR, + KEYBOARD_STRING, + TIMER_UPDATE, +}; + typedef struct { - void *data; - uint32_t size; - struct Message *next; + void *data; + uint8_t type; + uint32_t size; } Message; #endif diff --git a/src/include/osTasks.h b/src/include/osTasks.h index 2865863..ef8c0bf 100644 --- a/src/include/osTasks.h +++ b/src/include/osTasks.h @@ -5,6 +5,8 @@ extern void initOSTasks(); -extern Task* getPrinterTask(); +extern Task *getPrinterTask(); -#endif \ No newline at end of file +extern Task *getKeyboardConsumer(); + +#endif diff --git a/src/include/task.h b/src/include/task.h index 0b8e1b4..d708423 100644 --- a/src/include/task.h +++ b/src/include/task.h @@ -1,34 +1,38 @@ #ifndef TASK_H #define TASK_H -#include +#include #include +#include +#include extern void initTasking(); - -typedef struct __attribute__ ((packed)) { + +typedef struct __attribute__((packed)) { uint32_t eax, ebx, ecx, edx, esi, edi, esp, ebp, eip, eflags, cr3; } Registers; - + typedef struct Task { - Registers registers; // the register states for the task - struct Task *nextTask; // linked list of tasks that need to be done - void* stack; - Message* message; + Registers registers; + void *stack; + ListElement *messages; } Task; - + extern void initTasking(); -extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir); - +extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, + uint32_t *pagedir); + extern void yield(); -extern void yields(); // yield, but schedule the currently running task +extern void yields(); extern void switchTask(Registers *old, Registers *new); -extern void schedule(Task* task); // schedule a task to be run in the future +extern void schedule(Task *task); extern void destroyCurrentTask(); -extern void setRunningTask(Task* task); // set the task currently executed -extern void sendMessage(Task* task, Message* message); +extern void setRunningTask(Task *task); +extern void sendMessage(Task *task, Message *message); -extern Message* popMessage(Task* task); +extern Message *popMessage(Task *task); -#endif \ No newline at end of file +extern bool isTaskQueueEmpty(); + +#endif diff --git a/src/include/list.h b/src/include/list.h new file mode 100644 index 0000000..fe8c91f --- /dev/null +++ b/src/include/list.h @@ -0,0 +1,16 @@ +#ifndef LIST_H +#define LIST_H + +#define NULL (void *)0 + +typedef struct ListElement { + struct ListElement *next; + void *data; +} ListElement; + +extern void listAdd(ListElement **list, void *data); +extern void listAddSet(ListElement **list, void *data); + +extern void *popBeginning(ListElement **list); + +#endif diff --git a/src/include/message.h b/src/include/message.h index 12e3a85..ece324e 100644 --- a/src/include/message.h +++ b/src/include/message.h @@ -3,10 +3,16 @@ #include +enum MessageTypes { + KEYBOARD_CHAR, + KEYBOARD_STRING, + TIMER_UPDATE, +}; + typedef struct { - void *data; - uint32_t size; - struct Message *next; + void *data; + uint8_t type; + uint32_t size; } Message; #endif diff --git a/src/include/osTasks.h b/src/include/osTasks.h index 2865863..ef8c0bf 100644 --- a/src/include/osTasks.h +++ b/src/include/osTasks.h @@ -5,6 +5,8 @@ extern void initOSTasks(); -extern Task* getPrinterTask(); +extern Task *getPrinterTask(); -#endif \ No newline at end of file +extern Task *getKeyboardConsumer(); + +#endif diff --git a/src/include/task.h b/src/include/task.h index 0b8e1b4..d708423 100644 --- a/src/include/task.h +++ b/src/include/task.h @@ -1,34 +1,38 @@ #ifndef TASK_H #define TASK_H -#include +#include #include +#include +#include extern void initTasking(); - -typedef struct __attribute__ ((packed)) { + +typedef struct __attribute__((packed)) { uint32_t eax, ebx, ecx, edx, esi, edi, esp, ebp, eip, eflags, cr3; } Registers; - + typedef struct Task { - Registers registers; // the register states for the task - struct Task *nextTask; // linked list of tasks that need to be done - void* stack; - Message* message; + Registers registers; + void *stack; + ListElement *messages; } Task; - + extern void initTasking(); -extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir); - +extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, + uint32_t *pagedir); + extern void yield(); -extern void yields(); // yield, but schedule the currently running task +extern void yields(); extern void switchTask(Registers *old, Registers *new); -extern void schedule(Task* task); // schedule a task to be run in the future +extern void schedule(Task *task); extern void destroyCurrentTask(); -extern void setRunningTask(Task* task); // set the task currently executed -extern void sendMessage(Task* task, Message* message); +extern void setRunningTask(Task *task); +extern void sendMessage(Task *task, Message *message); -extern Message* popMessage(Task* task); +extern Message *popMessage(Task *task); -#endif \ No newline at end of file +extern bool isTaskQueueEmpty(); + +#endif diff --git a/src/kernel/drivers/cpu/cpuid.asm b/src/kernel/drivers/cpu/cpuid.asm index 6be352a..3aed27d 100644 --- a/src/kernel/drivers/cpu/cpuid.asm +++ b/src/kernel/drivers/cpu/cpuid.asm @@ -1,5 +1,6 @@ section .text global getVendorId + getVendorId: mov eax, 0x00 cpuid diff --git a/src/include/list.h b/src/include/list.h new file mode 100644 index 0000000..fe8c91f --- /dev/null +++ b/src/include/list.h @@ -0,0 +1,16 @@ +#ifndef LIST_H +#define LIST_H + +#define NULL (void *)0 + +typedef struct ListElement { + struct ListElement *next; + void *data; +} ListElement; + +extern void listAdd(ListElement **list, void *data); +extern void listAddSet(ListElement **list, void *data); + +extern void *popBeginning(ListElement **list); + +#endif diff --git a/src/include/message.h b/src/include/message.h index 12e3a85..ece324e 100644 --- a/src/include/message.h +++ b/src/include/message.h @@ -3,10 +3,16 @@ #include +enum MessageTypes { + KEYBOARD_CHAR, + KEYBOARD_STRING, + TIMER_UPDATE, +}; + typedef struct { - void *data; - uint32_t size; - struct Message *next; + void *data; + uint8_t type; + uint32_t size; } Message; #endif diff --git a/src/include/osTasks.h b/src/include/osTasks.h index 2865863..ef8c0bf 100644 --- a/src/include/osTasks.h +++ b/src/include/osTasks.h @@ -5,6 +5,8 @@ extern void initOSTasks(); -extern Task* getPrinterTask(); +extern Task *getPrinterTask(); -#endif \ No newline at end of file +extern Task *getKeyboardConsumer(); + +#endif diff --git a/src/include/task.h b/src/include/task.h index 0b8e1b4..d708423 100644 --- a/src/include/task.h +++ b/src/include/task.h @@ -1,34 +1,38 @@ #ifndef TASK_H #define TASK_H -#include +#include #include +#include +#include extern void initTasking(); - -typedef struct __attribute__ ((packed)) { + +typedef struct __attribute__((packed)) { uint32_t eax, ebx, ecx, edx, esi, edi, esp, ebp, eip, eflags, cr3; } Registers; - + typedef struct Task { - Registers registers; // the register states for the task - struct Task *nextTask; // linked list of tasks that need to be done - void* stack; - Message* message; + Registers registers; + void *stack; + ListElement *messages; } Task; - + extern void initTasking(); -extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir); - +extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, + uint32_t *pagedir); + extern void yield(); -extern void yields(); // yield, but schedule the currently running task +extern void yields(); extern void switchTask(Registers *old, Registers *new); -extern void schedule(Task* task); // schedule a task to be run in the future +extern void schedule(Task *task); extern void destroyCurrentTask(); -extern void setRunningTask(Task* task); // set the task currently executed -extern void sendMessage(Task* task, Message* message); +extern void setRunningTask(Task *task); +extern void sendMessage(Task *task, Message *message); -extern Message* popMessage(Task* task); +extern Message *popMessage(Task *task); -#endif \ No newline at end of file +extern bool isTaskQueueEmpty(); + +#endif diff --git a/src/kernel/drivers/cpu/cpuid.asm b/src/kernel/drivers/cpu/cpuid.asm index 6be352a..3aed27d 100644 --- a/src/kernel/drivers/cpu/cpuid.asm +++ b/src/kernel/drivers/cpu/cpuid.asm @@ -1,5 +1,6 @@ section .text global getVendorId + getVendorId: mov eax, 0x00 cpuid diff --git a/src/kernel/drivers/interrupts/irqs.asm b/src/kernel/drivers/interrupts/irqs.asm index 3e6670b..3a413ed 100644 --- a/src/kernel/drivers/interrupts/irqs.asm +++ b/src/kernel/drivers/interrupts/irqs.asm @@ -28,6 +28,7 @@ extern handleIRQ irqHandler: + cli pusha push ds push es @@ -49,4 +50,5 @@ pop ds popa add esp, 8 - iret \ No newline at end of file + sti + iret diff --git a/src/include/list.h b/src/include/list.h new file mode 100644 index 0000000..fe8c91f --- /dev/null +++ b/src/include/list.h @@ -0,0 +1,16 @@ +#ifndef LIST_H +#define LIST_H + +#define NULL (void *)0 + +typedef struct ListElement { + struct ListElement *next; + void *data; +} ListElement; + +extern void listAdd(ListElement **list, void *data); +extern void listAddSet(ListElement **list, void *data); + +extern void *popBeginning(ListElement **list); + +#endif diff --git a/src/include/message.h b/src/include/message.h index 12e3a85..ece324e 100644 --- a/src/include/message.h +++ b/src/include/message.h @@ -3,10 +3,16 @@ #include +enum MessageTypes { + KEYBOARD_CHAR, + KEYBOARD_STRING, + TIMER_UPDATE, +}; + typedef struct { - void *data; - uint32_t size; - struct Message *next; + void *data; + uint8_t type; + uint32_t size; } Message; #endif diff --git a/src/include/osTasks.h b/src/include/osTasks.h index 2865863..ef8c0bf 100644 --- a/src/include/osTasks.h +++ b/src/include/osTasks.h @@ -5,6 +5,8 @@ extern void initOSTasks(); -extern Task* getPrinterTask(); +extern Task *getPrinterTask(); -#endif \ No newline at end of file +extern Task *getKeyboardConsumer(); + +#endif diff --git a/src/include/task.h b/src/include/task.h index 0b8e1b4..d708423 100644 --- a/src/include/task.h +++ b/src/include/task.h @@ -1,34 +1,38 @@ #ifndef TASK_H #define TASK_H -#include +#include #include +#include +#include extern void initTasking(); - -typedef struct __attribute__ ((packed)) { + +typedef struct __attribute__((packed)) { uint32_t eax, ebx, ecx, edx, esi, edi, esp, ebp, eip, eflags, cr3; } Registers; - + typedef struct Task { - Registers registers; // the register states for the task - struct Task *nextTask; // linked list of tasks that need to be done - void* stack; - Message* message; + Registers registers; + void *stack; + ListElement *messages; } Task; - + extern void initTasking(); -extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir); - +extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, + uint32_t *pagedir); + extern void yield(); -extern void yields(); // yield, but schedule the currently running task +extern void yields(); extern void switchTask(Registers *old, Registers *new); -extern void schedule(Task* task); // schedule a task to be run in the future +extern void schedule(Task *task); extern void destroyCurrentTask(); -extern void setRunningTask(Task* task); // set the task currently executed -extern void sendMessage(Task* task, Message* message); +extern void setRunningTask(Task *task); +extern void sendMessage(Task *task, Message *message); -extern Message* popMessage(Task* task); +extern Message *popMessage(Task *task); -#endif \ No newline at end of file +extern bool isTaskQueueEmpty(); + +#endif diff --git a/src/kernel/drivers/cpu/cpuid.asm b/src/kernel/drivers/cpu/cpuid.asm index 6be352a..3aed27d 100644 --- a/src/kernel/drivers/cpu/cpuid.asm +++ b/src/kernel/drivers/cpu/cpuid.asm @@ -1,5 +1,6 @@ section .text global getVendorId + getVendorId: mov eax, 0x00 cpuid diff --git a/src/kernel/drivers/interrupts/irqs.asm b/src/kernel/drivers/interrupts/irqs.asm index 3e6670b..3a413ed 100644 --- a/src/kernel/drivers/interrupts/irqs.asm +++ b/src/kernel/drivers/interrupts/irqs.asm @@ -28,6 +28,7 @@ extern handleIRQ irqHandler: + cli pusha push ds push es @@ -49,4 +50,5 @@ pop ds popa add esp, 8 - iret \ No newline at end of file + sti + iret diff --git a/src/kernel/drivers/interrupts/irqs.c b/src/kernel/drivers/interrupts/irqs.c index c7bf183..60d95f8 100644 --- a/src/kernel/drivers/interrupts/irqs.c +++ b/src/kernel/drivers/interrupts/irqs.c @@ -1,9 +1,9 @@ -#include +#include <_stdio.h> #include +#include #include #include #include -#include <_stdio.h> #define OFFSET_1 32 #define OFFSET_2 40 @@ -43,13 +43,13 @@ remapPIC(OFFSET_1, OFFSET_2); } -void* irqHandlers[16]; +void *irqHandlers[16]; -void setIRQHandler(uint8_t irqNumber, void* fun) { +void setIRQHandler(uint8_t irqNumber, void *fun) { irqHandlers[irqNumber] = fun; } -void handleIRQ(regs* registers) { +void handleIRQ(regs *registers) { if (registers->int_no >= OFFSET_2) { outb(0xA0, 0x20); } @@ -60,5 +60,9 @@ handler(); return; } + if (irqNumber == 7 || irqNumber == 2) { + // irq2 should not be fired, irq 7 is a spurious irq + return; + } printf("unhandeled IRQ no. 0x%x was triggered!\n", irqNumber); -} \ No newline at end of file +} diff --git a/src/include/list.h b/src/include/list.h new file mode 100644 index 0000000..fe8c91f --- /dev/null +++ b/src/include/list.h @@ -0,0 +1,16 @@ +#ifndef LIST_H +#define LIST_H + +#define NULL (void *)0 + +typedef struct ListElement { + struct ListElement *next; + void *data; +} ListElement; + +extern void listAdd(ListElement **list, void *data); +extern void listAddSet(ListElement **list, void *data); + +extern void *popBeginning(ListElement **list); + +#endif diff --git a/src/include/message.h b/src/include/message.h index 12e3a85..ece324e 100644 --- a/src/include/message.h +++ b/src/include/message.h @@ -3,10 +3,16 @@ #include +enum MessageTypes { + KEYBOARD_CHAR, + KEYBOARD_STRING, + TIMER_UPDATE, +}; + typedef struct { - void *data; - uint32_t size; - struct Message *next; + void *data; + uint8_t type; + uint32_t size; } Message; #endif diff --git a/src/include/osTasks.h b/src/include/osTasks.h index 2865863..ef8c0bf 100644 --- a/src/include/osTasks.h +++ b/src/include/osTasks.h @@ -5,6 +5,8 @@ extern void initOSTasks(); -extern Task* getPrinterTask(); +extern Task *getPrinterTask(); -#endif \ No newline at end of file +extern Task *getKeyboardConsumer(); + +#endif diff --git a/src/include/task.h b/src/include/task.h index 0b8e1b4..d708423 100644 --- a/src/include/task.h +++ b/src/include/task.h @@ -1,34 +1,38 @@ #ifndef TASK_H #define TASK_H -#include +#include #include +#include +#include extern void initTasking(); - -typedef struct __attribute__ ((packed)) { + +typedef struct __attribute__((packed)) { uint32_t eax, ebx, ecx, edx, esi, edi, esp, ebp, eip, eflags, cr3; } Registers; - + typedef struct Task { - Registers registers; // the register states for the task - struct Task *nextTask; // linked list of tasks that need to be done - void* stack; - Message* message; + Registers registers; + void *stack; + ListElement *messages; } Task; - + extern void initTasking(); -extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir); - +extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, + uint32_t *pagedir); + extern void yield(); -extern void yields(); // yield, but schedule the currently running task +extern void yields(); extern void switchTask(Registers *old, Registers *new); -extern void schedule(Task* task); // schedule a task to be run in the future +extern void schedule(Task *task); extern void destroyCurrentTask(); -extern void setRunningTask(Task* task); // set the task currently executed -extern void sendMessage(Task* task, Message* message); +extern void setRunningTask(Task *task); +extern void sendMessage(Task *task, Message *message); -extern Message* popMessage(Task* task); +extern Message *popMessage(Task *task); -#endif \ No newline at end of file +extern bool isTaskQueueEmpty(); + +#endif diff --git a/src/kernel/drivers/cpu/cpuid.asm b/src/kernel/drivers/cpu/cpuid.asm index 6be352a..3aed27d 100644 --- a/src/kernel/drivers/cpu/cpuid.asm +++ b/src/kernel/drivers/cpu/cpuid.asm @@ -1,5 +1,6 @@ section .text global getVendorId + getVendorId: mov eax, 0x00 cpuid diff --git a/src/kernel/drivers/interrupts/irqs.asm b/src/kernel/drivers/interrupts/irqs.asm index 3e6670b..3a413ed 100644 --- a/src/kernel/drivers/interrupts/irqs.asm +++ b/src/kernel/drivers/interrupts/irqs.asm @@ -28,6 +28,7 @@ extern handleIRQ irqHandler: + cli pusha push ds push es @@ -49,4 +50,5 @@ pop ds popa add esp, 8 - iret \ No newline at end of file + sti + iret diff --git a/src/kernel/drivers/interrupts/irqs.c b/src/kernel/drivers/interrupts/irqs.c index c7bf183..60d95f8 100644 --- a/src/kernel/drivers/interrupts/irqs.c +++ b/src/kernel/drivers/interrupts/irqs.c @@ -1,9 +1,9 @@ -#include +#include <_stdio.h> #include +#include #include #include #include -#include <_stdio.h> #define OFFSET_1 32 #define OFFSET_2 40 @@ -43,13 +43,13 @@ remapPIC(OFFSET_1, OFFSET_2); } -void* irqHandlers[16]; +void *irqHandlers[16]; -void setIRQHandler(uint8_t irqNumber, void* fun) { +void setIRQHandler(uint8_t irqNumber, void *fun) { irqHandlers[irqNumber] = fun; } -void handleIRQ(regs* registers) { +void handleIRQ(regs *registers) { if (registers->int_no >= OFFSET_2) { outb(0xA0, 0x20); } @@ -60,5 +60,9 @@ handler(); return; } + if (irqNumber == 7 || irqNumber == 2) { + // irq2 should not be fired, irq 7 is a spurious irq + return; + } printf("unhandeled IRQ no. 0x%x was triggered!\n", irqNumber); -} \ No newline at end of file +} diff --git a/src/kernel/drivers/interrupts/timer/timer.c b/src/kernel/drivers/interrupts/timer/timer.c index b9ba3af..267077e 100644 --- a/src/kernel/drivers/interrupts/timer/timer.c +++ b/src/kernel/drivers/interrupts/timer/timer.c @@ -1,10 +1,9 @@ -#include #include <_stdio.h> #include -#include -#include #include - +#include +#include +#include #define PIT_A 0x40 #define PIT_CONTROL 0x43 @@ -28,24 +27,25 @@ #define CMD_COUNTER2 0x80 void setTimerFreq(uint32_t hz) { - int divisor = PIT_SCALE / hz; - outb(PIT_CONTROL, CMD_BINARY | CMD_MODE3 | CMD_RW_BOTH | CMD_COUNTER0); - outb(PIT_A, (uint8_t) divisor); - outb(PIT_A, (uint8_t) (divisor >> 8)); + int divisor = PIT_SCALE / hz; + outb(PIT_CONTROL, CMD_BINARY | CMD_MODE3 | CMD_RW_BOTH | CMD_COUNTER0); + outb(PIT_A, (uint8_t)divisor); + outb(PIT_A, (uint8_t)(divisor >> 8)); } uint32_t timerMillis = 0; +uint32_t time = 0; + void timerHandler() { - timerMillis++; - if (timerMillis % 1000 == 0) { - // printf("second\n"); - // yields(); - } + timerMillis++; + if (timerMillis % 1000 == 0) { + printf("\e[s\e[Htime since power on :0x%x seconds\e[u", ++time); + } } void setupTimer() { - printf("setting timer frequency to 1kHz\n"); - setTimerFreq(1000); - setIRQHandler(0, &timerHandler); + printf("setting timer frequency to 1kHz\n"); + setTimerFreq(1000); + setIRQHandler(0, &timerHandler); } diff --git a/src/include/list.h b/src/include/list.h new file mode 100644 index 0000000..fe8c91f --- /dev/null +++ b/src/include/list.h @@ -0,0 +1,16 @@ +#ifndef LIST_H +#define LIST_H + +#define NULL (void *)0 + +typedef struct ListElement { + struct ListElement *next; + void *data; +} ListElement; + +extern void listAdd(ListElement **list, void *data); +extern void listAddSet(ListElement **list, void *data); + +extern void *popBeginning(ListElement **list); + +#endif diff --git a/src/include/message.h b/src/include/message.h index 12e3a85..ece324e 100644 --- a/src/include/message.h +++ b/src/include/message.h @@ -3,10 +3,16 @@ #include +enum MessageTypes { + KEYBOARD_CHAR, + KEYBOARD_STRING, + TIMER_UPDATE, +}; + typedef struct { - void *data; - uint32_t size; - struct Message *next; + void *data; + uint8_t type; + uint32_t size; } Message; #endif diff --git a/src/include/osTasks.h b/src/include/osTasks.h index 2865863..ef8c0bf 100644 --- a/src/include/osTasks.h +++ b/src/include/osTasks.h @@ -5,6 +5,8 @@ extern void initOSTasks(); -extern Task* getPrinterTask(); +extern Task *getPrinterTask(); -#endif \ No newline at end of file +extern Task *getKeyboardConsumer(); + +#endif diff --git a/src/include/task.h b/src/include/task.h index 0b8e1b4..d708423 100644 --- a/src/include/task.h +++ b/src/include/task.h @@ -1,34 +1,38 @@ #ifndef TASK_H #define TASK_H -#include +#include #include +#include +#include extern void initTasking(); - -typedef struct __attribute__ ((packed)) { + +typedef struct __attribute__((packed)) { uint32_t eax, ebx, ecx, edx, esi, edi, esp, ebp, eip, eflags, cr3; } Registers; - + typedef struct Task { - Registers registers; // the register states for the task - struct Task *nextTask; // linked list of tasks that need to be done - void* stack; - Message* message; + Registers registers; + void *stack; + ListElement *messages; } Task; - + extern void initTasking(); -extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir); - +extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, + uint32_t *pagedir); + extern void yield(); -extern void yields(); // yield, but schedule the currently running task +extern void yields(); extern void switchTask(Registers *old, Registers *new); -extern void schedule(Task* task); // schedule a task to be run in the future +extern void schedule(Task *task); extern void destroyCurrentTask(); -extern void setRunningTask(Task* task); // set the task currently executed -extern void sendMessage(Task* task, Message* message); +extern void setRunningTask(Task *task); +extern void sendMessage(Task *task, Message *message); -extern Message* popMessage(Task* task); +extern Message *popMessage(Task *task); -#endif \ No newline at end of file +extern bool isTaskQueueEmpty(); + +#endif diff --git a/src/kernel/drivers/cpu/cpuid.asm b/src/kernel/drivers/cpu/cpuid.asm index 6be352a..3aed27d 100644 --- a/src/kernel/drivers/cpu/cpuid.asm +++ b/src/kernel/drivers/cpu/cpuid.asm @@ -1,5 +1,6 @@ section .text global getVendorId + getVendorId: mov eax, 0x00 cpuid diff --git a/src/kernel/drivers/interrupts/irqs.asm b/src/kernel/drivers/interrupts/irqs.asm index 3e6670b..3a413ed 100644 --- a/src/kernel/drivers/interrupts/irqs.asm +++ b/src/kernel/drivers/interrupts/irqs.asm @@ -28,6 +28,7 @@ extern handleIRQ irqHandler: + cli pusha push ds push es @@ -49,4 +50,5 @@ pop ds popa add esp, 8 - iret \ No newline at end of file + sti + iret diff --git a/src/kernel/drivers/interrupts/irqs.c b/src/kernel/drivers/interrupts/irqs.c index c7bf183..60d95f8 100644 --- a/src/kernel/drivers/interrupts/irqs.c +++ b/src/kernel/drivers/interrupts/irqs.c @@ -1,9 +1,9 @@ -#include +#include <_stdio.h> #include +#include #include #include #include -#include <_stdio.h> #define OFFSET_1 32 #define OFFSET_2 40 @@ -43,13 +43,13 @@ remapPIC(OFFSET_1, OFFSET_2); } -void* irqHandlers[16]; +void *irqHandlers[16]; -void setIRQHandler(uint8_t irqNumber, void* fun) { +void setIRQHandler(uint8_t irqNumber, void *fun) { irqHandlers[irqNumber] = fun; } -void handleIRQ(regs* registers) { +void handleIRQ(regs *registers) { if (registers->int_no >= OFFSET_2) { outb(0xA0, 0x20); } @@ -60,5 +60,9 @@ handler(); return; } + if (irqNumber == 7 || irqNumber == 2) { + // irq2 should not be fired, irq 7 is a spurious irq + return; + } printf("unhandeled IRQ no. 0x%x was triggered!\n", irqNumber); -} \ No newline at end of file +} diff --git a/src/kernel/drivers/interrupts/timer/timer.c b/src/kernel/drivers/interrupts/timer/timer.c index b9ba3af..267077e 100644 --- a/src/kernel/drivers/interrupts/timer/timer.c +++ b/src/kernel/drivers/interrupts/timer/timer.c @@ -1,10 +1,9 @@ -#include #include <_stdio.h> #include -#include -#include #include - +#include +#include +#include #define PIT_A 0x40 #define PIT_CONTROL 0x43 @@ -28,24 +27,25 @@ #define CMD_COUNTER2 0x80 void setTimerFreq(uint32_t hz) { - int divisor = PIT_SCALE / hz; - outb(PIT_CONTROL, CMD_BINARY | CMD_MODE3 | CMD_RW_BOTH | CMD_COUNTER0); - outb(PIT_A, (uint8_t) divisor); - outb(PIT_A, (uint8_t) (divisor >> 8)); + int divisor = PIT_SCALE / hz; + outb(PIT_CONTROL, CMD_BINARY | CMD_MODE3 | CMD_RW_BOTH | CMD_COUNTER0); + outb(PIT_A, (uint8_t)divisor); + outb(PIT_A, (uint8_t)(divisor >> 8)); } uint32_t timerMillis = 0; +uint32_t time = 0; + void timerHandler() { - timerMillis++; - if (timerMillis % 1000 == 0) { - // printf("second\n"); - // yields(); - } + timerMillis++; + if (timerMillis % 1000 == 0) { + printf("\e[s\e[Htime since power on :0x%x seconds\e[u", ++time); + } } void setupTimer() { - printf("setting timer frequency to 1kHz\n"); - setTimerFreq(1000); - setIRQHandler(0, &timerHandler); + printf("setting timer frequency to 1kHz\n"); + setTimerFreq(1000); + setIRQHandler(0, &timerHandler); } diff --git a/src/kernel/drivers/textMode/_stdio.c b/src/kernel/drivers/textMode/_stdio.c index ced3147..b0e2cce 100644 --- a/src/kernel/drivers/textMode/_stdio.c +++ b/src/kernel/drivers/textMode/_stdio.c @@ -111,11 +111,10 @@ va_end(valist); Message *message = malloc(sizeof(Message)); - message->data = data; message->size = size; - message->next = 0x00; - sendMessage(getPrinterTask(), message); + message->type = -1; + listAdd(&getPrinterTask()->messages, message); schedule(getPrinterTask()); } diff --git a/src/include/list.h b/src/include/list.h new file mode 100644 index 0000000..fe8c91f --- /dev/null +++ b/src/include/list.h @@ -0,0 +1,16 @@ +#ifndef LIST_H +#define LIST_H + +#define NULL (void *)0 + +typedef struct ListElement { + struct ListElement *next; + void *data; +} ListElement; + +extern void listAdd(ListElement **list, void *data); +extern void listAddSet(ListElement **list, void *data); + +extern void *popBeginning(ListElement **list); + +#endif diff --git a/src/include/message.h b/src/include/message.h index 12e3a85..ece324e 100644 --- a/src/include/message.h +++ b/src/include/message.h @@ -3,10 +3,16 @@ #include +enum MessageTypes { + KEYBOARD_CHAR, + KEYBOARD_STRING, + TIMER_UPDATE, +}; + typedef struct { - void *data; - uint32_t size; - struct Message *next; + void *data; + uint8_t type; + uint32_t size; } Message; #endif diff --git a/src/include/osTasks.h b/src/include/osTasks.h index 2865863..ef8c0bf 100644 --- a/src/include/osTasks.h +++ b/src/include/osTasks.h @@ -5,6 +5,8 @@ extern void initOSTasks(); -extern Task* getPrinterTask(); +extern Task *getPrinterTask(); -#endif \ No newline at end of file +extern Task *getKeyboardConsumer(); + +#endif diff --git a/src/include/task.h b/src/include/task.h index 0b8e1b4..d708423 100644 --- a/src/include/task.h +++ b/src/include/task.h @@ -1,34 +1,38 @@ #ifndef TASK_H #define TASK_H -#include +#include #include +#include +#include extern void initTasking(); - -typedef struct __attribute__ ((packed)) { + +typedef struct __attribute__((packed)) { uint32_t eax, ebx, ecx, edx, esi, edi, esp, ebp, eip, eflags, cr3; } Registers; - + typedef struct Task { - Registers registers; // the register states for the task - struct Task *nextTask; // linked list of tasks that need to be done - void* stack; - Message* message; + Registers registers; + void *stack; + ListElement *messages; } Task; - + extern void initTasking(); -extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir); - +extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, + uint32_t *pagedir); + extern void yield(); -extern void yields(); // yield, but schedule the currently running task +extern void yields(); extern void switchTask(Registers *old, Registers *new); -extern void schedule(Task* task); // schedule a task to be run in the future +extern void schedule(Task *task); extern void destroyCurrentTask(); -extern void setRunningTask(Task* task); // set the task currently executed -extern void sendMessage(Task* task, Message* message); +extern void setRunningTask(Task *task); +extern void sendMessage(Task *task, Message *message); -extern Message* popMessage(Task* task); +extern Message *popMessage(Task *task); -#endif \ No newline at end of file +extern bool isTaskQueueEmpty(); + +#endif diff --git a/src/kernel/drivers/cpu/cpuid.asm b/src/kernel/drivers/cpu/cpuid.asm index 6be352a..3aed27d 100644 --- a/src/kernel/drivers/cpu/cpuid.asm +++ b/src/kernel/drivers/cpu/cpuid.asm @@ -1,5 +1,6 @@ section .text global getVendorId + getVendorId: mov eax, 0x00 cpuid diff --git a/src/kernel/drivers/interrupts/irqs.asm b/src/kernel/drivers/interrupts/irqs.asm index 3e6670b..3a413ed 100644 --- a/src/kernel/drivers/interrupts/irqs.asm +++ b/src/kernel/drivers/interrupts/irqs.asm @@ -28,6 +28,7 @@ extern handleIRQ irqHandler: + cli pusha push ds push es @@ -49,4 +50,5 @@ pop ds popa add esp, 8 - iret \ No newline at end of file + sti + iret diff --git a/src/kernel/drivers/interrupts/irqs.c b/src/kernel/drivers/interrupts/irqs.c index c7bf183..60d95f8 100644 --- a/src/kernel/drivers/interrupts/irqs.c +++ b/src/kernel/drivers/interrupts/irqs.c @@ -1,9 +1,9 @@ -#include +#include <_stdio.h> #include +#include #include #include #include -#include <_stdio.h> #define OFFSET_1 32 #define OFFSET_2 40 @@ -43,13 +43,13 @@ remapPIC(OFFSET_1, OFFSET_2); } -void* irqHandlers[16]; +void *irqHandlers[16]; -void setIRQHandler(uint8_t irqNumber, void* fun) { +void setIRQHandler(uint8_t irqNumber, void *fun) { irqHandlers[irqNumber] = fun; } -void handleIRQ(regs* registers) { +void handleIRQ(regs *registers) { if (registers->int_no >= OFFSET_2) { outb(0xA0, 0x20); } @@ -60,5 +60,9 @@ handler(); return; } + if (irqNumber == 7 || irqNumber == 2) { + // irq2 should not be fired, irq 7 is a spurious irq + return; + } printf("unhandeled IRQ no. 0x%x was triggered!\n", irqNumber); -} \ No newline at end of file +} diff --git a/src/kernel/drivers/interrupts/timer/timer.c b/src/kernel/drivers/interrupts/timer/timer.c index b9ba3af..267077e 100644 --- a/src/kernel/drivers/interrupts/timer/timer.c +++ b/src/kernel/drivers/interrupts/timer/timer.c @@ -1,10 +1,9 @@ -#include #include <_stdio.h> #include -#include -#include #include - +#include +#include +#include #define PIT_A 0x40 #define PIT_CONTROL 0x43 @@ -28,24 +27,25 @@ #define CMD_COUNTER2 0x80 void setTimerFreq(uint32_t hz) { - int divisor = PIT_SCALE / hz; - outb(PIT_CONTROL, CMD_BINARY | CMD_MODE3 | CMD_RW_BOTH | CMD_COUNTER0); - outb(PIT_A, (uint8_t) divisor); - outb(PIT_A, (uint8_t) (divisor >> 8)); + int divisor = PIT_SCALE / hz; + outb(PIT_CONTROL, CMD_BINARY | CMD_MODE3 | CMD_RW_BOTH | CMD_COUNTER0); + outb(PIT_A, (uint8_t)divisor); + outb(PIT_A, (uint8_t)(divisor >> 8)); } uint32_t timerMillis = 0; +uint32_t time = 0; + void timerHandler() { - timerMillis++; - if (timerMillis % 1000 == 0) { - // printf("second\n"); - // yields(); - } + timerMillis++; + if (timerMillis % 1000 == 0) { + printf("\e[s\e[Htime since power on :0x%x seconds\e[u", ++time); + } } void setupTimer() { - printf("setting timer frequency to 1kHz\n"); - setTimerFreq(1000); - setIRQHandler(0, &timerHandler); + printf("setting timer frequency to 1kHz\n"); + setTimerFreq(1000); + setIRQHandler(0, &timerHandler); } diff --git a/src/kernel/drivers/textMode/_stdio.c b/src/kernel/drivers/textMode/_stdio.c index ced3147..b0e2cce 100644 --- a/src/kernel/drivers/textMode/_stdio.c +++ b/src/kernel/drivers/textMode/_stdio.c @@ -111,11 +111,10 @@ va_end(valist); Message *message = malloc(sizeof(Message)); - message->data = data; message->size = size; - message->next = 0x00; - sendMessage(getPrinterTask(), message); + message->type = -1; + listAdd(&getPrinterTask()->messages, message); schedule(getPrinterTask()); } diff --git a/src/kernel/drivers/textMode/terminal.c b/src/kernel/drivers/textMode/terminal.c index ecd58b0..20800e6 100644 --- a/src/kernel/drivers/textMode/terminal.c +++ b/src/kernel/drivers/textMode/terminal.c @@ -76,6 +76,8 @@ uint32_t *currentBuffer = &ansiEscapeBuffer1; +uint32_t savedCursor = 0; + #define addBuffer(i) \ case i + '0': \ *currentBuffer *= 10; \ @@ -170,6 +172,15 @@ setCursorOffset(cursorOffset); currentState = STANDARD; return; + case 's': + savedCursor = cursorOffset; + currentState = STANDARD; + return; + case 'u': + cursorOffset = savedCursor; + setCursorOffset(cursorOffset); + currentState = STANDARD; + return; } } } diff --git a/src/include/list.h b/src/include/list.h new file mode 100644 index 0000000..fe8c91f --- /dev/null +++ b/src/include/list.h @@ -0,0 +1,16 @@ +#ifndef LIST_H +#define LIST_H + +#define NULL (void *)0 + +typedef struct ListElement { + struct ListElement *next; + void *data; +} ListElement; + +extern void listAdd(ListElement **list, void *data); +extern void listAddSet(ListElement **list, void *data); + +extern void *popBeginning(ListElement **list); + +#endif diff --git a/src/include/message.h b/src/include/message.h index 12e3a85..ece324e 100644 --- a/src/include/message.h +++ b/src/include/message.h @@ -3,10 +3,16 @@ #include +enum MessageTypes { + KEYBOARD_CHAR, + KEYBOARD_STRING, + TIMER_UPDATE, +}; + typedef struct { - void *data; - uint32_t size; - struct Message *next; + void *data; + uint8_t type; + uint32_t size; } Message; #endif diff --git a/src/include/osTasks.h b/src/include/osTasks.h index 2865863..ef8c0bf 100644 --- a/src/include/osTasks.h +++ b/src/include/osTasks.h @@ -5,6 +5,8 @@ extern void initOSTasks(); -extern Task* getPrinterTask(); +extern Task *getPrinterTask(); -#endif \ No newline at end of file +extern Task *getKeyboardConsumer(); + +#endif diff --git a/src/include/task.h b/src/include/task.h index 0b8e1b4..d708423 100644 --- a/src/include/task.h +++ b/src/include/task.h @@ -1,34 +1,38 @@ #ifndef TASK_H #define TASK_H -#include +#include #include +#include +#include extern void initTasking(); - -typedef struct __attribute__ ((packed)) { + +typedef struct __attribute__((packed)) { uint32_t eax, ebx, ecx, edx, esi, edi, esp, ebp, eip, eflags, cr3; } Registers; - + typedef struct Task { - Registers registers; // the register states for the task - struct Task *nextTask; // linked list of tasks that need to be done - void* stack; - Message* message; + Registers registers; + void *stack; + ListElement *messages; } Task; - + extern void initTasking(); -extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir); - +extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, + uint32_t *pagedir); + extern void yield(); -extern void yields(); // yield, but schedule the currently running task +extern void yields(); extern void switchTask(Registers *old, Registers *new); -extern void schedule(Task* task); // schedule a task to be run in the future +extern void schedule(Task *task); extern void destroyCurrentTask(); -extern void setRunningTask(Task* task); // set the task currently executed -extern void sendMessage(Task* task, Message* message); +extern void setRunningTask(Task *task); +extern void sendMessage(Task *task, Message *message); -extern Message* popMessage(Task* task); +extern Message *popMessage(Task *task); -#endif \ No newline at end of file +extern bool isTaskQueueEmpty(); + +#endif diff --git a/src/kernel/drivers/cpu/cpuid.asm b/src/kernel/drivers/cpu/cpuid.asm index 6be352a..3aed27d 100644 --- a/src/kernel/drivers/cpu/cpuid.asm +++ b/src/kernel/drivers/cpu/cpuid.asm @@ -1,5 +1,6 @@ section .text global getVendorId + getVendorId: mov eax, 0x00 cpuid diff --git a/src/kernel/drivers/interrupts/irqs.asm b/src/kernel/drivers/interrupts/irqs.asm index 3e6670b..3a413ed 100644 --- a/src/kernel/drivers/interrupts/irqs.asm +++ b/src/kernel/drivers/interrupts/irqs.asm @@ -28,6 +28,7 @@ extern handleIRQ irqHandler: + cli pusha push ds push es @@ -49,4 +50,5 @@ pop ds popa add esp, 8 - iret \ No newline at end of file + sti + iret diff --git a/src/kernel/drivers/interrupts/irqs.c b/src/kernel/drivers/interrupts/irqs.c index c7bf183..60d95f8 100644 --- a/src/kernel/drivers/interrupts/irqs.c +++ b/src/kernel/drivers/interrupts/irqs.c @@ -1,9 +1,9 @@ -#include +#include <_stdio.h> #include +#include #include #include #include -#include <_stdio.h> #define OFFSET_1 32 #define OFFSET_2 40 @@ -43,13 +43,13 @@ remapPIC(OFFSET_1, OFFSET_2); } -void* irqHandlers[16]; +void *irqHandlers[16]; -void setIRQHandler(uint8_t irqNumber, void* fun) { +void setIRQHandler(uint8_t irqNumber, void *fun) { irqHandlers[irqNumber] = fun; } -void handleIRQ(regs* registers) { +void handleIRQ(regs *registers) { if (registers->int_no >= OFFSET_2) { outb(0xA0, 0x20); } @@ -60,5 +60,9 @@ handler(); return; } + if (irqNumber == 7 || irqNumber == 2) { + // irq2 should not be fired, irq 7 is a spurious irq + return; + } printf("unhandeled IRQ no. 0x%x was triggered!\n", irqNumber); -} \ No newline at end of file +} diff --git a/src/kernel/drivers/interrupts/timer/timer.c b/src/kernel/drivers/interrupts/timer/timer.c index b9ba3af..267077e 100644 --- a/src/kernel/drivers/interrupts/timer/timer.c +++ b/src/kernel/drivers/interrupts/timer/timer.c @@ -1,10 +1,9 @@ -#include #include <_stdio.h> #include -#include -#include #include - +#include +#include +#include #define PIT_A 0x40 #define PIT_CONTROL 0x43 @@ -28,24 +27,25 @@ #define CMD_COUNTER2 0x80 void setTimerFreq(uint32_t hz) { - int divisor = PIT_SCALE / hz; - outb(PIT_CONTROL, CMD_BINARY | CMD_MODE3 | CMD_RW_BOTH | CMD_COUNTER0); - outb(PIT_A, (uint8_t) divisor); - outb(PIT_A, (uint8_t) (divisor >> 8)); + int divisor = PIT_SCALE / hz; + outb(PIT_CONTROL, CMD_BINARY | CMD_MODE3 | CMD_RW_BOTH | CMD_COUNTER0); + outb(PIT_A, (uint8_t)divisor); + outb(PIT_A, (uint8_t)(divisor >> 8)); } uint32_t timerMillis = 0; +uint32_t time = 0; + void timerHandler() { - timerMillis++; - if (timerMillis % 1000 == 0) { - // printf("second\n"); - // yields(); - } + timerMillis++; + if (timerMillis % 1000 == 0) { + printf("\e[s\e[Htime since power on :0x%x seconds\e[u", ++time); + } } void setupTimer() { - printf("setting timer frequency to 1kHz\n"); - setTimerFreq(1000); - setIRQHandler(0, &timerHandler); + printf("setting timer frequency to 1kHz\n"); + setTimerFreq(1000); + setIRQHandler(0, &timerHandler); } diff --git a/src/kernel/drivers/textMode/_stdio.c b/src/kernel/drivers/textMode/_stdio.c index ced3147..b0e2cce 100644 --- a/src/kernel/drivers/textMode/_stdio.c +++ b/src/kernel/drivers/textMode/_stdio.c @@ -111,11 +111,10 @@ va_end(valist); Message *message = malloc(sizeof(Message)); - message->data = data; message->size = size; - message->next = 0x00; - sendMessage(getPrinterTask(), message); + message->type = -1; + listAdd(&getPrinterTask()->messages, message); schedule(getPrinterTask()); } diff --git a/src/kernel/drivers/textMode/terminal.c b/src/kernel/drivers/textMode/terminal.c index ecd58b0..20800e6 100644 --- a/src/kernel/drivers/textMode/terminal.c +++ b/src/kernel/drivers/textMode/terminal.c @@ -76,6 +76,8 @@ uint32_t *currentBuffer = &ansiEscapeBuffer1; +uint32_t savedCursor = 0; + #define addBuffer(i) \ case i + '0': \ *currentBuffer *= 10; \ @@ -170,6 +172,15 @@ setCursorOffset(cursorOffset); currentState = STANDARD; return; + case 's': + savedCursor = cursorOffset; + currentState = STANDARD; + return; + case 'u': + cursorOffset = savedCursor; + setCursorOffset(cursorOffset); + currentState = STANDARD; + return; } } } diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index bd0f8db..6835a28 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -21,7 +21,7 @@ printf("cpu data:\n"); printCPUData(); while (1) { - if (getCurrentTask()->nextTask == 0) { + if (isTaskQueueEmpty()) { asm volatile("hlt"); } yields(); diff --git a/src/include/list.h b/src/include/list.h new file mode 100644 index 0000000..fe8c91f --- /dev/null +++ b/src/include/list.h @@ -0,0 +1,16 @@ +#ifndef LIST_H +#define LIST_H + +#define NULL (void *)0 + +typedef struct ListElement { + struct ListElement *next; + void *data; +} ListElement; + +extern void listAdd(ListElement **list, void *data); +extern void listAddSet(ListElement **list, void *data); + +extern void *popBeginning(ListElement **list); + +#endif diff --git a/src/include/message.h b/src/include/message.h index 12e3a85..ece324e 100644 --- a/src/include/message.h +++ b/src/include/message.h @@ -3,10 +3,16 @@ #include +enum MessageTypes { + KEYBOARD_CHAR, + KEYBOARD_STRING, + TIMER_UPDATE, +}; + typedef struct { - void *data; - uint32_t size; - struct Message *next; + void *data; + uint8_t type; + uint32_t size; } Message; #endif diff --git a/src/include/osTasks.h b/src/include/osTasks.h index 2865863..ef8c0bf 100644 --- a/src/include/osTasks.h +++ b/src/include/osTasks.h @@ -5,6 +5,8 @@ extern void initOSTasks(); -extern Task* getPrinterTask(); +extern Task *getPrinterTask(); -#endif \ No newline at end of file +extern Task *getKeyboardConsumer(); + +#endif diff --git a/src/include/task.h b/src/include/task.h index 0b8e1b4..d708423 100644 --- a/src/include/task.h +++ b/src/include/task.h @@ -1,34 +1,38 @@ #ifndef TASK_H #define TASK_H -#include +#include #include +#include +#include extern void initTasking(); - -typedef struct __attribute__ ((packed)) { + +typedef struct __attribute__((packed)) { uint32_t eax, ebx, ecx, edx, esi, edi, esp, ebp, eip, eflags, cr3; } Registers; - + typedef struct Task { - Registers registers; // the register states for the task - struct Task *nextTask; // linked list of tasks that need to be done - void* stack; - Message* message; + Registers registers; + void *stack; + ListElement *messages; } Task; - + extern void initTasking(); -extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir); - +extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, + uint32_t *pagedir); + extern void yield(); -extern void yields(); // yield, but schedule the currently running task +extern void yields(); extern void switchTask(Registers *old, Registers *new); -extern void schedule(Task* task); // schedule a task to be run in the future +extern void schedule(Task *task); extern void destroyCurrentTask(); -extern void setRunningTask(Task* task); // set the task currently executed -extern void sendMessage(Task* task, Message* message); +extern void setRunningTask(Task *task); +extern void sendMessage(Task *task, Message *message); -extern Message* popMessage(Task* task); +extern Message *popMessage(Task *task); -#endif \ No newline at end of file +extern bool isTaskQueueEmpty(); + +#endif diff --git a/src/kernel/drivers/cpu/cpuid.asm b/src/kernel/drivers/cpu/cpuid.asm index 6be352a..3aed27d 100644 --- a/src/kernel/drivers/cpu/cpuid.asm +++ b/src/kernel/drivers/cpu/cpuid.asm @@ -1,5 +1,6 @@ section .text global getVendorId + getVendorId: mov eax, 0x00 cpuid diff --git a/src/kernel/drivers/interrupts/irqs.asm b/src/kernel/drivers/interrupts/irqs.asm index 3e6670b..3a413ed 100644 --- a/src/kernel/drivers/interrupts/irqs.asm +++ b/src/kernel/drivers/interrupts/irqs.asm @@ -28,6 +28,7 @@ extern handleIRQ irqHandler: + cli pusha push ds push es @@ -49,4 +50,5 @@ pop ds popa add esp, 8 - iret \ No newline at end of file + sti + iret diff --git a/src/kernel/drivers/interrupts/irqs.c b/src/kernel/drivers/interrupts/irqs.c index c7bf183..60d95f8 100644 --- a/src/kernel/drivers/interrupts/irqs.c +++ b/src/kernel/drivers/interrupts/irqs.c @@ -1,9 +1,9 @@ -#include +#include <_stdio.h> #include +#include #include #include #include -#include <_stdio.h> #define OFFSET_1 32 #define OFFSET_2 40 @@ -43,13 +43,13 @@ remapPIC(OFFSET_1, OFFSET_2); } -void* irqHandlers[16]; +void *irqHandlers[16]; -void setIRQHandler(uint8_t irqNumber, void* fun) { +void setIRQHandler(uint8_t irqNumber, void *fun) { irqHandlers[irqNumber] = fun; } -void handleIRQ(regs* registers) { +void handleIRQ(regs *registers) { if (registers->int_no >= OFFSET_2) { outb(0xA0, 0x20); } @@ -60,5 +60,9 @@ handler(); return; } + if (irqNumber == 7 || irqNumber == 2) { + // irq2 should not be fired, irq 7 is a spurious irq + return; + } printf("unhandeled IRQ no. 0x%x was triggered!\n", irqNumber); -} \ No newline at end of file +} diff --git a/src/kernel/drivers/interrupts/timer/timer.c b/src/kernel/drivers/interrupts/timer/timer.c index b9ba3af..267077e 100644 --- a/src/kernel/drivers/interrupts/timer/timer.c +++ b/src/kernel/drivers/interrupts/timer/timer.c @@ -1,10 +1,9 @@ -#include #include <_stdio.h> #include -#include -#include #include - +#include +#include +#include #define PIT_A 0x40 #define PIT_CONTROL 0x43 @@ -28,24 +27,25 @@ #define CMD_COUNTER2 0x80 void setTimerFreq(uint32_t hz) { - int divisor = PIT_SCALE / hz; - outb(PIT_CONTROL, CMD_BINARY | CMD_MODE3 | CMD_RW_BOTH | CMD_COUNTER0); - outb(PIT_A, (uint8_t) divisor); - outb(PIT_A, (uint8_t) (divisor >> 8)); + int divisor = PIT_SCALE / hz; + outb(PIT_CONTROL, CMD_BINARY | CMD_MODE3 | CMD_RW_BOTH | CMD_COUNTER0); + outb(PIT_A, (uint8_t)divisor); + outb(PIT_A, (uint8_t)(divisor >> 8)); } uint32_t timerMillis = 0; +uint32_t time = 0; + void timerHandler() { - timerMillis++; - if (timerMillis % 1000 == 0) { - // printf("second\n"); - // yields(); - } + timerMillis++; + if (timerMillis % 1000 == 0) { + printf("\e[s\e[Htime since power on :0x%x seconds\e[u", ++time); + } } void setupTimer() { - printf("setting timer frequency to 1kHz\n"); - setTimerFreq(1000); - setIRQHandler(0, &timerHandler); + printf("setting timer frequency to 1kHz\n"); + setTimerFreq(1000); + setIRQHandler(0, &timerHandler); } diff --git a/src/kernel/drivers/textMode/_stdio.c b/src/kernel/drivers/textMode/_stdio.c index ced3147..b0e2cce 100644 --- a/src/kernel/drivers/textMode/_stdio.c +++ b/src/kernel/drivers/textMode/_stdio.c @@ -111,11 +111,10 @@ va_end(valist); Message *message = malloc(sizeof(Message)); - message->data = data; message->size = size; - message->next = 0x00; - sendMessage(getPrinterTask(), message); + message->type = -1; + listAdd(&getPrinterTask()->messages, message); schedule(getPrinterTask()); } diff --git a/src/kernel/drivers/textMode/terminal.c b/src/kernel/drivers/textMode/terminal.c index ecd58b0..20800e6 100644 --- a/src/kernel/drivers/textMode/terminal.c +++ b/src/kernel/drivers/textMode/terminal.c @@ -76,6 +76,8 @@ uint32_t *currentBuffer = &ansiEscapeBuffer1; +uint32_t savedCursor = 0; + #define addBuffer(i) \ case i + '0': \ *currentBuffer *= 10; \ @@ -170,6 +172,15 @@ setCursorOffset(cursorOffset); currentState = STANDARD; return; + case 's': + savedCursor = cursorOffset; + currentState = STANDARD; + return; + case 'u': + cursorOffset = savedCursor; + setCursorOffset(cursorOffset); + currentState = STANDARD; + return; } } } diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index bd0f8db..6835a28 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -21,7 +21,7 @@ printf("cpu data:\n"); printCPUData(); while (1) { - if (getCurrentTask()->nextTask == 0) { + if (isTaskQueueEmpty()) { asm volatile("hlt"); } yields(); diff --git a/src/kernel/task/osTasks.c b/src/kernel/task/osTasks.c index dfa6988..da46b2e 100644 --- a/src/kernel/task/osTasks.c +++ b/src/kernel/task/osTasks.c @@ -7,10 +7,11 @@ Task mainTask; Task printerTask; +Task *keyboardConsumer = &mainTask; void printLoop() { while (1) { - Message *message = popMessage(&printerTask); + Message *message = popBeginning(&printerTask.messages); if (message == 0) { yield(); continue; @@ -25,6 +26,7 @@ void initOSTasks() { setRunningTask(&mainTask); + keyboardConsumer = &mainTask; createTask(&printerTask, (uint32_t)printLoop, 0x0, 0x0); schedule(&printerTask); // more tasks . . . @@ -32,3 +34,4 @@ } inline Task *getPrinterTask() { return &printerTask; } +inline Task *getKeyboardConsumer() { return keyboardConsumer; } diff --git a/src/include/list.h b/src/include/list.h new file mode 100644 index 0000000..fe8c91f --- /dev/null +++ b/src/include/list.h @@ -0,0 +1,16 @@ +#ifndef LIST_H +#define LIST_H + +#define NULL (void *)0 + +typedef struct ListElement { + struct ListElement *next; + void *data; +} ListElement; + +extern void listAdd(ListElement **list, void *data); +extern void listAddSet(ListElement **list, void *data); + +extern void *popBeginning(ListElement **list); + +#endif diff --git a/src/include/message.h b/src/include/message.h index 12e3a85..ece324e 100644 --- a/src/include/message.h +++ b/src/include/message.h @@ -3,10 +3,16 @@ #include +enum MessageTypes { + KEYBOARD_CHAR, + KEYBOARD_STRING, + TIMER_UPDATE, +}; + typedef struct { - void *data; - uint32_t size; - struct Message *next; + void *data; + uint8_t type; + uint32_t size; } Message; #endif diff --git a/src/include/osTasks.h b/src/include/osTasks.h index 2865863..ef8c0bf 100644 --- a/src/include/osTasks.h +++ b/src/include/osTasks.h @@ -5,6 +5,8 @@ extern void initOSTasks(); -extern Task* getPrinterTask(); +extern Task *getPrinterTask(); -#endif \ No newline at end of file +extern Task *getKeyboardConsumer(); + +#endif diff --git a/src/include/task.h b/src/include/task.h index 0b8e1b4..d708423 100644 --- a/src/include/task.h +++ b/src/include/task.h @@ -1,34 +1,38 @@ #ifndef TASK_H #define TASK_H -#include +#include #include +#include +#include extern void initTasking(); - -typedef struct __attribute__ ((packed)) { + +typedef struct __attribute__((packed)) { uint32_t eax, ebx, ecx, edx, esi, edi, esp, ebp, eip, eflags, cr3; } Registers; - + typedef struct Task { - Registers registers; // the register states for the task - struct Task *nextTask; // linked list of tasks that need to be done - void* stack; - Message* message; + Registers registers; + void *stack; + ListElement *messages; } Task; - + extern void initTasking(); -extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir); - +extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, + uint32_t *pagedir); + extern void yield(); -extern void yields(); // yield, but schedule the currently running task +extern void yields(); extern void switchTask(Registers *old, Registers *new); -extern void schedule(Task* task); // schedule a task to be run in the future +extern void schedule(Task *task); extern void destroyCurrentTask(); -extern void setRunningTask(Task* task); // set the task currently executed -extern void sendMessage(Task* task, Message* message); +extern void setRunningTask(Task *task); +extern void sendMessage(Task *task, Message *message); -extern Message* popMessage(Task* task); +extern Message *popMessage(Task *task); -#endif \ No newline at end of file +extern bool isTaskQueueEmpty(); + +#endif diff --git a/src/kernel/drivers/cpu/cpuid.asm b/src/kernel/drivers/cpu/cpuid.asm index 6be352a..3aed27d 100644 --- a/src/kernel/drivers/cpu/cpuid.asm +++ b/src/kernel/drivers/cpu/cpuid.asm @@ -1,5 +1,6 @@ section .text global getVendorId + getVendorId: mov eax, 0x00 cpuid diff --git a/src/kernel/drivers/interrupts/irqs.asm b/src/kernel/drivers/interrupts/irqs.asm index 3e6670b..3a413ed 100644 --- a/src/kernel/drivers/interrupts/irqs.asm +++ b/src/kernel/drivers/interrupts/irqs.asm @@ -28,6 +28,7 @@ extern handleIRQ irqHandler: + cli pusha push ds push es @@ -49,4 +50,5 @@ pop ds popa add esp, 8 - iret \ No newline at end of file + sti + iret diff --git a/src/kernel/drivers/interrupts/irqs.c b/src/kernel/drivers/interrupts/irqs.c index c7bf183..60d95f8 100644 --- a/src/kernel/drivers/interrupts/irqs.c +++ b/src/kernel/drivers/interrupts/irqs.c @@ -1,9 +1,9 @@ -#include +#include <_stdio.h> #include +#include #include #include #include -#include <_stdio.h> #define OFFSET_1 32 #define OFFSET_2 40 @@ -43,13 +43,13 @@ remapPIC(OFFSET_1, OFFSET_2); } -void* irqHandlers[16]; +void *irqHandlers[16]; -void setIRQHandler(uint8_t irqNumber, void* fun) { +void setIRQHandler(uint8_t irqNumber, void *fun) { irqHandlers[irqNumber] = fun; } -void handleIRQ(regs* registers) { +void handleIRQ(regs *registers) { if (registers->int_no >= OFFSET_2) { outb(0xA0, 0x20); } @@ -60,5 +60,9 @@ handler(); return; } + if (irqNumber == 7 || irqNumber == 2) { + // irq2 should not be fired, irq 7 is a spurious irq + return; + } printf("unhandeled IRQ no. 0x%x was triggered!\n", irqNumber); -} \ No newline at end of file +} diff --git a/src/kernel/drivers/interrupts/timer/timer.c b/src/kernel/drivers/interrupts/timer/timer.c index b9ba3af..267077e 100644 --- a/src/kernel/drivers/interrupts/timer/timer.c +++ b/src/kernel/drivers/interrupts/timer/timer.c @@ -1,10 +1,9 @@ -#include #include <_stdio.h> #include -#include -#include #include - +#include +#include +#include #define PIT_A 0x40 #define PIT_CONTROL 0x43 @@ -28,24 +27,25 @@ #define CMD_COUNTER2 0x80 void setTimerFreq(uint32_t hz) { - int divisor = PIT_SCALE / hz; - outb(PIT_CONTROL, CMD_BINARY | CMD_MODE3 | CMD_RW_BOTH | CMD_COUNTER0); - outb(PIT_A, (uint8_t) divisor); - outb(PIT_A, (uint8_t) (divisor >> 8)); + int divisor = PIT_SCALE / hz; + outb(PIT_CONTROL, CMD_BINARY | CMD_MODE3 | CMD_RW_BOTH | CMD_COUNTER0); + outb(PIT_A, (uint8_t)divisor); + outb(PIT_A, (uint8_t)(divisor >> 8)); } uint32_t timerMillis = 0; +uint32_t time = 0; + void timerHandler() { - timerMillis++; - if (timerMillis % 1000 == 0) { - // printf("second\n"); - // yields(); - } + timerMillis++; + if (timerMillis % 1000 == 0) { + printf("\e[s\e[Htime since power on :0x%x seconds\e[u", ++time); + } } void setupTimer() { - printf("setting timer frequency to 1kHz\n"); - setTimerFreq(1000); - setIRQHandler(0, &timerHandler); + printf("setting timer frequency to 1kHz\n"); + setTimerFreq(1000); + setIRQHandler(0, &timerHandler); } diff --git a/src/kernel/drivers/textMode/_stdio.c b/src/kernel/drivers/textMode/_stdio.c index ced3147..b0e2cce 100644 --- a/src/kernel/drivers/textMode/_stdio.c +++ b/src/kernel/drivers/textMode/_stdio.c @@ -111,11 +111,10 @@ va_end(valist); Message *message = malloc(sizeof(Message)); - message->data = data; message->size = size; - message->next = 0x00; - sendMessage(getPrinterTask(), message); + message->type = -1; + listAdd(&getPrinterTask()->messages, message); schedule(getPrinterTask()); } diff --git a/src/kernel/drivers/textMode/terminal.c b/src/kernel/drivers/textMode/terminal.c index ecd58b0..20800e6 100644 --- a/src/kernel/drivers/textMode/terminal.c +++ b/src/kernel/drivers/textMode/terminal.c @@ -76,6 +76,8 @@ uint32_t *currentBuffer = &ansiEscapeBuffer1; +uint32_t savedCursor = 0; + #define addBuffer(i) \ case i + '0': \ *currentBuffer *= 10; \ @@ -170,6 +172,15 @@ setCursorOffset(cursorOffset); currentState = STANDARD; return; + case 's': + savedCursor = cursorOffset; + currentState = STANDARD; + return; + case 'u': + cursorOffset = savedCursor; + setCursorOffset(cursorOffset); + currentState = STANDARD; + return; } } } diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index bd0f8db..6835a28 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -21,7 +21,7 @@ printf("cpu data:\n"); printCPUData(); while (1) { - if (getCurrentTask()->nextTask == 0) { + if (isTaskQueueEmpty()) { asm volatile("hlt"); } yields(); diff --git a/src/kernel/task/osTasks.c b/src/kernel/task/osTasks.c index dfa6988..da46b2e 100644 --- a/src/kernel/task/osTasks.c +++ b/src/kernel/task/osTasks.c @@ -7,10 +7,11 @@ Task mainTask; Task printerTask; +Task *keyboardConsumer = &mainTask; void printLoop() { while (1) { - Message *message = popMessage(&printerTask); + Message *message = popBeginning(&printerTask.messages); if (message == 0) { yield(); continue; @@ -25,6 +26,7 @@ void initOSTasks() { setRunningTask(&mainTask); + keyboardConsumer = &mainTask; createTask(&printerTask, (uint32_t)printLoop, 0x0, 0x0); schedule(&printerTask); // more tasks . . . @@ -32,3 +34,4 @@ } inline Task *getPrinterTask() { return &printerTask; } +inline Task *getKeyboardConsumer() { return keyboardConsumer; } diff --git a/src/kernel/task/task.c b/src/kernel/task/task.c index 3964e7c..de1f096 100644 --- a/src/kernel/task/task.c +++ b/src/kernel/task/task.c @@ -1,13 +1,16 @@ -#include -#include #include <_stdio.h> +#include +#include +#include #define STACK_SIZE 0x100000 Task *currentTask; +ListElement *scheduledTasks = NULL; -void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir) { - void* stack = mallocTask(STACK_SIZE, task); +void createTask(Task *task, uint32_t mainFunction, uint32_t flags, + uint32_t *pagedir) { + void *stack = mallocTask(STACK_SIZE, task); task->registers.eax = 0; task->registers.ebx = 0; task->registers.ecx = 0; @@ -16,76 +19,37 @@ task->registers.edi = 0; task->registers.eflags = flags; task->registers.eip = mainFunction; - task->registers.cr3 = (uint32_t) pagedir; - task->registers.esp = STACK_SIZE + (uint32_t) stack; - task->nextTask = 0; + task->registers.cr3 = (uint32_t)pagedir; + task->registers.esp = STACK_SIZE + (uint32_t)stack; task->stack = stack; + task->messages = NULL; } void yield() { - Task* last = currentTask; - currentTask = last->nextTask; - if (currentTask == 0x00) { - while (1); + Task *last = currentTask; + currentTask = popBeginning(&scheduledTasks); + if (currentTask == NULL) { + while (1) + ; return; } - last->nextTask = 0x00; switchTask(&(last->registers), &(currentTask->registers)); } -void schedule(Task* task) { - Task* test = currentTask; - if (currentTask == 0x00) { - currentTask = task; - currentTask->nextTask = 0x00; - return; - } - while (test->nextTask != 0x0) { - if (test->nextTask == task) { - return; // don't schedule if the task is already in the queue - } - test = test->nextTask; - } - if (test->nextTask == task) { - return; - } - test->nextTask = task; -} - -void setRunningTask(Task* task) { - currentTask = task; -} - -void yields() { +inline void yields() { schedule(currentTask); yield(); } -void destroyCurrentTask() { +inline void destroyCurrentTask() { freeTaskAllocations(currentTask); yield(); } -Task* getCurrentTask() { - return currentTask; -} +inline Task *getCurrentTask() { return currentTask; } -void sendMessage(Task* task, Message* message) { - Message* currentMessage = task->message; - if (currentMessage == 0) { - task->message = message; - return; - } - while (currentMessage->next != 0) { - currentMessage = currentMessage->next; - } - currentMessage->next = message; -} +inline void schedule(Task *task) { listAddSet(&scheduledTasks, task); } -Message* popMessage(Task* task) { - Message* currentMessage = task->message; - if (currentMessage != 0) { - task->message = currentMessage->next; - } - return currentMessage; -} \ No newline at end of file +inline void setRunningTask(Task *task) { currentTask = task; } + +inline bool isTaskQueueEmpty() { return scheduledTasks == NULL; } diff --git a/src/include/list.h b/src/include/list.h new file mode 100644 index 0000000..fe8c91f --- /dev/null +++ b/src/include/list.h @@ -0,0 +1,16 @@ +#ifndef LIST_H +#define LIST_H + +#define NULL (void *)0 + +typedef struct ListElement { + struct ListElement *next; + void *data; +} ListElement; + +extern void listAdd(ListElement **list, void *data); +extern void listAddSet(ListElement **list, void *data); + +extern void *popBeginning(ListElement **list); + +#endif diff --git a/src/include/message.h b/src/include/message.h index 12e3a85..ece324e 100644 --- a/src/include/message.h +++ b/src/include/message.h @@ -3,10 +3,16 @@ #include +enum MessageTypes { + KEYBOARD_CHAR, + KEYBOARD_STRING, + TIMER_UPDATE, +}; + typedef struct { - void *data; - uint32_t size; - struct Message *next; + void *data; + uint8_t type; + uint32_t size; } Message; #endif diff --git a/src/include/osTasks.h b/src/include/osTasks.h index 2865863..ef8c0bf 100644 --- a/src/include/osTasks.h +++ b/src/include/osTasks.h @@ -5,6 +5,8 @@ extern void initOSTasks(); -extern Task* getPrinterTask(); +extern Task *getPrinterTask(); -#endif \ No newline at end of file +extern Task *getKeyboardConsumer(); + +#endif diff --git a/src/include/task.h b/src/include/task.h index 0b8e1b4..d708423 100644 --- a/src/include/task.h +++ b/src/include/task.h @@ -1,34 +1,38 @@ #ifndef TASK_H #define TASK_H -#include +#include #include +#include +#include extern void initTasking(); - -typedef struct __attribute__ ((packed)) { + +typedef struct __attribute__((packed)) { uint32_t eax, ebx, ecx, edx, esi, edi, esp, ebp, eip, eflags, cr3; } Registers; - + typedef struct Task { - Registers registers; // the register states for the task - struct Task *nextTask; // linked list of tasks that need to be done - void* stack; - Message* message; + Registers registers; + void *stack; + ListElement *messages; } Task; - + extern void initTasking(); -extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir); - +extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, + uint32_t *pagedir); + extern void yield(); -extern void yields(); // yield, but schedule the currently running task +extern void yields(); extern void switchTask(Registers *old, Registers *new); -extern void schedule(Task* task); // schedule a task to be run in the future +extern void schedule(Task *task); extern void destroyCurrentTask(); -extern void setRunningTask(Task* task); // set the task currently executed -extern void sendMessage(Task* task, Message* message); +extern void setRunningTask(Task *task); +extern void sendMessage(Task *task, Message *message); -extern Message* popMessage(Task* task); +extern Message *popMessage(Task *task); -#endif \ No newline at end of file +extern bool isTaskQueueEmpty(); + +#endif diff --git a/src/kernel/drivers/cpu/cpuid.asm b/src/kernel/drivers/cpu/cpuid.asm index 6be352a..3aed27d 100644 --- a/src/kernel/drivers/cpu/cpuid.asm +++ b/src/kernel/drivers/cpu/cpuid.asm @@ -1,5 +1,6 @@ section .text global getVendorId + getVendorId: mov eax, 0x00 cpuid diff --git a/src/kernel/drivers/interrupts/irqs.asm b/src/kernel/drivers/interrupts/irqs.asm index 3e6670b..3a413ed 100644 --- a/src/kernel/drivers/interrupts/irqs.asm +++ b/src/kernel/drivers/interrupts/irqs.asm @@ -28,6 +28,7 @@ extern handleIRQ irqHandler: + cli pusha push ds push es @@ -49,4 +50,5 @@ pop ds popa add esp, 8 - iret \ No newline at end of file + sti + iret diff --git a/src/kernel/drivers/interrupts/irqs.c b/src/kernel/drivers/interrupts/irqs.c index c7bf183..60d95f8 100644 --- a/src/kernel/drivers/interrupts/irqs.c +++ b/src/kernel/drivers/interrupts/irqs.c @@ -1,9 +1,9 @@ -#include +#include <_stdio.h> #include +#include #include #include #include -#include <_stdio.h> #define OFFSET_1 32 #define OFFSET_2 40 @@ -43,13 +43,13 @@ remapPIC(OFFSET_1, OFFSET_2); } -void* irqHandlers[16]; +void *irqHandlers[16]; -void setIRQHandler(uint8_t irqNumber, void* fun) { +void setIRQHandler(uint8_t irqNumber, void *fun) { irqHandlers[irqNumber] = fun; } -void handleIRQ(regs* registers) { +void handleIRQ(regs *registers) { if (registers->int_no >= OFFSET_2) { outb(0xA0, 0x20); } @@ -60,5 +60,9 @@ handler(); return; } + if (irqNumber == 7 || irqNumber == 2) { + // irq2 should not be fired, irq 7 is a spurious irq + return; + } printf("unhandeled IRQ no. 0x%x was triggered!\n", irqNumber); -} \ No newline at end of file +} diff --git a/src/kernel/drivers/interrupts/timer/timer.c b/src/kernel/drivers/interrupts/timer/timer.c index b9ba3af..267077e 100644 --- a/src/kernel/drivers/interrupts/timer/timer.c +++ b/src/kernel/drivers/interrupts/timer/timer.c @@ -1,10 +1,9 @@ -#include #include <_stdio.h> #include -#include -#include #include - +#include +#include +#include #define PIT_A 0x40 #define PIT_CONTROL 0x43 @@ -28,24 +27,25 @@ #define CMD_COUNTER2 0x80 void setTimerFreq(uint32_t hz) { - int divisor = PIT_SCALE / hz; - outb(PIT_CONTROL, CMD_BINARY | CMD_MODE3 | CMD_RW_BOTH | CMD_COUNTER0); - outb(PIT_A, (uint8_t) divisor); - outb(PIT_A, (uint8_t) (divisor >> 8)); + int divisor = PIT_SCALE / hz; + outb(PIT_CONTROL, CMD_BINARY | CMD_MODE3 | CMD_RW_BOTH | CMD_COUNTER0); + outb(PIT_A, (uint8_t)divisor); + outb(PIT_A, (uint8_t)(divisor >> 8)); } uint32_t timerMillis = 0; +uint32_t time = 0; + void timerHandler() { - timerMillis++; - if (timerMillis % 1000 == 0) { - // printf("second\n"); - // yields(); - } + timerMillis++; + if (timerMillis % 1000 == 0) { + printf("\e[s\e[Htime since power on :0x%x seconds\e[u", ++time); + } } void setupTimer() { - printf("setting timer frequency to 1kHz\n"); - setTimerFreq(1000); - setIRQHandler(0, &timerHandler); + printf("setting timer frequency to 1kHz\n"); + setTimerFreq(1000); + setIRQHandler(0, &timerHandler); } diff --git a/src/kernel/drivers/textMode/_stdio.c b/src/kernel/drivers/textMode/_stdio.c index ced3147..b0e2cce 100644 --- a/src/kernel/drivers/textMode/_stdio.c +++ b/src/kernel/drivers/textMode/_stdio.c @@ -111,11 +111,10 @@ va_end(valist); Message *message = malloc(sizeof(Message)); - message->data = data; message->size = size; - message->next = 0x00; - sendMessage(getPrinterTask(), message); + message->type = -1; + listAdd(&getPrinterTask()->messages, message); schedule(getPrinterTask()); } diff --git a/src/kernel/drivers/textMode/terminal.c b/src/kernel/drivers/textMode/terminal.c index ecd58b0..20800e6 100644 --- a/src/kernel/drivers/textMode/terminal.c +++ b/src/kernel/drivers/textMode/terminal.c @@ -76,6 +76,8 @@ uint32_t *currentBuffer = &ansiEscapeBuffer1; +uint32_t savedCursor = 0; + #define addBuffer(i) \ case i + '0': \ *currentBuffer *= 10; \ @@ -170,6 +172,15 @@ setCursorOffset(cursorOffset); currentState = STANDARD; return; + case 's': + savedCursor = cursorOffset; + currentState = STANDARD; + return; + case 'u': + cursorOffset = savedCursor; + setCursorOffset(cursorOffset); + currentState = STANDARD; + return; } } } diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index bd0f8db..6835a28 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -21,7 +21,7 @@ printf("cpu data:\n"); printCPUData(); while (1) { - if (getCurrentTask()->nextTask == 0) { + if (isTaskQueueEmpty()) { asm volatile("hlt"); } yields(); diff --git a/src/kernel/task/osTasks.c b/src/kernel/task/osTasks.c index dfa6988..da46b2e 100644 --- a/src/kernel/task/osTasks.c +++ b/src/kernel/task/osTasks.c @@ -7,10 +7,11 @@ Task mainTask; Task printerTask; +Task *keyboardConsumer = &mainTask; void printLoop() { while (1) { - Message *message = popMessage(&printerTask); + Message *message = popBeginning(&printerTask.messages); if (message == 0) { yield(); continue; @@ -25,6 +26,7 @@ void initOSTasks() { setRunningTask(&mainTask); + keyboardConsumer = &mainTask; createTask(&printerTask, (uint32_t)printLoop, 0x0, 0x0); schedule(&printerTask); // more tasks . . . @@ -32,3 +34,4 @@ } inline Task *getPrinterTask() { return &printerTask; } +inline Task *getKeyboardConsumer() { return keyboardConsumer; } diff --git a/src/kernel/task/task.c b/src/kernel/task/task.c index 3964e7c..de1f096 100644 --- a/src/kernel/task/task.c +++ b/src/kernel/task/task.c @@ -1,13 +1,16 @@ -#include -#include #include <_stdio.h> +#include +#include +#include #define STACK_SIZE 0x100000 Task *currentTask; +ListElement *scheduledTasks = NULL; -void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir) { - void* stack = mallocTask(STACK_SIZE, task); +void createTask(Task *task, uint32_t mainFunction, uint32_t flags, + uint32_t *pagedir) { + void *stack = mallocTask(STACK_SIZE, task); task->registers.eax = 0; task->registers.ebx = 0; task->registers.ecx = 0; @@ -16,76 +19,37 @@ task->registers.edi = 0; task->registers.eflags = flags; task->registers.eip = mainFunction; - task->registers.cr3 = (uint32_t) pagedir; - task->registers.esp = STACK_SIZE + (uint32_t) stack; - task->nextTask = 0; + task->registers.cr3 = (uint32_t)pagedir; + task->registers.esp = STACK_SIZE + (uint32_t)stack; task->stack = stack; + task->messages = NULL; } void yield() { - Task* last = currentTask; - currentTask = last->nextTask; - if (currentTask == 0x00) { - while (1); + Task *last = currentTask; + currentTask = popBeginning(&scheduledTasks); + if (currentTask == NULL) { + while (1) + ; return; } - last->nextTask = 0x00; switchTask(&(last->registers), &(currentTask->registers)); } -void schedule(Task* task) { - Task* test = currentTask; - if (currentTask == 0x00) { - currentTask = task; - currentTask->nextTask = 0x00; - return; - } - while (test->nextTask != 0x0) { - if (test->nextTask == task) { - return; // don't schedule if the task is already in the queue - } - test = test->nextTask; - } - if (test->nextTask == task) { - return; - } - test->nextTask = task; -} - -void setRunningTask(Task* task) { - currentTask = task; -} - -void yields() { +inline void yields() { schedule(currentTask); yield(); } -void destroyCurrentTask() { +inline void destroyCurrentTask() { freeTaskAllocations(currentTask); yield(); } -Task* getCurrentTask() { - return currentTask; -} +inline Task *getCurrentTask() { return currentTask; } -void sendMessage(Task* task, Message* message) { - Message* currentMessage = task->message; - if (currentMessage == 0) { - task->message = message; - return; - } - while (currentMessage->next != 0) { - currentMessage = currentMessage->next; - } - currentMessage->next = message; -} +inline void schedule(Task *task) { listAddSet(&scheduledTasks, task); } -Message* popMessage(Task* task) { - Message* currentMessage = task->message; - if (currentMessage != 0) { - task->message = currentMessage->next; - } - return currentMessage; -} \ No newline at end of file +inline void setRunningTask(Task *task) { currentTask = task; } + +inline bool isTaskQueueEmpty() { return scheduledTasks == NULL; } diff --git a/src/kernel/util/list.c b/src/kernel/util/list.c new file mode 100644 index 0000000..b14b60c --- /dev/null +++ b/src/kernel/util/list.c @@ -0,0 +1,66 @@ +#include +#include + +void listAdd(ListElement **list, void *data) { + ListElement *element = *list; + if (element == NULL) { + *list = malloc(sizeof(ListElement)); + element = *list; + element->next = NULL; + } else { + for (; element->next; element = element->next) { + } + element->next = malloc(sizeof(ListElement)); + element = element->next; + } + element->data = data; +} + +void listAddSet(ListElement **list, void *data) { + ListElement *element = *list; + if (element == NULL) { + *list = malloc(sizeof(ListElement)); + element = *list; + element->next = NULL; + } else { + for (; element->next; element = element->next) { + if (element->data == data) { + return; + } + } + element->next = malloc(sizeof(ListElement)); + element = element->next; + element->next = NULL; + } + element->data = data; +} + +void *popBeginning(ListElement **list) { + if (*list == NULL) { + return NULL; + } + ListElement *element = *list; + void *result = (*list)->data; + *list = (*list)->next; + free(element); + return result; +} + +void *popEnd(ListElement **list) { + if (list == NULL) { + return NULL; + } + ListElement *before = NULL; + ListElement *current = *list; + for (; current->next; current = current->next) { + before = current; + } + void *result = current->data; + free(current); + if (before != NULL) { + before->next = NULL; + } else { + *list = NULL; + } + return result; +} diff --git a/src/include/list.h b/src/include/list.h new file mode 100644 index 0000000..fe8c91f --- /dev/null +++ b/src/include/list.h @@ -0,0 +1,16 @@ +#ifndef LIST_H +#define LIST_H + +#define NULL (void *)0 + +typedef struct ListElement { + struct ListElement *next; + void *data; +} ListElement; + +extern void listAdd(ListElement **list, void *data); +extern void listAddSet(ListElement **list, void *data); + +extern void *popBeginning(ListElement **list); + +#endif diff --git a/src/include/message.h b/src/include/message.h index 12e3a85..ece324e 100644 --- a/src/include/message.h +++ b/src/include/message.h @@ -3,10 +3,16 @@ #include +enum MessageTypes { + KEYBOARD_CHAR, + KEYBOARD_STRING, + TIMER_UPDATE, +}; + typedef struct { - void *data; - uint32_t size; - struct Message *next; + void *data; + uint8_t type; + uint32_t size; } Message; #endif diff --git a/src/include/osTasks.h b/src/include/osTasks.h index 2865863..ef8c0bf 100644 --- a/src/include/osTasks.h +++ b/src/include/osTasks.h @@ -5,6 +5,8 @@ extern void initOSTasks(); -extern Task* getPrinterTask(); +extern Task *getPrinterTask(); -#endif \ No newline at end of file +extern Task *getKeyboardConsumer(); + +#endif diff --git a/src/include/task.h b/src/include/task.h index 0b8e1b4..d708423 100644 --- a/src/include/task.h +++ b/src/include/task.h @@ -1,34 +1,38 @@ #ifndef TASK_H #define TASK_H -#include +#include #include +#include +#include extern void initTasking(); - -typedef struct __attribute__ ((packed)) { + +typedef struct __attribute__((packed)) { uint32_t eax, ebx, ecx, edx, esi, edi, esp, ebp, eip, eflags, cr3; } Registers; - + typedef struct Task { - Registers registers; // the register states for the task - struct Task *nextTask; // linked list of tasks that need to be done - void* stack; - Message* message; + Registers registers; + void *stack; + ListElement *messages; } Task; - + extern void initTasking(); -extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir); - +extern void createTask(Task *task, uint32_t mainFunction, uint32_t flags, + uint32_t *pagedir); + extern void yield(); -extern void yields(); // yield, but schedule the currently running task +extern void yields(); extern void switchTask(Registers *old, Registers *new); -extern void schedule(Task* task); // schedule a task to be run in the future +extern void schedule(Task *task); extern void destroyCurrentTask(); -extern void setRunningTask(Task* task); // set the task currently executed -extern void sendMessage(Task* task, Message* message); +extern void setRunningTask(Task *task); +extern void sendMessage(Task *task, Message *message); -extern Message* popMessage(Task* task); +extern Message *popMessage(Task *task); -#endif \ No newline at end of file +extern bool isTaskQueueEmpty(); + +#endif diff --git a/src/kernel/drivers/cpu/cpuid.asm b/src/kernel/drivers/cpu/cpuid.asm index 6be352a..3aed27d 100644 --- a/src/kernel/drivers/cpu/cpuid.asm +++ b/src/kernel/drivers/cpu/cpuid.asm @@ -1,5 +1,6 @@ section .text global getVendorId + getVendorId: mov eax, 0x00 cpuid diff --git a/src/kernel/drivers/interrupts/irqs.asm b/src/kernel/drivers/interrupts/irqs.asm index 3e6670b..3a413ed 100644 --- a/src/kernel/drivers/interrupts/irqs.asm +++ b/src/kernel/drivers/interrupts/irqs.asm @@ -28,6 +28,7 @@ extern handleIRQ irqHandler: + cli pusha push ds push es @@ -49,4 +50,5 @@ pop ds popa add esp, 8 - iret \ No newline at end of file + sti + iret diff --git a/src/kernel/drivers/interrupts/irqs.c b/src/kernel/drivers/interrupts/irqs.c index c7bf183..60d95f8 100644 --- a/src/kernel/drivers/interrupts/irqs.c +++ b/src/kernel/drivers/interrupts/irqs.c @@ -1,9 +1,9 @@ -#include +#include <_stdio.h> #include +#include #include #include #include -#include <_stdio.h> #define OFFSET_1 32 #define OFFSET_2 40 @@ -43,13 +43,13 @@ remapPIC(OFFSET_1, OFFSET_2); } -void* irqHandlers[16]; +void *irqHandlers[16]; -void setIRQHandler(uint8_t irqNumber, void* fun) { +void setIRQHandler(uint8_t irqNumber, void *fun) { irqHandlers[irqNumber] = fun; } -void handleIRQ(regs* registers) { +void handleIRQ(regs *registers) { if (registers->int_no >= OFFSET_2) { outb(0xA0, 0x20); } @@ -60,5 +60,9 @@ handler(); return; } + if (irqNumber == 7 || irqNumber == 2) { + // irq2 should not be fired, irq 7 is a spurious irq + return; + } printf("unhandeled IRQ no. 0x%x was triggered!\n", irqNumber); -} \ No newline at end of file +} diff --git a/src/kernel/drivers/interrupts/timer/timer.c b/src/kernel/drivers/interrupts/timer/timer.c index b9ba3af..267077e 100644 --- a/src/kernel/drivers/interrupts/timer/timer.c +++ b/src/kernel/drivers/interrupts/timer/timer.c @@ -1,10 +1,9 @@ -#include #include <_stdio.h> #include -#include -#include #include - +#include +#include +#include #define PIT_A 0x40 #define PIT_CONTROL 0x43 @@ -28,24 +27,25 @@ #define CMD_COUNTER2 0x80 void setTimerFreq(uint32_t hz) { - int divisor = PIT_SCALE / hz; - outb(PIT_CONTROL, CMD_BINARY | CMD_MODE3 | CMD_RW_BOTH | CMD_COUNTER0); - outb(PIT_A, (uint8_t) divisor); - outb(PIT_A, (uint8_t) (divisor >> 8)); + int divisor = PIT_SCALE / hz; + outb(PIT_CONTROL, CMD_BINARY | CMD_MODE3 | CMD_RW_BOTH | CMD_COUNTER0); + outb(PIT_A, (uint8_t)divisor); + outb(PIT_A, (uint8_t)(divisor >> 8)); } uint32_t timerMillis = 0; +uint32_t time = 0; + void timerHandler() { - timerMillis++; - if (timerMillis % 1000 == 0) { - // printf("second\n"); - // yields(); - } + timerMillis++; + if (timerMillis % 1000 == 0) { + printf("\e[s\e[Htime since power on :0x%x seconds\e[u", ++time); + } } void setupTimer() { - printf("setting timer frequency to 1kHz\n"); - setTimerFreq(1000); - setIRQHandler(0, &timerHandler); + printf("setting timer frequency to 1kHz\n"); + setTimerFreq(1000); + setIRQHandler(0, &timerHandler); } diff --git a/src/kernel/drivers/textMode/_stdio.c b/src/kernel/drivers/textMode/_stdio.c index ced3147..b0e2cce 100644 --- a/src/kernel/drivers/textMode/_stdio.c +++ b/src/kernel/drivers/textMode/_stdio.c @@ -111,11 +111,10 @@ va_end(valist); Message *message = malloc(sizeof(Message)); - message->data = data; message->size = size; - message->next = 0x00; - sendMessage(getPrinterTask(), message); + message->type = -1; + listAdd(&getPrinterTask()->messages, message); schedule(getPrinterTask()); } diff --git a/src/kernel/drivers/textMode/terminal.c b/src/kernel/drivers/textMode/terminal.c index ecd58b0..20800e6 100644 --- a/src/kernel/drivers/textMode/terminal.c +++ b/src/kernel/drivers/textMode/terminal.c @@ -76,6 +76,8 @@ uint32_t *currentBuffer = &ansiEscapeBuffer1; +uint32_t savedCursor = 0; + #define addBuffer(i) \ case i + '0': \ *currentBuffer *= 10; \ @@ -170,6 +172,15 @@ setCursorOffset(cursorOffset); currentState = STANDARD; return; + case 's': + savedCursor = cursorOffset; + currentState = STANDARD; + return; + case 'u': + cursorOffset = savedCursor; + setCursorOffset(cursorOffset); + currentState = STANDARD; + return; } } } diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index bd0f8db..6835a28 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -21,7 +21,7 @@ printf("cpu data:\n"); printCPUData(); while (1) { - if (getCurrentTask()->nextTask == 0) { + if (isTaskQueueEmpty()) { asm volatile("hlt"); } yields(); diff --git a/src/kernel/task/osTasks.c b/src/kernel/task/osTasks.c index dfa6988..da46b2e 100644 --- a/src/kernel/task/osTasks.c +++ b/src/kernel/task/osTasks.c @@ -7,10 +7,11 @@ Task mainTask; Task printerTask; +Task *keyboardConsumer = &mainTask; void printLoop() { while (1) { - Message *message = popMessage(&printerTask); + Message *message = popBeginning(&printerTask.messages); if (message == 0) { yield(); continue; @@ -25,6 +26,7 @@ void initOSTasks() { setRunningTask(&mainTask); + keyboardConsumer = &mainTask; createTask(&printerTask, (uint32_t)printLoop, 0x0, 0x0); schedule(&printerTask); // more tasks . . . @@ -32,3 +34,4 @@ } inline Task *getPrinterTask() { return &printerTask; } +inline Task *getKeyboardConsumer() { return keyboardConsumer; } diff --git a/src/kernel/task/task.c b/src/kernel/task/task.c index 3964e7c..de1f096 100644 --- a/src/kernel/task/task.c +++ b/src/kernel/task/task.c @@ -1,13 +1,16 @@ -#include -#include #include <_stdio.h> +#include +#include +#include #define STACK_SIZE 0x100000 Task *currentTask; +ListElement *scheduledTasks = NULL; -void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir) { - void* stack = mallocTask(STACK_SIZE, task); +void createTask(Task *task, uint32_t mainFunction, uint32_t flags, + uint32_t *pagedir) { + void *stack = mallocTask(STACK_SIZE, task); task->registers.eax = 0; task->registers.ebx = 0; task->registers.ecx = 0; @@ -16,76 +19,37 @@ task->registers.edi = 0; task->registers.eflags = flags; task->registers.eip = mainFunction; - task->registers.cr3 = (uint32_t) pagedir; - task->registers.esp = STACK_SIZE + (uint32_t) stack; - task->nextTask = 0; + task->registers.cr3 = (uint32_t)pagedir; + task->registers.esp = STACK_SIZE + (uint32_t)stack; task->stack = stack; + task->messages = NULL; } void yield() { - Task* last = currentTask; - currentTask = last->nextTask; - if (currentTask == 0x00) { - while (1); + Task *last = currentTask; + currentTask = popBeginning(&scheduledTasks); + if (currentTask == NULL) { + while (1) + ; return; } - last->nextTask = 0x00; switchTask(&(last->registers), &(currentTask->registers)); } -void schedule(Task* task) { - Task* test = currentTask; - if (currentTask == 0x00) { - currentTask = task; - currentTask->nextTask = 0x00; - return; - } - while (test->nextTask != 0x0) { - if (test->nextTask == task) { - return; // don't schedule if the task is already in the queue - } - test = test->nextTask; - } - if (test->nextTask == task) { - return; - } - test->nextTask = task; -} - -void setRunningTask(Task* task) { - currentTask = task; -} - -void yields() { +inline void yields() { schedule(currentTask); yield(); } -void destroyCurrentTask() { +inline void destroyCurrentTask() { freeTaskAllocations(currentTask); yield(); } -Task* getCurrentTask() { - return currentTask; -} +inline Task *getCurrentTask() { return currentTask; } -void sendMessage(Task* task, Message* message) { - Message* currentMessage = task->message; - if (currentMessage == 0) { - task->message = message; - return; - } - while (currentMessage->next != 0) { - currentMessage = currentMessage->next; - } - currentMessage->next = message; -} +inline void schedule(Task *task) { listAddSet(&scheduledTasks, task); } -Message* popMessage(Task* task) { - Message* currentMessage = task->message; - if (currentMessage != 0) { - task->message = currentMessage->next; - } - return currentMessage; -} \ No newline at end of file +inline void setRunningTask(Task *task) { currentTask = task; } + +inline bool isTaskQueueEmpty() { return scheduledTasks == NULL; } diff --git a/src/kernel/util/list.c b/src/kernel/util/list.c new file mode 100644 index 0000000..b14b60c --- /dev/null +++ b/src/kernel/util/list.c @@ -0,0 +1,66 @@ +#include +#include + +void listAdd(ListElement **list, void *data) { + ListElement *element = *list; + if (element == NULL) { + *list = malloc(sizeof(ListElement)); + element = *list; + element->next = NULL; + } else { + for (; element->next; element = element->next) { + } + element->next = malloc(sizeof(ListElement)); + element = element->next; + } + element->data = data; +} + +void listAddSet(ListElement **list, void *data) { + ListElement *element = *list; + if (element == NULL) { + *list = malloc(sizeof(ListElement)); + element = *list; + element->next = NULL; + } else { + for (; element->next; element = element->next) { + if (element->data == data) { + return; + } + } + element->next = malloc(sizeof(ListElement)); + element = element->next; + element->next = NULL; + } + element->data = data; +} + +void *popBeginning(ListElement **list) { + if (*list == NULL) { + return NULL; + } + ListElement *element = *list; + void *result = (*list)->data; + *list = (*list)->next; + free(element); + return result; +} + +void *popEnd(ListElement **list) { + if (list == NULL) { + return NULL; + } + ListElement *before = NULL; + ListElement *current = *list; + for (; current->next; current = current->next) { + before = current; + } + void *result = current->data; + free(current); + if (before != NULL) { + before->next = NULL; + } else { + *list = NULL; + } + return result; +} diff --git a/src/kernel/util/tree-os.c b/src/kernel/util/tree-os.c index 94327b4..f2ada34 100644 --- a/src/kernel/util/tree-os.c +++ b/src/kernel/util/tree-os.c @@ -2,7 +2,7 @@ #include #include -const char *logo = "\ +const char *logo = "\n\ _______ \n\ |__ __| \n\ | |_ __ ___ ___ ___ ___ \n\