Unified · Split
| @@ -1,10 +1,25 @@ | ||
| 1 | +CONF=pc64 | |
| 2 | + | |
| 1 | 3 | ARCH = amd64 |
| 4 | +RUSTC = rustc | |
| 5 | +CC = gcc | |
| 2 | 6 | LD = ld |
| 3 | −NASM = nasm | |
| 7 | +AS = nasm | |
| 4 | 8 | QEMU = qemu-system-i386 -curses |
| 5 | 9 | |
| 6 | −OBJECTS = rust9front.o | |
| 7 | −ASMOBJECTS = $(wildcard *.asm) | |
| 10 | +LDFLAGS = --gc-sections -T $(CONF).ld | |
| 11 | +RUSTFLAGS = -C soft-float -O --target=$(CONF).json | |
| 12 | + | |
| 13 | +OBJ= \ | |
| 14 | + $(CONF).o \ | |
| 15 | + l.o\ | |
| 16 | + | |
| 17 | +RUSTFILES= \ | |
| 18 | + macros.rs \ | |
| 19 | + unwind.rs \ | |
| 20 | + main.rs \ | |
| 21 | + | |
| 22 | +LIBCORE = libcore.rlib | |
| 8 | 23 | |
| 9 | 24 | all: $(BUILDDIR) rust9front.bin |
| 10 | 25 | |
| @@ -12,10 +27,26 @@ $(BUILDDIR): · 1 unmodified line | ||
| 12 | 27 | mkdir -p $(BUILDDIR) |
| 13 | 28 | |
| 14 | 29 | rust9front.o: l.asm |
| 15 | − $(NASM) -f elf32 -Wall -o $@ $< | |
| 30 | + $(AS) -f elf32 -Wall -o $@ $< | |
| 16 | 31 | |
| 17 | −rust9front.bin: rust9front.o | |
| 18 | − $(LD) -m elf_i386 -o $@ $^ | |
| 32 | +rust9front.bin: $(OBJ) | |
| 33 | + $(LD) $(LDFLAGS) -o $@ $(OBJ) | |
| 19 | 34 | |
| 20 | 35 | debug: rust9front.bin |
| 21 | 36 | $(QEMU) -s -S -kernel $< |
| 37 | + | |
| 38 | +$(CONF).o: $(CONF).rs $(LIBCORE) | |
| 39 | + $(RUSTC) $(RUSTFLAGS) -o $@ --emit=obj,dep-info $< --extern core=$(LIBCORE) | |
| 40 | + | |
| 41 | +%.o: %.c | |
| 42 | + $(CC) -c -o $@ $< $(CFLAGS) | |
| 43 | + | |
| 44 | +%.o: %.asm | |
| 45 | + $(AS) -Wall -o $@ $< $(ASFLAGS) | |
| 46 | + | |
| 47 | +libcore.rlib: libcore/lib.rs | |
| 48 | + $(RUSTC) $(RUSTFLAGS) -o $@ --crate-type=lib --emit=link,dep-info $< | |
| 49 | + | |
| 50 | +clean: | |
| 51 | + rm -f *.d *.rlib *.o *.bin | |
| 52 | + | |
| @@ -0,0 +1,29 @@ | ||
| 1 | +use prelude::*; | |
| 2 | + | |
| 3 | +/// Write a string to the output channel | |
| 4 | +/// | |
| 5 | +/// This method is unsafe because it does port accesses without synchronisation | |
| 6 | +pub unsafe fn puts(s: &str) | |
| 7 | +{ | |
| 8 | + for b in s.bytes() | |
| 9 | + { | |
| 10 | + putb(b); | |
| 11 | + } | |
| 12 | +} | |
| 13 | + | |
| 14 | +/// Write a single byte to the output channel | |
| 15 | +/// | |
| 16 | +/// This method is unsafe because it does port accesses without synchronisation | |
| 17 | +pub unsafe fn putb(b: u8) | |
| 18 | +{ | |
| 19 | + // Wait for the serial port's fifo to not be empty | |
| 20 | + while (::io::inb(0x3F8+5) & 0x20) == 0 | |
| 21 | + { | |
| 22 | + // Do nothing | |
| 23 | + } | |
| 24 | + // Send the byte out the serial port | |
| 25 | + ::io::outb(0x3F8, b); | |
| 26 | + | |
| 27 | + // Also send to the bochs 0xe9 hack | |
| 28 | + ::io::outb(0xe9, b); | |
| 29 | +} | |
| @@ -0,0 +1,42 @@ | ||
| 1 | +/// Write a byte to the specified port | |
| 2 | +pub unsafe fn outb(port: u16, val: u8) | |
| 3 | +{ | |
| 4 | + asm!("outb %al, %dx" : : "{dx}"(port), "{al}"(val)); | |
| 5 | +} | |
| 6 | + | |
| 7 | +/// Read a single byte from the specified port | |
| 8 | +pub unsafe fn inb(port: u16) -> u8 | |
| 9 | +{ | |
| 10 | + let ret : u8; | |
| 11 | + asm!("inb %dx, %al" : "={ax}"(ret) : "{dx}"(port)); | |
| 12 | + return ret; | |
| 13 | +} | |
| 14 | + | |
| 15 | +/// Write a word (16-bits) to the specified port | |
| 16 | +pub unsafe fn outw(port: u16, val: u16) | |
| 17 | +{ | |
| 18 | + asm!("outb %ax, %dx" : : "{dx}"(port), "{al}"(val)); | |
| 19 | +} | |
| 20 | + | |
| 21 | +/// Read a word (16-bits) from the specified port | |
| 22 | +pub unsafe fn inw(port: u16) -> u16 | |
| 23 | +{ | |
| 24 | + let ret : u16; | |
| 25 | + asm!("inb %dx, %ax" : "={ax}"(ret) : "{dx}"(port)); | |
| 26 | + return ret; | |
| 27 | +} | |
| 28 | + | |
| 29 | +/// Write a long/double-word (32-bits) to the specified port | |
| 30 | +pub unsafe fn outl(port: u16, val: u32) | |
| 31 | +{ | |
| 32 | + asm!("outb %eax, %dx" : : "{dx}"(port), "{al}"(val)); | |
| 33 | +} | |
| 34 | + | |
| 35 | +/// Read a long/double-word (32-bits) from the specified port | |
| 36 | +pub unsafe fn inl(port: u16) -> u32 | |
| 37 | +{ | |
| 38 | + let ret : u32; | |
| 39 | + asm!("inb %dx, %eax" : "={ax}"(ret) : "{dx}"(port)); | |
| 40 | + return ret; | |
| 41 | +} | |
| 42 | + | |
| @@ -0,0 +1,61 @@ | ||
| 1 | +use prelude::*; | |
| 2 | +use core::atomic; | |
| 3 | +use core::fmt; | |
| 4 | + | |
| 5 | +/// A formatter object | |
| 6 | +pub struct Writer(bool); | |
| 7 | + | |
| 8 | +/// A primitive lock for the logging output | |
| 9 | +/// | |
| 10 | +/// This is not really a lock. Since there is no threading at the moment, all | |
| 11 | +/// it does is prevent writing when a collision would occur. | |
| 12 | +static LOGGING_LOCK: atomic::AtomicBool = atomic::ATOMIC_BOOL_INIT; | |
| 13 | + | |
| 14 | +impl Writer | |
| 15 | +{ | |
| 16 | + /// Obtain a logger for the specified module | |
| 17 | + pub fn get(module: &str) -> Writer { | |
| 18 | + // This "acquires" the lock (actually just disables output if paralel writes are attempted | |
| 19 | + let mut ret = Writer( ! LOGGING_LOCK.swap(true, atomic::Ordering::Acquire) ); | |
| 20 | + | |
| 21 | + // Print the module name before returning (prefixes all messages) | |
| 22 | + { | |
| 23 | + use core::fmt::Write; | |
| 24 | + let _ = write!(&mut ret, "[{}] ", module); | |
| 25 | + } | |
| 26 | + | |
| 27 | + ret | |
| 28 | + } | |
| 29 | +} | |
| 30 | + | |
| 31 | +impl ::core::ops::Drop for Writer | |
| 32 | +{ | |
| 33 | + fn drop(&mut self) | |
| 34 | + { | |
| 35 | + // Write a terminating newline before releasing the lock | |
| 36 | + { | |
| 37 | + use core::fmt::Write; | |
| 38 | + let _ = write!(self, "\n"); | |
| 39 | + } | |
| 40 | + // On drop, "release" the lock | |
| 41 | + if self.0 { | |
| 42 | + LOGGING_LOCK.store(false, atomic::Ordering::Release); | |
| 43 | + } | |
| 44 | + } | |
| 45 | +} | |
| 46 | + | |
| 47 | +impl fmt::Write for Writer | |
| 48 | +{ | |
| 49 | + fn write_str(&mut self, s: &str) -> fmt::Result | |
| 50 | + { | |
| 51 | + // If the lock is owned by this instance, then we can safely write to the output | |
| 52 | + if self.0 | |
| 53 | + { | |
| 54 | + unsafe { | |
| 55 | + ::debug::puts( s ); | |
| 56 | + } | |
| 57 | + } | |
| 58 | + Ok( () ) | |
| 59 | + } | |
| 60 | +} | |
| 61 | + | |
| @@ -0,0 +1,8 @@ | ||
| 1 | +macro_rules! log{ | |
| 2 | + ( $($arg:tt)* ) => ({ | |
| 3 | + // Import the Writer trait (required by write!) | |
| 4 | + use core::fmt::Write; | |
| 5 | + let _ = write!(&mut ::logging::Writer::get(module_path!()), $($arg)*); | |
| 6 | + }) | |
| 7 | +} | |
| 8 | + | |
| @@ -0,0 +1,15 @@ | ||
| 1 | +{ | |
| 2 | + "data-layout": "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128", | |
| 3 | + "llvm-target": "x86_64-unknown-linux-gnu", | |
| 4 | + "target-endian": "little", | |
| 5 | + "target-pointer-width": "64", | |
| 6 | + "features": "-mmx,-sse,-sse2,-sse3,-ssse3", | |
| 7 | + "os": "tifflin", | |
| 8 | + "arch": "x86_64", | |
| 9 | + "pre-link-args": ["-m64"], | |
| 10 | + "no-compiler-rt": true, | |
| 11 | + "disable-redzone": true, | |
| 12 | + "eliminate-frame-pointer": false, | |
| 13 | + "morestack": false | |
| 14 | +} | |
| 15 | + | |
| @@ -0,0 +1,28 @@ | ||
| 1 | +//#![crate_type="lib"] | |
| 2 | +#![feature(no_std)] | |
| 3 | +#![feature(asm)] | |
| 4 | +#![feature(core)] | |
| 5 | +#![feature(lang_items)] | |
| 6 | +#![no_std] | |
| 7 | + | |
| 8 | +#[macro_use] | |
| 9 | +extern crate core; | |
| 10 | + | |
| 11 | +#[macro_use] | |
| 12 | +mod macros; | |
| 13 | + | |
| 14 | +mod io; | |
| 15 | +pub mod debug; | |
| 16 | + | |
| 17 | +mod prelude; | |
| 18 | +pub mod unwind; | |
| 19 | + | |
| 20 | +mod logging; | |
| 21 | + | |
| 22 | +#[no_mangle] | |
| 23 | +pub extern "C" fn main() | |
| 24 | +{ | |
| 25 | +} | |
| 26 | + | |
| 27 | +// vim: ft=rust | |
| 28 | + | |
| @@ -0,0 +1,2 @@ | ||
| 1 | +pub use core::prelude::*; | |
| 2 | + | |
| @@ -0,0 +1,71 @@ | ||
| 1 | +use prelude::*; | |
| 2 | + | |
| 3 | +#[lang="panic_fmt"] | |
| 4 | +#[no_mangle] | |
| 5 | +pub fn rust_begin_unwind(args: ::core::fmt::Arguments, file: &str, line: usize) -> ! | |
| 6 | +{ | |
| 7 | + // 'args' will print to the formatted string passed to panic! | |
| 8 | + log!("file='{}', line={} :: {}", file, line, args); | |
| 9 | + loop {} | |
| 10 | +} | |
| 11 | + | |
| 12 | +#[lang="stack_exhausted"] | |
| 13 | +#[no_mangle] | |
| 14 | +pub fn __morestack() -> ! | |
| 15 | +{ | |
| 16 | + loop {} | |
| 17 | +} | |
| 18 | + | |
| 19 | + | |
| 20 | +#[allow(non_camel_case_types)] | |
| 21 | +#[repr(C)] | |
| 22 | +#[derive(Clone,Copy)] | |
| 23 | +pub enum _Unwind_Reason_Code | |
| 24 | +{ | |
| 25 | + _URC_NO_REASON = 0, | |
| 26 | + _URC_FOREIGN_EXCEPTION_CAUGHT = 1, | |
| 27 | + _URC_FATAL_PHASE2_ERROR = 2, | |
| 28 | + _URC_FATAL_PHASE1_ERROR = 3, | |
| 29 | + _URC_NORMAL_STOP = 4, | |
| 30 | + _URC_END_OF_STACK = 5, | |
| 31 | + _URC_HANDLER_FOUND = 6, | |
| 32 | + _URC_INSTALL_CONTEXT = 7, | |
| 33 | + _URC_CONTINUE_UNWIND = 8, | |
| 34 | +} | |
| 35 | + | |
| 36 | +#[allow(non_camel_case_types)] | |
| 37 | +#[derive(Clone,Copy)] | |
| 38 | +pub struct _Unwind_Context; | |
| 39 | + | |
| 40 | +#[allow(non_camel_case_types)] | |
| 41 | +pub type _Unwind_Action = u32; | |
| 42 | +static _UA_SEARCH_PHASE: _Unwind_Action = 1; | |
| 43 | + | |
| 44 | +#[allow(non_camel_case_types)] | |
| 45 | +#[repr(C)] | |
| 46 | +#[derive(Clone,Copy)] | |
| 47 | +#[allow(raw_pointer_derive)] | |
| 48 | +pub struct _Unwind_Exception | |
| 49 | +{ | |
| 50 | + exception_class: u64, | |
| 51 | + exception_cleanup: fn(_Unwind_Reason_Code,*const _Unwind_Exception), | |
| 52 | + private: [u64; 2], | |
| 53 | +} | |
| 54 | + | |
| 55 | +#[lang="eh_personality"] | |
| 56 | +#[no_mangle] | |
| 57 | +pub fn rust_eh_personality( | |
| 58 | + _version: isize, _actions: _Unwind_Action, _exception_class: u64, | |
| 59 | + _exception_object: &_Unwind_Exception, _context: &_Unwind_Context | |
| 60 | + ) -> _Unwind_Reason_Code | |
| 61 | +{ | |
| 62 | + loop{} | |
| 63 | +} | |
| 64 | + | |
| 65 | +#[no_mangle] | |
| 66 | +#[allow(non_snake_case)] | |
| 67 | +pub fn _Unwind_Resume() | |
| 68 | +{ | |
| 69 | + loop{} | |
| 70 | +} | |
| 71 | + | |