Fix segment error in GRUB
diff --git a/src/kernel/Makefile b/src/kernel/Makefile
index 16c5628..f8f2117 100644
--- a/src/kernel/Makefile
+++ b/src/kernel/Makefile
@@ -12,7 +12,8 @@
 			paging.o \
 			switch_table.o \
 			scan_codes.o
-CFLAGS = -nostdlib -nostdinc -fno-builtin -fno-stack-protector -ffreestanding -m32 -O2 -g
+CFLAGS = -nostdlib -nostdinc -fno-builtin -fno-stack-protector -ffreestanding \
+			-m32 -O2 -g -Wall -Wno-unused-function -Wno-unused-variable
 LDFLAGS = -Tlink.ld -melf_i386
 ASMFLAGS = -felf
 QEMUFLAGS = -d cpu_reset
diff --git a/src/kernel/boot.s b/src/kernel/boot.s
index d80261a..e235516 100644
--- a/src/kernel/boot.s
+++ b/src/kernel/boot.s
@@ -16,6 +16,9 @@
 STACK_SIZE equ 0x4000
 
 
+
+;;;;;;;;;;;;;;;;;;;;; DATA ;;;;;;;;;;;;;;;;;;;;;
+
 	[section .data align = 0x1000]
 page_directory:	
 	dd 0b010000011				; Identity map first 4 megs
@@ -23,6 +26,59 @@
 	dd 0b010000011 				; Map kernel memory to zero page too 
 	times (1024 - KERNEL_PAGE_NUMBER - 1) dd 0
 
+gdt:
+	;; First entry, null segment
+	dw 0 						; zero limit
+	dw 0						; base low
+
+	db 0 						; base middle
+	db 0						; access
+	db 0						; granularity
+	db 0						; base high
+
+	;; Second entry, code segment
+	dw 0xffffffff				; max limit
+	dw 0
+
+	db 0
+	db 0x9a						; access
+	db 0xcf 					; granularity
+	db 0
+
+	;; Third entry, data segment
+	dw 0xffffffff				; max limit
+	dw 0
+
+	db 0
+	db 0x92						; access
+	db 0xcf 					; granularity
+	db 0
+
+	;; Fourth entry, user code segment
+	dw 0xffffffff				; max limit
+	dw 0
+
+	db 0
+	db 0xfa						; access
+	db 0xcf 					; granularity
+	db 0
+
+	;; Fifth entry, user data segment
+	dw 0xffffffff				; max limit
+	dw 0
+
+	db 0
+	db 0xf2						; access
+	db 0xcf 					; granularity
+	db 0
+
+gdt_pointer:
+	dw (8 * 5 - 1)				; sizeof(gdt entry) * 5 - 1
+	dd (gdt - KERNEL_VIRTUAL_BASE) ; Remember, PHYSICAL address
+
+
+;;;;;;;;;;;;;;;;;;;;; CODE ;;;;;;;;;;;;;;;;;;;;;
+	
 	[bits 32]
 	[section .text]
 	[global mboot]
@@ -43,9 +99,21 @@
 	[global start]
 	[extern kmain]				; C code
 
-start equ (_start - KERNEL_VIRTUAL_BASE)
+start equ (_start)
 	
 _start:
+	;; First set up GDT
+	mov eax, (gdt_pointer - KERNEL_VIRTUAL_BASE)
+	lgdt [eax]					; Load GDT
+
+	mov ax, 0x10				; Offset of data segment
+	mov ds, ax
+	mov es, ax
+	mov fs, ax
+	mov gs, ax
+	mov ss, ax
+
+enable_paging:
 	mov ecx, (page_directory - KERNEL_VIRTUAL_BASE) ; Physical address
 	mov cr3, ecx
 
diff --git a/src/kernel/main.c b/src/kernel/main.c
index 59fc65c..a866852 100644
--- a/src/kernel/main.c
+++ b/src/kernel/main.c
@@ -8,6 +8,7 @@
 int kmain(void *mboot)
 {
 	init_paging();
+	init_vga();
 
 	vga_clear();
 	vga_set_color(LIGHT_BLUE, BLACK);
diff --git a/src/kernel/paging.c b/src/kernel/paging.c
index 458de21..9da17dc 100644
--- a/src/kernel/paging.c
+++ b/src/kernel/paging.c
@@ -94,7 +94,7 @@
 	kpanic("first_free_frame failed! no free frames");
 }
 
-void alloc_frame(uint *page, bool for_kernel, bool writable)
+void alloc_frame(uint *page, bool user, bool writable)
 {
 	if (*page >> 12)
 		return; /* frame already allocated */
@@ -102,6 +102,7 @@
 	uint frame = first_free_frame();
 	//	kprintf("first_free_frame found %d\n", frame);
 	set_frame(frame * 0x1000); /* mark as mapped */
+	*page = frame | 1 | writable << 1 | user << 2;
 }
 
 void free_frame(uint page)
