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
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
.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
--- /dev/null
+#ifndef X86_TTY_H
+#define X86_TTY_H
+extern void screen_clear(void);
+extern void kprint(char *string);
+#endif
--- /dev/null
+#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;
+ }
+}
+#include <tty.h>
+
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");
}
--- /dev/null
+ENTRY(_start)
+OUTPUT_FORMAT(binary)
+
+SECTIONS
+{
+ . = 0x1000;
+
+ .text : { *(.text) }
+ .data : { *(.data) }
+ .bss : { *(.bss) }
+}