diff --git a/build.ninja b/build.ninja index 64d8975..96637c7 100644 --- a/build.ninja +++ b/build.ninja @@ -23,14 +23,15 @@ build ./build/i386/pic.o: gcc ./src/arch/i386/kernel/drivers/pic.c build ./build/i386/cmos.o: gcc ./src/arch/i386/kernel/drivers/cmos.c build ./build/i386/keyboard.o: gcc ./src/arch/i386/kernel/drivers/keyboard.c build ./build/i386/fpu.o: gcc ./src/arch/i386/kernel/drivers/fpu.c +build ./build/i386/pit.o: gcc ./src/arch/i386/kernel/drivers/pit.c build ./build/i386/console.o: gcc ./src/arch/i386/kernel/console.c build ./build/i386/kernel.o: gcc ./src/arch/i386/kernel/kernel.c -build ./isodir/boot/piriquitOS-i386.bin: ld ./build/libc/string.o ./build/i386/boot.o ./build/i386/gdt.asm.o ./build/i386/gdt.c.o ./build/i386/idt.c.o ./build/i386/idt.asm.o ./build/i386/irq.o ./build/i386/exceptions.o ./build/i386/isr.o ./build/i386/io.o ./build/i386/vga.o ./build/i386/pic.o ./build/i386/cmos.o ./build/i386/keyboard.o ./build/i386/console.o ./build/i386/fpu.o ./build/i386/kernel.o +build ./isodir/boot/piriquitOS-i386.bin: ld ./build/libc/string.o ./build/i386/boot.o ./build/i386/gdt.asm.o ./build/i386/gdt.c.o ./build/i386/idt.c.o ./build/i386/idt.asm.o ./build/i386/irq.o ./build/i386/exceptions.o ./build/i386/isr.o ./build/i386/io.o ./build/i386/vga.o ./build/i386/pic.o ./build/i386/cmos.o ./build/i386/keyboard.o ./build/i386/pit.o ./build/i386/console.o ./build/i386/fpu.o ./build/i386/kernel.o build ./build/piriquitOS-i386.iso: iso ./isodir #phony build libc: phony ./build/libc/string.o ./libs/libc.a -build i386: phony ./build/libc/string.o ./build/i386/boot.o ./build/i386/gdt.asm.o ./build/i386/idt.asm.o ./build/i386/irq.o ./build/i386/exceptions.o ./build/i386/isr.o ./build/i386/io.o ./build/i386/vga.o ./build/i386/pic.o ./build/i386/cmos.o ./build/i386/keyboard.o ./build/i386/console.o ./build/i386/fpu.o ./build/i386/kernel.o ./isodir/boot/piriquitOS-i386.bin ./build/piriquitOS-i386.iso +build i386: phony ./build/libc/string.o ./build/i386/boot.o ./build/i386/gdt.asm.o ./build/i386/idt.asm.o ./build/i386/irq.o ./build/i386/exceptions.o ./build/i386/isr.o ./build/i386/io.o ./build/i386/vga.o ./build/i386/pic.o ./build/i386/cmos.o ./build/i386/keyboard.o ./build/i386/console.o ./build/i386/fpu.o ./build/i386/pit.o ./build/i386/kernel.o ./isodir/boot/piriquitOS-i386.bin ./build/piriquitOS-i386.iso default help diff --git a/rules.ninja b/rules.ninja index f9c6d0c..12abdf1 100644 --- a/rules.ninja +++ b/rules.ninja @@ -1,6 +1,6 @@ NASMARGS = -f elf32 -LDARGS = -m elf_i386 -T ./src/arch/i386/linker.ld -nostdlib -CCARGS = -m32 -std=gnu99 -ffreestanding -Wall -Wextra -c +LDARGS = -m elf_i386 -T ./src/arch/i386/linker.ld -nostdlib -z noexecstack +CCARGS = -m32 -std=gnu99 -ffreestanding -fcompare-debug -Wall -Wextra -c CCINCLUDES = -L./libs -lc -I ./src/arch/i386/kernel/include ARARGS = -rcs diff --git a/src/arch/i386/kernel/drivers/cmos.c b/src/arch/i386/kernel/drivers/cmos.c index ff2893a..c3704db 100644 --- a/src/arch/i386/kernel/drivers/cmos.c +++ b/src/arch/i386/kernel/drivers/cmos.c @@ -1,4 +1,6 @@ #include "../include/drivers/cmos.h" +#include "../include/drivers/pic.h" +#include "../include/isr.h" #include "../include/io.h" void rtc_handler(struct registers_t *r) { @@ -8,6 +10,8 @@ void rtc_handler(struct registers_t *r) { u8 day = cmos_read(RTC_DAY); u8 month = cmos_read(RTC_MONTH); u8 year = cmos_read(RTC_YEAR); + + pic_eoi(IRQ_CMOS); } void init_cmos(){ diff --git a/src/arch/i386/kernel/drivers/pic.c b/src/arch/i386/kernel/drivers/pic.c index f22c3e2..3b82932 100644 --- a/src/arch/i386/kernel/drivers/pic.c +++ b/src/arch/i386/kernel/drivers/pic.c @@ -1,6 +1,4 @@ #include "../include/libc/include/types.h" -#include "../include/isr.h" -#include "../include/idt.h" #include "../include/io.h" #include "../include/drivers/pic.h" @@ -8,27 +6,27 @@ void init_pic() { printf("Initiating PIC...\n"); u8 a1, a2; - a1 = inportb(PIC1_DATA); - a2 = inportb(PIC2_DATA); + a1 = inportb(PIC_MASTER_DATA); + a2 = inportb(PIC_SLAVE_DATA); - outportb(PIC1_COMMAND, ICW1); - outportb(PIC2_COMMAND, ICW1); + outportb(PIC_MASTER_COMMAND, PIC_ICW1); + outportb(PIC_SLAVE_COMMAND, PIC_ICW1); - outportb(PIC1_DATA, 0x20); - outportb(PIC2_DATA, 0x28); + outportb(PIC_MASTER_DATA, 0x20); + outportb(PIC_SLAVE_DATA, 0x28); - outportb(PIC1_DATA, 4); - outportb(PIC2_DATA, 2); + outportb(PIC_MASTER_DATA, 4); + outportb(PIC_SLAVE_DATA, 2); - outportb(PIC1_DATA, ICW4_8086); - outportb(PIC2_DATA, ICW4_8086); + outportb(PIC_MASTER_DATA, PIC_ICW4_8086); + outportb(PIC_SLAVE_DATA, PIC_ICW4_8086); - outportb(PIC1_DATA, a1); - outportb(PIC2_DATA, a2); + outportb(PIC_MASTER_DATA, a1); + outportb(PIC_SLAVE_DATA, a2); } void pic_eoi(u8 irq) { if(irq >= 0x28) - outportb(PIC2, PIC_EOI); - outportb(PIC1, PIC_EOI); + outportb(PIC_SLAVE_COMMAND, PIC_EOI); + outportb(PIC_MASTER_COMMAND, PIC_EOI); } diff --git a/src/arch/i386/kernel/drivers/pit.c b/src/arch/i386/kernel/drivers/pit.c new file mode 100644 index 0000000..f5669de --- /dev/null +++ b/src/arch/i386/kernel/drivers/pit.c @@ -0,0 +1,92 @@ +#include "../include/drivers/pit.h" +#include "../include/console.h" +#include "../include/io.h" +#include "../include/isr.h" + +u64 ticks; +const u32 freq = 100; + +void pit_handler(struct registers_t *r) { ticks += 1; } + +void init_pit() { + printf("Initiating PIT...\n"); + isr_register_interrupt_handler(IRQ_BASE + IRQ_TIMER, pit_handler); + start_pit_timer(); +} + +void start_pit_timer() { + if (freq == 0) { + printf("Can't divide by zero!"); + return; + } + + u16 divisor = 1193180 / freq; + + outportb(PIT_COMMAND_PORT, PIT_COMMAND_REGISTER); + outportb(PIT_CH0_DATA_PORT, (u8)(divisor & 0xFF)); // Send the low byte + outportb(PIT_CH0_DATA_PORT, (u8)((divisor >> 8) & 0xFF)); // Send the high byte +} + +void stop_pit_timer() { outportb(PIT_COMMAND_PORT, 0x30); } + +u8 read_pit(u8 channel) { + u8 port; + switch (channel) { + case 0: + port = PIT_CH0_DATA_PORT; + break; + case 1: + port = PIT_CH1_DATA_PORT; + break; + case 2: + port = PIT_CH2_DATA_PORT; + break; + default: + // Handle invalid channel + break; + } + + // Read from the specified channel + u8 value = inportb(port); + return value; +} + +void write_pit(u8 channel, u8 value) { + u8 port; + switch (channel) { + case 0: + port = PIT_CH0_DATA_PORT; + break; + case 1: + port = PIT_CH1_DATA_PORT; + break; + case 2: + port = PIT_CH2_DATA_PORT; + break; + default: + // Handle invalid channel + break; + } + + // Write to the specified channel + outportb(port, value); +} + +void sleep(u32 milliseconds) { + // Calculate the number of PIT ticks needed for the delay + u32 ticks = milliseconds * 1000 / ticks; + + // Save the current PIT channel 0 count + u8 initialCounter = inportb(PIT_CH0_DATA_PORT); + + start_pit_timer(); + + while (ticks > 0) { + // Wait for PIT interrupt + ticks--; + } + + // Restore the initial PIT channel 0 count + outportb(PIT_COMMAND_REGISTER, 0x36); // Set the operating mode to square wave generator + outportb(PIT_CH0_DATA_PORT, initialCounter); // Set the initial counter value +} diff --git a/src/arch/i386/kernel/include/drivers/cmos.h b/src/arch/i386/kernel/include/drivers/cmos.h index b1671fe..2efaf83 100644 --- a/src/arch/i386/kernel/include/drivers/cmos.h +++ b/src/arch/i386/kernel/include/drivers/cmos.h @@ -7,13 +7,12 @@ #define CMOS_ADDR_REG 0x70 #define CMOS_DATA_REG 0x71 -//RTC register addresses #define RTC_SECONDS 0x00 #define RTC_MINUTES 0x02 #define RTC_HOURS 0x04 #define RTC_DAY 0x07 #define RTC_MONTH 0x08 -#define RTC_YEAR 0x09 +#define RTC_YEAR 0x09 //last two digits void init_cmos(); u8 cmos_read(u8 reg); diff --git a/src/arch/i386/kernel/include/drivers/pic.h b/src/arch/i386/kernel/include/drivers/pic.h index 26712df..c410644 100644 --- a/src/arch/i386/kernel/include/drivers/pic.h +++ b/src/arch/i386/kernel/include/drivers/pic.h @@ -3,17 +3,15 @@ #include "../libc/include/types.h" -#define PIC1 0x20 //master PIC -#define PIC2 0xA0 //slave PIC -#define PIC1_COMMAND PIC1 -#define PIC1_DATA (PIC1+1) //master data -#define PIC2_COMMAND PIC2 -#define PIC2_DATA (PIC2+1) //slave data +#define PIC_MASTER_COMMAND 0X20 +#define PIC_MASTER_DATA 0X21 +#define PIC_SLAVE_COMMAND 0XA0 +#define PIC_SLAVE_DATA 0xA1 #define PIC_EOI 0x20 -#define ICW1 0x11 /* interrupt control command word PIC for initialization */ -#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */ +#define PIC_ICW1 0x11 /* interrupt control command word PIC for initialization */ +#define PIC_ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */ void init_pic(); diff --git a/src/arch/i386/kernel/include/drivers/pit.h b/src/arch/i386/kernel/include/drivers/pit.h new file mode 100644 index 0000000..dae7aa0 --- /dev/null +++ b/src/arch/i386/kernel/include/drivers/pit.h @@ -0,0 +1,19 @@ +#ifndef PIT_H +#define PIT_H + +#define PIT_CH0_DATA_PORT 0x40 +#define PIT_CH1_DATA_PORT 0x41 +#define PIT_CH2_DATA_PORT 0x42 +#define PIT_COMMAND_PORT 0x43 +#define PIT_COMMAND_REGISTER 0x36 + +#include "../libc/include/types.h" + +void init_pit(); +void start_pit_timer(); +void stop_pit_timer(); +void sleep(u32 milliseconds); +u8 read_pit(u8 channel); +void write_pit(u8 channel, u8 value); + +#endif diff --git a/src/arch/i386/kernel/include/io.h b/src/arch/i386/kernel/include/io.h index d3f3ad5..a9cc1e4 100644 --- a/src/arch/i386/kernel/include/io.h +++ b/src/arch/i386/kernel/include/io.h @@ -4,13 +4,11 @@ #include "libc/include/types.h" u8 inportb(u16 port); -u16 inports(u16 port); +u16 inportw(u16 port); u32 inportl(u16 port); -void outportb(u16 port, u8 val); -void outports(u16 port, u16 data); +void outportb(u16 port, u8 data); +void outportw(u16 port, u16 data); void outportl(u16 port, u32 data); -void insw(u16 port, void *buffer, u32 count); - #endif diff --git a/src/arch/i386/kernel/include/isr.h b/src/arch/i386/kernel/include/isr.h index 23c093e..248c801 100644 --- a/src/arch/i386/kernel/include/isr.h +++ b/src/arch/i386/kernel/include/isr.h @@ -73,21 +73,21 @@ extern void irq_14(); extern void irq_15(); #define IRQ_BASE 0x20 -#define IRQ_TIMER 0x20 -#define IRQ_KEYBOARD 0x21 -#define IRQ_CASCADE 0x22 -#define IRQ_SERIAL_PORT2 0x23 -#define IRQ_SERIAL_PORT1 0x24 -#define IRQ_AUDIO 0x25 -#define IRQ_DISKETTE_DRIVE 0x26 -#define IRQ_PARALLEL_PORT 0x27 -#define IRQ_CMOS 0x28 -#define IRQ_CGA 0x29 -#define IRQ_NIC1 0x2A -#define IRQ_NIC2 0x2B -#define IRQ_AUXILIARY 0x2C -#define IRQ_FPU 0x2D -#define IRQ_ATA1 0x2E -#define IRQ_ATA2 0x2F +#define IRQ_TIMER 0x00 +#define IRQ_KEYBOARD 0x01 +#define IRQ_CASCADE 0x02 +#define IRQ_SERIAL_PORT2 0x03 +#define IRQ_SERIAL_PORT1 0x04 +#define IRQ_AUDIO 0x05 +#define IRQ_DISKETTE_DRIVE 0x06 +#define IRQ_PARALLEL_PORT 0x07 +#define IRQ_CMOS 0x08 +#define IRQ_ACPI 0x09 +#define IRQ_NIC1 0x0A +#define IRQ_NIC2 0x0B +#define IRQ_AUXILIARY 0x0C +#define IRQ_FPU 0x0D +#define IRQ_ATA1 0x0E +#define IRQ_ATA2 0x0F #endif diff --git a/src/arch/i386/kernel/io.c b/src/arch/i386/kernel/io.c index 289cfde..0f5fbbe 100644 --- a/src/arch/i386/kernel/io.c +++ b/src/arch/i386/kernel/io.c @@ -1,57 +1,33 @@ -#include "./include/libc/include/types.h" -#include "./include/libc/include/defines.h" #include "include/io.h" +#include "./include/libc/include/defines.h" +#include "./include/libc/include/types.h" -u8 inportb(u16 port) -{ - u8 ret; - asmv("inb %1, %0" - : "=a"(ret) - : "Nd"(port)); - return ret; -} - -void outportb(u16 port, u8 val) -{ - asmv("outb %1, %0" ::"dN"(port), "a"(val)); +u8 inportb(u16 port) { + u8 ret; + asmv("inb %1, %0" : "=a"(ret) : "dN"(port)); + return ret; } -u16 inports(u16 port) -{ - u16 rv; - asmv("inw %1, %0" - : "=a"(rv) - : "dN"(port)); - return rv; +void outportb(u16 port, u8 data) { + asmv("outb %1, %0" ::"dN"(port), "a"(data)); } -void outports(u16 port, u16 data) -{ - asmv("outw %1, %0" - : - : "dN"(port), "a"(data)); +u16 inportw(u16 port) { + u16 rv; + asmv("inw %1, %0" : "=a"(rv) : "dN"(port)); + return rv; } -u32 inportl(u16 port) -{ - u32 rv; - asmv("inl %%dx, %%eax" - : "=a"(rv) - : "dN"(port)); - return rv; +void outportw(u16 port, u16 data) { + asmv("outw %1, %0" : : "dN"(port), "a"(data)); } -void outportl(u16 port, u32 data) -{ - asmv("outl %%eax, %%dx" - : - : "dN"(port), "a"(data)); +u32 inportl(u16 port) { + u32 rv; + asmv("inl %%dx, %%eax" : "=a"(rv) : "dN"(port)); + return rv; } -void insw(u16 port, void *buffer, u32 count) -{ - asmv("cld; rep insw" - : "+D"(buffer), "+c"(count) - : "d"(port) - : "memory"); +void outportl(u16 port, u32 data) { + asmv("outl %%eax, %%dx" : : "dN"(port), "a"(data)); } diff --git a/src/arch/i386/kernel/kernel.c b/src/arch/i386/kernel/kernel.c index 2a19908..b7bc6de 100644 --- a/src/arch/i386/kernel/kernel.c +++ b/src/arch/i386/kernel/kernel.c @@ -1,12 +1,12 @@ -#include "./include/libc/include/string.h" #include "./include/libc/include/defines.h" -#include "include/kernel.h" #include "include/console.h" +#include "include/drivers/vga.h" #include "include/gdt.h" #include "include/drivers/pic.h" #include "include/drivers/keyboard.h" #include "include/drivers/cmos.h" #include "include/drivers/fpu.h" +#include "include/drivers/pit.h" void cpuid(u32 type, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx) { @@ -59,9 +59,9 @@ void shutdown() int brand = cpuid_info(0); if (brand == BRAND_QEMU) - outports(0x604, 0x2000); + outportw(0x604, 0x2000); else - outports(0x4004, 0x3400); + outportw(0x4004, 0x3400); } void kmain() @@ -73,17 +73,14 @@ void kmain() init_gdt(); init_pic(); init_idt(); + init_pit(); init_cmos(); init_fpu(); init_keyboard(); - printf("TESTS\n"); - printf("FPU test: "); - float_print("", 1.73728, "\n"); - while (1) { - printf(shell); + printf("%s", shell); memset(buffer, 0, sizeof(buffer)); getstr_bound(buffer, strlen(shell)); @@ -99,7 +96,7 @@ void kmain() cpuid_info(1); }else if (strcmp(buffer, "help") == 0) { - printf("Commands: help, cpuid, echo, shutdown\n"); + printf("Commands:\n help\n cpuid\n echo\n time\n shutdown\n"); }else if (is_echo(buffer)) { printf("%s\n", buffer + 5); @@ -111,8 +108,12 @@ void kmain() u8 seconds = cmos_read(RTC_SECONDS); u8 minutes = cmos_read(RTC_MINUTES); u8 hours = cmos_read(RTC_HOURS); + u8 day = cmos_read(RTC_DAY); + u8 month = cmos_read(RTC_MONTH); + u8 year = cmos_read(RTC_YEAR); printf("Time: %d:%d:%d\n", hours, minutes, seconds); + printf("Date: %d/%d/%d\n", day, month, year); }else { printf("invalid command: %s\n", buffer);