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 @@
1CONF=pc64
2
1ARCH = amd643ARCH = amd64
4RUSTC = rustc
5CC = gcc
2LD = ld6LD = ld
3NASM = nasm7AS = nasm
4QEMU = qemu-system-i386 -curses8QEMU = qemu-system-i386 -curses
5 9
6OBJECTS = rust9front.o10LDFLAGS = --gc-sections -T $(CONF).ld
7ASMOBJECTS = $(wildcard *.asm)11RUSTFLAGS = -C soft-float -O --target=$(CONF).json
12
13OBJ= \
14 $(CONF).o \
15 l.o\
16
17RUSTFILES= \
18 macros.rs \
19 unwind.rs \
20 main.rs \
21
22LIBCORE = libcore.rlib
8 23
9all: $(BUILDDIR) rust9front.bin24all: $(BUILDDIR) rust9front.bin
10 25
@@ -12,10 +27,26 @@ $(BUILDDIR): · 1 unmodified line
12 mkdir -p $(BUILDDIR)27 mkdir -p $(BUILDDIR)
13 28
14rust9front.o: l.asm29rust9front.o: l.asm
15 $(NASM) -f elf32 -Wall -o $@ $<30 $(AS) -f elf32 -Wall -o $@ $<
16 31
17rust9front.bin: rust9front.o32rust9front.bin: $(OBJ)
18 $(LD) -m elf_i386 -o $@ $^33 $(LD) $(LDFLAGS) -o $@ $(OBJ)
19 34
20debug: rust9front.bin35debug: rust9front.bin
21 $(QEMU) -s -S -kernel $<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
47libcore.rlib: libcore/lib.rs
48 $(RUSTC) $(RUSTFLAGS) -o $@ --crate-type=lib --emit=link,dep-info $<
49
50clean:
51 rm -f *.d *.rlib *.o *.bin
52
pc64/debug.rs+29−0
@@ -0,0 +1,29 @@
1use prelude::*;
2
3/// Write a string to the output channel
4///
5/// This method is unsafe because it does port accesses without synchronisation
6pub 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
17pub 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
2pub 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
8pub 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
16pub 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
22pub 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
30pub 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
36pub 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 @@
1use prelude::*;
2use core::atomic;
3use core::fmt;
4
5/// A formatter object
6pub 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.
12static LOGGING_LOCK: atomic::AtomicBool = atomic::ATOMIC_BOOL_INIT;
13
14impl 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
31impl ::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
47impl 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 @@
1macro_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]
9extern crate core;
10
11#[macro_use]
12mod macros;
13
14mod io;
15pub mod debug;
16
17mod prelude;
18pub mod unwind;
19
20mod logging;
21
22#[no_mangle]
23pub extern "C" fn main()
24{
25}
26
27// vim: ft=rust
28
pc64/prelude.rs+2−0
@@ -0,0 +1,2 @@
1pub use core::prelude::*;
2
pc64/unwind.rs+71−0
@@ -0,0 +1,71 @@
1use prelude::*;
2
3#[lang="panic_fmt"]
4#[no_mangle]
5pub 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]
14pub fn __morestack() -> !
15{
16 loop {}
17}
18
19
20#[allow(non_camel_case_types)]
21#[repr(C)]
22#[derive(Clone,Copy)]
23pub 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)]
38pub struct _Unwind_Context;
39
40#[allow(non_camel_case_types)]
41pub type _Unwind_Action = u32;
42static _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)]
48pub 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]
57pub 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)]
67pub fn _Unwind_Resume()
68{
69 loop{}
70}
71