From: Duje Mihanović Date: Tue, 7 Sep 2021 20:05:14 +0000 (+0200) Subject: Add linker script and partial VGA driver X-Git-Tag: 0.1.0~24 X-Git-Url: http://git.dujemihanovic.xyz/%22http:/www.sics.se/static/%7B%7B%20%24.Site.BaseURL%20%7D%7Dposts/%7B%7B%20.RelPermalink%20%7D%7D?a=commitdiff_plain;h=3d58037b465f917b19b0f786c334ed70e1065857;p=nameless-os.git Add linker script and partial VGA driver --- diff --git a/Makefile b/Makefile index 7001c99..c895701 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,8 @@ AS = yasm LD = i686-elf-ld CC = i686-elf-gcc +KERNEL_OBJ = kernel/entry.o kernel/arch/x86/tty/tty.o kernel/kernel.o + all: boot.img boot.img: boot kernel/kernel.bin @@ -11,16 +13,19 @@ boot.img: boot kernel/kernel.bin boot: boot.s $(AS) -f bin boot.s -o $@ -kernel/kernel.bin: kernel/entry.o kernel/kernel.o - $(LD) -o $@ -Ttext 0x1000 kernel/entry.o kernel/kernel.o --oformat=binary +kernel/kernel.bin: ${KERNEL_OBJ} + $(LD) -o $@ -T kernel/linker.ld ${KERNEL_OBJ} --oformat=binary kernel/entry.o: kernel/entry.s $(AS) -f elf kernel/entry.s -o $@ +kernel/arch/x86/tty/tty.o: kernel/arch/x86/tty/tty.c + $(CC) -o $@ -ffreestanding -c kernel/arch/x86/tty/tty.c + kernel/kernel.o: kernel/kernel.c - $(CC) -o $@ -ffreestanding -c kernel/kernel.c + $(CC) -o $@ -Iinclude/arch/x86 -ffreestanding -c kernel/kernel.c clean: - rm boot kernel/kernel.bin kernel/entry.o kernel/kernel.o boot.img + rm boot kernel/kernel.bin ${KERNEL_OBJ} boot.img .PHONY: all clean diff --git a/boot.s b/boot.s index de5887d..6181a73 100644 --- a/boot.s +++ b/boot.s @@ -97,7 +97,7 @@ pmprint .loop mov al, [ebx] ; read next char and put it in al - mov ah, 0Fh ; puts the VGA text mode color white on black into ah + mov ah, 00000111b ; puts the VGA text mode color white on black into ah cmp al, 0 ; if the next character is null, we reached end of string je .done ; so return the instruction diff --git a/include/arch/x86/tty.h b/include/arch/x86/tty.h new file mode 100644 index 0000000..ced66d7 --- /dev/null +++ b/include/arch/x86/tty.h @@ -0,0 +1,5 @@ +#ifndef X86_TTY_H +#define X86_TTY_H +extern void screen_clear(void); +extern void kprint(char *string); +#endif diff --git a/kernel/arch/x86/tty/tty.c b/kernel/arch/x86/tty/tty.c new file mode 100644 index 0000000..6d250c5 --- /dev/null +++ b/kernel/arch/x86/tty/tty.c @@ -0,0 +1,49 @@ +#define VGA_WIDTH 80 +#define VGA_HEIGHT 25 + +char *video_memory = (char *) 0xB8000; /* VGA VRAM starts at 0xB8000 */ + +static int cursor_x = 0; +static int cursor_y = 0; + +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] = 0x07; + 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(char *string) +{ + char next_char; + 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; } + if ( cursor_x >= VGA_WIDTH ) { cursor_x = 0; cursor_y++; } + if ( cursor_y >= VGA_HEIGHT ) { scroll_up(); } + next_char = *++string; + } +} diff --git a/kernel/kernel.c b/kernel/kernel.c index e04b875..c0ecb80 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -1,5 +1,14 @@ +#include + void _start(void) { - char *video_memory = (char *) 0xB8000; /* VGA VRAM starts at 0xB8000 */ - *video_memory = 'A'; /* put an A at the beginning of the VRAM */ + screen_clear(); + kprint("Hello there!\n\n\ + Hopefully your machine manages to print this text.\n\ + If it did, that's great news because I managed to write a partial VGA driver.\n\n\ + Right now, the short-term roadmap is as follows:\n\n\ + * Enable interrupts using the PIC.\n\ + * Write a driver for the Intel 8042 PS/2 controller so the OS can receive keystrokes.\n\ + * A working i8042 driver will also aid in enabling A20 Gate, which should be done ASAP so the OS can address odd (as in odd/even number) megabytes.\n\n\ + Feel free to mess around with the code, although I doubt it will be very interesting at the moment.\n"); } diff --git a/kernel/linker.ld b/kernel/linker.ld new file mode 100644 index 0000000..d68e9f2 --- /dev/null +++ b/kernel/linker.ld @@ -0,0 +1,11 @@ +ENTRY(_start) +OUTPUT_FORMAT(binary) + +SECTIONS +{ + . = 0x1000; + + .text : { *(.text) } + .data : { *(.data) } + .bss : { *(.bss) } +}