summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksa Vučković <aleksav013@gmail.com>2021-10-25 22:41:21 +0200
committerAleksa Vučković <aleksav013@gmail.com>2021-10-25 22:41:21 +0200
commit39822cdb0acdd1eec66c2e18e0711fd3cd6f033d (patch)
tree313eb08002f6e6e1c6564f2d411287745079da22
parent20dd72e40dc2728d3c5335d860e4b8ab8da14fcc (diff)
Adding first 32 IRQs; PIT finally working
-rw-r--r--Makefile6
-rw-r--r--src/as/boot.s12
-rw-r--r--src/as/irq.s273
-rw-r--r--src/c/gdt.c13
-rw-r--r--src/c/idt.c100
-rw-r--r--src/c/irq_handler.c204
-rw-r--r--src/c/kernel.c7
-rw-r--r--src/c/keyboard.c7
-rw-r--r--src/c/stack_protector.c22
-rw-r--r--src/c/timer.c45
-rw-r--r--src/c/tty.c32
-rw-r--r--src/c/vga.c43
-rw-r--r--src/include/heap.h5
-rw-r--r--src/include/irq.h39
-rw-r--r--src/include/vga.h29
15 files changed, 726 insertions, 111 deletions
diff --git a/Makefile b/Makefile
index 7e99767..dd02b46 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ ARCH=i686-elf
export CC=$(ARCH)-gcc
export AS=$(ARCH)-as
-export CFLAGS=-ffreestanding -O2 -Wall -Wextra
+export CFLAGS=-ffreestanding -O2 -Wall -Wextra -fstack-protector-all
MKDIR=mkdir -p
RM=rm -rf
@@ -21,8 +21,8 @@ ISO=$(TARGET).iso
CRTI_SOURCE=crti.s
CRTN_SOURCE=crtn.s
-AS_SOURCE=boot.s
-C_SOURCES=gdt.c heap.c idt.c kernel.c keyboard.c keymap.c stdio.c string.c tty.c vga.c
+AS_SOURCE=boot.s irq.s
+C_SOURCES=gdt.c heap.c idt.c kernel.c keyboard.c keymap.c stdio.c string.c tty.c vga.c irq_handler.c stack_protector.c timer.c
C_SOURCE_FILES=$(patsubst %,$(C_SOURCE_DIR)/%,$(C_SOURCES))
export C_OBJECTS=$(patsubst %,$(BUILD_DIR)/%,$(C_SOURCES:c=o))
diff --git a/src/as/boot.s b/src/as/boot.s
index 6fe5ab8..68e5947 100644
--- a/src/as/boot.s
+++ b/src/as/boot.s
@@ -14,14 +14,9 @@
.global load_gdt
.global load_idt
.global enable_interrupts
-.global keyboard_handler
.global ioport_in
.global ioport_out
-.extern init_gdt_table
-.extern handle_keyboard_interrupt
-.extern kernel_main
-
load_gdt:
movl 4(%esp), %edx
lgdt (%edx)
@@ -33,13 +28,6 @@ load_idt:
sti
ret
-keyboard_handler:
- pushal
- cld
- call handle_keyboard_interrupt
- popal
- iretl
-
ioport_in:
movl 4(%esp),%edx
in %dx,%al
diff --git a/src/as/irq.s b/src/as/irq.s
new file mode 100644
index 0000000..71d578d
--- /dev/null
+++ b/src/as/irq.s
@@ -0,0 +1,273 @@
+.global irq0
+.global irq1
+.global irq2
+.global irq3
+.global irq4
+.global irq5
+.global irq6
+.global irq7
+.global irq8
+.global irq9
+.global irq10
+.global irq11
+.global irq12
+.global irq13
+.global irq14
+.global irq15
+.global irq16
+.global irq17
+.global irq18
+.global irq19
+.global irq20
+.global irq21
+.global irq22
+.global irq23
+.global irq24
+.global irq25
+.global irq26
+.global irq27
+.global irq28
+.global irq29
+.global irq30
+.global irq31
+.global timer_irq
+.global keyboard_irq
+
+
+irq0:
+ pushal
+ cld
+ call irq0_handler
+ popal
+ iretl
+
+irq1:
+ pushal
+ cld
+ call irq1_handler
+ popal
+ iretl
+
+irq2:
+ pushal
+ cld
+ call irq2_handler
+ popal
+ iretl
+
+irq3:
+ pushal
+ cld
+ call irq3_handler
+ popal
+ iretl
+
+irq4:
+ pushal
+ cld
+ call irq4_handler
+ popal
+ iretl
+
+irq5:
+ pushal
+ cld
+ call irq5_handler
+ popal
+ iretl
+
+irq6:
+ pushal
+ cld
+ call irq6_handler
+ popal
+ iretl
+
+irq7:
+ pushal
+ cld
+ call irq7_handler
+ popal
+ iretl
+
+irq8:
+ pushal
+ cld
+ call irq8_handler
+ popal
+ iretl
+
+irq9:
+ pushal
+ cld
+ call irq9_handler
+ popal
+ iretl
+
+irq10:
+ pushal
+ cld
+ call irq10_handler
+ popal
+ iretl
+
+irq11:
+ pushal
+ cld
+ call irq11_handler
+ popal
+ iretl
+
+irq12:
+ pushal
+ cld
+ call irq12_handler
+ popal
+ iretl
+
+irq13:
+ pushal
+ cld
+ call irq13_handler
+ popal
+ iretl
+
+irq14:
+ pushal
+ cld
+ call irq14_handler
+ popal
+ iretl
+
+irq15:
+ pushal
+ cld
+ call irq15_handler
+ popal
+ iretl
+
+irq16:
+ pushal
+ cld
+ call irq16_handler
+ popal
+ iretl
+
+irq17:
+ pushal
+ cld
+ call irq17_handler
+ popal
+ iretl
+
+irq18:
+ pushal
+ cld
+ call irq18_handler
+ popal
+ iretl
+
+irq19:
+ pushal
+ cld
+ call irq19_handler
+ popal
+ iretl
+
+irq20:
+ pushal
+ cld
+ call irq20_handler
+ popal
+ iretl
+
+irq21:
+ pushal
+ cld
+ call irq21_handler
+ popal
+ iretl
+
+irq22:
+ pushal
+ cld
+ call irq22_handler
+ popal
+ iretl
+
+irq23:
+ pushal
+ cld
+ call irq23_handler
+ popal
+ iretl
+
+irq24:
+ pushal
+ cld
+ call irq24_handler
+ popal
+ iretl
+
+irq25:
+ pushal
+ cld
+ call irq25_handler
+ popal
+ iretl
+
+irq26:
+ pushal
+ cld
+ call irq26_handler
+ popal
+ iretl
+
+irq27:
+ pushal
+ cld
+ call irq27_handler
+ popal
+ iretl
+
+irq28:
+ pushal
+ cld
+ call irq28_handler
+ popal
+ iretl
+
+irq29:
+ pushal
+ cld
+ call irq29_handler
+ popal
+ iretl
+
+irq30:
+ pushal
+ cld
+ call irq30_handler
+ popal
+ iretl
+
+irq31:
+ pushal
+ cld
+ call irq31_handler
+ popal
+ iretl
+
+timer_irq:
+ pushal
+ cld
+ call timer_handler
+ popal
+ iretl
+
+keyboard_irq:
+ pushal
+ cld
+ call keyboard_handler
+ popal
+ iretl
diff --git a/src/c/gdt.c b/src/c/gdt.c
index 8fcda3a..32d070b 100644
--- a/src/c/gdt.c
+++ b/src/c/gdt.c
@@ -19,7 +19,7 @@ struct gdt_pointer
// asm function
extern void load_gdt(struct gdt_pointer *gdtp);
-struct gdt_entry gdt[3];
+struct gdt_entry gdt[5];
struct gdt_pointer gdtp;
void init_gdt_entry(size_t num, uint32_t limit, uint32_t base, uint8_t access, uint8_t limit_flags)
@@ -37,12 +37,11 @@ void init_gdt_table()
gdtp.size=sizeof(gdt)-1;
gdtp.offset=(uint32_t)&gdt;
- //null
- init_gdt_entry(0,0,0,0,0);
- //code
- init_gdt_entry(1,0xffffffff,0,0b10011010,0b11001111);
- //data
- init_gdt_entry(2,0xffffffff,0,0b10010010,0b11001111);
+ init_gdt_entry(0,0,0,0,0); // null segment
+ init_gdt_entry(1,0xffffffff,0,0b10011010,0b11001111); // code segment
+ init_gdt_entry(2,0xffffffff,0,0b10010010,0b11001111); // data segment
+ init_gdt_entry(3,0xffffffff,0,0b11111010,0b11001111); // user mode code segment
+ init_gdt_entry(4,0xffffffff,0,0b11110010,0b11001111); // user mode data segment
load_gdt(&gdtp);
}
diff --git a/src/c/idt.c b/src/c/idt.c
index 274db6d..d12015e 100644
--- a/src/c/idt.c
+++ b/src/c/idt.c
@@ -1,6 +1,8 @@
#include"../include/types.h"
+#include"../include/irq.h"
+#include"../include/asm.h"
-#define INTERRUPT_GATE_32 0x8e
+#define INTERRUPT_GATE_32 0x8E
#define KERNEL_CODE 0x08
#define KERNEL_DATA 0x10
@@ -25,10 +27,9 @@ struct idt_pointer
uint32_t offset;
} __attribute__((packed));
-// asm function
+
extern void load_idt(struct idt_pointer *idtp);
-extern void keyboard_handler();
-extern void ioport_out(uint8_t port, char data);
+extern void keyboard_irq();
struct idt_entry idt[256];
struct idt_pointer idtp;
@@ -41,57 +42,64 @@ void init_idt_entry(size_t num, uint32_t offset, uint16_t selector, uint8_t type
idt[num].type_attr=type_attr;
idt[num].offset2=(offset & 0xffff0000)>>16;
}
-
-void init_idt_table()
+void add_idt_entry(size_t num,uint32_t offset)
{
- // Program the PICs - Programmable Interrupt Controllers
- // Background:
- // In modern architectures, the PIC is not a separate chip.
- // It is emulated in the CPU for backwards compatability.
- // The APIC (Advanced Programmable Interrupt Controller)
- // is the new version of the PIC that is integrated into the CPU.
- // Default vector offset for PIC is 8
- // This maps IRQ0 to interrupt 8, IRQ1 to interrupt 9, etc.
- // This is a problem. The CPU reserves the first 32 interrupts for
- // CPU exceptions such as divide by 0, etc.
- // In programming the PICs, we move this offset to 0x2 (32) so that
- // we can handle all interrupts coming to the PICs without overlapping
- // with any CPU exceptions.
+ init_idt_entry(num,offset,KERNEL_CODE,INTERRUPT_GATE_32);
+}
- // Send ICWs - Initialization Command Words
- // PIC1: IO Port 0x20 (command), 0xA0 (data)
- // PIC2: IO Port 0x21 (command), 0xA1 (data)
- // ICW1: Initialization command
- // Send a fixed value of 0x11 to each PIC to tell it to expect ICW2-4
- // Restart PIC1
+void init_pic()
+{
ioport_out(PIC1_COMMAND_PORT, 0x11);
ioport_out(PIC2_COMMAND_PORT, 0x11);
- // ICW2: Vector Offset (this is what we are fixing)
- // Start PIC1 at 32 (0x20 in hex) (IRQ0=0x20, ..., IRQ7=0x27)
- // Start PIC2 right after, at 40 (0x28 in hex)
ioport_out(PIC1_DATA_PORT, 0x20);
ioport_out(PIC2_DATA_PORT, 0x28);
- // ICW3: Cascading (how master/slave PICs are wired/daisy chained)
- // Tell PIC1 there is a slave PIC at IRQ2 (why 4? don't ask me - https://wiki.osdev.org/8259_PIC)
- // Tell PIC2 "its cascade identity" - again, I'm shaky on this concept. More resources in notes
- ioport_out(PIC1_DATA_PORT, 0x0);
- ioport_out(PIC2_DATA_PORT, 0x0);
- // ICW4: "Gives additional information about the environemnt"
- // See notes for some potential values
- // We are using 8086/8088 (MCS-80/85) mode
- // Not sure if that's relevant, but there it is.
- // Other modes appear to be special slave/master configurations (see wiki)
- ioport_out(PIC1_DATA_PORT, 0x1);
- ioport_out(PIC2_DATA_PORT, 0x1);
- // Voila! PICs are initialized
-
- // Mask all interrupts (why? not entirely sure)
- // 0xff is 16 bits that are all 1.
- // This masks each of the 16 interrupts for that PIC.
+ ioport_out(PIC1_DATA_PORT, 0x04);
+ ioport_out(PIC2_DATA_PORT, 0x02);
+ ioport_out(PIC1_DATA_PORT, 0x01);
+ ioport_out(PIC2_DATA_PORT, 0x01);
ioport_out(PIC1_DATA_PORT, 0xff);
ioport_out(PIC2_DATA_PORT, 0xff);
- init_idt_entry(0x21,(uint32_t)keyboard_handler,KERNEL_CODE,INTERRUPT_GATE_32);
+ ioport_out(PIC1_DATA_PORT, 0xFC);
+}
+
+void init_idt_table()
+{
+ init_pic();
+ add_idt_entry(0,(uint32_t)irq0);
+ add_idt_entry(1,(uint32_t)irq1);
+ add_idt_entry(2,(uint32_t)irq2);
+ add_idt_entry(3,(uint32_t)irq3);
+ add_idt_entry(4,(uint32_t)irq4);
+ add_idt_entry(5,(uint32_t)irq5);
+ add_idt_entry(6,(uint32_t)irq6);
+ add_idt_entry(7,(uint32_t)irq7);
+ add_idt_entry(8,(uint32_t)irq8);
+ add_idt_entry(9,(uint32_t)irq9);
+ add_idt_entry(10,(uint32_t)irq10);
+ add_idt_entry(11,(uint32_t)irq11);
+ add_idt_entry(12,(uint32_t)irq12);
+ add_idt_entry(13,(uint32_t)irq13);
+ add_idt_entry(14,(uint32_t)irq14);
+ add_idt_entry(15,(uint32_t)irq15);
+ add_idt_entry(16,(uint32_t)irq16);
+ add_idt_entry(17,(uint32_t)irq17);
+ add_idt_entry(18,(uint32_t)irq18);
+ add_idt_entry(19,(uint32_t)irq19);
+ add_idt_entry(20,(uint32_t)irq20);
+ add_idt_entry(21,(uint32_t)irq21);
+ add_idt_entry(22,(uint32_t)irq22);
+ add_idt_entry(23,(uint32_t)irq23);
+ add_idt_entry(24,(uint32_t)irq24);
+ add_idt_entry(25,(uint32_t)irq25);
+ add_idt_entry(26,(uint32_t)irq26);
+ add_idt_entry(27,(uint32_t)irq27);
+ add_idt_entry(28,(uint32_t)irq28);
+ add_idt_entry(29,(uint32_t)irq29);
+ add_idt_entry(30,(uint32_t)irq30);
+ add_idt_entry(31,(uint32_t)irq31);
+ add_idt_entry(32,(uint32_t)timer_irq);
+ add_idt_entry(33,(uint32_t)keyboard_irq);
idtp.size=sizeof(struct idt_entry)*256-1;
idtp.offset=(uint32_t)&idt;
diff --git a/src/c/irq_handler.c b/src/c/irq_handler.c
new file mode 100644
index 0000000..6b80a52
--- /dev/null
+++ b/src/c/irq_handler.c
@@ -0,0 +1,204 @@
+#include"../include/stdio.h"
+#include"../include/asm.h"
+
+#define INTERRUPT_GATE_32 0x8e
+
+#define KERNEL_CODE 0x08
+#define KERNEL_DATA 0x10
+
+#define PIC1_COMMAND_PORT 0x20
+#define PIC1_DATA_PORT 0x21
+#define PIC2_COMMAND_PORT 0xA0
+#define PIC2_DATA_PORT 0xA1
+
+void irq0_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 0.\n");
+}
+
+void irq1_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 1.\n");
+}
+
+void irq2_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 2.\n");
+}
+
+void irq3_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 3.\n");
+}
+
+void irq4_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 4.\n");
+}
+
+void irq5_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 5.\n");
+}
+
+void irq6_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 6.\n");
+}
+
+void irq7_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 7.\n");
+}
+
+void irq8_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 8.\n");
+}
+
+void irq9_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 9.\n");
+}
+
+void irq10_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 10.\n");
+}
+
+void irq11_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 11.\n");
+}
+
+void irq12_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 12.\n");
+}
+
+void irq13_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 13.\n");
+}
+
+void irq14_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 14.\n");
+}
+
+void irq15_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 15.\n");
+}
+
+void irq16_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 16.\n");
+}
+
+void irq17_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 17.\n");
+}
+
+void irq18_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 18.\n");
+}
+
+void irq19_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 19.\n");
+}
+
+void irq20_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 20.\n");
+}
+
+void irq21_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 21.\n");
+}
+
+void irq22_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 22.\n");
+}
+
+void irq23_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 23.\n");
+}
+
+void irq24_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 24.\n");
+}
+
+void irq25_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 25.\n");
+}
+
+void irq26_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 26.\n");
+}
+
+void irq27_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 27.\n");
+}
+
+void irq28_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 28.\n");
+}
+
+void irq29_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 29.\n");
+}
+
+void irq30_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 30.\n");
+}
+
+void irq31_handler()
+{
+ ioport_out(PIC1_COMMAND_PORT, 0x20);
+ printf("Interrupt 31.\n");
+}
diff --git a/src/c/kernel.c b/src/c/kernel.c
index e18a7c0..62f444c 100644
--- a/src/c/kernel.c
+++ b/src/c/kernel.c
@@ -3,6 +3,7 @@
void terminal_initialize(void);
void init_idt_table(void);
void init_keyboard(void);
+void init_timer(uint32_t frequency);
void prompt(void);
void kernel_main(void)
@@ -10,8 +11,10 @@ void kernel_main(void)
terminal_initialize();
init_idt_table();
init_keyboard();
- k_heapBMInit(&kheap);
-
+ init_timer(50);
+ //k_heapBMInit(&kheap);
+ //k_heapBMAddBlock(&kheap, 0x100000, 0x100000, 16);
prompt();
+
while(1) __asm__("hlt\n\t");
}
diff --git a/src/c/keyboard.c b/src/c/keyboard.c
index 548cdda..473ec20 100644
--- a/src/c/keyboard.c
+++ b/src/c/keyboard.c
@@ -17,7 +17,6 @@ size_t buffer_index=0;
void previous_field(void);
void terminal_putchar(char c);
void tty(char *buffer);
-void prompt(void);
void clear();
void us_en(char keymap[]);
@@ -26,9 +25,6 @@ bool ispressed[128];
void init_keyboard()
{
- // 0xFD = 1111 1101 in binary. enables only IRQ1
- // Why IRQ1? Remember, IRQ0 exists, it's 0-based
- ioport_out(PIC1_DATA_PORT, 0xFD);
us_en(charcode);
}
@@ -52,7 +48,6 @@ void enter()
for(int i=0;i<BUFFER_SIZE;i++) buffer[i]='\0';
buffer_index=0;
}
- prompt();
return;
}
@@ -64,7 +59,7 @@ void space()
#define lshift ispressed[0x2A]
#define lctrl ispressed[0x1D]
-void handle_keyboard_interrupt()
+void keyboard_handler()
{
ioport_out(PIC1_COMMAND_PORT, 0x20);
uint8_t status = ioport_in(KEYBOARD_STATUS_PORT);
diff --git a/src/c/stack_protector.c b/src/c/stack_protector.c
new file mode 100644
index 0000000..50e4316
--- /dev/null
+++ b/src/c/stack_protector.c
@@ -0,0 +1,22 @@
+#include <stdint.h>
+#include"../include/stdio.h"
+
+#if UINT32_MAX == UINTPTR_MAX
+#define STACK_CHK_GUARD 0xe2dee396
+#else
+#define STACK_CHK_GUARD 0x595e9fbd94fda766
+#endif
+
+uintptr_t __stack_chk_guard = STACK_CHK_GUARD;
+
+__attribute__((noreturn))
+void __stack_chk_fail(void)
+{
+#if __STDC_HOSTED__
+ printf("Stack smashing detected\n");
+ abort();
+#elif __is_myos_kernel
+ printf("Stack smashing detected\n");
+ panic("Stack smashing detected");
+#endif
+}
diff --git a/src/c/timer.c b/src/c/timer.c
new file mode 100644
index 0000000..edeea21
--- /dev/null
+++ b/src/c/timer.c
@@ -0,0 +1,45 @@
+#include"../include/types.h"
+#include"../include/asm.h"
+#include"../include/stdio.h"
+
+void add_idt_entry(size_t num,uint32_t offset);
+
+uint32_t tick=0;
+const uint32_t TICKS_PER_SECOND=50;
+extern uint32_t time;
+uint32_t time=0;
+
+void timer_handler()
+{
+ tick++;
+ if(tick==TICKS_PER_SECOND)
+ {
+ //printf("%d seconds passed\n",time);
+ tick=0;
+ time++;
+ }
+
+ ioport_out(0x20, 0x20);
+ ioport_out(0xa0,0x20);
+}
+
+void init_timer(uint32_t frequency)
+{
+ // Firstly, register our timer callback.
+
+ // The value we send to the PIT is the value to divide it's input clock
+ // (1193180 Hz) by, to get our required frequency. Important to note is
+ // that the divisor must be small enough to fit into 16-bits.
+ uint32_t divisor = 1193180 / frequency;
+
+ // Send the command byte.
+ ioport_out(0x43, 0x36);
+
+ // Divisor has to be sent byte-wise, so split here into upper/lower bytes.
+ uint8_t l = (uint8_t)(divisor & 0xFF);
+ uint8_t h = (uint8_t)( (divisor>>8) & 0xFF );
+
+ // Send the frequency divisor.
+ ioport_out(0x40, l);
+ ioport_out(0x40, h);
+}
diff --git a/src/c/tty.c b/src/c/tty.c
index 5728a47..8516489 100644
--- a/src/c/tty.c
+++ b/src/c/tty.c
@@ -1,10 +1,12 @@
#include"../include/types.h"
#include"../include/string.h"
#include"../include/stdio.h"
+#include"../include/vga.h"
#define CMD_LENGTH 20
void clear();
+extern uint32_t time;
size_t pieces(char pieces[][CMD_LENGTH],char *buffer)
{
@@ -61,6 +63,33 @@ void number(size_t numberof,char parts[][CMD_LENGTH])
}
}
+void uptime()
+{
+ printf("System uptime is: %d seconds\n",time);
+}
+
+void prompt()
+{
+ printf("[user@myos] > ");
+}
+
+void neofetch()
+{
+ set_color(VGA_COLOR_RED,VGA_COLOR_BLACK);
+ printf(" <*>\n");
+ printf(" <*>\n");
+ printf(" <*>\n");
+ printf(" <*>\n");
+ printf(" <*>\n");
+ printf(" <*>\n");
+ printf(" <*>\n");
+ printf("<*******>\n");
+ printf(" <***>\n");
+ printf(" <*>\n");
+ set_color(VGA_COLOR_LIGHT_GREY,VGA_COLOR_BLACK);
+ uptime();
+}
+
void tty(char *buffer)
{
char parts[CMD_LENGTH][CMD_LENGTH];
@@ -71,5 +100,8 @@ void tty(char *buffer)
else if(stringcmp(parts[0],"merge")) merge(parts);
else if(stringcmp(parts[0],"ls")) ls(numberof,parts);
else if(stringcmp(parts[0],"number")) number(numberof,parts);
+ else if(stringcmp(parts[0],"uptime")) uptime();
+ else if(stringcmp(parts[0],"neofetch")) neofetch();
else printf("command not found: %s\n",parts[0]);
+ prompt();
}
diff --git a/src/c/vga.c b/src/c/vga.c
index 07dec60..8c1824b 100644
--- a/src/c/vga.c
+++ b/src/c/vga.c
@@ -1,33 +1,16 @@
#include"../include/types.h"
#include"../include/string.h"
#include"../include/asm.h"
+#include"../include/vga.h"
-static const size_t VGA_WIDTH = 80;
-static const size_t VGA_HEIGHT = 25;
-
-
-enum vga_color {
- VGA_COLOR_BLACK = 0,
- VGA_COLOR_BLUE = 1,
- VGA_COLOR_GREEN = 2,
- VGA_COLOR_CYAN = 3,
- VGA_COLOR_RED = 4,
- VGA_COLOR_MAGENTA = 5,
- VGA_COLOR_BROWN = 6,
- VGA_COLOR_LIGHT_GREY = 7,
- VGA_COLOR_DARK_GREY = 8,
- VGA_COLOR_LIGHT_BLUE = 9,
- VGA_COLOR_LIGHT_GREEN = 10,
- VGA_COLOR_LIGHT_CYAN = 11,
- VGA_COLOR_LIGHT_RED = 12,
- VGA_COLOR_LIGHT_MAGENTA = 13,
- VGA_COLOR_LIGHT_BROWN = 14,
- VGA_COLOR_WHITE = 15,
-};
+size_t terminal_row;
+size_t terminal_column;
+uint8_t terminal_color;
+uint16_t* terminal_buffer;
-static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg)
+void set_color(enum vga_color fg, enum vga_color bg)
{
- return fg | bg << 4;
+ terminal_color = fg | bg << 4;
}
static inline uint16_t vga_entry(unsigned char uc, uint8_t color)
@@ -35,16 +18,11 @@ static inline uint16_t vga_entry(unsigned char uc, uint8_t color)
return (uint16_t) uc | (uint16_t) color << 8;
}
-size_t terminal_row;
-size_t terminal_column;
-uint8_t terminal_color;
-uint16_t* terminal_buffer;
-
void terminal_initialize()
{
terminal_row=0;
terminal_column=0;
- terminal_color=vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK);
+ set_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK);
terminal_buffer=(uint16_t*) 0xB8000;
for(size_t y=0;y<VGA_HEIGHT;y++)
{
@@ -113,11 +91,6 @@ void terminal_writefloat(double num)
terminal_writestring(str);
}
-void prompt()
-{
- terminal_writestring("[user@myos] > ");
-}
-
void clear()
{
for(size_t i=0;i<VGA_HEIGHT;i++) for(size_t j=0;j<VGA_WIDTH;j++) terminal_putchar(' ');
diff --git a/src/include/heap.h b/src/include/heap.h
index 2f66501..4eebd04 100644
--- a/src/include/heap.h
+++ b/src/include/heap.h
@@ -1,3 +1,6 @@
+#ifndef HEAP_H
+#define HEAP_H
+
#include"types.h"
typedef struct _KHEAPBLOCKBM {
@@ -21,3 +24,5 @@ extern KHEAPBM kheap;
#define kmalloc k_heapBMAlloc
#define kfree k_heapBMFree
+
+#endif
diff --git a/src/include/irq.h b/src/include/irq.h
new file mode 100644
index 0000000..58b3cd3
--- /dev/null
+++ b/src/include/irq.h
@@ -0,0 +1,39 @@
+#ifndef IRQ_H
+#define IRQ_H
+
+extern void irq0();
+extern void irq1();
+extern void irq2();
+extern void irq3();
+extern void irq4();
+extern void irq5();
+extern void irq6();
+extern void irq7();
+extern void irq8();
+extern void irq9();
+extern void irq10();
+extern void irq11();
+extern void irq12();
+extern void irq13();
+extern void irq14();
+extern void irq15();
+extern void irq16();
+extern void irq17();
+extern void irq18();
+extern void irq19();
+extern void irq20();
+extern void irq21();
+extern void irq22();
+extern void irq23();
+extern void irq24();
+extern void irq25();
+extern void irq26();
+extern void irq27();
+extern void irq28();
+extern void irq29();
+extern void irq30();
+extern void irq31();
+extern void timer_irq();
+extern void keyboard_irq();
+
+#endif
diff --git a/src/include/vga.h b/src/include/vga.h
new file mode 100644
index 0000000..d828e48
--- /dev/null
+++ b/src/include/vga.h
@@ -0,0 +1,29 @@
+#ifndef VGA_H
+#define VGA_H
+
+#include"types.h"
+
+static const size_t VGA_WIDTH = 80;
+static const size_t VGA_HEIGHT = 25;
+
+enum vga_color {
+ VGA_COLOR_BLACK = 0,
+ VGA_COLOR_BLUE = 1,
+ VGA_COLOR_GREEN = 2,
+ VGA_COLOR_CYAN = 3,
+ VGA_COLOR_RED = 4,
+ VGA_COLOR_MAGENTA = 5,
+ VGA_COLOR_BROWN = 6,
+ VGA_COLOR_LIGHT_GREY = 7,
+ VGA_COLOR_DARK_GREY = 8,
+ VGA_COLOR_LIGHT_BLUE = 9,
+ VGA_COLOR_LIGHT_GREEN = 10,
+ VGA_COLOR_LIGHT_CYAN = 11,
+ VGA_COLOR_LIGHT_RED = 12,
+ VGA_COLOR_LIGHT_MAGENTA = 13,
+ VGA_COLOR_LIGHT_BROWN = 14,
+ VGA_COLOR_WHITE = 15,
+};
+void set_color(enum vga_color fg, enum vga_color bg);
+
+#endif