diff --git a/src/include/cpuid.h b/src/include/cpuid.h new file mode 100644 index 0000000..600d06e --- /dev/null +++ b/src/include/cpuid.h @@ -0,0 +1,6 @@ +#ifndef CPUID_H +#define CPUID_H + +extern void printCPUData(); + +#endif diff --git a/src/include/cpuid.h b/src/include/cpuid.h new file mode 100644 index 0000000..600d06e --- /dev/null +++ b/src/include/cpuid.h @@ -0,0 +1,6 @@ +#ifndef CPUID_H +#define CPUID_H + +extern void printCPUData(); + +#endif diff --git a/src/include/interrupts.h b/src/include/interrupts.h index f8ed10a..db0bc6c 100644 --- a/src/include/interrupts.h +++ b/src/include/interrupts.h @@ -4,16 +4,16 @@ #include typedef struct { - uint16_t isr_low; - uint16_t codeSegment; - uint8_t reserved; - uint8_t attributes; - uint16_t isr_high; + uint16_t isr_low; + uint16_t codeSegment; + uint8_t reserved; + uint8_t attributes; + uint16_t isr_high; } __attribute__((packed)) IDTEntry; typedef struct { - uint16_t limit; - uint32_t base; + uint16_t limit; + uint32_t base; } __attribute__((packed)) IDTR; typedef struct { @@ -23,7 +23,7 @@ unsigned int eip, cs, eflags, useresp, ss; } __attribute__((packed)) regs; -extern void initInterrupts(); -extern void setInterrupt(uint8_t vector, void* callback); +extern void setupInterrupts(); +extern void setInterrupt(uint8_t vector, void *callback); -#endif \ No newline at end of file +#endif diff --git a/src/include/cpuid.h b/src/include/cpuid.h new file mode 100644 index 0000000..600d06e --- /dev/null +++ b/src/include/cpuid.h @@ -0,0 +1,6 @@ +#ifndef CPUID_H +#define CPUID_H + +extern void printCPUData(); + +#endif diff --git a/src/include/interrupts.h b/src/include/interrupts.h index f8ed10a..db0bc6c 100644 --- a/src/include/interrupts.h +++ b/src/include/interrupts.h @@ -4,16 +4,16 @@ #include typedef struct { - uint16_t isr_low; - uint16_t codeSegment; - uint8_t reserved; - uint8_t attributes; - uint16_t isr_high; + uint16_t isr_low; + uint16_t codeSegment; + uint8_t reserved; + uint8_t attributes; + uint16_t isr_high; } __attribute__((packed)) IDTEntry; typedef struct { - uint16_t limit; - uint32_t base; + uint16_t limit; + uint32_t base; } __attribute__((packed)) IDTR; typedef struct { @@ -23,7 +23,7 @@ unsigned int eip, cs, eflags, useresp, ss; } __attribute__((packed)) regs; -extern void initInterrupts(); -extern void setInterrupt(uint8_t vector, void* callback); +extern void setupInterrupts(); +extern void setInterrupt(uint8_t vector, void *callback); -#endif \ No newline at end of file +#endif diff --git a/src/include/util.h b/src/include/util.h new file mode 100644 index 0000000..9a7c7aa --- /dev/null +++ b/src/include/util.h @@ -0,0 +1,6 @@ +#ifndef UTIL_H +#define UTIL_H + +#define max(x, y) (x > y ? (x) : (y)) + +#endif diff --git a/src/include/cpuid.h b/src/include/cpuid.h new file mode 100644 index 0000000..600d06e --- /dev/null +++ b/src/include/cpuid.h @@ -0,0 +1,6 @@ +#ifndef CPUID_H +#define CPUID_H + +extern void printCPUData(); + +#endif diff --git a/src/include/interrupts.h b/src/include/interrupts.h index f8ed10a..db0bc6c 100644 --- a/src/include/interrupts.h +++ b/src/include/interrupts.h @@ -4,16 +4,16 @@ #include typedef struct { - uint16_t isr_low; - uint16_t codeSegment; - uint8_t reserved; - uint8_t attributes; - uint16_t isr_high; + uint16_t isr_low; + uint16_t codeSegment; + uint8_t reserved; + uint8_t attributes; + uint16_t isr_high; } __attribute__((packed)) IDTEntry; typedef struct { - uint16_t limit; - uint32_t base; + uint16_t limit; + uint32_t base; } __attribute__((packed)) IDTR; typedef struct { @@ -23,7 +23,7 @@ unsigned int eip, cs, eflags, useresp, ss; } __attribute__((packed)) regs; -extern void initInterrupts(); -extern void setInterrupt(uint8_t vector, void* callback); +extern void setupInterrupts(); +extern void setInterrupt(uint8_t vector, void *callback); -#endif \ No newline at end of file +#endif diff --git a/src/include/util.h b/src/include/util.h new file mode 100644 index 0000000..9a7c7aa --- /dev/null +++ b/src/include/util.h @@ -0,0 +1,6 @@ +#ifndef UTIL_H +#define UTIL_H + +#define max(x, y) (x > y ? (x) : (y)) + +#endif diff --git a/src/kernel/drivers/cpu/cpuid.asm b/src/kernel/drivers/cpu/cpuid.asm new file mode 100644 index 0000000..6be352a --- /dev/null +++ b/src/kernel/drivers/cpu/cpuid.asm @@ -0,0 +1,11 @@ +section .text +global getVendorId +getVendorId: + mov eax, 0x00 + cpuid + mov eax, esp + mov eax, [eax+4] + mov [eax], ebx + mov [eax+8], ecx + mov [eax+4], edx + ret diff --git a/src/include/cpuid.h b/src/include/cpuid.h new file mode 100644 index 0000000..600d06e --- /dev/null +++ b/src/include/cpuid.h @@ -0,0 +1,6 @@ +#ifndef CPUID_H +#define CPUID_H + +extern void printCPUData(); + +#endif diff --git a/src/include/interrupts.h b/src/include/interrupts.h index f8ed10a..db0bc6c 100644 --- a/src/include/interrupts.h +++ b/src/include/interrupts.h @@ -4,16 +4,16 @@ #include typedef struct { - uint16_t isr_low; - uint16_t codeSegment; - uint8_t reserved; - uint8_t attributes; - uint16_t isr_high; + uint16_t isr_low; + uint16_t codeSegment; + uint8_t reserved; + uint8_t attributes; + uint16_t isr_high; } __attribute__((packed)) IDTEntry; typedef struct { - uint16_t limit; - uint32_t base; + uint16_t limit; + uint32_t base; } __attribute__((packed)) IDTR; typedef struct { @@ -23,7 +23,7 @@ unsigned int eip, cs, eflags, useresp, ss; } __attribute__((packed)) regs; -extern void initInterrupts(); -extern void setInterrupt(uint8_t vector, void* callback); +extern void setupInterrupts(); +extern void setInterrupt(uint8_t vector, void *callback); -#endif \ No newline at end of file +#endif diff --git a/src/include/util.h b/src/include/util.h new file mode 100644 index 0000000..9a7c7aa --- /dev/null +++ b/src/include/util.h @@ -0,0 +1,6 @@ +#ifndef UTIL_H +#define UTIL_H + +#define max(x, y) (x > y ? (x) : (y)) + +#endif diff --git a/src/kernel/drivers/cpu/cpuid.asm b/src/kernel/drivers/cpu/cpuid.asm new file mode 100644 index 0000000..6be352a --- /dev/null +++ b/src/kernel/drivers/cpu/cpuid.asm @@ -0,0 +1,11 @@ +section .text +global getVendorId +getVendorId: + mov eax, 0x00 + cpuid + mov eax, esp + mov eax, [eax+4] + mov [eax], ebx + mov [eax+8], ecx + mov [eax+4], edx + ret diff --git a/src/kernel/drivers/cpu/cpuid.c b/src/kernel/drivers/cpu/cpuid.c new file mode 100644 index 0000000..2ab6e70 --- /dev/null +++ b/src/kernel/drivers/cpu/cpuid.c @@ -0,0 +1,14 @@ +#include <_stdio.h> +#include +#include + +extern void getVendorId(char *string); + +void printCPUData() { + char *vendorID = malloc(13 * sizeof(char)); + vendorID[12] = 0x00; + getVendorId(vendorID); + printf("vendor id: %s\n", vendorID); + free(vendorID); + yields(); +} diff --git a/src/include/cpuid.h b/src/include/cpuid.h new file mode 100644 index 0000000..600d06e --- /dev/null +++ b/src/include/cpuid.h @@ -0,0 +1,6 @@ +#ifndef CPUID_H +#define CPUID_H + +extern void printCPUData(); + +#endif diff --git a/src/include/interrupts.h b/src/include/interrupts.h index f8ed10a..db0bc6c 100644 --- a/src/include/interrupts.h +++ b/src/include/interrupts.h @@ -4,16 +4,16 @@ #include typedef struct { - uint16_t isr_low; - uint16_t codeSegment; - uint8_t reserved; - uint8_t attributes; - uint16_t isr_high; + uint16_t isr_low; + uint16_t codeSegment; + uint8_t reserved; + uint8_t attributes; + uint16_t isr_high; } __attribute__((packed)) IDTEntry; typedef struct { - uint16_t limit; - uint32_t base; + uint16_t limit; + uint32_t base; } __attribute__((packed)) IDTR; typedef struct { @@ -23,7 +23,7 @@ unsigned int eip, cs, eflags, useresp, ss; } __attribute__((packed)) regs; -extern void initInterrupts(); -extern void setInterrupt(uint8_t vector, void* callback); +extern void setupInterrupts(); +extern void setInterrupt(uint8_t vector, void *callback); -#endif \ No newline at end of file +#endif diff --git a/src/include/util.h b/src/include/util.h new file mode 100644 index 0000000..9a7c7aa --- /dev/null +++ b/src/include/util.h @@ -0,0 +1,6 @@ +#ifndef UTIL_H +#define UTIL_H + +#define max(x, y) (x > y ? (x) : (y)) + +#endif diff --git a/src/kernel/drivers/cpu/cpuid.asm b/src/kernel/drivers/cpu/cpuid.asm new file mode 100644 index 0000000..6be352a --- /dev/null +++ b/src/kernel/drivers/cpu/cpuid.asm @@ -0,0 +1,11 @@ +section .text +global getVendorId +getVendorId: + mov eax, 0x00 + cpuid + mov eax, esp + mov eax, [eax+4] + mov [eax], ebx + mov [eax+8], ecx + mov [eax+4], edx + ret diff --git a/src/kernel/drivers/cpu/cpuid.c b/src/kernel/drivers/cpu/cpuid.c new file mode 100644 index 0000000..2ab6e70 --- /dev/null +++ b/src/kernel/drivers/cpu/cpuid.c @@ -0,0 +1,14 @@ +#include <_stdio.h> +#include +#include + +extern void getVendorId(char *string); + +void printCPUData() { + char *vendorID = malloc(13 * sizeof(char)); + vendorID[12] = 0x00; + getVendorId(vendorID); + printf("vendor id: %s\n", vendorID); + free(vendorID); + yields(); +} diff --git a/src/kernel/drivers/interrupts/interrupts.c b/src/kernel/drivers/interrupts/interrupts.c index 7c2f4b8..f9959de 100644 --- a/src/kernel/drivers/interrupts/interrupts.c +++ b/src/kernel/drivers/interrupts/interrupts.c @@ -1,33 +1,32 @@ -#include #include <_stdio.h> #include +#include +#include +#include #include #include #include -#include -#include IDTR idtr; -IDTEntry* entries; -void* buffer; +IDTEntry *entries; +void *buffer; -void setInterrupt(uint8_t vector, void* callback) { - IDTEntry* descriptor = &entries[vector]; - descriptor->isr_low = (uint32_t)callback & 0xFFFF; - descriptor->codeSegment = 0x08; - descriptor->attributes = 0x8E; - descriptor->isr_high = (uint32_t)callback >> 16; - descriptor->reserved = 0; +void setInterrupt(uint8_t vector, void *callback) { + IDTEntry *descriptor = &entries[vector]; + descriptor->isr_low = (uint32_t)callback & 0xFFFF; + descriptor->codeSegment = 0x08; + descriptor->attributes = 0x8E; + descriptor->isr_high = (uint32_t)callback >> 16; + descriptor->reserved = 0; } - -void initInterrupts() { +void setupInterrupts() { buffer = malloc(sizeof(IDTEntry) * 257); - entries = (IDTEntry*) (((int) buffer + sizeof(IDTEntry) >> 3) << 3); + entries = (IDTEntry *)(((int)buffer + sizeof(IDTEntry) >> 3) << 3); idtr.limit = sizeof(IDTEntry) * 256 - 1; - idtr.base = (uint32_t) entries; + idtr.base = (uint32_t)entries; setupExceptions(); setupIRQs(); - __asm__ volatile ("lidt %0" : : "memory"(idtr)); - __asm__ volatile ("sti"); -} \ No newline at end of file + __asm__ volatile("lidt %0" : : "memory"(idtr)); + __asm__ volatile("sti"); +} diff --git a/src/include/cpuid.h b/src/include/cpuid.h new file mode 100644 index 0000000..600d06e --- /dev/null +++ b/src/include/cpuid.h @@ -0,0 +1,6 @@ +#ifndef CPUID_H +#define CPUID_H + +extern void printCPUData(); + +#endif diff --git a/src/include/interrupts.h b/src/include/interrupts.h index f8ed10a..db0bc6c 100644 --- a/src/include/interrupts.h +++ b/src/include/interrupts.h @@ -4,16 +4,16 @@ #include typedef struct { - uint16_t isr_low; - uint16_t codeSegment; - uint8_t reserved; - uint8_t attributes; - uint16_t isr_high; + uint16_t isr_low; + uint16_t codeSegment; + uint8_t reserved; + uint8_t attributes; + uint16_t isr_high; } __attribute__((packed)) IDTEntry; typedef struct { - uint16_t limit; - uint32_t base; + uint16_t limit; + uint32_t base; } __attribute__((packed)) IDTR; typedef struct { @@ -23,7 +23,7 @@ unsigned int eip, cs, eflags, useresp, ss; } __attribute__((packed)) regs; -extern void initInterrupts(); -extern void setInterrupt(uint8_t vector, void* callback); +extern void setupInterrupts(); +extern void setInterrupt(uint8_t vector, void *callback); -#endif \ No newline at end of file +#endif diff --git a/src/include/util.h b/src/include/util.h new file mode 100644 index 0000000..9a7c7aa --- /dev/null +++ b/src/include/util.h @@ -0,0 +1,6 @@ +#ifndef UTIL_H +#define UTIL_H + +#define max(x, y) (x > y ? (x) : (y)) + +#endif diff --git a/src/kernel/drivers/cpu/cpuid.asm b/src/kernel/drivers/cpu/cpuid.asm new file mode 100644 index 0000000..6be352a --- /dev/null +++ b/src/kernel/drivers/cpu/cpuid.asm @@ -0,0 +1,11 @@ +section .text +global getVendorId +getVendorId: + mov eax, 0x00 + cpuid + mov eax, esp + mov eax, [eax+4] + mov [eax], ebx + mov [eax+8], ecx + mov [eax+4], edx + ret diff --git a/src/kernel/drivers/cpu/cpuid.c b/src/kernel/drivers/cpu/cpuid.c new file mode 100644 index 0000000..2ab6e70 --- /dev/null +++ b/src/kernel/drivers/cpu/cpuid.c @@ -0,0 +1,14 @@ +#include <_stdio.h> +#include +#include + +extern void getVendorId(char *string); + +void printCPUData() { + char *vendorID = malloc(13 * sizeof(char)); + vendorID[12] = 0x00; + getVendorId(vendorID); + printf("vendor id: %s\n", vendorID); + free(vendorID); + yields(); +} diff --git a/src/kernel/drivers/interrupts/interrupts.c b/src/kernel/drivers/interrupts/interrupts.c index 7c2f4b8..f9959de 100644 --- a/src/kernel/drivers/interrupts/interrupts.c +++ b/src/kernel/drivers/interrupts/interrupts.c @@ -1,33 +1,32 @@ -#include #include <_stdio.h> #include +#include +#include +#include #include #include #include -#include -#include IDTR idtr; -IDTEntry* entries; -void* buffer; +IDTEntry *entries; +void *buffer; -void setInterrupt(uint8_t vector, void* callback) { - IDTEntry* descriptor = &entries[vector]; - descriptor->isr_low = (uint32_t)callback & 0xFFFF; - descriptor->codeSegment = 0x08; - descriptor->attributes = 0x8E; - descriptor->isr_high = (uint32_t)callback >> 16; - descriptor->reserved = 0; +void setInterrupt(uint8_t vector, void *callback) { + IDTEntry *descriptor = &entries[vector]; + descriptor->isr_low = (uint32_t)callback & 0xFFFF; + descriptor->codeSegment = 0x08; + descriptor->attributes = 0x8E; + descriptor->isr_high = (uint32_t)callback >> 16; + descriptor->reserved = 0; } - -void initInterrupts() { +void setupInterrupts() { buffer = malloc(sizeof(IDTEntry) * 257); - entries = (IDTEntry*) (((int) buffer + sizeof(IDTEntry) >> 3) << 3); + entries = (IDTEntry *)(((int)buffer + sizeof(IDTEntry) >> 3) << 3); idtr.limit = sizeof(IDTEntry) * 256 - 1; - idtr.base = (uint32_t) entries; + idtr.base = (uint32_t)entries; setupExceptions(); setupIRQs(); - __asm__ volatile ("lidt %0" : : "memory"(idtr)); - __asm__ volatile ("sti"); -} \ No newline at end of file + __asm__ volatile("lidt %0" : : "memory"(idtr)); + __asm__ volatile("sti"); +} diff --git a/src/kernel/drivers/interrupts/keyboard/keyboard.c b/src/kernel/drivers/interrupts/keyboard/keyboard.c index 8c199d3..01d381b 100644 --- a/src/kernel/drivers/interrupts/keyboard/keyboard.c +++ b/src/kernel/drivers/interrupts/keyboard/keyboard.c @@ -8,6 +8,15 @@ uint64_t pressedKeys1 = 0; uint64_t pressedKeys2 = 0; +enum { + MODIFIER_LEFT_SHIFT = 0x01 << 0, + MODIFIER_RIGHT_SHIFT = 0x01 << 1, + MODIFIER_LEFT_CONTROL = 0x01 << 2, + MODIFIER_RIGHT_CONTROL = 0x01 << 3 +}; + +const char modifierScancodes[] = {0x2A, 0x36, 0x1D, 0x9D}; + unsigned char keycodes[128] = { 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', @@ -25,6 +34,17 @@ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +const char capitalKeycodes[128] = { + 0, 27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', + '+', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', + '{', '}', '\n', 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', + ':', '\"', '~', 0, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', + '>', '?', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0, 0, + '+', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +uint8_t modifiers = 0; + uint8_t getScancode() { int_fast16_t scancode = -1; for (uint16_t i = 0; i < 1000; i++) { @@ -38,8 +58,14 @@ } void keyboardHandler() { - int_fast16_t scancode = getScancode(); - if (scancode < 0) { + uint8_t scancode = getScancode(); + if (scancode & 0x80) { + scancode = scancode & 0x7F; + for (uint8_t i = 0; i < sizeof(modifierScancodes); i++) { + if (scancode == modifierScancodes[i]) { + modifiers = modifiers & (0xFF ^ 0x01 << i); + } + } return; } if (scancode == 0xE0) { @@ -56,7 +82,18 @@ return; } if (!(scancode & 0x80)) { - printf("%c", keycodes[scancode]); + for (uint8_t i = 0; i < sizeof(modifierScancodes); i++) { + if (scancode == modifierScancodes[i]) { + modifiers = modifiers | 0x01 << i; + return; + } + } + if (modifiers & MODIFIER_LEFT_SHIFT || + modifiers & MODIFIER_RIGHT_SHIFT) { + printf("%c", capitalKeycodes[scancode]); + } else { + printf("%c", keycodes[scancode]); + } } } diff --git a/src/include/cpuid.h b/src/include/cpuid.h new file mode 100644 index 0000000..600d06e --- /dev/null +++ b/src/include/cpuid.h @@ -0,0 +1,6 @@ +#ifndef CPUID_H +#define CPUID_H + +extern void printCPUData(); + +#endif diff --git a/src/include/interrupts.h b/src/include/interrupts.h index f8ed10a..db0bc6c 100644 --- a/src/include/interrupts.h +++ b/src/include/interrupts.h @@ -4,16 +4,16 @@ #include typedef struct { - uint16_t isr_low; - uint16_t codeSegment; - uint8_t reserved; - uint8_t attributes; - uint16_t isr_high; + uint16_t isr_low; + uint16_t codeSegment; + uint8_t reserved; + uint8_t attributes; + uint16_t isr_high; } __attribute__((packed)) IDTEntry; typedef struct { - uint16_t limit; - uint32_t base; + uint16_t limit; + uint32_t base; } __attribute__((packed)) IDTR; typedef struct { @@ -23,7 +23,7 @@ unsigned int eip, cs, eflags, useresp, ss; } __attribute__((packed)) regs; -extern void initInterrupts(); -extern void setInterrupt(uint8_t vector, void* callback); +extern void setupInterrupts(); +extern void setInterrupt(uint8_t vector, void *callback); -#endif \ No newline at end of file +#endif diff --git a/src/include/util.h b/src/include/util.h new file mode 100644 index 0000000..9a7c7aa --- /dev/null +++ b/src/include/util.h @@ -0,0 +1,6 @@ +#ifndef UTIL_H +#define UTIL_H + +#define max(x, y) (x > y ? (x) : (y)) + +#endif diff --git a/src/kernel/drivers/cpu/cpuid.asm b/src/kernel/drivers/cpu/cpuid.asm new file mode 100644 index 0000000..6be352a --- /dev/null +++ b/src/kernel/drivers/cpu/cpuid.asm @@ -0,0 +1,11 @@ +section .text +global getVendorId +getVendorId: + mov eax, 0x00 + cpuid + mov eax, esp + mov eax, [eax+4] + mov [eax], ebx + mov [eax+8], ecx + mov [eax+4], edx + ret diff --git a/src/kernel/drivers/cpu/cpuid.c b/src/kernel/drivers/cpu/cpuid.c new file mode 100644 index 0000000..2ab6e70 --- /dev/null +++ b/src/kernel/drivers/cpu/cpuid.c @@ -0,0 +1,14 @@ +#include <_stdio.h> +#include +#include + +extern void getVendorId(char *string); + +void printCPUData() { + char *vendorID = malloc(13 * sizeof(char)); + vendorID[12] = 0x00; + getVendorId(vendorID); + printf("vendor id: %s\n", vendorID); + free(vendorID); + yields(); +} diff --git a/src/kernel/drivers/interrupts/interrupts.c b/src/kernel/drivers/interrupts/interrupts.c index 7c2f4b8..f9959de 100644 --- a/src/kernel/drivers/interrupts/interrupts.c +++ b/src/kernel/drivers/interrupts/interrupts.c @@ -1,33 +1,32 @@ -#include #include <_stdio.h> #include +#include +#include +#include #include #include #include -#include -#include IDTR idtr; -IDTEntry* entries; -void* buffer; +IDTEntry *entries; +void *buffer; -void setInterrupt(uint8_t vector, void* callback) { - IDTEntry* descriptor = &entries[vector]; - descriptor->isr_low = (uint32_t)callback & 0xFFFF; - descriptor->codeSegment = 0x08; - descriptor->attributes = 0x8E; - descriptor->isr_high = (uint32_t)callback >> 16; - descriptor->reserved = 0; +void setInterrupt(uint8_t vector, void *callback) { + IDTEntry *descriptor = &entries[vector]; + descriptor->isr_low = (uint32_t)callback & 0xFFFF; + descriptor->codeSegment = 0x08; + descriptor->attributes = 0x8E; + descriptor->isr_high = (uint32_t)callback >> 16; + descriptor->reserved = 0; } - -void initInterrupts() { +void setupInterrupts() { buffer = malloc(sizeof(IDTEntry) * 257); - entries = (IDTEntry*) (((int) buffer + sizeof(IDTEntry) >> 3) << 3); + entries = (IDTEntry *)(((int)buffer + sizeof(IDTEntry) >> 3) << 3); idtr.limit = sizeof(IDTEntry) * 256 - 1; - idtr.base = (uint32_t) entries; + idtr.base = (uint32_t)entries; setupExceptions(); setupIRQs(); - __asm__ volatile ("lidt %0" : : "memory"(idtr)); - __asm__ volatile ("sti"); -} \ No newline at end of file + __asm__ volatile("lidt %0" : : "memory"(idtr)); + __asm__ volatile("sti"); +} diff --git a/src/kernel/drivers/interrupts/keyboard/keyboard.c b/src/kernel/drivers/interrupts/keyboard/keyboard.c index 8c199d3..01d381b 100644 --- a/src/kernel/drivers/interrupts/keyboard/keyboard.c +++ b/src/kernel/drivers/interrupts/keyboard/keyboard.c @@ -8,6 +8,15 @@ uint64_t pressedKeys1 = 0; uint64_t pressedKeys2 = 0; +enum { + MODIFIER_LEFT_SHIFT = 0x01 << 0, + MODIFIER_RIGHT_SHIFT = 0x01 << 1, + MODIFIER_LEFT_CONTROL = 0x01 << 2, + MODIFIER_RIGHT_CONTROL = 0x01 << 3 +}; + +const char modifierScancodes[] = {0x2A, 0x36, 0x1D, 0x9D}; + unsigned char keycodes[128] = { 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', @@ -25,6 +34,17 @@ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +const char capitalKeycodes[128] = { + 0, 27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', + '+', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', + '{', '}', '\n', 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', + ':', '\"', '~', 0, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', + '>', '?', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0, 0, + '+', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +uint8_t modifiers = 0; + uint8_t getScancode() { int_fast16_t scancode = -1; for (uint16_t i = 0; i < 1000; i++) { @@ -38,8 +58,14 @@ } void keyboardHandler() { - int_fast16_t scancode = getScancode(); - if (scancode < 0) { + uint8_t scancode = getScancode(); + if (scancode & 0x80) { + scancode = scancode & 0x7F; + for (uint8_t i = 0; i < sizeof(modifierScancodes); i++) { + if (scancode == modifierScancodes[i]) { + modifiers = modifiers & (0xFF ^ 0x01 << i); + } + } return; } if (scancode == 0xE0) { @@ -56,7 +82,18 @@ return; } if (!(scancode & 0x80)) { - printf("%c", keycodes[scancode]); + for (uint8_t i = 0; i < sizeof(modifierScancodes); i++) { + if (scancode == modifierScancodes[i]) { + modifiers = modifiers | 0x01 << i; + return; + } + } + if (modifiers & MODIFIER_LEFT_SHIFT || + modifiers & MODIFIER_RIGHT_SHIFT) { + printf("%c", capitalKeycodes[scancode]); + } else { + printf("%c", keycodes[scancode]); + } } } diff --git a/src/kernel/drivers/textMode/_stdio.c b/src/kernel/drivers/textMode/_stdio.c index 261c3f4..ced3147 100644 --- a/src/kernel/drivers/textMode/_stdio.c +++ b/src/kernel/drivers/textMode/_stdio.c @@ -8,120 +8,121 @@ #include #include #include +#include char HEX_CHARS[] = "0123456789ABCDEF"; void putHex(char **write, uint32_t x) { - if (x == 0) { - **write = HEX_CHARS[x]; - (*write)++; - **write = HEX_CHARS[x]; - (*write)++; - return; - } - bool alreadyWriting = false; - for (int position = 3; position >= 0; position--) { - uint8_t byte = (x >> (position * 8)) & 0xFF; - if (byte != 0x00) { - alreadyWriting = true; + if (x == 0) { + **write = HEX_CHARS[x]; + (*write)++; + **write = HEX_CHARS[x]; + (*write)++; + return; } - if (alreadyWriting) { - **write = HEX_CHARS[byte >> 4]; - (*write)++; - **write = HEX_CHARS[byte & 0x0F]; - (*write)++; + bool alreadyWriting = false; + for (int position = 3; position >= 0; position--) { + uint8_t byte = (x >> (position * 8)) & 0xFF; + if (byte != 0x00 && !alreadyWriting) { + alreadyWriting = true; + } + if (alreadyWriting) { + **write = HEX_CHARS[byte >> 4]; + (*write)++; + **write = HEX_CHARS[byte & 0x0F]; + (*write)++; + } } - } } uint8_t hexLength(uint32_t x) { - bool alreadyWriting = false; - uint8_t size = 0; - for (int position = 3; position >= 0; position--) { - uint8_t byte = (x >> (position * 8)) & 0xFF; - if (byte != 0x00) { - alreadyWriting = true; + bool alreadyWriting = false; + uint8_t size = 0; + for (int position = 3; position >= 0; position--) { + uint8_t byte = (x >> (position * 8)) & 0xFF; + if (byte != 0x00 && !alreadyWriting) { + alreadyWriting = true; + } + if (alreadyWriting) { + size += 2; + } } - if (alreadyWriting) { - size += 2; - } - } - return size; + return max(size, 2); } uint32_t getInsertLength(char insertType, uint32_t x) { - switch (insertType) { - case 's': - return strlen((char *)x); - case 'x': - return hexLength(x); - case 'c': - return 1; - } - return 0; + switch (insertType) { + case 's': + return strlen((char *)x); + case 'x': + return hexLength(x); + case 'c': + return 1; + } + return 0; } void stringInsert(char **write, uint32_t x) { - char *string = (char *)x; - uint32_t length = strlen(string); - for (uint32_t position = 0; position < length; position++) { - **write = string[position]; - (*write)++; - } + char *string = (char *)x; + uint32_t length = strlen(string); + for (uint32_t position = 0; position < length; position++) { + **write = string[position]; + (*write)++; + } } void handleInsert(char **write, char insertType, uint32_t x) { - switch (insertType) { - case 's': - stringInsert(write, x); - return; - case 'x': - putHex(write, x); - return; - case 'c': - **write = x; - return; - } + switch (insertType) { + case 's': + stringInsert(write, x); + return; + case 'x': + putHex(write, x); + return; + case 'c': + **write = x; + return; + } } void printf(const char *format, ...) { - uint32_t size = 0; - va_list valist; - va_start(valist, format); - for (int i = 0; format[i] != 0; i++) { - if (format[i] == '%') { - size += getInsertLength(format[++i], va_arg(valist, uint32_t)); - continue; + uint32_t size = 0; + va_list valist; + va_start(valist, format); + for (int i = 0; format[i] != 0; i++) { + if (format[i] == '%') { + size += getInsertLength(format[++i], va_arg(valist, uint32_t)); + continue; + } + size++; } - size++; - } - va_start(valist, format); + va_start(valist, format); - char *data = malloc(size); - char *write = data; - for (int i = 0; format[i] != 0; i++) { - if (format[i] == '%') { - handleInsert(&write, format[++i], va_arg(valist, uint32_t)); - continue; + char *data = malloc(size); + char *write = data; + for (int i = 0; format[i] != 0; i++) { + if (format[i] == '%') { + handleInsert(&write, format[++i], va_arg(valist, uint32_t)); + continue; + } + *write = format[i]; + write++; } - *write = format[i]; - write++; - } - va_end(valist); + va_end(valist); - Message *message = malloc(sizeof(Message)); + Message *message = malloc(sizeof(Message)); - message->data = data; - message->size = size; - message->next = 0x00; - sendMessage(getPrinterTask(), message); - schedule(getPrinterTask()); + message->data = data; + message->size = size; + message->next = 0x00; + sendMessage(getPrinterTask(), message); + schedule(getPrinterTask()); } uint32_t strlen(char *string) { - uint32_t length = 0; - while (string[length] != 0) { - length++; - } - return length; + uint32_t length = 0; + while (string[length] != 0) { + length++; + } + return length; } diff --git a/src/include/cpuid.h b/src/include/cpuid.h new file mode 100644 index 0000000..600d06e --- /dev/null +++ b/src/include/cpuid.h @@ -0,0 +1,6 @@ +#ifndef CPUID_H +#define CPUID_H + +extern void printCPUData(); + +#endif diff --git a/src/include/interrupts.h b/src/include/interrupts.h index f8ed10a..db0bc6c 100644 --- a/src/include/interrupts.h +++ b/src/include/interrupts.h @@ -4,16 +4,16 @@ #include typedef struct { - uint16_t isr_low; - uint16_t codeSegment; - uint8_t reserved; - uint8_t attributes; - uint16_t isr_high; + uint16_t isr_low; + uint16_t codeSegment; + uint8_t reserved; + uint8_t attributes; + uint16_t isr_high; } __attribute__((packed)) IDTEntry; typedef struct { - uint16_t limit; - uint32_t base; + uint16_t limit; + uint32_t base; } __attribute__((packed)) IDTR; typedef struct { @@ -23,7 +23,7 @@ unsigned int eip, cs, eflags, useresp, ss; } __attribute__((packed)) regs; -extern void initInterrupts(); -extern void setInterrupt(uint8_t vector, void* callback); +extern void setupInterrupts(); +extern void setInterrupt(uint8_t vector, void *callback); -#endif \ No newline at end of file +#endif diff --git a/src/include/util.h b/src/include/util.h new file mode 100644 index 0000000..9a7c7aa --- /dev/null +++ b/src/include/util.h @@ -0,0 +1,6 @@ +#ifndef UTIL_H +#define UTIL_H + +#define max(x, y) (x > y ? (x) : (y)) + +#endif diff --git a/src/kernel/drivers/cpu/cpuid.asm b/src/kernel/drivers/cpu/cpuid.asm new file mode 100644 index 0000000..6be352a --- /dev/null +++ b/src/kernel/drivers/cpu/cpuid.asm @@ -0,0 +1,11 @@ +section .text +global getVendorId +getVendorId: + mov eax, 0x00 + cpuid + mov eax, esp + mov eax, [eax+4] + mov [eax], ebx + mov [eax+8], ecx + mov [eax+4], edx + ret diff --git a/src/kernel/drivers/cpu/cpuid.c b/src/kernel/drivers/cpu/cpuid.c new file mode 100644 index 0000000..2ab6e70 --- /dev/null +++ b/src/kernel/drivers/cpu/cpuid.c @@ -0,0 +1,14 @@ +#include <_stdio.h> +#include +#include + +extern void getVendorId(char *string); + +void printCPUData() { + char *vendorID = malloc(13 * sizeof(char)); + vendorID[12] = 0x00; + getVendorId(vendorID); + printf("vendor id: %s\n", vendorID); + free(vendorID); + yields(); +} diff --git a/src/kernel/drivers/interrupts/interrupts.c b/src/kernel/drivers/interrupts/interrupts.c index 7c2f4b8..f9959de 100644 --- a/src/kernel/drivers/interrupts/interrupts.c +++ b/src/kernel/drivers/interrupts/interrupts.c @@ -1,33 +1,32 @@ -#include #include <_stdio.h> #include +#include +#include +#include #include #include #include -#include -#include IDTR idtr; -IDTEntry* entries; -void* buffer; +IDTEntry *entries; +void *buffer; -void setInterrupt(uint8_t vector, void* callback) { - IDTEntry* descriptor = &entries[vector]; - descriptor->isr_low = (uint32_t)callback & 0xFFFF; - descriptor->codeSegment = 0x08; - descriptor->attributes = 0x8E; - descriptor->isr_high = (uint32_t)callback >> 16; - descriptor->reserved = 0; +void setInterrupt(uint8_t vector, void *callback) { + IDTEntry *descriptor = &entries[vector]; + descriptor->isr_low = (uint32_t)callback & 0xFFFF; + descriptor->codeSegment = 0x08; + descriptor->attributes = 0x8E; + descriptor->isr_high = (uint32_t)callback >> 16; + descriptor->reserved = 0; } - -void initInterrupts() { +void setupInterrupts() { buffer = malloc(sizeof(IDTEntry) * 257); - entries = (IDTEntry*) (((int) buffer + sizeof(IDTEntry) >> 3) << 3); + entries = (IDTEntry *)(((int)buffer + sizeof(IDTEntry) >> 3) << 3); idtr.limit = sizeof(IDTEntry) * 256 - 1; - idtr.base = (uint32_t) entries; + idtr.base = (uint32_t)entries; setupExceptions(); setupIRQs(); - __asm__ volatile ("lidt %0" : : "memory"(idtr)); - __asm__ volatile ("sti"); -} \ No newline at end of file + __asm__ volatile("lidt %0" : : "memory"(idtr)); + __asm__ volatile("sti"); +} diff --git a/src/kernel/drivers/interrupts/keyboard/keyboard.c b/src/kernel/drivers/interrupts/keyboard/keyboard.c index 8c199d3..01d381b 100644 --- a/src/kernel/drivers/interrupts/keyboard/keyboard.c +++ b/src/kernel/drivers/interrupts/keyboard/keyboard.c @@ -8,6 +8,15 @@ uint64_t pressedKeys1 = 0; uint64_t pressedKeys2 = 0; +enum { + MODIFIER_LEFT_SHIFT = 0x01 << 0, + MODIFIER_RIGHT_SHIFT = 0x01 << 1, + MODIFIER_LEFT_CONTROL = 0x01 << 2, + MODIFIER_RIGHT_CONTROL = 0x01 << 3 +}; + +const char modifierScancodes[] = {0x2A, 0x36, 0x1D, 0x9D}; + unsigned char keycodes[128] = { 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', @@ -25,6 +34,17 @@ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +const char capitalKeycodes[128] = { + 0, 27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', + '+', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', + '{', '}', '\n', 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', + ':', '\"', '~', 0, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', + '>', '?', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0, 0, + '+', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +uint8_t modifiers = 0; + uint8_t getScancode() { int_fast16_t scancode = -1; for (uint16_t i = 0; i < 1000; i++) { @@ -38,8 +58,14 @@ } void keyboardHandler() { - int_fast16_t scancode = getScancode(); - if (scancode < 0) { + uint8_t scancode = getScancode(); + if (scancode & 0x80) { + scancode = scancode & 0x7F; + for (uint8_t i = 0; i < sizeof(modifierScancodes); i++) { + if (scancode == modifierScancodes[i]) { + modifiers = modifiers & (0xFF ^ 0x01 << i); + } + } return; } if (scancode == 0xE0) { @@ -56,7 +82,18 @@ return; } if (!(scancode & 0x80)) { - printf("%c", keycodes[scancode]); + for (uint8_t i = 0; i < sizeof(modifierScancodes); i++) { + if (scancode == modifierScancodes[i]) { + modifiers = modifiers | 0x01 << i; + return; + } + } + if (modifiers & MODIFIER_LEFT_SHIFT || + modifiers & MODIFIER_RIGHT_SHIFT) { + printf("%c", capitalKeycodes[scancode]); + } else { + printf("%c", keycodes[scancode]); + } } } diff --git a/src/kernel/drivers/textMode/_stdio.c b/src/kernel/drivers/textMode/_stdio.c index 261c3f4..ced3147 100644 --- a/src/kernel/drivers/textMode/_stdio.c +++ b/src/kernel/drivers/textMode/_stdio.c @@ -8,120 +8,121 @@ #include #include #include +#include char HEX_CHARS[] = "0123456789ABCDEF"; void putHex(char **write, uint32_t x) { - if (x == 0) { - **write = HEX_CHARS[x]; - (*write)++; - **write = HEX_CHARS[x]; - (*write)++; - return; - } - bool alreadyWriting = false; - for (int position = 3; position >= 0; position--) { - uint8_t byte = (x >> (position * 8)) & 0xFF; - if (byte != 0x00) { - alreadyWriting = true; + if (x == 0) { + **write = HEX_CHARS[x]; + (*write)++; + **write = HEX_CHARS[x]; + (*write)++; + return; } - if (alreadyWriting) { - **write = HEX_CHARS[byte >> 4]; - (*write)++; - **write = HEX_CHARS[byte & 0x0F]; - (*write)++; + bool alreadyWriting = false; + for (int position = 3; position >= 0; position--) { + uint8_t byte = (x >> (position * 8)) & 0xFF; + if (byte != 0x00 && !alreadyWriting) { + alreadyWriting = true; + } + if (alreadyWriting) { + **write = HEX_CHARS[byte >> 4]; + (*write)++; + **write = HEX_CHARS[byte & 0x0F]; + (*write)++; + } } - } } uint8_t hexLength(uint32_t x) { - bool alreadyWriting = false; - uint8_t size = 0; - for (int position = 3; position >= 0; position--) { - uint8_t byte = (x >> (position * 8)) & 0xFF; - if (byte != 0x00) { - alreadyWriting = true; + bool alreadyWriting = false; + uint8_t size = 0; + for (int position = 3; position >= 0; position--) { + uint8_t byte = (x >> (position * 8)) & 0xFF; + if (byte != 0x00 && !alreadyWriting) { + alreadyWriting = true; + } + if (alreadyWriting) { + size += 2; + } } - if (alreadyWriting) { - size += 2; - } - } - return size; + return max(size, 2); } uint32_t getInsertLength(char insertType, uint32_t x) { - switch (insertType) { - case 's': - return strlen((char *)x); - case 'x': - return hexLength(x); - case 'c': - return 1; - } - return 0; + switch (insertType) { + case 's': + return strlen((char *)x); + case 'x': + return hexLength(x); + case 'c': + return 1; + } + return 0; } void stringInsert(char **write, uint32_t x) { - char *string = (char *)x; - uint32_t length = strlen(string); - for (uint32_t position = 0; position < length; position++) { - **write = string[position]; - (*write)++; - } + char *string = (char *)x; + uint32_t length = strlen(string); + for (uint32_t position = 0; position < length; position++) { + **write = string[position]; + (*write)++; + } } void handleInsert(char **write, char insertType, uint32_t x) { - switch (insertType) { - case 's': - stringInsert(write, x); - return; - case 'x': - putHex(write, x); - return; - case 'c': - **write = x; - return; - } + switch (insertType) { + case 's': + stringInsert(write, x); + return; + case 'x': + putHex(write, x); + return; + case 'c': + **write = x; + return; + } } void printf(const char *format, ...) { - uint32_t size = 0; - va_list valist; - va_start(valist, format); - for (int i = 0; format[i] != 0; i++) { - if (format[i] == '%') { - size += getInsertLength(format[++i], va_arg(valist, uint32_t)); - continue; + uint32_t size = 0; + va_list valist; + va_start(valist, format); + for (int i = 0; format[i] != 0; i++) { + if (format[i] == '%') { + size += getInsertLength(format[++i], va_arg(valist, uint32_t)); + continue; + } + size++; } - size++; - } - va_start(valist, format); + va_start(valist, format); - char *data = malloc(size); - char *write = data; - for (int i = 0; format[i] != 0; i++) { - if (format[i] == '%') { - handleInsert(&write, format[++i], va_arg(valist, uint32_t)); - continue; + char *data = malloc(size); + char *write = data; + for (int i = 0; format[i] != 0; i++) { + if (format[i] == '%') { + handleInsert(&write, format[++i], va_arg(valist, uint32_t)); + continue; + } + *write = format[i]; + write++; } - *write = format[i]; - write++; - } - va_end(valist); + va_end(valist); - Message *message = malloc(sizeof(Message)); + Message *message = malloc(sizeof(Message)); - message->data = data; - message->size = size; - message->next = 0x00; - sendMessage(getPrinterTask(), message); - schedule(getPrinterTask()); + message->data = data; + message->size = size; + message->next = 0x00; + sendMessage(getPrinterTask(), message); + schedule(getPrinterTask()); } uint32_t strlen(char *string) { - uint32_t length = 0; - while (string[length] != 0) { - length++; - } - return length; + uint32_t length = 0; + while (string[length] != 0) { + length++; + } + return length; } diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index c9b62b9..bd0f8db 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -1,29 +1,29 @@ #include <_stdio.h> #include -#include +#include #include #include -#include #include #include #include -#include #include extern uint32_t _kernel_end; void kernelMain() { - initMemoryAllocation( - 0x1000000); // initializing stacks after the kernel seems not to work :( - // otherwise, _kernel_end should be passed here - initOSTasks(); - drawLogo(); - printf("initializing interrupts\n"); - setupDevices(); - initInterrupts(); - yields(); - while (1) { - asm volatile("hlt"); - yields(); - } + initMemoryAllocation( + 0x1000000); // initializing stacks after the kernel seems not to work :( + // otherwise, _kernel_end should be passed here + initOSTasks(); + drawLogo(); + setupDevices(); + setupInterrupts(); + printf("cpu data:\n"); + printCPUData(); + while (1) { + if (getCurrentTask()->nextTask == 0) { + asm volatile("hlt"); + } + yields(); + } }