diff --git a/ableos/.cargo/config.toml b/ableos/.cargo/config.toml
index 3526375..75f0784 100644
--- a/ableos/.cargo/config.toml
+++ b/ableos/.cargo/config.toml
@@ -9,3 +9,5 @@ build-std = ["core", "compiler_builtins"]
 [target.'cfg(target_arch = "x86_64")']
 # --quiet suppresses warning messages from the bootimage crate
 runner = "bootimage runner --quiet"
+[target.riscv64gc-unknown-none-elf]
+rustflags = "-C link-arg=-T../ableos/src/arch/riscv/virt.lds"
diff --git a/ableos/src/arch/riscv/asm/boot.asm b/ableos/src/arch/riscv/asm/boot.asm
deleted file mode 100644
index 2259f6c..0000000
--- a/ableos/src/arch/riscv/asm/boot.asm
+++ /dev/null
@@ -1,58 +0,0 @@
-.S
-# bootloader for SoS
-# Stephen Marz
-# 8 February 2019
-.option norvc
-.section .data
-
-.section .text.init
-.global _start
-_start:
-	# Any hardware threads (hart) that are not bootstrapping
-	# need to wait for an IPI
-	csrr	t0, mhartid
-	bnez	t0, 3f
-	# SATP should be zero, but let's make sure
-	csrw	satp, zero
-.option push
-.option norelax
-	la		gp, _global_pointer
-.option pop
-
-	# The BSS section is expected to be zero
-	la 		a0, _bss_start
-	la		a1, _bss_end
-	bgeu	a0, a1, 2f
-1:
-	sd		zero, (a0)
-	addi	a0, a0, 8
-	bltu	a0, a1, 1b
-2:
-
-
-
-3:
-	wfi
-	j	3b
-
-# Control registers, set the stack, mstatus, mepc,
-# and mtvec to return to the main function.
-# li		t5, 0xffff;
-# csrw	medeleg, t5
-# csrw	mideleg, t5
-la		sp, _stack
-# We use mret here so that the mstatus register
-# is properly updated.
-li		t0, (0b11 << 11) | (1 << 7) | (1 << 3)
-csrw	mstatus, t0
-la		t1, kernel_main
-csrw	mepc, t1
-la		t2, asm_trap_vector
-csrw	mtvec, t2
-li		t3, (1 << 3) | (1 << 7) | (1 << 11)
-csrw	mie, t3
-la		ra, 4f
-mret
-4:
-	wfi
-	j	4b
diff --git a/ableos/src/arch/riscv/asm/trap.asm b/ableos/src/arch/riscv/asm/trap.asm
deleted file mode 100644
index 60e9351..0000000
--- a/ableos/src/arch/riscv/asm/trap.asm
+++ /dev/null
@@ -1,8 +0,0 @@
-# trap.S
-# Assembly-level trap handler.
-.section .text
-.global asm_trap_vector
-asm_trap_vector:
-    # We get here when the CPU is interrupted
-	# for any reason.
-    mret
diff --git a/ableos/src/arch/riscv/drivers/graphics.rs b/ableos/src/arch/riscv/drivers/graphics.rs
new file mode 100644
index 0000000..66ad297
--- /dev/null
+++ b/ableos/src/arch/riscv/drivers/graphics.rs
@@ -0,0 +1,31 @@
+use crate::driver_traits::graphics::{Graphics, Point, Rgb};
+
+pub struct GraphicsBuffer;
+
+#[allow(unused)]
+impl Graphics for GraphicsBuffer {
+    fn put_line(coords_start: Point, coords_end: Point, thickness: u32, color: Rgb) {
+        todo!()
+    }
+    fn put_rect(coords_start: Point, coords_end: Point, color: Rgb) {
+        todo!()
+    }
+    fn put_circle(coords: Point, radius: u32) {
+        todo!()
+    }
+    fn put_triangle(coords_1: Point, coords_2: Point, coords_3: Point, thickness: u32, color: Rgb) {
+        todo!();
+    }
+    fn put_pixel(coords: Point, color: Rgb) {
+        todo!()
+    }
+    fn paint_cursor(coords: Point) {
+        todo!()
+    }
+    fn hide_cursor() {}
+    fn show_cursor() {}
+    fn draw() {}
+    fn clear() {
+        todo!()
+    }
+}
diff --git a/ableos/src/arch/riscv/drivers/mod.rs b/ableos/src/arch/riscv/drivers/mod.rs
new file mode 100644
index 0000000..b832ebf
--- /dev/null
+++ b/ableos/src/arch/riscv/drivers/mod.rs
@@ -0,0 +1,2 @@
+pub mod graphics;
+pub mod serial;
diff --git a/ableos/src/arch/riscv/drivers/serial.rs b/ableos/src/arch/riscv/drivers/serial.rs
new file mode 100644
index 0000000..da9bc6c
--- /dev/null
+++ b/ableos/src/arch/riscv/drivers/serial.rs
@@ -0,0 +1,11 @@
+#[macro_export]
+macro_rules! serial_print {
+    ($($arg:tt)*) => {};
+}
+/// Prints to the host through the serial interface, appending a newline.
+#[macro_export]
+macro_rules! serial_println {
+    () => {};
+    ($fmt:expr) => {};
+    ($fmt:expr, $($arg:tt)*) => {};
+}
diff --git a/ableos/src/arch/riscv/firmwear/opensbi-riscv64-generic-fw_jump.bin b/ableos/src/arch/riscv/firmwear/opensbi-riscv64-generic-fw_jump.bin
new file mode 100755
index 0000000..099967f
Binary files /dev/null and b/ableos/src/arch/riscv/firmwear/opensbi-riscv64-generic-fw_jump.bin differ
diff --git a/ableos/src/arch/riscv/init.rs b/ableos/src/arch/riscv/init.rs
new file mode 100644
index 0000000..12cd021
--- /dev/null
+++ b/ableos/src/arch/riscv/init.rs
@@ -0,0 +1 @@
+pub fn init() {}
diff --git a/ableos/src/arch/riscv/mod.rs b/ableos/src/arch/riscv/mod.rs
new file mode 100644
index 0000000..7368637
--- /dev/null
+++ b/ableos/src/arch/riscv/mod.rs
@@ -0,0 +1,46 @@
+pub mod drivers;
+pub mod init;
+#[naked]
+#[no_mangle]
+unsafe extern "C" fn _boot() -> ! {
+    #[rustfmt::skip]
+    asm!("
+        csrw sie, zero
+        csrci sstatus, 2
+
+        .option push
+        .option norelax
+        lla gp, __global_pointer$
+        .option pop
+
+        lla sp, __tmp_stack_top
+
+        lla t0, __bss_start
+        lla t1, __bss_end
+
+        1:
+            beq t0, t1, 2f
+            sd zero, (t0)
+            addi t0, t0, 8
+            j 1b
+
+        2:
+            j {}
+    ",
+    sym _start, options(noreturn));
+}
+
+extern "C" fn _start() -> ! {
+    let uart_data = 0x10000000 as *mut u8;
+    for c in b"Hello, world!\n" {
+        unsafe { uart_data.write_volatile(*c) };
+    }
+
+    sloop()
+}
+
+pub fn sloop() -> ! {
+    loop {
+        unsafe { asm!("nop") };
+    }
+}
diff --git a/ableos/src/arch/riscv/virt.lds b/ableos/src/arch/riscv/virt.lds
new file mode 100644
index 0000000..c471c85
--- /dev/null
+++ b/ableos/src/arch/riscv/virt.lds
@@ -0,0 +1,64 @@
+OUTPUT_ARCH(riscv64gc)
+
+ENTRY(_boot);
+
+
+SECTIONS {
+    . = 0x80200000;
+    .text : {
+        PROVIDE(__text_start = .);
+        PROVIDE(KERNEL_START = .);
+        *(.init.boot)
+        *(.init.rust)
+        *(.text .text.*)
+        . = ALIGN(4K);
+        PROVIDE(__text_end = .);
+    }
+
+    .data : {
+        PROVIDE(__data_start = .);
+        *(.data .data.* .rodata .rodata.*)
+        . = ALIGN(8);
+        PROVIDE(__tmp_stack_bottom = .);
+        . += 1024 * 1024 * 4;
+        PROVIDE(__tmp_stack_top = .);
+        . += 4096;
+        PROVIDE(__scratch_stack = .);
+        . = ALIGN(8);
+    }
+
+    . = ALIGN(8);
+
+    .sdata : {
+        PROVIDE(__global_pointer$ = .);
+        *(.sdata .sdata.*)       
+        . = ALIGN(4K);
+        PROVIDE(__data_end = .); 
+    }
+
+    PROVIDE(__bss_start = .);
+    .sbss : {
+        *(.sbss .sbss.*);
+    }
+
+    .bss : {
+        *(.bss .bss.*)
+    }
+    . = ALIGN(4K);
+    PROVIDE(__bss_end = .);
+
+    .tdata : {
+        . = ALIGN(4K);
+        PROVIDE(__tdata_start = .);
+        
+        *(.tdata .tdata.*)
+
+        . = ALIGN(4K);
+        PROVIDE(__tdata_end = .);
+    }
+
+    . = ALIGN(2M);
+    PROVIDE(KERNEL_END = .);
+
+    /DISCARD/ : { *(.eh_frame_hdr .eh_frame) }
+}
diff --git a/ableos/src/arch/x86_64/mod.rs b/ableos/src/arch/x86_64/mod.rs
index 3aec32e..f38307c 100644
--- a/ableos/src/arch/x86_64/mod.rs
+++ b/ableos/src/arch/x86_64/mod.rs
@@ -11,6 +11,10 @@ pub extern "C" fn _start() -> ! {
 
 #[allow(unused)]
 pub fn shutdown() -> ! {
+    unsafe {
+        cpuio::outw(0x2000, 0x604);
+    }
+
     sloop();
 }
 
@@ -21,7 +25,7 @@ pub fn sloop() -> ! {
 }
 #[cfg(test)]
 pub fn test_runner(tests: &[&dyn Fn()]) {
-	for test in tests {
-		test();
-	}
+    for test in tests {
+        test();
+    }
 }
diff --git a/ableos/src/driver_traits/graphics.rs b/ableos/src/driver_traits/graphics.rs
index c95178c..88fde1a 100644
--- a/ableos/src/driver_traits/graphics.rs
+++ b/ableos/src/driver_traits/graphics.rs
@@ -1,9 +1,16 @@
 #![allow(unused)]
 pub enum GModes {
-	Vga800x600,
-	Custom(u16, u16),
+    Vga800x600,
+    Custom(u16, u16),
 }
 pub type GCoord = usize;
+
+// TODO remap to a bitmasked u32
+/* REASON: More effecient memory wise so less overhead on the wasm memory
+Current: u32+u32+u32
+Proposed: u32 with bitmaps
+*/
+
 pub struct Rgb {
     pub r: u32,
     pub g: u32,
diff --git a/ableos/src/kmain.rs b/ableos/src/kmain.rs
index 0a87b50..f917606 100644
--- a/ableos/src/kmain.rs
+++ b/ableos/src/kmain.rs
@@ -33,8 +33,9 @@ pub extern "C" fn kernel_main() {
         AES::init_rng();
 
         */
-
+    #[cfg(not(target_arch = "riscv64"))]
     println!("init");
+
     {
         use crate::experiments::mail::MailBoxes;
         let mut x = MailBoxes::new();
@@ -44,7 +45,7 @@ pub extern "C" fn kernel_main() {
     }
 
     // stack_overflow();
-
+    // crate::arch::shutdown();
     loop {}
 }
 // TODO: reimplement for the random handler
diff --git a/ableos/src/lib.rs b/ableos/src/lib.rs
index 33f5828..6ca5156 100644
--- a/ableos/src/lib.rs
+++ b/ableos/src/lib.rs
@@ -8,6 +8,7 @@
 #![reexport_test_harness_main = "test_main"]
 #![feature(custom_test_frameworks)]
 #![test_runner(crate::arch::test_runner)]
+#![feature(naked_functions)]
 #[cfg(target_arch = "arm")]
 #[path = "arch/aarch32/mod.rs"]
 mod arch;
@@ -19,18 +20,21 @@ mod arch;
 #[cfg(target_arch = "x86_64")]
 #[path = "arch/x86_64/mod.rs"]
 mod arch;
-#[cfg(target_arch = "mips")]
-#[path = "arch/ps_portable/mod.rs"]
+#[cfg(target_arch = "riscv64")]
+#[path = "arch/riscv/mod.rs"]
 mod arch;
 #[macro_use]
 pub mod print;
+
+use arch::drivers::serial;
+
+mod driver_traits;
+mod experiments;
 #[cfg(not(target_arch = "mips"))]
 // pub mod allocator;
 mod kmain;
 #[cfg(not(target_arch = "mips"))]
 mod panic;
-mod driver_traits;
-mod experiments;
 pub use experiments::server;
 pub mod keyboard;
 pub mod relib;
diff --git a/ableos/src/print.rs b/ableos/src/print.rs
index 8579f70..f47c61a 100644
--- a/ableos/src/print.rs
+++ b/ableos/src/print.rs
@@ -30,7 +30,10 @@ impl core::fmt::Write for Stdout {
         kprint!("{}", s);
         Ok(())
     }
-
+    #[cfg(target_arch = "riscv64")]
+    fn write_str(&mut self, s: &str) -> Result<(), Error> {
+        Ok(())
+    }
     #[cfg(target_arch = "mips")]
     fn write_str(&mut self, s: &str) -> Result<(), Error> {
         use psp::dprint;
diff --git a/repbuild/src/main.rs b/repbuild/src/main.rs
index 78e05b7..3cdad2d 100644
--- a/repbuild/src/main.rs
+++ b/repbuild/src/main.rs
@@ -12,6 +12,7 @@ enum Command {
         machine: Option<MachineType>,
     },
 }
+
 #[derive(clap::ArgEnum, Debug, Clone)]
 enum MachineType {
     X86,
@@ -56,29 +57,16 @@ fn main() -> anyhow::Result<()> {
                         .run()?;
                     #[rustfmt::skip]
                     xshell::cmd!(
-                        "
-                    qemu-system-riscv64
-      -machine virt
-      -cpu rv64
-      -smp 8
-      -m 128M
-      -bios opensbi-riscv64-generic-fw_jump.bin
-      -kernel blog_os/target/riscv64gc-unknown-none-elf/release/blog_os
-
-                        "
-                    )
-                    .run()?;
+                        "qemu-system-riscv64
+                            -machine virt
+                            -cpu rv64
+                            -smp 8
+                            -m 128M
+                            -bios src/arch/riscv/firmwear/opensbi-riscv64-generic-fw_jump.bin
+                            -kernel target/riscv64gc-unknown-none-elf/release/ableos"
+                        ).run()?;
                 }
             }
-            /*
-                #[rustfmt::skip]
-                xshell::cmd!("
-                    qemu-system-x86_64
-                        -drive format=raw,file=../../ableos/target/x86_64-ableos/release/bootimage-ableos.bin
-                        {debug_log...}
-                "
-            ).run()?;
-            */
         }
     }