From 61760f9301427ea56a62ec02af3d0d8ae4745be7 Mon Sep 17 00:00:00 2001 From: Danny Holman Date: Mon, 27 May 2024 13:58:00 -0500 Subject: drivers: create a subdir just for driver code Create a subdirectory branching from the project root. This directory will contain nothing but driver and device code. Signed-off-by: Danny Holman --- Makefile | 8 ++ arch/i386/include/kernel/framebuffer.h | 17 ---- arch/i386/include/kernel/keyboard.h | 32 -------- arch/i386/include/kernel/vga.h | 33 -------- arch/i386/kernel/framebuffer.c | 105 ------------------------ arch/i386/kernel/keyboard.c | 144 --------------------------------- drivers/input/keyboard.c | 142 ++++++++++++++++++++++++++++++++ drivers/video/framebuffer.c | 109 +++++++++++++++++++++++++ 8 files changed, 259 insertions(+), 331 deletions(-) delete mode 100644 arch/i386/include/kernel/framebuffer.h delete mode 100644 arch/i386/include/kernel/keyboard.h delete mode 100644 arch/i386/include/kernel/vga.h delete mode 100644 arch/i386/kernel/framebuffer.c delete mode 100644 arch/i386/kernel/keyboard.c create mode 100644 drivers/input/keyboard.c create mode 100644 drivers/video/framebuffer.c diff --git a/Makefile b/Makefile index 9a50fb6..abab3f7 100644 --- a/Makefile +++ b/Makefile @@ -36,15 +36,23 @@ KERNEL_OBJS=$(KERNEL_ARCH_OBJS) \ kernel/sched.o \ kernel/kthread.o \ +DRIVER_OBJS=drivers/video/framebuffer.o \ + drivers/input/keyboard.o \ + drivers/pci/pci.o \ + drivers/pci/ide.o \ + drivers/tty/tty_vga.o \ + OBJS=$(ARCHDIR)/boot/crti.o \ $(ARCHDIR)/crtbegin.o \ $(KERNEL_OBJS) \ + $(DRIVER_OBJS) \ $(LIBK_OBJS) \ $(ARCHDIR)/crtend.o \ $(ARCHDIR)/boot/crtn.o \ LINK_LIST=$(LDFLAGS) \ $(KERNEL_OBJS) \ + $(DRIVER_OBJS) \ $(LIBK_OBJS) \ $(LIBS) \ diff --git a/arch/i386/include/kernel/framebuffer.h b/arch/i386/include/kernel/framebuffer.h deleted file mode 100644 index ef0249c..0000000 --- a/arch/i386/include/kernel/framebuffer.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef I386_FRAMEBUFFER_H -#define I386_FRAMEBUFFER_H - -#include -#include - -void fb_init(void); -void fb_setcolor(uint8_t color); -void fb_putchar(char c); -void fb_setpos(int x, int y); - -static inline void fb_write(const char *data, size_t size) { - for (size_t i = 0; i < size; i++) - fb_putchar(data[i]); -} - -#endif diff --git a/arch/i386/include/kernel/keyboard.h b/arch/i386/include/kernel/keyboard.h deleted file mode 100644 index 7b63993..0000000 --- a/arch/i386/include/kernel/keyboard.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef I386_KEYBOARD_H -#define I386_KEYBOARD_H - -#include - -#define KB_STAT 0x64 -#define KB_DATA 0x60 - -#define KB_DIB 0x01 -#define KB_SHIFT (1<<0) -#define KB_CTL (1<<1) -#define KB_ALT (1<<2) -#define KB_CPSLK (1<<3) -#define KB_NUMLK (1<<4) -#define KB_SCLLK (1<<5) -#define KB_E0ESC (1<<6) - -#define KB_HOME 0xE0 -#define KB_END 0xE1 -#define KB_UP 0xE2 -#define KB_DOWN 0xE3 -#define KB_LEFT 0xE4 -#define KB_RGHT 0xE5 -#define KB_PGUP 0xE6 -#define KB_PGDN 0xE7 -#define KB_INS 0xE8 -#define KB_DEL 0xE9 - -char keyboard_getchar(void); -void keyboard_handler(void); - -#endif diff --git a/arch/i386/include/kernel/vga.h b/arch/i386/include/kernel/vga.h deleted file mode 100644 index e89f202..0000000 --- a/arch/i386/include/kernel/vga.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef I386_VGA_H -#define I386_VGA_H - -#include - -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_LIGHT_WHITE = 15, -}; - -static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg) { - return fg | bg << 4; -} - -static inline uint16_t vga_entry(unsigned char uc, uint8_t color) { - return (uint16_t)uc | (uint16_t)color << 8; -} - -#endif diff --git a/arch/i386/kernel/framebuffer.c b/arch/i386/kernel/framebuffer.c deleted file mode 100644 index 602bddb..0000000 --- a/arch/i386/kernel/framebuffer.c +++ /dev/null @@ -1,105 +0,0 @@ -#include -#include -#include -#include -#include -#include - -static const size_t VGA_WIDTH = 80; -static const size_t VGA_HEIGHT = 25; -static uint16_t *const VGA_MEMORY = (uint16_t*)0xC03FF000; - -static size_t fb_row; -static size_t fb_column; -static uint8_t fb_color; -static uint16_t *framebuffer; - -void _enable_cursor(uint8_t cursor_start, uint8_t cursor_end) { - outb(0x3D4, 0x0A); - outb(0x3D5, (inb(0x3D5) & 0xC0) | cursor_start); - - outb(0x3D4, 0x0B); - outb(0x3D5, (inb(0x3D5) & 0xE0) | cursor_end); -} - -void _update_cursor(size_t x, size_t y) { - uint16_t pos = y * VGA_WIDTH + x; - - outb(0x3D4, 0x0F); - outb(0x3D5, (uint8_t)(pos & 0xFF)); - outb(0x3D4, 0x0E); - outb(0x3D5, (uint8_t)((pos >> 8) & 0xFF)); -} - -void _fb_putentryat(unsigned char c, uint8_t color, size_t x, size_t y) { - const size_t index = y * VGA_WIDTH + x; - framebuffer[index] = vga_entry(c, color); -} - -void _fb_scroll(void) { - for (size_t i = 0; i < VGA_HEIGHT-1; i++) { - for (size_t j = 0; j < VGA_WIDTH; j++) - framebuffer[i * VGA_WIDTH + j] = VGA_MEMORY[(i+1) * VGA_WIDTH + j]; - } -} - -void fb_init(void) { - map_page(NULL, 0xB8000, (uintptr_t)VGA_MEMORY, 0x003); - - fb_row = 0; - fb_column = 0; - fb_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK); - framebuffer = VGA_MEMORY; - for (size_t y = 0; y < VGA_HEIGHT; y++) { - for (size_t x = 0; x < VGA_WIDTH; x++) - _fb_putentryat(' ', fb_color, x, y); - } - _enable_cursor(0, 0); - _update_cursor(0, 0); -} - -void fb_setcolor(uint8_t color) { - fb_color = color; -} - -void fb_setpos(int x, int y) { - fb_row = y; - fb_column = x; -} - -void fb_putchar(char c) { - unsigned char uc = c; - switch (uc) { - case '\r': - fb_column = 0; - break; - case '\n': - fb_column = 0; - if (++fb_row == VGA_HEIGHT) { - fb_row--; - _fb_scroll(); - } - break; - case '\t': - fb_column += 4; - if (++fb_column == VGA_WIDTH) { - fb_column = 4; - if (++fb_row == VGA_HEIGHT) { - fb_row--; - _fb_scroll(); - } - } - break; - default: - _fb_putentryat(uc, fb_color, fb_column, fb_row); - if (++fb_column == VGA_WIDTH) { - fb_column = 0; - if (++fb_row == VGA_HEIGHT) { - fb_row--; - _fb_scroll(); - } - } - break; - } - _update_cursor(fb_column, fb_row+1); -} diff --git a/arch/i386/kernel/keyboard.c b/arch/i386/kernel/keyboard.c deleted file mode 100644 index 96aea3a..0000000 --- a/arch/i386/kernel/keyboard.c +++ /dev/null @@ -1,144 +0,0 @@ -#include -#include -#include - -#define C(k) (k - '@') - -static uint8_t keymap_modifiers[256] = { - [0x1D] KB_CTL, - [0x2A] KB_SHIFT, - [0x36] KB_SHIFT, - [0x38] KB_ALT, - [0x9D] KB_CTL, - [0xB8] KB_ALT -}; - -static uint8_t keymap_toggles[256] = { - [0x3A] KB_CPSLK, - [0x45] KB_NUMLK, - [0x46] KB_SCLLK -}; - -static uint8_t keymap_normal[256] = { - 0, 0x1B, '1', '2', '3', '4', '5', '6', - '7', '8', '9', '0', '-', '=', '\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, '7', - '8', '9', '-', '4', '5', '6', '+', '1', - '2', '3', '0', '.', 0, 0, 0, 0, - [0x9C] '\n', - [0xB5] '/', - [0xC8] KB_UP, - [0xD0] KB_DOWN, - [0xC9] KB_PGUP, - [0xD1] KB_PGDN, - [0xCB] KB_LEFT, - [0xCD] KB_RGHT, - [0x97] KB_HOME, - [0xCF] KB_END, - [0xD2] KB_INS, - [0xD3] KB_DEL -}; - -static uint8_t keymap_shifted[256] = { - 0, 0x33, '!', '@', '#', '$', '%', '^', - '&', '*', '(', ')', '_', '+', '\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, '7', - '8', '9', '-', '4', '5', '6', '+', '1', - '2', '3', '0', '.', 0, 0, 0, 0, - [0x9C] '\n', - [0xB5] '/', - [0xC8] KB_UP, - [0xD0] KB_DOWN, - [0xC9] KB_PGUP, - [0xD1] KB_PGDN, - [0xCB] KB_LEFT, - [0xCD] KB_RGHT, - [0x97] KB_HOME, - [0xCF] KB_END, - [0xD2] KB_INS, - [0xD3] KB_DEL -}; - -static uint8_t keymap_control[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - C('Q'), C('W'), C('E'), C('R'), C('T'), C('Y'), C('U'), C('I'), - C('O'), C('P'), 0, 0, '\r', 0, C('A'), C('S'), - C('D'), C('F'), C('G'), C('H'), C('J'), C('K'), C('L'), 0, - 0, 0, 0, C('\\'), C('Z'), C('X'), C('C'), C('V'), - C('B'), C('N'), C('M'), 0, 0, C('/'), 0, 0, - [0x9C] '\r', - [0xB5] C('/'), - [0xC8] KB_UP, - [0xD0] KB_DOWN, - [0xC9] KB_PGUP, - [0xD1] KB_PGDN, - [0xCB] KB_LEFT, - [0xCD] KB_RGHT, - [0x97] KB_HOME, - [0xCF] KB_END, - [0xD2] KB_INS, - [0xD3] KB_DEL -}; - -static uint8_t* keymaps[4] = { - keymap_normal, - keymap_shifted, - keymap_control, - keymap_control, -}; - -char keyboard_buffer[4096]; -int kbuf_pos = 0; - -char keyboard_getchar(void) { - static int shift = 0; - uint8_t st = inb(KB_STAT); - if ((st & KB_DIB) == 0) - return -1; - - uint8_t data = inb(KB_DATA); - - if (data == 0xE0) { - shift |= KB_E0ESC; - return -1; - } else if (data & 0x80) { - if (!(shift & KB_E0ESC)) - data &= 0x7F; - shift &= ~(keymap_modifiers[data] | KB_E0ESC); - return -1; - } else if (shift & KB_E0ESC) { - data |= 0x80; - shift &= ~KB_E0ESC; - } - - shift |= keymap_modifiers[data]; - shift ^= keymap_toggles[data]; - char c = keymaps[shift & (KB_CTL | KB_SHIFT)][data]; - if (shift & KB_CPSLK) { - if ('a' <= c && c <= 'z') - c += 'A' - 'a'; - else if ('A' <= c && c <= 'Z') - c += 'a' - 'A'; - } - return c; -} - -void keyboard_handler(void) { - char c = keyboard_getchar(); - if (c != -1) - keyboard_buffer[kbuf_pos++]; - return; -} diff --git a/drivers/input/keyboard.c b/drivers/input/keyboard.c new file mode 100644 index 0000000..f2a8eba --- /dev/null +++ b/drivers/input/keyboard.c @@ -0,0 +1,142 @@ +#include +#include +#include +#include +#include +#include + +static uint8_t keymap_modifiers[256] = { + [0x1D] KB_CTL, + [0x2A] KB_SHIFT, + [0x36] KB_SHIFT, + [0x38] KB_ALT, + [0x9D] KB_CTL, + [0xB8] KB_ALT +}; + +static uint8_t keymap_toggles[256] = { + [0x3A] KB_CPSLK, + [0x45] KB_NUMLK, + [0x46] KB_SCLLK +}; + +static uint8_t keymap_normal[256] = { + 0, 0x1B, '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '-', '=', '\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, '7', + '8', '9', '-', '4', '5', '6', '+', '1', + '2', '3', '0', '.', 0, 0, 0, 0, + [0x9C] '\n', + [0xB5] '/', + [0xC8] KB_UP, + [0xD0] KB_DOWN, + [0xC9] KB_PGUP, + [0xD1] KB_PGDN, + [0xCB] KB_LEFT, + [0xCD] KB_RGHT, + [0x97] KB_HOME, + [0xCF] KB_END, + [0xD2] KB_INS, + [0xD3] KB_DEL +}; + +static uint8_t keymap_shifted[256] = { + 0, 0x33, '!', '@', '#', '$', '%', '^', + '&', '*', '(', ')', '_', '+', '\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, '7', + '8', '9', '-', '4', '5', '6', '+', '1', + '2', '3', '0', '.', 0, 0, 0, 0, + [0x9C] '\n', + [0xB5] '/', + [0xC8] KB_UP, + [0xD0] KB_DOWN, + [0xC9] KB_PGUP, + [0xD1] KB_PGDN, + [0xCB] KB_LEFT, + [0xCD] KB_RGHT, + [0x97] KB_HOME, + [0xCF] KB_END, + [0xD2] KB_INS, + [0xD3] KB_DEL +}; + +static uint8_t keymap_control[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + C('Q'), C('W'), C('E'), C('R'), C('T'), C('Y'), C('U'), C('I'), + C('O'), C('P'), 0, 0, '\r', 0, C('A'), C('S'), + C('D'), C('F'), C('G'), C('H'), C('J'), C('K'), C('L'), 0, + 0, 0, 0, C('\\'), C('Z'), C('X'), C('C'), C('V'), + C('B'), C('N'), C('M'), 0, 0, C('/'), 0, 0, + [0x9C] '\r', + [0xB5] C('/'), + [0xC8] KB_UP, + [0xD0] KB_DOWN, + [0xC9] KB_PGUP, + [0xD1] KB_PGDN, + [0xCB] KB_LEFT, + [0xCD] KB_RGHT, + [0x97] KB_HOME, + [0xCF] KB_END, + [0xD2] KB_INS, + [0xD3] KB_DEL +}; + +static uint8_t* keymaps[4] = { + keymap_normal, + keymap_shifted, + keymap_control, + keymap_control, +}; + +char keyboard_getchar(void) { + static int shift = 0; + uint8_t st = inb(KB_STAT); + if ((st & KB_DIB) == 0) + return -1; + + uint8_t data = inb(KB_DATA); + + if (data == 0xE0) { + shift |= KB_E0ESC; + return -1; + } else if (data & 0x80) { + if (!(shift & KB_E0ESC)) + data &= 0x7F; + shift &= ~(keymap_modifiers[data] | KB_E0ESC); + return -1; + } else if (shift & KB_E0ESC) { + data |= 0x80; + shift &= ~KB_E0ESC; + } + + shift |= keymap_modifiers[data]; + shift ^= keymap_toggles[data]; + char c = keymaps[shift & (KB_CTL | KB_SHIFT)][data]; + if (shift & KB_CPSLK) { + if ('a' <= c && c <= 'z') + c += 'A' - 'a'; + else if ('A' <= c && c <= 'Z') + c += 'a' - 'A'; + } + return c; +} + +void keyboard_handler(struct isr_frame *frame) { + char c = keyboard_getchar(); + if (c != -1) + tty_getchar(c); + return; +} diff --git a/drivers/video/framebuffer.c b/drivers/video/framebuffer.c new file mode 100644 index 0000000..3df3df4 --- /dev/null +++ b/drivers/video/framebuffer.c @@ -0,0 +1,109 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static size_t fb_row; +static size_t fb_column; +static uint8_t fb_color; +static uint16_t *framebuffer; + +void _enable_cursor(uint8_t cursor_start, uint8_t cursor_end) { + outb(0x3D4, 0x0A); + outb(0x3D5, (inb(0x3D5) & 0xC0) | cursor_start); + + outb(0x3D4, 0x0B); + outb(0x3D5, (inb(0x3D5) & 0xE0) | cursor_end); +} + +void _update_cursor(size_t x, size_t y) { + uint16_t pos = y * VGA_WIDTH + x; + + outb(0x3D4, 0x0F); + outb(0x3D5, (uint8_t)(pos & 0xFF)); + outb(0x3D4, 0x0E); + outb(0x3D5, (uint8_t)((pos >> 8) & 0xFF)); +} + +void _fb_putentryat(unsigned char c, uint8_t color, size_t x, size_t y) { + const size_t index = y * VGA_WIDTH + x; + framebuffer[index] = vga_entry(c, color); +} + +void _fb_scroll(void) { + for (size_t i = 0; i < VGA_HEIGHT-1; i++) { + for (size_t j = 0; j < VGA_WIDTH; j++) + framebuffer[i * VGA_WIDTH + j] = VGA_MEMORY[(i+1) * VGA_WIDTH + j]; + } +} + +void fb_init(void) { + fb_row = 0; + fb_column = 0; + fb_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK); + framebuffer = VGA_MEMORY; + for (size_t y = 0; y < VGA_HEIGHT; y++) { + for (size_t x = 0; x < VGA_WIDTH; x++) + _fb_putentryat(' ', fb_color, x, y); + } + _enable_cursor(0, 0); + _update_cursor(0, 0); +} + +void fb_setcolor(uint8_t color) { + fb_color = color; +} + +void fb_setpos(int x, int y) { + fb_row = y; + fb_column = x; + _update_cursor(fb_column, fb_row+1); +} + +void fb_offsetpos(int dx, int dy) { + fb_row += dy; + fb_column += dx; + _update_cursor(fb_column, fb_row+1); +} + +void fb_putchar(char c) { + unsigned char uc = c; + switch (uc) { + case '\r': + fb_column = 0; + break; + case '\n': + fb_column = 0; + if (++fb_row == VGA_HEIGHT) { + fb_row--; + _fb_scroll(); + } + break; + case '\t': + fb_column += 4; + if (++fb_column == VGA_WIDTH) { + fb_column = 4; + if (++fb_row == VGA_HEIGHT) { + fb_row--; + _fb_scroll(); + } + } + break; + default: + _fb_putentryat(uc, fb_color, fb_column, fb_row); + if (++fb_column == VGA_WIDTH) { + fb_column = 0; + if (++fb_row == VGA_HEIGHT) { + fb_row--; + _fb_scroll(); + } + } + break; + } + _update_cursor(fb_column, fb_row+1); +} -- cgit v1.2.3