From a4534660fecb1b571c24ad82e67bc6c2fb814cb9 Mon Sep 17 00:00:00 2001 From: Danny Holman Date: Sun, 24 Jan 2021 21:10:57 -0600 Subject: x86: reorganize the i386 directory Add structure to the internals of the x86 directory. Signed-off-by: Danny Holman --- arch/i386/boot.s | 32 ---------------------- arch/i386/boot/boot.s | 32 ++++++++++++++++++++++ arch/i386/boot/crti.s | 15 +++++++++++ arch/i386/boot/crtn.s | 7 +++++ arch/i386/boot/tty.c | 55 +++++++++++++++++++++++++++++++++++++ arch/i386/boot/vga.h | 33 +++++++++++++++++++++++ arch/i386/crti.s | 15 ----------- arch/i386/crtn.s | 7 ----- arch/i386/include/gdt.h | 69 +++++++++++++++++++++++++++++++++++++++++++++++ arch/i386/kernel/pic.h | 16 +++++++++++ arch/i386/kernel/serial.c | 47 ++++++++++++++++++++++++++++++++ arch/i386/make.config | 7 ++--- arch/i386/pic.h | 16 ----------- arch/i386/serial.c | 47 -------------------------------- arch/i386/tty.c | 55 ------------------------------------- arch/i386/vga.h | 33 ----------------------- 16 files changed, 278 insertions(+), 208 deletions(-) delete mode 100644 arch/i386/boot.s create mode 100644 arch/i386/boot/boot.s create mode 100644 arch/i386/boot/crti.s create mode 100644 arch/i386/boot/crtn.s create mode 100644 arch/i386/boot/tty.c create mode 100644 arch/i386/boot/vga.h delete mode 100644 arch/i386/crti.s delete mode 100644 arch/i386/crtn.s create mode 100644 arch/i386/include/gdt.h create mode 100644 arch/i386/kernel/pic.h create mode 100644 arch/i386/kernel/serial.c delete mode 100644 arch/i386/pic.h delete mode 100644 arch/i386/serial.c delete mode 100644 arch/i386/tty.c delete mode 100644 arch/i386/vga.h (limited to 'arch/i386') diff --git a/arch/i386/boot.s b/arch/i386/boot.s deleted file mode 100644 index 56ac227..0000000 --- a/arch/i386/boot.s +++ /dev/null @@ -1,32 +0,0 @@ -.set ALIGN, 1<<0 -.set MEMINFO, 1<<1 -.set FLAGS, ALIGN | MEMINFO -.set MAGIC, 0x1BADB002 -.set CHECKSUM, -(MAGIC + FLAGS) - -.section .multiboot -.align 4 -.long MAGIC -.long FLAGS -.long CHECKSUM - -.section .bss -.align 16 -stack_bottom: -.skip 16384 -stack_top: - -.section .text -.global _start -.type _start, @function - -_start: - movl $stack_top, %esp - - call _init - call kernel_main - - cli -1: hlt - jmp 1b -.size _start, . - _start diff --git a/arch/i386/boot/boot.s b/arch/i386/boot/boot.s new file mode 100644 index 0000000..56ac227 --- /dev/null +++ b/arch/i386/boot/boot.s @@ -0,0 +1,32 @@ +.set ALIGN, 1<<0 +.set MEMINFO, 1<<1 +.set FLAGS, ALIGN | MEMINFO +.set MAGIC, 0x1BADB002 +.set CHECKSUM, -(MAGIC + FLAGS) + +.section .multiboot +.align 4 +.long MAGIC +.long FLAGS +.long CHECKSUM + +.section .bss +.align 16 +stack_bottom: +.skip 16384 +stack_top: + +.section .text +.global _start +.type _start, @function + +_start: + movl $stack_top, %esp + + call _init + call kernel_main + + cli +1: hlt + jmp 1b +.size _start, . - _start diff --git a/arch/i386/boot/crti.s b/arch/i386/boot/crti.s new file mode 100644 index 0000000..4e1e4cb --- /dev/null +++ b/arch/i386/boot/crti.s @@ -0,0 +1,15 @@ +.section .init +.global _init +.type _init, @function + +_init: + pushl %ebp + movl %esp, %ebp + +.section .fini +.global _fini +.type _fini, @function + +_fini: + pushl %ebp + movl %esp, %ebp diff --git a/arch/i386/boot/crtn.s b/arch/i386/boot/crtn.s new file mode 100644 index 0000000..447afb1 --- /dev/null +++ b/arch/i386/boot/crtn.s @@ -0,0 +1,7 @@ +.section .init + popl %ebp + ret + +.section .fini + popl %ebp + ret diff --git a/arch/i386/boot/tty.c b/arch/i386/boot/tty.c new file mode 100644 index 0000000..9c3985b --- /dev/null +++ b/arch/i386/boot/tty.c @@ -0,0 +1,55 @@ +#include "vga.h" +#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*)0xB8000; + +static size_t terminal_row; +static size_t terminal_column; +static uint8_t terminal_color; +static uint16_t *terminal_buffer; + +void tty_init(void) { + terminal_row = 0; + terminal_column = 0; + terminal_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK); + terminal_buffer = VGA_MEMORY; + for (size_t y = 0; y < VGA_HEIGHT; y++) { + for (size_t x = 0; x < VGA_WIDTH; x++) { + const size_t index = y * VGA_WIDTH + x; + terminal_buffer[index] = vga_entry(' ', terminal_color); + } + } +} + +void tty_setcolor(uint8_t color) { + terminal_color = color; +} + +void tty_putentryat(unsigned char c, uint8_t color, size_t x, size_t y) { + const size_t index = y * VGA_WIDTH + x; + terminal_buffer[index] = vga_entry(c, color); +} + +void tty_putchar(char c) { + unsigned char uc = c; + tty_putentryat(uc, terminal_color, terminal_column, terminal_row); + if (++terminal_column == VGA_WIDTH) { + terminal_column = 0; + if (++terminal_row == VGA_HEIGHT) + terminal_row = 0; + } +} + +void tty_write(const char *data, size_t size) { + for (size_t i = 0; i < size; i++) + tty_putchar(data[i]); +} + +void tty_writestring(const char *data) { + tty_write(data, strlen(data)); +} diff --git a/arch/i386/boot/vga.h b/arch/i386/boot/vga.h new file mode 100644 index 0000000..e89f202 --- /dev/null +++ b/arch/i386/boot/vga.h @@ -0,0 +1,33 @@ +#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/crti.s b/arch/i386/crti.s deleted file mode 100644 index 4e1e4cb..0000000 --- a/arch/i386/crti.s +++ /dev/null @@ -1,15 +0,0 @@ -.section .init -.global _init -.type _init, @function - -_init: - pushl %ebp - movl %esp, %ebp - -.section .fini -.global _fini -.type _fini, @function - -_fini: - pushl %ebp - movl %esp, %ebp diff --git a/arch/i386/crtn.s b/arch/i386/crtn.s deleted file mode 100644 index 447afb1..0000000 --- a/arch/i386/crtn.s +++ /dev/null @@ -1,7 +0,0 @@ -.section .init - popl %ebp - ret - -.section .fini - popl %ebp - ret diff --git a/arch/i386/include/gdt.h b/arch/i386/include/gdt.h new file mode 100644 index 0000000..4ffa155 --- /dev/null +++ b/arch/i386/include/gdt.h @@ -0,0 +1,69 @@ +#ifndef GDT_H +#define GDT_H + +#include + +#define SEG_DESCTYPE(x) ((x) << 0x04) +#define SEG_PRES(x) ((x) << 0x07) +#define SEG_SAVL(x) ((x) << 0x0C) +#define SEG_LONG(x) ((x) << 0x0D) +#define SEG_SIZE(x) ((x) << 0x0E) +#define SEG_GRAN(x) ((x) << 0x0F) +#define SEG_PRIV(x) (((x) & 0x03) << 0x05) + +#define SEG_DATA_RD 0x00 +#define SEG_DATA_RDA 0x01 +#define SEG_DATA_RDWR 0x02 +#define SEG_DATA_RDWRA 0x03 +#define SEG_DATA_RDEXPD 0x04 +#define SEG_DATA_RDEXPDA 0x05 +#define SEG_DATA_RDWREXD 0x06 +#define SEG_DATA_RDWREXDA 0x07 +#define SEG_CODE_EX 0x08 +#define SEG_CODE_EXA 0x09 +#define SEG_CODE_EXRD 0x0A +#define SEG_CODE_EXRDA 0x0B +#define SEG_CODE_EXC 0x0C +#define SEG_CODE_EXCA 0x0D +#define SEG_CODE_EXRDC 0x0E +#define SEG_CODE_EXRDCA 0x0F + +#define GDT_CODE_PL0 SEG_DESCTYPE(1) | SEG_PRES(1) | SEG_SAVL(0) | \ + SEG_LONG(0) | SEG_SIZE(1) | SEG_GRAN(1) | \ + SEG_PRIV(0) | SEG_CODE_EXRD + +#define GDT_DATA_PL0 SEG_DESCTYPE(1) | SEG_PRES(1) | SEG_SAVL(0) | \ + SEG_LONG(0) | SEG_SIZE(1) | SEG_GRAN(1) | \ + SEG_PRIV(0) | SEG_CODE_RDWR + +#define GDT_CODE_PL3 SEG_DESCTYPE(1) | SEG_PRES(1) | SEG_SAVL(0) | \ + SEG_LONG(0) | SEG_SIZE(1) | SEG_GRAN(1) | \ + SEG_PRIV(3) | SEG_DATA_EXRD + +#define GDT_DATA_PL3 SEG_DESCTYPE(1) | SEG_PRES(1) | SEG_SAVL(0) | \ + SEG_LONG(0) | SEG_SIZE(1) | SEG_GRAN(1) | \ + SEG_PRIV(3) | SEG_DATA_RDWR + +struct gdt { + uint16_t size; + uint32_t offset; +} __attribute__((packed)); + +void flush_gdt(void); + +uint64_t create_descriptor(uint32_t base, uint32_t limit, uint16_t flag) { + uint64_t descriptor; + + descriptor = limit & 0x000F0000; + descriptor |= (flag << 8) & 0x00F0FF00; + descriptor |= (base >> 16) & 0x000000FF; + descriptor |= base & 0xFF000000; + + descriptor <<= 32; + descriptor |= base << 16; + descriptor |= limit & 0x0000FFFF; + + return descriptor; +} + +#endif diff --git a/arch/i386/kernel/pic.h b/arch/i386/kernel/pic.h new file mode 100644 index 0000000..da4a2ee --- /dev/null +++ b/arch/i386/kernel/pic.h @@ -0,0 +1,16 @@ +#ifndef PIC_H +#define PIC_H + +#include + +static inline void outb(uint16_t port, uint8_t value) { + asm volatile("outb %0, %1" : : "a"(value), "Nd"(port)); +} + +static inline uint8_t inb(uint16_t port) { + uint8_t ret; + asm volatile("inb %1, %0" : "=a"(ret) : "Nd"(port)); + return ret; +} + +#endif diff --git a/arch/i386/kernel/serial.c b/arch/i386/kernel/serial.c new file mode 100644 index 0000000..20bd8f9 --- /dev/null +++ b/arch/i386/kernel/serial.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include "pic.h" + +#define PORT 0x3f8 + +int serial_init(void) { + outb(PORT + 1, 0x00); + outb(PORT + 3, 0x80); + outb(PORT + 0, 0x03); + outb(PORT + 1, 0x00); + outb(PORT + 3, 0x03); + outb(PORT + 2, 0xC7); + outb(PORT + 4, 0x0B); + outb(PORT + 4, 0x1E); + outb(PORT + 0, 0xAE); + + if (inb(PORT + 0) != 0xAE) + return -1; + + outb(PORT + 4, 0x0F); + return 0; +} + +int serial_recieved(void) { + return inb(PORT + 5) & 1; +} + +char read_serial(void) { + while (serial_recieved() == 0); + return inb(PORT); +} + +int is_transmit_empty(void) { + return inb(PORT + 5) & 0x20; +} + +void write_serial(char a) { + while (is_transmit_empty() == 0); + outb(PORT, a); +} + +void serial_writestring(const char *str) { + for (size_t i = 0; i < strlen(str); i++) + write_serial(str[i]); +} diff --git a/arch/i386/make.config b/arch/i386/make.config index 680760f..3add948 100644 --- a/arch/i386/make.config +++ b/arch/i386/make.config @@ -1,7 +1,8 @@ KERNEL_ARCH_CFLAGS= KERNEL_ARCH_LDFLAGS= KERNEL_ARCH_LIBS= +KERNEL_ARCH_INCLUDE=$(ARCHDIR)/include -KERNEL_ARCH_OBJS=$(ARCHDIR)/boot.o \ - $(ARCHDIR)/tty.o \ - $(ARCHDIR)/serial.o \ +KERNEL_ARCH_OBJS=$(ARCHDIR)/boot/boot.o \ + $(ARCHDIR)/boot/tty.o \ + $(ARCHDIR)/kernel/serial.o \ diff --git a/arch/i386/pic.h b/arch/i386/pic.h deleted file mode 100644 index da4a2ee..0000000 --- a/arch/i386/pic.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef PIC_H -#define PIC_H - -#include - -static inline void outb(uint16_t port, uint8_t value) { - asm volatile("outb %0, %1" : : "a"(value), "Nd"(port)); -} - -static inline uint8_t inb(uint16_t port) { - uint8_t ret; - asm volatile("inb %1, %0" : "=a"(ret) : "Nd"(port)); - return ret; -} - -#endif diff --git a/arch/i386/serial.c b/arch/i386/serial.c deleted file mode 100644 index 20bd8f9..0000000 --- a/arch/i386/serial.c +++ /dev/null @@ -1,47 +0,0 @@ -#include -#include -#include -#include "pic.h" - -#define PORT 0x3f8 - -int serial_init(void) { - outb(PORT + 1, 0x00); - outb(PORT + 3, 0x80); - outb(PORT + 0, 0x03); - outb(PORT + 1, 0x00); - outb(PORT + 3, 0x03); - outb(PORT + 2, 0xC7); - outb(PORT + 4, 0x0B); - outb(PORT + 4, 0x1E); - outb(PORT + 0, 0xAE); - - if (inb(PORT + 0) != 0xAE) - return -1; - - outb(PORT + 4, 0x0F); - return 0; -} - -int serial_recieved(void) { - return inb(PORT + 5) & 1; -} - -char read_serial(void) { - while (serial_recieved() == 0); - return inb(PORT); -} - -int is_transmit_empty(void) { - return inb(PORT + 5) & 0x20; -} - -void write_serial(char a) { - while (is_transmit_empty() == 0); - outb(PORT, a); -} - -void serial_writestring(const char *str) { - for (size_t i = 0; i < strlen(str); i++) - write_serial(str[i]); -} diff --git a/arch/i386/tty.c b/arch/i386/tty.c deleted file mode 100644 index 9c3985b..0000000 --- a/arch/i386/tty.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "vga.h" -#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*)0xB8000; - -static size_t terminal_row; -static size_t terminal_column; -static uint8_t terminal_color; -static uint16_t *terminal_buffer; - -void tty_init(void) { - terminal_row = 0; - terminal_column = 0; - terminal_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK); - terminal_buffer = VGA_MEMORY; - for (size_t y = 0; y < VGA_HEIGHT; y++) { - for (size_t x = 0; x < VGA_WIDTH; x++) { - const size_t index = y * VGA_WIDTH + x; - terminal_buffer[index] = vga_entry(' ', terminal_color); - } - } -} - -void tty_setcolor(uint8_t color) { - terminal_color = color; -} - -void tty_putentryat(unsigned char c, uint8_t color, size_t x, size_t y) { - const size_t index = y * VGA_WIDTH + x; - terminal_buffer[index] = vga_entry(c, color); -} - -void tty_putchar(char c) { - unsigned char uc = c; - tty_putentryat(uc, terminal_color, terminal_column, terminal_row); - if (++terminal_column == VGA_WIDTH) { - terminal_column = 0; - if (++terminal_row == VGA_HEIGHT) - terminal_row = 0; - } -} - -void tty_write(const char *data, size_t size) { - for (size_t i = 0; i < size; i++) - tty_putchar(data[i]); -} - -void tty_writestring(const char *data) { - tty_write(data, strlen(data)); -} diff --git a/arch/i386/vga.h b/arch/i386/vga.h deleted file mode 100644 index e89f202..0000000 --- a/arch/i386/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 -- cgit v1.2.3