@@ -109,7 +110,8 @@
 	clear_frame(page / 0x1000);
 }
 
-void map_4mb(size_t virt_start, size_t phys_start, bool user, bool rw)
+void map_4mb(uint *dir, size_t virt_start, size_t phys_start, bool user,
+			 bool rw)
 {
 	uint page = virt_start / 0x1000;
 	uint table = virt_start >> 22;
@@ -119,15 +121,46 @@
 		set_frame(page + i);
 	}
 
-	page_directory[table] = 0b10000011;
+	dir[table] = 0b10000011;
+}
+
+uint *get_or_create_table(uint *dir, uint table, bool user, bool rw)
+{
+	if (dir[table] >> 12)
+	{
+		return (uint *)(size_t)(dir[table] ^ 0xfff);
+	}
+
+	uint *page_table = kmalloc_a(sizeof(uint[1024]));
+	dir[table] = (uint)page_table | 1 | rw << 1 | user << 2;
+	return page_table;
+}
+
+void map_page(uint *dir, size_t virt_start, bool user, bool rw)
+{
+	uint page = virt_start / 0x1000;
+	uint table = virt_start >> 22;
+	uint frame = first_free_frame();
+
+	// If 4mb map OR (maps to table AND table maps page)
+	if ((dir[table] & 1 && dir[table] & 1 << 7) ||
+		(dir[table] >> 12 && ((uint *)(size_t)dir[table])[page] & 1))
+	{
+		return;
+	}
+
+	set_frame(frame);
+	uint *t = get_or_create_table(dir, table, user, rw);
+	alloc_frame(t + page, user, rw);
 }
 
 /* paging stuff */
 
 void init_paging()
 {
+	frames = kmalloc_a(0x1000);
 	memset(page_directory, 0, 1024 * 4);
-	page_directory[KERNEL_PAGE_NUMBER] = 0b10000011;
+	map_4mb(page_directory, (size_t)KERNEL_VIRTUAL_BASE, 0, false, false);
 
 	load_page_directory((uint)page_directory - 0xC0000000);
 	add_interrupt_handler(14, page_fault);
diff --git a/src/kernel/vga.c b/src/kernel/vga.c
index de5e998..9edbdc4 100644
--- a/src/kernel/vga.c
+++ b/src/kernel/vga.c
@@ -1,5 +1,6 @@
 #include "vga.h"
 #include "io.h"
+#include "paging.h"
 #include "log.h"
 
 static uint cursor_x = 0;
@@ -7,16 +8,18 @@
 
 static ushort color = WHITE;
 
-static ushort *fb = (ushort *)(0xB8000 + 0xC0000000);
+static ushort *fb = (ushort *)PHYS_TO_VIRT(0xB8000);
 
 static void move_cursor()
 {
-	ushort loc = cursor_y * 80 + cursor_x;
-	outb(0x3d4, 14); // Setting high cursor byte
-	outb(0x3d4, loc >> 8);
+	ushort pos = cursor_y * 80 + cursor_x;
 
-	outb(0x3d4, 15); // low byte
-	outb(0x3d4, loc & 0xff);
+	outb(0x3d4, 0x0e);
+	outb(0x3d5, pos >> 8);
+	outb(0x3d4, 0x0f);
+	outb(0x3d5, pos & 0xff);
+
+	io_wait();
 }
 
 static void scroll()
@@ -39,7 +42,7 @@
 
 void vga_set_color(enum vga_colors fg, enum vga_colors bg)
 {
-	color = (bg << 4) | fg & 0xf;
+	color = (bg << 4) | (fg & 0xf);
 }
 
 void vga_put(char c)
@@ -108,8 +111,8 @@
 
 static bool vga_put_nibble(uchar n, bool first)
 {
-//	if (first && n == 0)
-//		return true;
+	//	if (first && n == 0)
+	//		return true;
 
 	if (n <= 9)
 		vga_put('0' + n);
@@ -131,3 +134,18 @@
 		first = vga_put_nibble(byte & 0x0f, first);
 	}
 }
+
+void init_vga()
+{
+	return;
+
+	outb(0x3D4, 0x09); // set maximum scan line register to 15
+	outb(0x3D5, 15);
+
+	outb(0x3D4, 0x0B); // set the cursor end line to 15
+	outb(0x3D5, 15);
+
+	outb(0x3D4, 0x0A); // set the cursor start line to 14 and enable cursor
+					   // visibility
+	outb(0x3D5, 10);
+}
diff --git a/src/kernel/vga.h b/src/kernel/vga.h
index 9c7ba16..d68a6d9 100644
--- a/src/kernel/vga.h
+++ b/src/kernel/vga.h
@@ -28,3 +28,5 @@
 void vga_putx(uint x);
 void vga_clear();
 void vga_write(char *c);
+
+void init_vga();