diff --git a/CMakeLists.txt b/CMakeLists.txt index e25c6fc..a873ef1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.15) project(new_kernel C ASM) -set(CMAKE_VERBOSE_MAKEFILE ON) +#set(CMAKE_VERBOSE_MAKEFILE ON) set(CMAKE_C_FLAGS "-g -ffreestanding -Wall -Wextra -fno-exceptions -fno-stack-protector -nostdinc -nostdlib -fno-pie -m32") set(CMAKE_ASM_NASM_OBJECT_FORMAT "elf") set(CMAKE_ASM_FLAGS --32) diff --git a/kernel/cpu/idt.h b/kernel/cpu/idt.h index de9cbb2..af39a1f 100644 --- a/kernel/cpu/idt.h +++ b/kernel/cpu/idt.h @@ -1,7 +1,7 @@ // // Created by rick on 8/18/19. // -#include "../types.h" +#include #ifndef MY_KERNEL_IDT_H #define MY_KERNEL_IDT_H diff --git a/kernel/cpu/isr.c b/kernel/cpu/isr.c index 0057c9f..dd9c2e7 100644 --- a/kernel/cpu/isr.c +++ b/kernel/cpu/isr.c @@ -9,6 +9,8 @@ #include #include +#define PIC_END_OF_INTERRUPT 0x20 + isr_t interrupt_handlers[256]; void isr_install() { @@ -133,11 +135,11 @@ void register_interrupt_handler(u8 n, isr_t handler) { void irq_handler(registers_t r) { /* After every interrupt we need to send an EOI to the PICs * or they will not send another interrupt again */ - if (r.int_no >= 40) port_byte_out(0xA0, 0x20); /* slave */ - port_byte_out(0x20, 0x20); /* master */ + if (r.int_no >= 40) port_byte_out(PORT_PIC_SLAVE_COMMAND, PIC_END_OF_INTERRUPT); /* slave */ + port_byte_out(PORT_PIC_MASTER_COMMAND, PIC_END_OF_INTERRUPT); /* master */ /* Handle the interrupt in a more modular way */ - if (interrupt_handlers[r.int_no] != 0) { + if (interrupt_handlers[r.int_no] != NULL) { isr_t handler = interrupt_handlers[r.int_no]; handler(r); } diff --git a/kernel/cpu/isr.h b/kernel/cpu/isr.h index 01afdd7..982534b 100644 --- a/kernel/cpu/isr.h +++ b/kernel/cpu/isr.h @@ -2,7 +2,7 @@ // Created by rick on 8/18/19. // -#include "../types.h" +#include #ifndef MY_KERNEL_ISR_H #define MY_KERNEL_ISR_H diff --git a/kernel/cpu/timer.c b/kernel/cpu/timer.c index d5e2c9d..b20571b 100644 --- a/kernel/cpu/timer.c +++ b/kernel/cpu/timer.c @@ -7,6 +7,28 @@ #include #include +// https://wiki.osdev.org/PIT +#define PIT_MODE_BIN_BCD (1 << 0) +#define PIT_MODE_BIN (0 << 0) +#define PIT_MODE_BCD (1 << 0) +#define PIT_GENERATOR_MODE (0b111 << 1) +#define PIT_MODE_INTERRUPT_ON_TERMINAL_COUNT (0b000 < 1) +#define PIT_MODE_HARDWARE_RETRIGGERABLE_ONE_SHOT (0b001 < 1) +#define PIT_MODE_HARDWARE_RATE_GENERATOR (0b010 < 1) +#define PIT_MODE_HARDWARE_SQUARE_WAVE_GENERATOR (0b011 < 1) +#define PIT_MODE_SOFTWARE_TRIGGERED_STROBE (0b100 << 1) +#define PIT_MODE_HARDWARE_TRIGGERED_STROBE (0b101 << 1) +#define PIT_ACCESS_MODE (0b11 << 4) +#define PIT_ACCESS_MODE_LATCH_COUNT (0b00 << 4) +#define PIT_ACCESS_MODE_L (0b01 << 4) +#define PIT_ACCESS_MODE_H (0b10 << 4) +#define PIT_ACCESS_MODE_LH (0b11 << 4) +#define PIT_CHANNEL (0b11 << 6) +#define PIT_CHANNEL_0 (0b00 << 6) +#define PIT_CHANNEL_1 (0b01 << 6) +#define PIT_CHANNEL_2 (0b10 << 6) +#define PIT_CHANNEL_READ_BACK (0b11 << 6) + u32 tick = 0; static void timer_callback(registers_t regs) { @@ -19,7 +41,7 @@ int init_timer(u32 freq) { u32 divisor = 1193180 / freq; u8 low = (u8) (divisor & 0xFF); u8 high = (u8) ((divisor >> 8) & 0xFF); - port_byte_out(PORT_PIT_COMMAND, PIT_MODE_BIN | PIT_MODE_SQUARE_WAVE | PIT_ACCESS_MODE_HL | PIT_CHANNEL_0); + port_byte_out(PORT_PIT_COMMAND, PIT_MODE_BIN | PIT_MODE_HARDWARE_SQUARE_WAVE_GENERATOR | PIT_ACCESS_MODE_LH | PIT_CHANNEL_0); port_byte_out(PORT_PIT_DATA_0, low); port_byte_out(PORT_PIT_DATA_0, high); return 0; diff --git a/kernel/cpu/timer.h b/kernel/cpu/timer.h index 569348a..a91e2c3 100644 --- a/kernel/cpu/timer.h +++ b/kernel/cpu/timer.h @@ -5,7 +5,7 @@ #ifndef MY_KERNEL_TIMER_H #define MY_KERNEL_TIMER_H -#include "../types.h" +#include int init_timer(u32 freq); diff --git a/kernel/drivers/ports.h b/kernel/drivers/ports.h index fad2d61..11db0a0 100644 --- a/kernel/drivers/ports.h +++ b/kernel/drivers/ports.h @@ -1,6 +1,11 @@ #ifndef MY_KERNEL_DRIVERS_PORT_H #define MY_KERNEL_DRIVERS_PORT_H +#define PORT_PIC_MASTER_COMMAND 0x20 +#define PORT_PIC_MASTER_DATA 0x21 +#define PORT_PIC_SLAVE_COMMAND 0xA0 +#define PORT_PIC_SLAVE_DATA 0xA1 + //http://www.osdever.net/FreeVGA/vga/crtcreg.htm#0A #define PORT_REG_SCREEN_CTRL 0x3d4 #define PORT_REG_SCREEN_CTRL_CURSOR_H 0x0E @@ -26,11 +31,6 @@ // https://wiki.osdev.org/PIT #define PORT_PIT_COMMAND 0x43 -#define PIT_MODE_BIN 0x0 -#define PIT_MODE_HW_STROBE 0b0101 -#define PIT_MODE_SQUARE_WAVE 0b0110 -#define PIT_ACCESS_MODE_HL 0b000011 -#define PIT_CHANNEL_0 0b00000000 #define PORT_PIT_DATA_0 0x40 #define PORT_PIT_DATA_1 0x41 #define PORT_PIT_DATA_3 0x42 diff --git a/kernel/drivers/serial.c b/kernel/drivers/serial.c index 595c066..3ad0744 100644 --- a/kernel/drivers/serial.c +++ b/kernel/drivers/serial.c @@ -6,16 +6,73 @@ #include #include +#define SERIAL_INTERRUPT_DATA_AVAILABLE (1 << 0) +#define SERIAL_INTERRUPT_TRANSMITTER_EMPTY (1 << 1) +#define SERIAL_INTERRUPT_BREAK_ERROR (1 << 2) +#define SERIAL_INTERRUPT_STATUS_CHANGE (1 << 3) + +#define LINE_STATUS_DATA_READY (1 << 0) +#define LINE_STATUS_OVERRUN_ERROR (1 << 1) +#define LINE_STATUS_PARITY_ERROR (1 << 2) +#define LINE_STATUS_FRAMING_ERROR (1 << 3) +#define LINE_STATUS_BREAK_INDICATOR (1 << 4) +#define LINE_STATUS_TRANSMITTER_HOLDING_REGISTER_EMPTY (1 << 5) +#define LINE_STATUS_TRANSMITTER_EMPTY (1 << 6) +#define LINE_STATUS_IMPENDING_ERROR (1 << 7) + +#define LINE_CONTROL_DATA_BITS_5 (0b00) +#define LINE_CONTROL_DATA_BITS_6 (0b01) +#define LINE_CONTROL_DATA_BITS_7 (0b10) +#define LINE_CONTROL_DATA_BITS_8 (0b11) +#define LINE_CONTROL_STOP_BITS_1 (0 << 2) +#define LINE_CONTROL_STOP_BITS_1_5_2 (1 << 2) +#define LINE_CONTROL_PARTY_NONE (0b000 << 3) +#define LINE_CONTROL_PARTY_ODD (0b001 << 3) +#define LINE_CONTROL_PARTY_EVEN (0b010 << 3) +#define LINE_CONTROL_PARTY_MARK (0b101 << 3) +#define LINE_CONTROL_PARTY_SPACE (0b111 << 3) +#define LINE_CONTROL_DIVISOR (1 << 7) + +#define FIFO_CONTROL_ENABLE (1 << 0) +#define FIFO_CONTROL_CLEAR_RECEIVE (1 << 1) +#define FIFO_CONTROL_CLEAR_TRANSMIT (1 << 2) +#define FIFO_CONTROL_DMA_MODE_SELECT (1 << 3) +// reserved +#define FIFO_CONTROL_64_BYTE_ENABLE (1 << 5) +#define FIFO_CONTROL_TRIGGER_LEVEL_1_BYTE (0b00 << 6) +#define FIFO_CONTROL_TRIGGER_LEVEL_4_BYTE (0b01 << 6) +#define FIFO_CONTROL_TRIGGER_LEVEL_8_BYTE (0b10 << 6) +#define FIFO_CONTROL_TRIGGER_LEVEL_14_BYTE (0b11 << 6) + +#define MODEM_CONTROL_DATA_TERMINAL_READY (1 << 0) +#define MODEM_CONTROL_REQUEST_TO_SEND (1 << 1) +#define MODEM_CONTROL_AUX_OUTPUT_1 (1 << 2) +#define MODEM_CONTROL_AUX_OUTPUT_2 (1 << 3) +#define MODEM_CONTROL_LOOPBACK_MODE (1 << 4) +#define MODEM_CONTROL_AUTOFLOW_CONTROL_ENABLED (1 << 5) + int serial_init() { - port_byte_out(PORT_SERIAL_0 + PORT_SERIAL_INTERRUPT, 0x00); // Disable all interrupts - port_byte_out(PORT_SERIAL_0 + PORT_SERIAL_LINE_CONTROL, 0x80); // Enable DLAB (set baud rate divisor) + port_byte_out(PORT_SERIAL_0 + PORT_SERIAL_INTERRUPT, 0); // Disable all interrupts + port_byte_out(PORT_SERIAL_0 + PORT_SERIAL_LINE_CONTROL, + LINE_CONTROL_DIVISOR); // Enable DLAB (set baud rate divisor) port_byte_out(PORT_SERIAL_0 + PORT_SERIAL_DLAB_LSB, 0x03); // Set divisor to 3 (lo byte) 38400 baud port_byte_out(PORT_SERIAL_0 + PORT_SERIAL_DLAB_MSB, 0x00); // (hi byte) - port_byte_out(PORT_SERIAL_0 + PORT_SERIAL_LINE_CONTROL, 0x03); // 8 bits, no parity, one stop bit + port_byte_out(PORT_SERIAL_0 + PORT_SERIAL_LINE_CONTROL, + LINE_CONTROL_DATA_BITS_8); // 8 bits, no parity, one stop bit port_byte_out(PORT_SERIAL_0 + PORT_SERIAL_INTERRUPT_ID_FIFO, - 0xC7); // Enable FIFO, clear them, with 14-byte threshold - port_byte_out(PORT_SERIAL_0 + PORT_SERIAL_MODEM_CONTROL, 0x0B); // IRQs enabled, RTS/DSR set - port_byte_out(PORT_SERIAL_0 + PORT_SERIAL_MODEM_CONTROL, 0x1E); // Set in loopback mode, test the serial chip + FIFO_CONTROL_ENABLE + | FIFO_CONTROL_CLEAR_RECEIVE + | FIFO_CONTROL_CLEAR_TRANSMIT + | FIFO_CONTROL_TRIGGER_LEVEL_14_BYTE); // Enable FIFO, clear them, with 14-byte threshold + port_byte_out(PORT_SERIAL_0 + PORT_SERIAL_MODEM_CONTROL, + MODEM_CONTROL_DATA_TERMINAL_READY + | MODEM_CONTROL_REQUEST_TO_SEND + | MODEM_CONTROL_AUX_OUTPUT_2); // IRQs enabled, RTS/DSR set + port_byte_out(PORT_SERIAL_0 + PORT_SERIAL_MODEM_CONTROL, + MODEM_CONTROL_REQUEST_TO_SEND + | MODEM_CONTROL_AUX_OUTPUT_1 + | MODEM_CONTROL_AUX_OUTPUT_2 + | MODEM_CONTROL_LOOPBACK_MODE); // Set in loopback mode, test the serial chip port_byte_out(PORT_SERIAL_0 + PORT_SERIAL_DATA, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte) @@ -26,12 +83,16 @@ int serial_init() { // If serial is not faulty set it in normal operation mode // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled) - port_byte_out(PORT_SERIAL_0 + PORT_SERIAL_MODEM_CONTROL, 0x0F); + port_byte_out(PORT_SERIAL_0 + PORT_SERIAL_MODEM_CONTROL, + MODEM_CONTROL_DATA_TERMINAL_READY + | MODEM_CONTROL_REQUEST_TO_SEND + | MODEM_CONTROL_AUX_OUTPUT_1 + | MODEM_CONTROL_AUX_OUTPUT_2); return 0; } int is_transmit_empty() { - return port_byte_in(PORT_SERIAL_0 + PORT_SERIAL_LINE_STATUS) & 0x20; + return port_byte_in(PORT_SERIAL_0 + PORT_SERIAL_LINE_STATUS) & LINE_STATUS_TRANSMITTER_HOLDING_REGISTER_EMPTY; } void write_serial(char a) { @@ -40,7 +101,7 @@ void write_serial(char a) { port_byte_out(PORT_SERIAL_0 + PORT_SERIAL_DATA, a); } -void serial_kprint(char *msg) { +void serial_kprint(const char *msg) { u32 i = 0; while (1) { char c = msg[i]; diff --git a/kernel/drivers/serial.h b/kernel/drivers/serial.h index 049de5d..9ba5577 100644 --- a/kernel/drivers/serial.h +++ b/kernel/drivers/serial.h @@ -7,6 +7,6 @@ int serial_init(); -void serial_kprint(char *msg); +void serial_kprint(const char *msg); #endif //NEW_KERNEL_SERIAL_H diff --git a/kernel/drivers/vgascreen.c b/kernel/drivers/vgascreen.c index b345383..a271b68 100644 --- a/kernel/drivers/vgascreen.c +++ b/kernel/drivers/vgascreen.c @@ -31,7 +31,7 @@ void vga_clear_screen() { set_cursor_offset(0); } -void kprint_at(char *message, int col, int row) { +void kprint_at(const char *message, int col, int row) { int offset; if (col > 0 && row > 0) { offset = get_offset(col, row); @@ -50,7 +50,7 @@ void kprint_at(char *message, int col, int row) { } -void vga_kprint(char *message) { +void vga_kprint(const char *message) { kprint_at(message, -1, -1); } diff --git a/kernel/drivers/vgascreen.h b/kernel/drivers/vgascreen.h index 7b485a9..7940ec0 100644 --- a/kernel/drivers/vgascreen.h +++ b/kernel/drivers/vgascreen.h @@ -29,6 +29,6 @@ void vga_clear_screen(); -void vga_kprint(char *msg); +void vga_kprint(const char *msg); #endif //MY_KERNEL_VGASCREEN_H diff --git a/kernel/kernel.c b/kernel/kernel.c index fcee24d..84dd133 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -7,7 +7,7 @@ #include #include #include -#include "kprint.h" +#include char *msg_booted = "Booted Successfully!\n"; @@ -25,8 +25,7 @@ void kmain(multiboot_info_t *multiboot_info) { // vga_print_string(msg_booted, VGA_WHITE | (VGA_DARK_GRAY << VGA_SHIFT_BG)); kprint(msg_booted); kprint((char *) multiboot_info->boot_loader_name); - multiboot_memory_map_t *fe = multiboot_info->mmap_addr; - +// multiboot_memory_map_t *fe = multiboot_info->mmap_addr; // port_byte_out(0x3d4, 14); // int pos = port_byte_in(0x3d5); // pos <<= 8; diff --git a/kernel/kprint.h b/kernel/kprint.h index 86b5b34..d638b29 100644 --- a/kernel/kprint.h +++ b/kernel/kprint.h @@ -9,7 +9,7 @@ #include -typedef void (*kprint_handler)(char *); +typedef void (*kprint_handler)(const char *); void kprint_register(kprint_handler);