1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
//! The os1 kernel is written and compiled as a library. It is then
//! compiled and linked together with assembly files to produce a binary.
//! The binary is written to the hard disk, which is then loaded.
//!
//! The kernel is compiled without any `libstd`. Only `libcore` and
//! `liballoc` are used, since they provide core Rust functionality.

// To use unstable features of Rust, we need to have nightly rustc
#![feature(no_std,
           lang_items,
           alloc,
           heap_api,
           box_syntax,
           box_patterns,
           const_fn,
           core_str_ext,
           core_slice_ext,
           dropck_parametricity,
           ptr_as_ref,
           core_intrinsics,
          )]

// Compile without libstd
#![no_std]

#![crate_type = "staticlib"]
#![crate_name = "os1"]

// use libcore
#[macro_use]
extern crate alloc;
extern crate rlibc;

// kernel module declarations
// debug must be first, since it defines macros the others need
#[macro_use]
mod debug;
mod bare_bones;

mod linked_list;
mod static_linked_list;
mod vec;
mod string;

mod fs;
mod interrupts;
mod io;
mod machine;
mod memory;
mod process;
mod sync;
mod vga;

// exported functions -- to use in asm functions
pub use self::process::context::store_kcontext;
pub use self::process::_proc_yield;
pub use self::interrupts::pic::pic_irq;
pub use self::memory::vmm_page_fault;

/// This is the entry point to the kernel. It is the first rust code that runs.
#[no_mangle]
pub fn kernel_main() {
    // make sure interrupts are off
    unsafe { machine::cli(); }

    // print new line after "x"
    bootlog! ("\n");

    /////////////////////////////////////////////////////
    // Start initing stuff                             //
    /////////////////////////////////////////////////////

    // init tss, heap, and vm
    interrupts::tss_init();

    // make the kernel heap 3MiB starting at 1MiB.
    // make memory data structures take up the next 4MiB.
    memory::init(1<<20, 3<<20);

    // init processes
    process::init();

    // init interupts
    interrupts::init(1000 /* hz */);

    // filesystem
    fs::init(self::io::ide::IDE::new(3 /* hdd */));

    /////////////////////////////////////////////////////
    // Done initing stuff                              //
    /////////////////////////////////////////////////////

    // yield to init process
    printf!("Everything inited! Here we go!\n");

    process::proc_yield(None);

    // yield should never return to here
    panic!("This should never happen!\n");

}