include arch/x86/irq/Makefile
-include arch/x86/tty/Makefile
-KERNEL_OBJ += $(addprefix arch/x86/, entry.o halt.o)
+KERNEL_OBJ += $(addprefix arch/x86/, entry.o halt.o tty.o)
#include <irq/idt.h>
#include <irq/interrupt.h>
-#include <tty.h>
+#include <kprint.h>
#include <stddef.h>
#include <irq/i8259a.h>
{
int interrupt = frame->interrupt;
if (int_handler_table[interrupt] == NULL) {
- kprint("WARNING: Unhandled interrupt ", 0);
+ kprint("WARNING: Unhandled interrupt ", VGA_YELLOW, VGA_BLACK);
kprintb(interrupt, 1);
- kprint(" occurred!\n", 0);
+ kprint(" occurred!\n", VGA_YELLOW, VGA_BLACK);
} else {
int ret = (*int_handler_table[interrupt])(frame);
if (ret) {
- kprint("WARNING: Error while handling interrupt ", 0);
+ kprint("WARNING: Error while handling interrupt ", VGA_YELLOW, VGA_BLACK);
kprintb(interrupt, 1);
- kprint("!\n", 0);
+ kprint("!\n", VGA_YELLOW, VGA_BLACK);
}
}
if (interrupt >= 0x20) {
--- /dev/null
+#include <io.h>
+#include <tty.h>
+#include <stdint.h>
+
+#define VGA_WIDTH 80
+#define VGA_HEIGHT 25
+
+static int cursor_x = 0; /* keep track of where cursor is */
+static int cursor_y = 0;
+static uint16_t crtc_port;
+
+static inline uint8_t vga_get_color(const enum vga_color fg, const enum vga_color bg)
+{
+ return fg&0xf | bg<<4;
+}
+
+static inline uint16_t vga_get_char(const enum vga_color fg, const enum vga_color bg, char character)
+{
+ return character | vga_get_color(fg, bg)<<8;
+}
+
+static inline char *vga_get_memory_address(int x, int y)
+{
+ return (char *) 0xb8000 + (y*VGA_WIDTH + x)*2;
+}
+
+static void vga_scroll_up(void)
+{
+ for (int y=1; y<VGA_HEIGHT; y++) {
+ for (int x = 0; x<VGA_WIDTH; x++) {
+ *vga_get_memory_address(x, y-1) = *vga_get_memory_address(x, y);
+ }
+ }
+
+ for (int x = 0; x<VGA_WIDTH; x++) {
+ *vga_get_memory_address(x, VGA_HEIGHT-1) = vga_get_char(VGA_LIGHT_GRAY, VGA_BLACK, ' ');
+ }
+ cursor_y = VGA_HEIGHT - 1;
+}
+
+static void vga_set_cursor(int x, int y)
+{
+ uint16_t cursor_address = y*VGA_WIDTH + x;
+
+ outb(crtc_port, 0xe);
+ outb(crtc_port+1, cursor_address>>8);
+ outb(crtc_port, 0xf);
+ outb(crtc_port+1, cursor_address);
+}
+
+static void vga_screen_clear(void)
+{
+ for (int y=0; y<VGA_HEIGHT; y++) {
+ for (int x=0; x<VGA_WIDTH; x++) {
+ *vga_get_memory_address(x, y) = vga_get_char(VGA_LIGHT_GRAY, VGA_BLACK, ' ');
+ }
+ }
+
+ cursor_x = 0;
+ cursor_y = 0;
+ vga_set_cursor(0, 0);
+}
+
+void vga_print_char(const char character, const enum vga_color fg, const enum vga_color bg)
+{
+ if (character == '\n') {
+ cursor_x = 0;
+ cursor_y++;
+ } else {
+ *vga_get_memory_address(cursor_x, cursor_y) = vga_get_char(fg, bg, character);
+ cursor_x++;
+ }
+
+ if (cursor_x >= VGA_WIDTH) {
+ cursor_x = 0;
+ cursor_y++;
+ }
+
+ if (cursor_y >= VGA_HEIGHT)
+ vga_scroll_up();
+
+ vga_set_cursor(cursor_x, cursor_y);
+}
+
+void vga_initialize()
+{
+ uint8_t vga_misc = inb(0x3cc);
+ if (vga_misc&1)
+ crtc_port = 0x3d4;
+ else
+ crtc_port = 0x3b4;
+
+ vga_screen_clear();
+}
+++ /dev/null
-KERNEL_OBJ += arch/x86/tty/tty.o
+++ /dev/null
-#include <io.h>
-#include <tty.h>
-#include <stdint.h>
-
-#define VGA_WIDTH 80
-#define VGA_HEIGHT 25
-
-volatile char *video_memory = (char *) 0xB8000; /* VGA VRAM starts at 0xB8000 */
-
-static int cursor_x = 0; /* keep track of where cursor is */
-static int cursor_y = 0;
-
-char *hex_chars = "0123456789ABCDEF";
-
-void screen_clear(void)
-{
- int x, y;
- for ( y = 0; y < VGA_HEIGHT; y++ ) {
- for ( x = 0; x < VGA_WIDTH; x++ ) {
- video_memory[(y * VGA_WIDTH + x) * 2 + 1] = VGA_COLOR_LIGHT_GRAY;
- video_memory[(y * VGA_WIDTH + x) * 2] = ' ';
- }
- }
-
- cursor_x = 0;
- cursor_y = 0;
-}
-
-void scroll_up(void)
-{
- int x, y;
- for ( y = 1; y < VGA_HEIGHT; y++ ) {
- for ( x = 0; x < VGA_WIDTH; x++ ) {
- video_memory[((y - 1) * VGA_WIDTH + x) * 2] = video_memory[(y * VGA_WIDTH + x) * 2];
- }
- }
- for ( x = 0; x < VGA_WIDTH; x++ ) {
- video_memory[((VGA_HEIGHT - 1) * VGA_WIDTH + x) * 2] = ' ';
- }
- cursor_y = VGA_HEIGHT - 1;
-}
-
-void kprint(const char *string, uint8_t color)
-{
- char next_char;
- uint8_t vga_misc_output;
- uint16_t crtc_port;
- next_char = *string;
-
- while ( next_char != 0 ) {
- if ( next_char == '\n') { cursor_x = 0; cursor_y++; }
- else { video_memory[(cursor_y * VGA_WIDTH + cursor_x) * 2] = next_char; video_memory[((cursor_y * VGA_WIDTH + cursor_x++) * 2)+ 1] = color != 0 ? color : VGA_COLOR_LIGHT_GRAY; }
- if ( cursor_x >= VGA_WIDTH ) { cursor_x = 0; cursor_y++; }
- if ( cursor_y >= VGA_HEIGHT ) { scroll_up(); }
- next_char = *++string;
- }
-
- vga_misc_output = inb(0x3CC);
- if (vga_misc_output & 0x1 == 0) {
- crtc_port = 0x3B4;
- } else {
- crtc_port = 0x3D4;
- }
-
- outb(crtc_port, 0xE);
- outb(crtc_port + 1, (cursor_y * VGA_WIDTH + cursor_x) >> 8);
- outb(crtc_port, 0xF);
- outb(crtc_port + 1, (cursor_y * VGA_WIDTH + cursor_x) & 0xFF);
-}
-
-void kprintc(const char character, uint8_t color)
-{
- uint8_t vga_misc_output;
- uint16_t crtc_port;
-
- if ( character == '\n') { cursor_x = 0; cursor_y++; }
- else { video_memory[(cursor_y * VGA_WIDTH + cursor_x) * 2] = character; video_memory[((cursor_y * VGA_WIDTH + cursor_x++) * 2)+ 1] = color != 0 ? color : VGA_COLOR_LIGHT_GRAY; }
- if ( cursor_x >= VGA_WIDTH ) { cursor_x = 0; cursor_y++; }
- if ( cursor_y >= VGA_HEIGHT ) { scroll_up(); }
-
- vga_misc_output = inb(0x3CC);
- if (vga_misc_output & 0x1 == 0) {
- crtc_port = 0x3B4;
- } else {
- crtc_port = 0x3D4;
- }
-
- outb(crtc_port, 0xE);
- outb(crtc_port + 1, (cursor_y * VGA_WIDTH + cursor_x) >> 8);
- outb(crtc_port, 0xF);
- outb(crtc_port + 1, (cursor_y * VGA_WIDTH + cursor_x) & 0xFF);
-
-}
-
-void kprintnibble(uint8_t nibble)
-{
- nibble &= 0xf;
- if (nibble < 0xa)
- kprintc('0' + nibble, 0);
- else kprintc('a' - 0xa + nibble, 0);
-}
-
-void kprintb(uint8_t byte, int print_delm)
-{
- if (print_delm)
- kprint("0x", 0);
-
- kprintnibble(byte >> 4);
- kprintnibble(byte);
-}
-
-void kprintw(uint16_t word, int print_delm)
-{
- if (print_delm)
- kprint("0x", 0);
-
- kprintb(word >> 8, 0);
- kprintb(word, 0);
-}
-
-void kprintd(uint32_t dword, int print_delm)
-{
- if (print_delm)
- kprint("0x", 0);
-
- kprintw(dword >> 16, 0);
- kprintw(dword, 0);
-}
-
-void kprintq(uint64_t qword, int print_delm)
-{
- if (print_delm)
- kprint("0x", 0);
-
- kprintd(qword >> 32, 0);
- kprintd(qword, 0);
-}
-
-int kprintdec(uint32_t num, uint8_t color)
-{
- char buffer[11];
- int digits = 10;
- /* TODO: make an actual memset function to use instead of this */
- for (int i=0; i<11; i++) {
- buffer[i] = 0;
- }
-
- /* put the numbers in the buffer */
- for (int i=9; i>0 && num>0; i--) {
- uint8_t currdigit = num%10;
- buffer[i] = currdigit+'0';
- num /= 10;
- }
-
- /* shift the array as much as needed */
- while (*buffer == '\0') {
- digits--;
- for (int i=0; i<9; i++) {
- buffer[i] = buffer[i+1];
- }
- }
-
- /* zero out any leftovers */
- if (digits < 10) {
- for (int i=digits; i<10; i++) {
- buffer[i] = '\0';
- }
- }
-
- kprint(buffer, color);
- return digits;
-}
--- /dev/null
+#ifndef X86_TTY_H
+#define X86_TTY_H
+
+enum vga_color {
+ VGA_BLACK,
+ VGA_BLUE,
+ VGA_GREEN,
+ VGA_TEAL,
+ VGA_DARK_RED,
+ VGA_MAGENTA,
+ VGA_BROWN,
+ VGA_LIGHT_GRAY,
+ VGA_DARK_GRAY,
+ VGA_PURPLE,
+ VGA_LIME,
+ VGA_CYAN,
+ VGA_BRIGHT_RED,
+ VGA_PINK,
+ VGA_YELLOW,
+ VGA_WHITE
+};
+
+extern void vga_initialize(void);
+extern void vga_print_char(const char character, enum vga_color fg, enum vga_color bg);
+#endif
--- /dev/null
+#ifndef KPRINT_H
+#define KPRINT_H
+
+#include <stdint.h>
+#include <tty.h>
+
+extern void tty_initialize();
+extern void kprint(const char *string, const enum vga_color fg, const enum vga_color bg);
+extern void kprintc(const char character, const enum vga_color fg, const enum vga_color bg);
+extern void kprintnibble(uint8_t nibble);
+extern void kprintb(const uint8_t byte, const int print_delm);
+extern void kprintw(const uint16_t word, const int print_delm);
+extern void kprintd(const uint32_t dword, const int print_delm);
+extern void kprintq(const uint64_t qword, const int print_delm);
+extern int kprintdec(uint32_t num, const enum vga_color fg, const enum vga_color bg);
+
+#endif
extern void halt();
#define PANIC(msg) \
- kprint("PANIC (", VGA_COLOR_BRIGHT_RED);\
- kprint(msg, VGA_COLOR_BRIGHT_RED);\
- kprint(") in ", VGA_COLOR_BRIGHT_RED);\
- kprint(__FILE__, VGA_COLOR_BRIGHT_RED);\
- kprintc(':', VGA_COLOR_BRIGHT_RED);\
- kprintdec(__LINE__, VGA_COLOR_BRIGHT_RED);\
- kprintc(':', VGA_COLOR_BRIGHT_RED);\
- kprint(__func__, VGA_COLOR_BRIGHT_RED);\
- kprint("()", VGA_COLOR_BRIGHT_RED);\
+ kprint("PANIC (", VGA_BRIGHT_RED, VGA_BLACK);\
+ kprint(msg, VGA_BRIGHT_RED, VGA_BLACK);\
+ kprint(") in ", VGA_BRIGHT_RED, VGA_BLACK);\
+ kprint(__FILE__, VGA_BRIGHT_RED, VGA_BLACK);\
+ kprintc(':', VGA_BRIGHT_RED, VGA_BLACK);\
+ kprintdec(__LINE__, VGA_BRIGHT_RED, VGA_BLACK);\
+ kprintc(':', VGA_BRIGHT_RED, VGA_BLACK);\
+ kprint(__func__, VGA_BRIGHT_RED, VGA_BLACK);\
+ kprint("()", VGA_BRIGHT_RED, VGA_BLACK);\
halt();
#endif
+++ /dev/null
-#ifndef TTY_H
-#define TTY_H
-
-#include <stdint.h>
-
-#define VGA_COLOR_BLACK 0x0
-#define VGA_COLOR_BLUE 0x1
-#define VGA_COLOR_GREEN 0x2
-#define VGA_COLOR_TEAL 0x3
-#define VGA_COLOR_DARK_RED 0x4
-#define VGA_COLOR_MAGENTA 0x5
-#define VGA_COLOR_BROWN 0x6
-#define VGA_COLOR_LIGHT_GRAY 0x7
-#define VGA_COLOR_DARK_GRAY 0x8
-#define VGA_COLOR_PURPLE 0x9
-#define VGA_COLOR_LIME 0xA
-#define VGA_COLOR_CYAN 0xB
-#define VGA_COLOR_BRIGHT_RED 0xC
-#define VGA_COLOR_PINK 0xD
-#define VGA_COLOR_YELLOW 0xE
-#define VGA_COLOR_WHITE 0xF
-
-extern void screen_clear(void);
-extern void kprint(const char *string, uint8_t color);
-extern void kprintc(const char character, uint8_t color);
-extern void kprintb(uint8_t byte, int print_delm);
-extern void kprintw(uint16_t word, int print_delm);
-extern void kprintd(uint32_t dword, int print_delm);
-extern void kprintq(uint64_t qword, int print_delm);
-extern int kprintdec(uint32_t num, uint8_t color);
-#endif
-KERNEL_OBJ += kernel/kernel.o
+KERNEL_OBJ += $(addprefix kernel/, kernel.o kprint.o)
-#include <tty.h>
+#include <kprint.h>
#include <io.h>
#include <irq/idt.h>
#include <irq/interrupt.h>
void print_e820(struct e820_map *mmap, int mmap_size)
{
- kprint(" Base | Length | Type | Attrib |\n", 0);
- kprint("------------------------------------------------------------\n", 0);
+ kprint(" Base | Length | Type | Attrib |\n", VGA_LIGHT_GRAY, VGA_BLACK);
+ kprint("------------------------------------------------------------\n", VGA_LIGHT_GRAY, VGA_BLACK);
for (int i=0; i<mmap_size; i++) {
kprintq(mmap[i].base, 1);
- kprintc('|', 0);
+ kprintc('|', VGA_LIGHT_GRAY, VGA_BLACK);
kprintq(mmap[i].length, 1);
- kprintc('|', 0);
+ kprintc('|', VGA_LIGHT_GRAY, VGA_BLACK);
kprintd(mmap[i].type, 1);
- kprintc('|', 0);
+ kprintc('|', VGA_LIGHT_GRAY, VGA_BLACK);
kprintd(mmap[i].attrib, 1);
- kprintc('|', 0);
- kprintc('\n', 0);
+ kprintc('|', VGA_LIGHT_GRAY, VGA_BLACK);
+ kprintc('\n', VGA_LIGHT_GRAY, VGA_BLACK);
}
}
/* Small handler for double faults. Will be put elsewhere eventually. */
int double_fault_handler(struct interrupt_frame *frame)
{
- kprint("Double fault occurred!\n", VGA_COLOR_BRIGHT_RED);
- kprint("EAX: ", 0);
+ kprint("Double fault occurred!\n", VGA_BRIGHT_RED, VGA_BLACK);
+ kprint("EAX: ", VGA_LIGHT_GRAY, VGA_BLACK);
kprintd(frame->eax, 1);
- kprintc(' ', 0);
- kprint("EBX: ", 0);
+ kprintc(' ', VGA_LIGHT_GRAY, VGA_BLACK);
+ kprint("EBX: ", VGA_LIGHT_GRAY, VGA_BLACK);
kprintd(frame->ebx, 1);
- kprintc(' ', 0);
- kprint("ECX: ", 0);
+ kprintc(' ', VGA_LIGHT_GRAY, VGA_BLACK);
+ kprint("ECX: ", VGA_LIGHT_GRAY, VGA_BLACK);
kprintd(frame->ecx, 1);
- kprintc(' ', 0);
- kprint("EDX: ", 0);
+ kprintc(' ', VGA_LIGHT_GRAY, VGA_BLACK);
+ kprint("EDX: ", VGA_LIGHT_GRAY, VGA_BLACK);
kprintd(frame->edx, 1);
- kprintc('\n', 0);
- kprint("EBP: ", 0);
+ kprintc('\n', VGA_LIGHT_GRAY, VGA_BLACK);
+ kprint("EBP: ", VGA_LIGHT_GRAY, VGA_BLACK);
kprintd(frame->ebp, 1);
- kprintc(' ', 0);
- kprint("ESP: ", 0);
+ kprintc(' ', VGA_LIGHT_GRAY, VGA_BLACK);
+ kprint("ESP: ", VGA_LIGHT_GRAY, VGA_BLACK);
kprintd(frame->esp, 1);
- kprintc('\n', 0);
- kprint("ESI: ", 0);
+ kprintc('\n', VGA_LIGHT_GRAY, VGA_BLACK);
+ kprint("ESI: ", VGA_LIGHT_GRAY, VGA_BLACK);
kprintd(frame->esi, 1);
- kprintc(' ', 0);
- kprint("EDI: ", 0);
+ kprintc(' ', VGA_LIGHT_GRAY, VGA_BLACK);
+ kprint("EDI: ", VGA_LIGHT_GRAY, VGA_BLACK);
kprintd(frame->edi, 1);
- kprintc('\n', 0);
- kprint("EIP: ", 0);
+ kprintc('\n', VGA_LIGHT_GRAY, VGA_BLACK);
+ kprint("EIP: ", VGA_LIGHT_GRAY, VGA_BLACK);
kprintd(frame->eip, 1);
- kprintc(' ', 0);
- kprint("EFLAGS: ", 0);
+ kprintc(' ', VGA_LIGHT_GRAY, VGA_BLACK);
+ kprint("EFLAGS: ", VGA_LIGHT_GRAY, VGA_BLACK);
kprintd(frame->eflags, 1);
- kprintc('\n', 0);
+ kprintc('\n', VGA_LIGHT_GRAY, VGA_BLACK);
PANIC("double fault");
}
void kmain(struct e820_map *mmap, int mmap_size)
{
- screen_clear();
- kprint("Welcome to Nameless OS!\nRunning revision: ", 0);
- kprint(GIT_COMMIT, 0);
- kprint("\n", 0);
- kprint("BIOS memory map:\n", 0);
+ vga_initialize();
+ kprint("Welcome to Nameless OS!\nRunning revision: ", VGA_LIGHT_GRAY, VGA_BLACK);
+ kprint(GIT_COMMIT, VGA_LIGHT_GRAY, VGA_BLACK);
+ kprint("\n", VGA_LIGHT_GRAY, VGA_BLACK);
+ kprint("BIOS memory map:\n", VGA_LIGHT_GRAY, VGA_BLACK);
print_e820(mmap, mmap_size);
- kprint("Preparing IDT...\n", 0);
+ kprint("Preparing IDT...\n", VGA_LIGHT_GRAY, VGA_BLACK);
for (int i=0; i<48; i++) {
idt_set_descriptor(idt, i, 0x8, _int_handler_table[i], IDT_INTERRUPT_GATE, 0);
}
- kprint("IDT prepared, loading...\n", 0);
+ kprint("IDT prepared, loading...\n", VGA_LIGHT_GRAY, VGA_BLACK);
populate_idtr(&idtr, idt);
load_idt(idtr);
- kprint("Setting up interrupts...\n", 0);
+ kprint("Setting up interrupts...\n", VGA_LIGHT_GRAY, VGA_BLACK);
register_interrupt(8, &double_fault_handler);
pic_init(0x20, 0x28);
pic_mask_all();
asm volatile ("sti");
- kprint("All done\n", 0);
+ kprint("All done\n", VGA_LIGHT_GRAY, VGA_BLACK);
while(1);
}
--- /dev/null
+#include <stdint.h>
+#include <kprint.h>
+
+void tty_initialize()
+{
+ vga_initialize();
+}
+
+void kprint(const char *string, const enum vga_color fg, const enum vga_color bg)
+{
+ char character = *string;
+ for (int i=1; character; i++) {
+ vga_print_char(character, fg, bg);
+ character = string[i];
+ }
+}
+
+void kprintc(const char character, const enum vga_color fg, const enum vga_color bg)
+{
+ vga_print_char(character, fg, bg);
+}
+
+void kprintnibble(uint8_t nibble)
+{
+ nibble &= 0xf;
+ if (nibble < 0xa)
+ kprintc('0' + nibble, VGA_LIGHT_GRAY, VGA_BLACK);
+ else kprintc('a' - 0xa + nibble, VGA_LIGHT_GRAY, VGA_BLACK);
+}
+
+void kprintb(const uint8_t byte, const int print_delm)
+{
+ if (print_delm)
+ kprint("0x", VGA_LIGHT_GRAY, VGA_BLACK);
+
+ kprintnibble(byte >> 4);
+ kprintnibble(byte);
+}
+
+void kprintw(const uint16_t word, const int print_delm)
+{
+ if (print_delm)
+ kprint("0x", VGA_LIGHT_GRAY, VGA_BLACK);
+
+ kprintb(word >> 8, 0);
+ kprintb(word, 0);
+}
+
+void kprintd(const uint32_t dword, const int print_delm)
+{
+ if (print_delm)
+ kprint("0x", VGA_LIGHT_GRAY, VGA_BLACK);
+
+ kprintw(dword >> 16, 0);
+ kprintw(dword, 0);
+}
+
+void kprintq(const uint64_t qword, const int print_delm)
+{
+ if (print_delm)
+ kprint("0x", VGA_LIGHT_GRAY, VGA_BLACK);
+
+ kprintd(qword >> 32, 0);
+ kprintd(qword, 0);
+}
+
+int kprintdec(uint32_t num, const enum vga_color fg, const enum vga_color bg)
+{
+ char buffer[11];
+ int digits = 10;
+ /* TODO: make an actual memset function to use instead of this */
+ for (int i=0; i<11; i++) {
+ buffer[i] = 0;
+ }
+
+ /* put the numbers in the buffer */
+ for (int i=9; i>0 && num>0; i--) {
+ const uint8_t currdigit = num%10;
+ buffer[i] = currdigit+'0';
+ num /= 10;
+ }
+
+ /* shift the array as much as needed */
+ while (*buffer == '\0') {
+ digits--;
+ for (int i=0; i<9; i++) {
+ buffer[i] = buffer[i+1];
+ }
+ }
+
+ /* zero out any leftovers */
+ if (digits < 10) {
+ for (int i=digits; i<10; i++) {
+ buffer[i] = '\0';
+ }
+ }
+
+ kprint(buffer, fg, bg);
+ return digits;
+}