~kameliya/syso

c121ae465bde244f5c1989fb880df4f7920c2042 — Yuki Izumi 4 years ago e8b3b01
allocator
M Cargo.lock => Cargo.lock +14 -0
@@ 3,6 3,7 @@ name = "syso"
version = "0.0.1"
dependencies = [
 "cpuio 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 "hole_list_allocator 0.0.1",
 "multiboot2 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
 "rlibc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]


@@ 18,6 19,18 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
name = "hole_list_allocator"
version = "0.0.1"
dependencies = [
 "linked_list_allocator 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "linked_list_allocator"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
name = "multiboot2"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 33,5 46,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dead7461c1127cf637931a1e50934eb6eee8bff2f74433ac7909e9afcee04a3"
"checksum cpuio 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "22b8e308ccfc5acf3b82f79c0eac444cf6114cb2ac67a230ca6c177210068daa"
"checksum linked_list_allocator 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "58bc6078c53efb4976165df37d3b3c7b9eddd7091d2ec2a2062eed524e20052e"
"checksum multiboot2 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88aedb52b616203e987bf9cd0c2779e281eefcfa23bd23dc9734f2dcf54079ad"
"checksum rlibc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc874b127765f014d792f16763a81245ab80500e2ad921ed4ee9e82481ee08fe"

M Cargo.toml => Cargo.toml +3 -0
@@ 11,6 11,9 @@ rlibc = "1.0.0"
cpuio = "0.2.0"
multiboot2 = "0.3.1"

[dependencies.hole_list_allocator]
path = "libs/hole_list_allocator"

[profile.dev]
panic = "abort"


M Makefile => Makefile +5 -1
@@ 27,7 27,7 @@ run: $(TARGET)-copy
$(TARGET)-copy: $(TARGET)
	MTOOLSRC=mtoolsrc mcopy -D o $(TARGET) $(COPYDEST)

.PHONY: $(TARGET)
.PHONY: $(TARGET) clean

$(TARGET): $(ASMS_OUT)
	cargo build --target=x86_64-unknown-linux-gnu


@@ 35,3 35,7 @@ $(TARGET): $(ASMS_OUT)

$(BUILD)/%.s.o: %.s
	$(AS) $(ASFLAGS) $< -o $@

clean:
	-cargo clean
	-rm $(ASMS_OUT) $(TARGET)

M entry.s => entry.s +2 -2
@@ 100,7 100,7 @@ enable_sse:
  .comm p3_table, 4096, 4096
  .local p2_table
  .comm p2_table, 4096, 4096
  .comm stack_bottom, 64
  .comm stack_bottom, 4096, 4096
  .comm stack_top, 0

.code64


@@ 112,7 112,7 @@ long_mode_start:
  mov %rax, (0xb8000)
  mov $0x4f724f754f744f65, %rax
  mov %rax, (0xb8008)
  mov $	0x4f214f644f654f6e, %rax
  mov $0x4f214f644f654f6e, %rax
  mov %rax, (0xb8010)

  hlt

A libs/hole_list_allocator/Cargo.toml => libs/hole_list_allocator/Cargo.toml +16 -0
@@ 0,0 1,16 @@
[package]
name = "hole_list_allocator"
version = "0.0.1"
authors = ["Yuki Izumi <yuki@kivikakk.ee>"]

[lib]


[dependencies]
linked_list_allocator = "0.2.2"

[profile.dev]
panic = "abort"

[profile.release]
panic = "abort"

A libs/hole_list_allocator/src/lib.rs => libs/hole_list_allocator/src/lib.rs +49 -0
@@ 0,0 1,49 @@
#![feature(allocator)]
#![feature(const_fn)]
#![allocator]
#![no_std]

extern crate linked_list_allocator;

use linked_list_allocator::Heap;

static mut HEAP: Heap = Heap::empty();

pub unsafe fn init(base: usize, size: usize) {
    HEAP = Heap::new(base, size);
}

#[no_mangle]
pub extern fn __rust_allocate(size: usize, align: usize) -> *mut u8 {
    match unsafe { HEAP.allocate_first_fit(size, align) } {
        Some(ptr) => ptr,
        None => panic!("__rust_allocate"),
    }
}

#[no_mangle]
pub extern fn __rust_usable_size(size: usize, _align: usize) -> usize {
    size
}

#[no_mangle]
pub extern fn __rust_deallocate(ptr: *mut u8, size: usize, align: usize) {
    unsafe { HEAP.deallocate(ptr, size, align) }
}

#[no_mangle]
pub extern fn __rust_reallocate(ptr: *mut u8, size: usize, new_size: usize,
                                align: usize) -> *mut u8 {
    use core::{ptr, cmp};
    let new_ptr = __rust_allocate(new_size, align);
    unsafe { ptr::copy(ptr, new_ptr, cmp::min(size, new_size)) };
    __rust_deallocate(ptr, size, align);
    new_ptr
}

#[no_mangle]
pub extern fn __rust_reallocate_inplace(_ptr: *mut u8, size: usize,
                                        _new_size: usize, _align: usize)
                                        -> usize {
    size
}

M src/console.rs => src/console.rs +1 -3
@@ 1,6 1,5 @@
use core::fmt::{self, Write};
use core::fmt;
use cpuio::Port;
use debug::DEBUG;

pub static mut CONSOLE: Console = Console {
    cx: 0,


@@ 90,7 89,6 @@ impl Console {
        cursor_data.write(((index >> 8) & 0xFF) as u8);
        cursor_idx.write(0xF);
        cursor_data.write((index & 0xFF) as u8);
        unsafe { write!(DEBUG, "set cursor to {},{}\n", self.cx, self.cy).unwrap() }
    }
}


M src/debug.rs => src/debug.rs +1 -0
@@ 1,6 1,7 @@
use core::fmt;
use cpuio::Port;

#[allow(dead_code)]
pub static mut DEBUG: Debug = Debug {};

pub struct Debug {}

M src/lib.rs => src/lib.rs +8 -24
@@ 1,10 1,16 @@
#![feature(alloc)]
#![feature(collections)]
#![feature(lang_items)]
#![feature(asm)]
#![feature(const_fn)]
#![no_std]

extern crate alloc;
extern crate collections;
extern crate rlibc;
extern crate cpuio;
extern crate multiboot2;
extern crate hole_list_allocator;

use core::fmt::Write;



@@ 12,6 18,7 @@ pub mod support;

mod console;
mod debug;
mod mem;

#[no_mangle]
pub extern fn rust_entry(multiboot_addr: usize) {


@@ 21,30 28,7 @@ pub extern fn rust_entry(multiboot_addr: usize) {
    write!(console, "syso :)\n").unwrap();

    let multiboot = unsafe { multiboot2::load(multiboot_addr) };

    let memory_map_tag = multiboot.memory_map_tag().expect("Memory map tag required");
    write!(console, "memory map:\n").unwrap();
    for area in memory_map_tag.memory_areas() {
        write!(console, "\tstart: 0x{:x}, length: 0x{:x}\n", area.base_addr, area.length).unwrap();
    }

    let elf_sections_tag = multiboot.elf_sections_tag().expect("ELF sections tag required");
    write!(console, "kernel sections:\n").unwrap();
    for section in elf_sections_tag.sections() {
        write!(console, "\taddr: 0x{:x}, size: 0x{:x}, flags: 0x{:x}\n", section.addr, section.size, section.flags).unwrap();
    }

    let kernel_start = elf_sections_tag.sections().map(|s| s.addr)
        .min().unwrap();
    let kernel_end = elf_sections_tag.sections().map(|s| s.addr + s.size)
        .max().unwrap();

    let multiboot_start = multiboot_addr;
    let multiboot_end = multiboot_start + (multiboot.total_size as usize);

    write!(console, "kernel_start: 0x{:x}, kernel_end: 0x{:x}\n", kernel_start, kernel_end).unwrap();
    write!(console, "multiboot_start: 0x{:x}, multiboot_end: 0x{:x}\n", multiboot_start, multiboot_end).unwrap();

    mem::init(&multiboot);

    write!(console, "> ").unwrap();


A src/mem.rs => src/mem.rs +58 -0
@@ 0,0 1,58 @@
use core::fmt::Write;
use collections::BTreeSet;
use multiboot2::BootInformation;
use hole_list_allocator;

use debug::DEBUG;

pub fn init(multiboot: &BootInformation) {
    let memory_map_tag = multiboot.memory_map_tag().expect("Memory map tag required");
    unsafe { write!(DEBUG, "memory map:\n").unwrap() }
    for area in memory_map_tag.memory_areas() {
        unsafe { write!(DEBUG, "\tstart: 0x{:x}, length: 0x{:x}\n", area.base_addr, area.length).unwrap() }
    }

    let elf_sections_tag = multiboot.elf_sections_tag().expect("ELF sections tag required");
    unsafe { write!(DEBUG, "kernel sections:\n").unwrap() }
    for section in elf_sections_tag.sections() {
        unsafe { write!(DEBUG, "\taddr: 0x{:x}, size: 0x{:x}, flags: 0x{:x}\n", section.addr, section.size, section.flags).unwrap() }
    }

    let kernel_start = elf_sections_tag.sections().map(|s| s.addr)
        .min().unwrap() as usize;
    let kernel_end = elf_sections_tag.sections().map(|s| s.addr + s.size)
        .max().unwrap() as usize;

    let multiboot_start = multiboot.start_address();
    let multiboot_end = multiboot.end_address();

    unsafe { write!(DEBUG, "kernel_start: 0x{:x}, kernel_end: 0x{:x}\n", kernel_start, kernel_end).unwrap() }
    unsafe { write!(DEBUG, "multiboot_start: 0x{:x}, multiboot_end: 0x{:x}\n", multiboot_start, multiboot_end).unwrap() }

    let heap_start = if kernel_end > multiboot_end { kernel_end } else { multiboot_end };

    unsafe { hole_list_allocator::init(0x20000, 0x20000) }
    unsafe { write!(DEBUG, "HEAP created at 0x{:x}\n", heap_start).unwrap() }

    let mut usable_memory: BTreeSet<Extent> = BTreeSet::new();

    usable_memory.insert(Extent::new(6, 9));
    usable_memory.insert(Extent::new(0, 3));
    usable_memory.insert(Extent::new(9, 13));
    unsafe { write!(DEBUG, "Usable memory: {:?}\n", usable_memory).unwrap() }
}

#[derive(PartialEq, Eq, Ord, PartialOrd, Debug)]
struct Extent {
    base: usize,
    length: usize,
}

impl Extent {
    fn new(base: usize, length: usize) -> Extent {
        Extent {
            base: base,
            length: length,
        }
    }
}

M syso.ld => syso.ld +0 -5
@@ 17,9 17,4 @@ SECTIONS
    *(.data.rel.ro.local*)
    *(.data.rel.ro .data.rel.ro.*)
  }

  .debug : {
    /* I don't know if I need these, but coalesce for now. */
    *(.debug_*)
  }
}