History

import some stuff from thepowersgang barebones kernel

mischief committed 11 years ago

Commit ff71dcc1 parent 4fad6179 files · +293 −6Browse files

Unified · Split

9 files
  1. pc64/Makefile +37 −6
  2. pc64/debug.rs +29 −0
  3. pc64/io.rs +42 −0
  4. pc64/logging.rs +61 −0
  5. pc64/macros.rs +8 −0
  6. pc64/pc64.json +15 −0
  7. pc64/pc64.rs +28 −0
  8. pc64/prelude.rs +2 −0
  9. pc64/unwind.rs +71 −0
pc64/Makefile+37−6
@@ -1,10 +1,25 @@
1+CONF=pc64
2+
13 ARCH = amd64
4+RUSTC = rustc
5+CC = gcc
26 LD = ld
3−NASM = nasm
7+AS = nasm
48 QEMU = qemu-system-i386 -curses
59
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
823
924 all: $(BUILDDIR) rust9front.bin
1025
@@ -12,10 +27,26 @@ $(BUILDDIR): · 1 unmodified line
1227 mkdir -p $(BUILDDIR)
1328
1429 rust9front.o: l.asm
15− $(NASM) -f elf32 -Wall -o $@ $<
30+ $(AS) -f elf32 -Wall -o $@ $<
1631
17−rust9front.bin: rust9front.o
18− $(LD) -m elf_i386 -o $@ $^
32+rust9front.bin: $(OBJ)
33+ $(LD) $(LDFLAGS) -o $@ $(OBJ)
1934
2035 debug: rust9front.bin
2136 $(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+
pc64/debug.rs+29−0
@@ -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+}
pc64/io.rs+42−0
@@ -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+
pc64/logging.rs+61−0
@@ -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+
pc64/macros.rs+8−0
@@ -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+
pc64/pc64.json+15−0
@@ -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+
pc64/pc64.rs+28−0
@@ -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+
pc64/prelude.rs+2−0
@@ -0,0 +1,2 @@
1+pub use core::prelude::*;
2+
pc64/unwind.rs+71−0
@@ -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+