aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--Cargo.toml7
-rw-r--r--Makefile29
-rw-r--r--_Makefile232
-rw-r--r--isofiles/boot/grub/grub.cfg8
-rwxr-xr-xkernelbin0 -> 26344 bytes
-rw-r--r--sections74
-rw-r--r--src/arch/mod.rs1
-rw-r--r--src/arch/x86_64/asm/io_port.s71
-rw-r--r--src/arch/x86_64/asm/startup.s12
-rw-r--r--src/arch/x86_64/cpu.rs0
-rw-r--r--src/arch/x86_64/io_port.rs0
-rw-r--r--src/arch/x86_64/linker.ld74
-rw-r--r--src/arch/x86_64/mod.rs5
-rw-r--r--src/arch/x86_64/pic.rs0
-rw-r--r--src/arch/x86_64/pit.rs0
-rw-r--r--src/arch/x86_64/plugbox.rs0
-rw-r--r--src/lib.rs23
-rw-r--r--src/machine/cgascr.rs36
-rw-r--r--src/machine/mod.rs1
-rw-r--r--src/main.rs3
-rw-r--r--x86_64_rustubs.json13
22 files changed, 585 insertions, 9 deletions
diff --git a/.gitignore b/.gitignore
index ea8c4bf..66cb0a5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,6 @@
/target
+Cargo.lock
+*.iso
+*.o
+/isofiles/boot/kernel
+
diff --git a/Cargo.toml b/Cargo.toml
index 4035bf7..6eef6ef 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -6,3 +6,10 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
+
+[profile.dev]
+panic = "abort"
+
+[profile.release]
+panic = "abort"
+
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..7a10efb
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,29 @@
+# this is an prototype makefile with hardcodings..
+# TODO reorganize...
+#
+
+all: bootdisk.iso
+
+
+bootdisk.iso : kernel
+ cp kernel isofiles/boot/
+ grub-mkrescue /usr/lib/grub/i386-pc -o bootdisk.iso isofiles
+
+kernel : rust_kernel startup.o
+ ld -static -e startup -T sections -o ./kernel startup.o target/x86_64_rustubs/debug/librustubs.rlib
+
+rust_kernel:
+ cargo rustc --target=x86_64_rustubs.json -- -C link-arg=-nostartfiles --emit=obj
+
+startup.o:
+ nasm -f elf64 -o startup.o src/arch/x86_64/asm/startup.s
+
+clean:
+ cargo clean
+ rm bootdisk.iso
+ rm startup.o
+ rm system
+ rm isofiles/boot/system
+
+qemu: bootdisk.iso
+ qemu-system-x86_64 -drive file=./bootdisk.iso,format=raw -k en-us
diff --git a/_Makefile b/_Makefile
new file mode 100644
index 0000000..d22a798
--- /dev/null
+++ b/_Makefile
@@ -0,0 +1,232 @@
+# This is the makefile goal ... TODO integrate the rust project into this...
+
+
+# -----------------------------------------------------------------------------
+#
+# M A K E F I L E
+#
+# for building OOStuBS, the teaching OS for "Operating-System Construction"
+# -----------------------------------------------------------------------------
+#
+# By entering 'make', the system's source codes get compiled and linked.
+# 'make bootdisk' writes the system image to an USB stick that allows to boot
+# the system on a real machine.
+# 'make clean' cleans up the directory.
+# The targets 'qemu', 'qemu-smp' and 'qemu-gdb' start the QEMU emulator in
+# single-core mode, multi-core mode (2 CPUs), respectively in single-core mode
+# waiting for a debugger to attach before starting the system.
+# The targets 'gdb', 'ddd' and 'cgdb' each run one of these three debuggers
+# that automatically connect to the GDB stub of an already started 'qemu-gdb'
+# (see above).
+#
+# -----------------------------------------------------------------------------
+
+# -----------------------------------------------------------------------------
+# source-code files
+
+STARTUP_SOURCE = ./startup.asm
+CC_SOURCES = $(shell find . -name "*.cc")
+C_SOURCES = $(shell find . -name "*.c")
+ASM_SOURCES = $(shell find ./machine -name "*.asm")
+
+# build settings
+#
+# ASMOBJFORMAT: assembler output format (must match the format of the used
+# C++ compiler to make linking possible)
+# OBJDIR: directory for storing object files
+# DEPDIR: directory for storing dependency files
+# DRIVE_HD: HDD/USB device the system image gets written to
+# with 'make bootdisk'
+# DELETE: file-deletion command
+# ASM: assembler command
+# CC/CXX: C/C++ compiler command
+# CFLAGS: C-compiler flags
+# CXXFLAGS: C++-compiler flags
+# QEMU: architecture-specific name of the QEMU command
+# MKRESCUE: name of the GRUB mkrescue program
+
+VERBOSE = @
+ASMOBJFORMAT = elf64
+OBJDIR = ./build
+DEPDIR = ./dep
+# ATTENTION: using the wrong device name here will destroy data on the specified
+# device! Do not run with root privileges!
+DRIVE_HD = /dev/sdz
+DELETE = rm
+ASM = nasm
+QEMU ?= qemu-system-x86_64
+CC ?= gcc
+CXX ?= g++
+CFLAGS := $(CFLAGS) -m64 -mno-red-zone -Wall -Wno-write-strings -fno-stack-protector -nostdlib -mno-sse -I. -g #-DDEBUG
+CXXFLAGS := $(CFLAGS) -Wno-non-virtual-dtor -fno-threadsafe-statics -fno-use-cxa-atexit -fno-rtti -fno-exceptions -std=c++11
+
+# enforce i386-pc grub variant also on EFI systems
+ifneq ($(wildcard /usr/lib/grub/i386-pc/.),)
+ MKRESCUE_OPTION ?= /usr/lib/grub/i386-pc
+else ifneq ($(wildcard /usr/share/grub2/i386-pc/.),)
+ MKRESCUE_OPTION ?= /usr/share/grub2/i386-pc
+else
+ MKRESCUE_OPTION ?=
+endif
+
+ifneq ($(shell which grub-mkrescue 2> /dev/null),)
+MKRESCUE = grub-mkrescue $(MKRESCUE_OPTION)
+endif
+ifneq ($(shell which grub2-mkrescue 2> /dev/null),)
+MKRESCUE = grub2-mkrescue $(MKRESCUE_OPTION)
+endif
+
+# -------------------------------------------------------------------------
+# names of sub-directories with source-code files
+
+VPATH = $(sort $(dir $(STARTUP_SOURCE) $(CC_SOURCES) $(C_SOURCES) $(ASM_SOURCES)))
+
+# -------------------------------------------------------------------------
+# lists of object files that are generated during compilation
+
+FIRST_OBJECT = $(addprefix $(OBJDIR)/,$(patsubst %.asm,_%.o, $(notdir $(STARTUP_SOURCE))))
+C_OBJECTS = $(notdir $(C_SOURCES:.c=.o))
+CC_OBJECTS = $(notdir $(CC_SOURCES:.cc=.o))
+
+DEP_FILES = $(patsubst %.o,$(DEPDIR)/%.d,$(C_OBJECTS))
+DEP_FILES += $(patsubst %.o,$(DEPDIR)/%.d,$(CC_OBJECTS))
+
+ASM_OBJECTS = $(patsubst %.asm,_%.o, $(notdir $(ASM_SOURCES)))
+OBJPRE = $(addprefix $(OBJDIR)/,$(ASM_OBJECTS) $(C_OBJECTS) $(CC_OBJECTS))
+
+# --------------------------------------------------------------------------
+# Default target: the image file for USB sticks and QEMU
+
+
+
+all: $(OBJDIR)/bootdisk.iso
+
+# --------------------------------------------------------------------------
+# rules for generating dependency files
+
+
+$(DEPDIR)/%.d : %.c
+ @echo "DEP $@"
+ @if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
+ $(VERBOSE) $(CC) $(CFLAGS) -MM -MT $(OBJDIR)/$*.o -MF $@ $<
+
+$(DEPDIR)/%.d : %.cc
+ @echo "DEP $@"
+ @if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
+ $(VERBOSE) $(CXX) $(CXXFLAGS) -MM -MT $(OBJDIR)/$*.o -MF $@ $<
+
+# --------------------------------------------------------------------------
+# rules for generating object files
+
+$(OBJDIR)/%.o : %.c
+ @echo "CC $@"
+ @if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
+ $(VERBOSE) $(CC) -c $(CFLAGS) -o $@ $<
+
+$(OBJDIR)/%.o : %.cc
+ @echo "CXX $@"
+ @if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
+ $(VERBOSE) $(CXX) -c $(CXXFLAGS) -o $@ $<
+
+$(OBJDIR)/_%.o : %.asm
+ @echo "ASM $@"
+ @if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
+ $(VERBOSE) $(ASM) -f $(ASMOBJFORMAT) -o $@ $<
+
+# --------------------------------------------------------------------------
+# linked system
+
+$(OBJDIR)/system: $(FIRST_OBJECT) $(OBJPRE)
+ @echo "LD $@"
+ @if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
+ $(VERBOSE) $(CXX) $(CXXFLAGS) -static -z max-page-size=0x1000 -e startup -T sections -o $(OBJDIR)/system $(FIRST_OBJECT) $(OBJPRE)
+
+# --------------------------------------------------------------------------
+# 'bootdisk.iso' consists of the system and a boot loader (GRUB) with boot
+# block and setup code. The system gets started via Multiboot, so we don't
+# have to care about switching to protected mode or how to deal with the BIOS.
+
+$(OBJDIR)/bootdisk.iso : $(OBJDIR)/system
+ @echo "BUILD $@"
+ @if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi
+ $(VERBOSE) cp $< isofiles/boot/system
+ $(VERBOSE) $(MKRESCUE) -o $@ isofiles
+
+# --------------------------------------------------------------------------
+# 'clean' deletes the generated system, the object files, and the dependency
+# files.
+
+clean:
+ @echo "RM $(OBJDIR)"
+ $(VERBOSE) rm -rf $(OBJDIR)
+ @echo "RM $(DEPDIR)"
+ $(VERBOSE) rm -rf $(DEPDIR)
+
+# 'list' shows the OBJS for debuging linker
+
+list:
+ @echo "C_OBJECTS $(C_OBJECTS)"
+ @echo "CC_OBJECTS $(CC_OBJECTS)"
+ @echo "OBJDIR $(OBJDIR)"
+ @echo "OBJPRE $(OBJPRE)"
+ @echo "FIRST_OBJECT $(FIRST_OBJECT)"
+
+
+# --------------------------------------------------------------------------
+# 'bootdisk' depends on bootdisk.iso, which in turn depends on the system. The
+# ISO image gets written to the specified drive, which can be a HDD/SSD or an
+# USB stick.
+# ATTENTION: using the wrong device name here will destroy data on the specified
+# device! Do not run with root privileges!
+
+bootdisk: $(OBJDIR)/bootdisk.iso
+ @echo "CP $<"
+ $(VERBOSE) cp $< $(DRIVE_HD)
+
+# --------------------------------------------------------------------------
+# 'qemu' runs the QEMU emulator with the system
+
+qemu: $(OBJDIR)/bootdisk.iso
+ $(QEMU) -drive file=build/bootdisk.iso,format=raw -k en-us
+
+# --------------------------------------------------------------------------
+# 'qemu-smp' runs QEMU in SMP (symmetric multi-processing) mode with 2 CPUs
+
+qemu-smp: $(OBJDIR)/bootdisk.iso
+ $(QEMU) -drive file=build/bootdisk.iso,format=raw -k en-us -smp 2
+
+# --------------------------------------------------------------------------
+# 'qemu-gdb' runs QEMU with an activated GDB stub, which waits for a debugger
+# (GDB, DDD, CGDB, etc.) to connect before starting the system.
+
+qemu-gdb: $(OBJDIR)/bootdisk.iso
+ $(VERBOSE) echo "target remote localhost:$(shell echo $$(( $$(id -u) % (65536 - 1024) + 1024 )))" > /tmp/gdbcommands.$(shell id -u)
+ $(QEMU) -drive file=build/bootdisk.iso,format=raw -k en-us -S -gdb tcp::$(shell echo $$(( $$(id -u) % (65536 - 1024) + 1024 )))
+
+# --------------------------------------------------------------------------
+# 'gdb' starts the GDB debugger and makes it connect to an already started
+# 'qemu-gdb'.
+
+gdb:
+ gdb -x /tmp/gdbcommands.$(shell id -u) $(OBJDIR)/system
+
+# --------------------------------------------------------------------------
+# 'ddd': same as 'gdb' but uses the 'ddd' debugger
+
+ddd:
+ ddd --gdb -x /tmp/gdbcommands.$(shell id -u) $(OBJDIR)/system
+
+# --------------------------------------------------------------------------
+# 'cgdb': same as 'gdb' but uses the 'cgdb' debugger
+
+cgdb:
+ cgdb -x /tmp/gdbcommands.$(shell id -u) $(OBJDIR)/system
+
+# --------------------------------------------------------------------------
+# include dependency files
+
+ifneq ($(MAKECMDGOALS),clean)
+-include $(DEP_FILES)
+endif
+
+.PHONY: clean bootdisk gdb ddd qemu qemu-smp qemu-gdb qemu-ddd qemu-cgdb
diff --git a/isofiles/boot/grub/grub.cfg b/isofiles/boot/grub/grub.cfg
new file mode 100644
index 0000000..2fc735b
--- /dev/null
+++ b/isofiles/boot/grub/grub.cfg
@@ -0,0 +1,8 @@
+set timeout=0
+set default=0
+
+menuentry "OOStuBS" {
+ insmod all_video
+ multiboot /boot/kernel
+ boot
+}
diff --git a/kernel b/kernel
new file mode 100755
index 0000000..889f35c
--- /dev/null
+++ b/kernel
Binary files differ
diff --git a/sections b/sections
new file mode 100644
index 0000000..7a03770
--- /dev/null
+++ b/sections
@@ -0,0 +1,74 @@
+SECTIONS
+{
+ . = 0x100000; /* system's start address */
+
+ .text :
+ {
+ *(".text")
+ *(".text.*")
+ *(".text$")
+ *(".init")
+ *(".fini")
+ *(".gnu.linkonce.*")
+ }
+
+ .init_array :
+ {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ KEEP (*(".ctors"))
+ KEEP (*(".ctor"))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ }
+
+ .fini_array :
+ {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT(.fini_array.*)))
+ KEEP (*(.fini_array))
+ KEEP (*(".dtors"))
+ KEEP (*(".dtor"))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ }
+
+ .data :
+ {
+ *(".data")
+ *(".data$")
+ *(".rodata")
+ *(".rodata.*")
+ *(".got")
+ *(".got.plt")
+ *(".eh_frame")
+ *(".eh_fram")
+ *(".jcr")
+ *(".note.*")
+ }
+
+ .bss :
+ {
+ ___BSS_START__ = .;
+ *(".bss")
+ *(".bss.*")
+ ___BSS_END__ = .;
+ }
+
+ /* global page table for 64-bit long mode */
+ .global_pagetable ALIGN(4096) (NOLOAD) :
+ {
+ *(".global_pagetable")
+ }
+
+/*
+ /DISCARD/ :
+ {
+ *(".note")
+ *(".comment")
+ *(".debug_line")
+ *(".debug_info")
+ *(".debug_abbrev")
+ *(".debug_aranges")
+ }
+*/
+}
diff --git a/src/arch/mod.rs b/src/arch/mod.rs
new file mode 100644
index 0000000..2a99bf5
--- /dev/null
+++ b/src/arch/mod.rs
@@ -0,0 +1 @@
+pub mod x86_64;
diff --git a/src/arch/x86_64/asm/io_port.s b/src/arch/x86_64/asm/io_port.s
index e69de29..9ddc4e6 100644
--- a/src/arch/x86_64/asm/io_port.s
+++ b/src/arch/x86_64/asm/io_port.s
@@ -0,0 +1,71 @@
+;***************************************************************************
+;* Operating-System Construction *
+;*---------------------------------------------------------------------------*
+;* *
+;* I O _ P O R T *
+;* *
+;*---------------------------------------------------------------------------*
+;* The functions defined here encapsulate the machine instructions 'in' and *
+;* 'out' for class IO_Port. *
+;*****************************************************************************
+
+; EXPORTED FUNCTIONS
+
+[GLOBAL outb]
+[GLOBAL outw]
+[GLOBAL inb]
+[GLOBAL inw]
+
+; FUNCTION IMPLEMENTATIONS
+
+[SECTION .text]
+
+; OUTB: Byte-wise output via an I/O port.
+;
+; C prototype: void outb (int port, int value);
+
+outb:
+ push rbp
+ mov rbp, rsp
+ mov rdx, rdi
+ mov rax, rsi
+ out dx, al
+ pop rbp
+ ret
+
+; OUTW: Word-wise output via an I/O port.
+;
+; C prototype: void outw (int port, int value);
+
+outw:
+ push rbp
+ mov rbp, rsp
+ mov rdx, rdi
+ mov rax, rsi
+ out dx, ax
+ pop rbp
+ ret
+
+; INB: Byte-wise input via an I/O port.
+;
+; C prototype: unsigned char inb (int port);
+
+inb:
+ push rbp
+ mov rbp, rsp
+ mov rdx, rdi
+ in al, dx
+ pop rbp
+ ret
+
+; INW: Word-wise input via an I/O port.
+;
+; C prototype: unsigned short inw (int port);
+
+inw:
+ push rbp
+ mov rbp, rsp
+ mov rdx, rdi
+ in ax, dx
+ pop rbp
+ ret
diff --git a/src/arch/x86_64/asm/startup.s b/src/arch/x86_64/asm/startup.s
index 4c696e1..7b5bbff 100644
--- a/src/arch/x86_64/asm/startup.s
+++ b/src/arch/x86_64/asm/startup.s
@@ -17,7 +17,7 @@
; Constants
;
-; stack for the main function
+; stack for the main function (renamed to _entry())
STACKSIZE: equ 65536
; video memory base address
@@ -59,8 +59,8 @@ pagetable_end: equ 0x200000
[GLOBAL _ZdlPvm]
; functions from the C parts of the system
-[EXTERN main]
-[EXTERN guardian]
+[EXTERN _entry]
+;[EXTERN guardian]
; addresses provided by the compiler
[EXTERN ___BSS_START__]
@@ -204,7 +204,7 @@ fill_tables3_done:
; system start, part 2 (in 64-bit Long Mode)
;
; This code clears the BSS segment and initializes IDT and PICs. Then the
-; constructors of global C++ objects are called, and finally main() is run.
+; constructors of global C++ objects are called, and finally _entry() is run.
;
longmode_start:
@@ -234,7 +234,7 @@ clear_bss:
;mov cr4, rax
call _init ; call constructors of global objects
- call main ; call the OS kernel's C / C++ part
+ call _entry ; call the OS kernel's C / C++ part
call _fini ; call destructors
cli ; Usually we should not get here.
hlt
@@ -279,7 +279,7 @@ wrapper_body:
; pass interrupt number as the first parameter
mov rdi, rax
- call guardian
+; call guardian
; restore volatile registers
pop r11
diff --git a/src/arch/x86_64/cpu.rs b/src/arch/x86_64/cpu.rs
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/arch/x86_64/cpu.rs
diff --git a/src/arch/x86_64/io_port.rs b/src/arch/x86_64/io_port.rs
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/arch/x86_64/io_port.rs
diff --git a/src/arch/x86_64/linker.ld b/src/arch/x86_64/linker.ld
new file mode 100644
index 0000000..7a03770
--- /dev/null
+++ b/src/arch/x86_64/linker.ld
@@ -0,0 +1,74 @@
+SECTIONS
+{
+ . = 0x100000; /* system's start address */
+
+ .text :
+ {
+ *(".text")
+ *(".text.*")
+ *(".text$")
+ *(".init")
+ *(".fini")
+ *(".gnu.linkonce.*")
+ }
+
+ .init_array :
+ {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ KEEP (*(".ctors"))
+ KEEP (*(".ctor"))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ }
+
+ .fini_array :
+ {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT(.fini_array.*)))
+ KEEP (*(.fini_array))
+ KEEP (*(".dtors"))
+ KEEP (*(".dtor"))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ }
+
+ .data :
+ {
+ *(".data")
+ *(".data$")
+ *(".rodata")
+ *(".rodata.*")
+ *(".got")
+ *(".got.plt")
+ *(".eh_frame")
+ *(".eh_fram")
+ *(".jcr")
+ *(".note.*")
+ }
+
+ .bss :
+ {
+ ___BSS_START__ = .;
+ *(".bss")
+ *(".bss.*")
+ ___BSS_END__ = .;
+ }
+
+ /* global page table for 64-bit long mode */
+ .global_pagetable ALIGN(4096) (NOLOAD) :
+ {
+ *(".global_pagetable")
+ }
+
+/*
+ /DISCARD/ :
+ {
+ *(".note")
+ *(".comment")
+ *(".debug_line")
+ *(".debug_info")
+ *(".debug_abbrev")
+ *(".debug_aranges")
+ }
+*/
+}
diff --git a/src/arch/x86_64/mod.rs b/src/arch/x86_64/mod.rs
new file mode 100644
index 0000000..ef06437
--- /dev/null
+++ b/src/arch/x86_64/mod.rs
@@ -0,0 +1,5 @@
+pub mod io_port;
+pub mod pic;
+pub mod pit;
+pub mod plugbox;
+pub mod cpu;
diff --git a/src/arch/x86_64/pic.rs b/src/arch/x86_64/pic.rs
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/arch/x86_64/pic.rs
diff --git a/src/arch/x86_64/pit.rs b/src/arch/x86_64/pit.rs
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/arch/x86_64/pit.rs
diff --git a/src/arch/x86_64/plugbox.rs b/src/arch/x86_64/plugbox.rs
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/arch/x86_64/plugbox.rs
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..767e547
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,23 @@
+#![no_std]
+#![no_main]
+mod arch;
+// use core::panic::PanicInfo;
+
+static HELLO: &[u8] = b"Hello World!";
+
+// #[panic_handler]
+// fn panic(_info: &PanicInfo) -> ! {
+//
+// loop {}
+// }
+
+#[no_mangle]
+pub extern "C" fn _entry() -> ! {
+ let vga_buffer = 0xb8000 as *mut u8;
+
+ unsafe {
+ *vga_buffer.offset(10 as isize * 2) = 'X' as u8;
+ *vga_buffer.offset(10 as isize * 2 + 1) = 0xb;
+ }
+ loop {}
+}
diff --git a/src/machine/cgascr.rs b/src/machine/cgascr.rs
new file mode 100644
index 0000000..a43e073
--- /dev/null
+++ b/src/machine/cgascr.rs
@@ -0,0 +1,36 @@
+const CGA_START:u32 = 0xb8000;
+
+#[allow(dead_code)]
+pub struct CGAScreen{
+ max_cows:u32,
+ max_rows:u32,
+}
+
+#[allow(dead_code)]
+impl CGAScreen{
+ pub fn new(cows:u32, rows:u32) -> Self {
+ Self {max_cows: cows, max_rows:rows,}
+ }
+
+ pub fn set_pos(x:u32, y:u32){
+
+ }
+
+ pub fn get_pos(x:&mut u32, y:&mut u32){
+ // TODO
+ *x = 1;
+ *y = 1;
+ }
+
+ pub fn putchar(c:char, attr:u8){
+
+ }
+
+ // this function should be the only one that "directly touches"
+ // the memory by address.
+ // and since it's unsafe, it shouldn't be public
+ fn show(&self, x:u32, y:u32, c:char, attr:u8){
+
+ }
+
+}
diff --git a/src/machine/mod.rs b/src/machine/mod.rs
new file mode 100644
index 0000000..4622e0b
--- /dev/null
+++ b/src/machine/mod.rs
@@ -0,0 +1 @@
+pub mod cgascr;
diff --git a/src/main.rs b/src/main.rs
deleted file mode 100644
index e7a11a9..0000000
--- a/src/main.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-fn main() {
- println!("Hello, world!");
-}
diff --git a/x86_64_rustubs.json b/x86_64_rustubs.json
new file mode 100644
index 0000000..2e90078
--- /dev/null
+++ b/x86_64_rustubs.json
@@ -0,0 +1,13 @@
+{
+ "llvm-target": "x86_64-unknown-none",
+ "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
+ "linker-flavor": "gcc",
+ "target-endian": "little",
+ "target-pointer-width": "64",
+ "target-c-int-width": "32",
+ "arch": "x86_64",
+ "os": "none",
+ "disable-redzone": true,
+ "features": "-mmx,-sse,-avx,+soft-float",
+ "frame-pointer": "always"
+}