Compare commits
4 Commits
kbd
...
834891fd2a
| Author | SHA1 | Date | |
|---|---|---|---|
| 834891fd2a | |||
| 3853a1ace3 | |||
| ead0ed6ae1 | |||
| fabe0b1a10 |
4
Makefile
4
Makefile
@@ -1,6 +1,8 @@
|
|||||||
|
SOURCES = src/io/kbd/ps2.c src/io/serial/serial.c src/io/term/printf.c src/io/term/term.c src/idt/idt.c src/mem/gdt/gdt.c src/mem/misc/utils.c src/time/timer.c src/kmain.c
|
||||||
|
|
||||||
build:
|
build:
|
||||||
rm -f *.o
|
rm -f *.o
|
||||||
x86_64-elf-gcc -g -c -I src src/kbd/ps2.c src/time/timer.c src/idt/idt.c src/mem/utils.c src/mem/gdt.c src/io/serial.c src/io/term.c src/io/printf.c src/kmain.c -Wall -Wextra -std=gnu99 -nostdlib -ffreestanding -fno-stack-protector -fno-stack-check -fno-PIC -ffunction-sections -fdata-sections -mcmodel=kernel
|
x86_64-elf-gcc -g -c -I src $(SOURCES) -Wall -Wextra -std=gnu99 -nostdlib -ffreestanding -fno-stack-protector -fno-stack-check -fno-PIC -ffunction-sections -fdata-sections -mcmodel=kernel
|
||||||
objcopy -O elf64-x86-64 -B i386 -I binary zap-light16.psf zap-light16.o
|
objcopy -O elf64-x86-64 -B i386 -I binary zap-light16.psf zap-light16.o
|
||||||
nasm -f elf64 src/idt/idt.S -o idt_stub.o
|
nasm -f elf64 src/idt/idt.S -o idt_stub.o
|
||||||
x86_64-elf-ld -o pepperk -T linker.ld *.o
|
x86_64-elf-ld -o pepperk -T linker.ld *.o
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
#include "idt.h"
|
#include "idt.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "../io/serial.h"
|
#include "../io/serial/serial.h"
|
||||||
#include "../kbd/ps2.h"
|
#include "../io/kbd/ps2.h"
|
||||||
|
#include <kernel.h>
|
||||||
|
|
||||||
struct interrupt_descriptor idt[256];
|
struct interrupt_descriptor idt[256];
|
||||||
struct idtr idt_reg;
|
struct idtr idt_reg;
|
||||||
@@ -49,7 +50,7 @@ void idt_init()
|
|||||||
idt_set_entry(i, vector_0_handler + (i*16), 0);
|
idt_set_entry(i, vector_0_handler + (i*16), 0);
|
||||||
}
|
}
|
||||||
idt_load(&idt);
|
idt_load(&idt);
|
||||||
serial_kputs("kernel: idt: Initialized IDT!\n");
|
DEBUG("IDT initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context)
|
struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context)
|
||||||
@@ -57,74 +58,74 @@ struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context)
|
|||||||
switch(context->vector_number)
|
switch(context->vector_number)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
serial_kputs("kernel: idt: Divide Error!\n");
|
DEBUG("Divide Error!");
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
serial_kputs("kernel: idt: Debug Exception!\n");
|
DEBUG("Debug Exception!");
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
serial_kputs("kernel: idt: NMI Interrupt!\n");
|
DEBUG("NMI Interrupt!");
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
serial_kputs("kernel: idt: Breakpoint Interrupt!\n");
|
DEBUG("Breakpoint Interrupt!");
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
serial_kputs("kernel: idt: Overflow Trap!\n");
|
DEBUG("Overflow Trap!");
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
serial_kputs("kernel: idt: BOUND Range Exceeded!\n");
|
DEBUG("BOUND Range Exceeded!");
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
serial_kputs("kernel: idt: Invalid Opcode!\n");
|
DEBUG("Invalid Opcode!");
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
serial_kputs("kernel: idt: Device Not Available!\n");
|
DEBUG("Device Not Available!");
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
serial_kputs("kernel: idt: Double Fault!\n");
|
DEBUG("Double Fault!");
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
serial_kputs("kernel: idt: Coprocessor Segment Overrun!\n");
|
DEBUG("Coprocessor Segment Overrun!");
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
serial_kputs("kernel: idt: Invalid TSS!\n");
|
DEBUG("Invalid TSS!");
|
||||||
break;
|
break;
|
||||||
case 11:
|
case 11:
|
||||||
serial_kputs("kernel: idt: Segment Not Present!\n");
|
DEBUG("Segment Not Present!");
|
||||||
break;
|
break;
|
||||||
case 12:
|
case 12:
|
||||||
serial_kputs("kernel: idt: Stack-Segment Fault!\n");
|
DEBUG("Stack-Segment Fault!");
|
||||||
break;
|
break;
|
||||||
case 13:
|
case 13:
|
||||||
serial_kputs("kernel: idt: General Protection Fault!\n");
|
DEBUG("General Protection Fault!");
|
||||||
break;
|
break;
|
||||||
case 14:
|
case 14:
|
||||||
serial_kputs("kernel: idt: Page Fault!\n");
|
DEBUG("Page Fault!");
|
||||||
break;
|
break;
|
||||||
case 15:
|
case 15:
|
||||||
serial_kputs("kernel: idt: Intel Reserved Interrupt! (Achievement unlocked: How Did We Get Here?)\n");
|
DEBUG("Intel Reserved Interrupt! (Achievement unlocked: How Did We Get Here?)");
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
serial_kputs("kernel: idt: x87 Floating-Point Error!\n");
|
DEBUG("x87 Floating-Point Error!");
|
||||||
break;
|
break;
|
||||||
case 17:
|
case 17:
|
||||||
serial_kputs("kernel: idt: Alignment Check Fault!\n");
|
DEBUG("Alignment Check Fault!");
|
||||||
break;
|
break;
|
||||||
case 18:
|
case 18:
|
||||||
serial_kputs("kernel: idt: Machine Check!\n");
|
DEBUG("Machine Check!");
|
||||||
break;
|
break;
|
||||||
case 19:
|
case 19:
|
||||||
serial_kputs("kernel: idt: SIMD Floating-Point Exception!\n");
|
DEBUG("SIMD Floating-Point Exception!");
|
||||||
break;
|
break;
|
||||||
case 20:
|
case 20:
|
||||||
serial_kputs("kernel: idt: Virtualization Exception!\n");
|
DEBUG("Virtualization Exception!");
|
||||||
break;
|
break;
|
||||||
case 21:
|
case 21:
|
||||||
serial_kputs("kernel: idt: Control Protection Exception!\n");
|
DEBUG("Control Protection Exception!");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 32:
|
case 32:
|
||||||
//serial_kputs("Tick!");
|
//DEBUG("Tick!");
|
||||||
ticks++;
|
ticks++;
|
||||||
// Send an EOI so that we can continue having interrupts
|
// Send an EOI so that we can continue having interrupts
|
||||||
outb(0x20, 0x20);
|
outb(0x20, 0x20);
|
||||||
@@ -135,7 +136,7 @@ struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
serial_kputs("kernel: idt: Unexpected interrupt\n");
|
DEBUG("Unexpected interrupt");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
// PS/2 Keyboard support
|
// PS/2 Keyboard support
|
||||||
|
|
||||||
#include "../io/serial.h"
|
#include "../serial/serial.h"
|
||||||
#include "../io/printf.h"
|
|
||||||
#include "ps2.h"
|
#include "ps2.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "../io/term.h"
|
#include "../term/term.h"
|
||||||
|
#include <kernel.h>
|
||||||
|
|
||||||
// The key status bitfield will be used to see if ALT, CONTROL, or SHIFT is pressed
|
// The key status bitfield will be used to see if ALT, CONTROL, or SHIFT is pressed
|
||||||
uint8_t key_status = 0b00000000;
|
uint8_t key_status = 0b00000000;
|
||||||
@@ -206,7 +206,7 @@ void keyboard_handler()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
serial_kputs("key pressed!\n");
|
skputs("key pressed!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// End of Interrupt (to master PIC)
|
// End of Interrupt (to master PIC)
|
||||||
@@ -230,7 +230,8 @@ void keyboard_init(unsigned char layout)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
serial_kputs("Unsupported layout.");
|
skputs("Unsupported layout.");
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
|
DEBUG("PS/2 Keyboard initialized");
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "../kernel.h"
|
#include <kernel.h>
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
|
|
||||||
void outb(int port, unsigned char data)
|
void outb(int port, unsigned char data)
|
||||||
@@ -36,7 +36,7 @@ int serial_init()
|
|||||||
// Set normal operation mode
|
// Set normal operation mode
|
||||||
outb(PORT + 4, 0x0F);
|
outb(PORT + 4, 0x0F);
|
||||||
|
|
||||||
serial_kputs("\n\nkernel: serial: Serial initialization OK!\n");
|
DEBUG("serial initialized");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,18 +45,20 @@ static int is_transmit_empty()
|
|||||||
return inb(PORT + 5) & 0x20;
|
return inb(PORT + 5) & 0x20;
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_serial(char c)
|
// Serial kernel putchar
|
||||||
|
void skputc(char c)
|
||||||
{
|
{
|
||||||
while (!is_transmit_empty()); // wait for free spot
|
while (!is_transmit_empty()); // wait for free spot
|
||||||
outb(PORT, c);
|
outb(PORT, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void serial_kputs(const char* str)
|
// Serial kernel putstring
|
||||||
|
void skputs(const char* str)
|
||||||
{
|
{
|
||||||
unsigned int i=0;
|
unsigned int i=0;
|
||||||
while (str[i])
|
while (str[i])
|
||||||
{
|
{
|
||||||
write_serial(str[i]);
|
skputc(str[i]);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@ void outb(int port, unsigned char data);
|
|||||||
unsigned char inb(int port);
|
unsigned char inb(int port);
|
||||||
|
|
||||||
int serial_init();
|
int serial_init();
|
||||||
void serial_kputs(const char* str);
|
void skputs(const char* str);
|
||||||
|
void skputc(char c);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <limine.h>
|
#include <limine.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "kernel.h"
|
#include <kernel.h>
|
||||||
#include "term.h"
|
#include "term.h"
|
||||||
|
|
||||||
extern struct limine_framebuffer* framebuffer;
|
extern struct limine_framebuffer* framebuffer;
|
||||||
@@ -35,6 +35,7 @@ int term_init()
|
|||||||
if (framebuffer)
|
if (framebuffer)
|
||||||
{
|
{
|
||||||
fb = framebuffer->address;
|
fb = framebuffer->address;
|
||||||
|
DEBUG("terminal initialized");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@@ -10,4 +10,12 @@ enum ErrorCodes
|
|||||||
#define CLEAR_INTERRUPTS __asm__ volatile("cli")
|
#define CLEAR_INTERRUPTS __asm__ volatile("cli")
|
||||||
#define SET_INTERRUPTS __asm__ volatile("sti")
|
#define SET_INTERRUPTS __asm__ volatile("sti")
|
||||||
|
|
||||||
|
#include "io/serial/serial.h"
|
||||||
|
#include "io/term/printf.h"
|
||||||
|
|
||||||
|
// Still lacks print formatting...
|
||||||
|
#define DEBUG(log, ...) \
|
||||||
|
printf("debug: [%s]: " log "\n", __FILE__, ##__VA_ARGS__); \
|
||||||
|
fctprintf((void*)&skputc, 0, "debug: [%s]: %s\n", __FILE__, log)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
23
src/kmain.c
23
src/kmain.c
@@ -1,15 +1,15 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <limine.h>
|
#include <limine.h>
|
||||||
#include "io/term.h"
|
#include "io/term/term.h"
|
||||||
#include "io/printf.h"
|
#include "io/term/printf.h"
|
||||||
#include "io/serial.h"
|
#include "io/serial/serial.h"
|
||||||
#include "mem/gdt.h"
|
#include "mem/gdt/gdt.h"
|
||||||
#include "mem/utils.h"
|
#include "mem/misc/utils.h"
|
||||||
#include "idt/idt.h"
|
#include "idt/idt.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "time/timer.h"
|
#include "time/timer.h"
|
||||||
#include "kbd/ps2.h"
|
#include "io/kbd/ps2.h"
|
||||||
|
|
||||||
// Limine version used
|
// Limine version used
|
||||||
__attribute__((used, section(".limine_requests")))
|
__attribute__((used, section(".limine_requests")))
|
||||||
@@ -48,9 +48,8 @@ void kmain()
|
|||||||
// Get the first framebuffer from the response
|
// Get the first framebuffer from the response
|
||||||
framebuffer = framebuffer_request.response->framebuffers[0];
|
framebuffer = framebuffer_request.response->framebuffers[0];
|
||||||
|
|
||||||
if (term_init()) hcf();
|
term_init();
|
||||||
|
serial_init();
|
||||||
if (serial_init()) kputs("kernel: serial: error: Cannot init serial communication!");
|
|
||||||
|
|
||||||
CLEAR_INTERRUPTS;
|
CLEAR_INTERRUPTS;
|
||||||
gdt_init();
|
gdt_init();
|
||||||
@@ -61,8 +60,8 @@ void kmain()
|
|||||||
keyboard_init(FR);
|
keyboard_init(FR);
|
||||||
|
|
||||||
// Draw something
|
// Draw something
|
||||||
printf("%s, %s!", "Hello", "world");
|
printf("%s, %s!\n", "Hello", "world");
|
||||||
|
// Yoohoooooo!
|
||||||
//printf("%d", 4/0);
|
DEBUG("kernel initialized successfully! hanging... wow=%d", 42);
|
||||||
hcf();
|
hcf();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "gdt.h"
|
#include "gdt.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "../io/serial.h"
|
#include "../../io/serial/serial.h"
|
||||||
|
#include <kernel.h>
|
||||||
|
|
||||||
// Descriptors are 8-byte wide (64bits)
|
// Descriptors are 8-byte wide (64bits)
|
||||||
// So the selectors will be (in bytes): 0x0, 0x8, 0x10, 0x18, etc..
|
// So the selectors will be (in bytes): 0x0, 0x8, 0x10, 0x18, etc..
|
||||||
@@ -78,5 +79,5 @@ void gdt_init()
|
|||||||
gdt_load();
|
gdt_load();
|
||||||
gdt_flush();
|
gdt_flush();
|
||||||
|
|
||||||
serial_kputs("kernel: gdt: Initialized GDT!\n");
|
DEBUG("GDT initialized");
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "../io/serial.h"
|
#include "../io/serial/serial.h"
|
||||||
|
#include <kernel.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
For now, the timer module will be using the PIC.
|
For now, the timer module will be using the PIC.
|
||||||
@@ -72,4 +73,5 @@ void timer_init()
|
|||||||
pic_remap();
|
pic_remap();
|
||||||
pic_enable();
|
pic_enable();
|
||||||
pit_init();
|
pit_init();
|
||||||
|
DEBUG("PIT initialized");
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user