Commit 931b705a authored by Nifou's avatar Nifou

Execute a binary with the rust's libstd!

parent c6bd772f
......@@ -85,6 +85,7 @@ name = "obsidianos-kernel"
version = "0.0.0"
dependencies = [
"bit_field 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"goblin 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"linked_list_allocator 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
......
......@@ -13,6 +13,7 @@ linked_list_allocator = "0.8.4"
multiboot2 = "0.8.2"
bit_field = "0.10.0"
x86 = "0.33.0"
bitflags = "1.2.1"
[dependencies.goblin]
default-features = false
......
......@@ -119,7 +119,7 @@ set_up_page_tables:
mov [(p2_table - 0xc0000000) + ecx * 8], eax ; map ecx-th entry
inc ecx ; increase counter
cmp ecx, 3 ; the kernel size is 0x400000 (see memory/mod.rs:KERNEL_SIZE), so 0x400000 / 0x200000 + 1 = 3
cmp ecx, 6 ; the kernel size is 0x800000 (see memory/mod.rs:KERNEL_SIZE), so 0x800000 / 0x200000 + 1 = 6
jne .map_p2_table ; else map the next entry
ret
......
......@@ -127,7 +127,7 @@ impl<'a> ElfLoader<'a> {
// Map the binary in the kernel's address space
let mappings =
memory::map(start, start + ph.p_filesz, Flags::PRESENT | Flags::WRITABLE);
memory::map(start, start + ph.p_memsz, Flags::PRESENT | Flags::WRITABLE);
// Copy the binary in memory
unsafe {
......
......@@ -75,6 +75,10 @@ impl InitFS {
String::from("/bin/hello2"),
include_bytes!("../../root/bin/hello2") as &[u8],
);
files.insert(
String::from("/bin/test-std"),
include_bytes!("../../root/bin/test-std") as &[u8],
);
files.insert(
String::from("/README.md"),
include_bytes!("../../README.md") as &[u8],
......
......@@ -135,6 +135,7 @@ pub extern "C" fn kmain(info_addr: usize) {
elf::load(String::from("/bin/hello"));
elf::load(String::from("/bin/hello2"));
elf::load(String::from("/bin/test-std"));
println!("ObsidianOS is ready!");
x86_64::instructions::interrupts::enable();
......
......@@ -55,7 +55,7 @@ pub const KERNEL_START_VIRT: u64 = 0xc0000000;
pub const KERNEL_START_PHYS: u64 = 0;
/// The size of the kernel
pub const KERNEL_SIZE: u64 = 0x400000;
pub const KERNEL_SIZE: u64 = 0x800000;
lazy_static! {
/// A global kernel memory mapper
......
/*
* Copyright (C) 2020 Nicolas Fouquet
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see https://www.gnu.org/licenses.
*/
//! Syscalls used to manage the memory
use bitflags::bitflags;
use x86_64::structures::paging::page_table::PageTableFlags as Flags;
use crate::tasking::scheduler::SCHEDULER;
use super::Syscall;
bitflags! {
struct MmapFlags: u32 {
const SHARED = 1 << 0;
const PRIVATE = 1 << 1;
const FIXED = 1 << 4;
const ANONYMOUS = 1 << 5;
}
}
bitflags! {
struct MmapProt: u32 {
const NONE = 0;
const READ = 1 << 0;
const WRITE = 1 << 1;
const EXEC = 1 << 2;
}
}
impl From<MmapProt> for Flags {
fn from(prot: MmapProt) -> Flags {
let mut flags = Flags::NO_EXECUTE;
if prot.contains(MmapProt::READ) {
flags.insert(Flags::PRESENT);
}
if prot.contains(MmapProt::WRITE) {
flags.insert(Flags::WRITABLE);
}
if prot.contains(MmapProt::EXEC) {
flags.remove(Flags::NO_EXECUTE);
}
flags.insert(Flags::USER_ACCESSIBLE);
flags
}
}
impl<'a> Syscall<'a> {
/// Map files or devices into memory
pub fn mmap(&self, addr: usize, len: usize, prot: usize, flags: usize, fd: usize, offset: usize)
-> usize {
println!("mmap({:#x}, {}, {}, {}, {:#x}, {})", addr, len, prot, flags, fd, offset);
let prot = MmapProt::from_bits_truncate(prot as u32);
let flags = MmapFlags::from_bits_truncate(flags as u32);
if flags.contains(MmapFlags::ANONYMOUS) {
if addr == 0 {
crate::memory::switch_to_kernel_page_table();
unsafe { SCHEDULER.force_unlock(); }
SCHEDULER.lock().get_current_mut().memory.map(0x300000, 0x300000 + len as u64, Flags::from(prot), Flags::PRESENT);
SCHEDULER.lock().get_current_mut().memory.switch_page_table();
0x300000
}
else {
addr
}
}
else {
0
}
}
/// Change data segment size
pub fn brk(&self, addr: usize) -> usize {
print!("brk({:#x}) = ", addr);
if addr == 0 {
println!("0x10000000");
crate::memory::switch_to_kernel_page_table();
unsafe { SCHEDULER.force_unlock(); }
SCHEDULER.lock().get_current_mut().memory.map(0x10000000, 0x10004000, Flags::PRESENT | Flags::WRITABLE, Flags::PRESENT);
SCHEDULER.lock().get_current_mut().memory.switch_page_table();
0x10000000
}
else {
println!("{:#x}", addr);
addr
}
}
}
/*
* Copyright (C) 2020 Nicolas Fouquet
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see https://www.gnu.org/licenses.
*/
//! Other syscalls
use x86_64::{
VirtAddr,
registers::model_specific::FsBase,
};
use super::Syscall;
impl<'a> Syscall<'a> {
/// Set og get some architecture specific registers
pub fn arch_prctl(&mut self, code: usize, addr: usize) -> usize {
println!("arch_prctl({:#x}, {:#x}) = 0", code, addr);
const ARCH_SET_FS: usize = 0x1002;
match code {
ARCH_SET_FS => {
unsafe { x86::msr::wrmsr(x86::msr::IA32_FS_BASE, addr as u64); }
},
_ => (),
}
0
}
}
......@@ -26,15 +26,14 @@ use crate::tasking::{
pub mod process;
pub mod fs;
pub mod memory;
pub mod misc;
#[allow(dead_code)]
#[repr(packed)]
#[derive(Debug, Clone, Copy)]
/// The stack which contains the registers saved and restored during a syscall
pub struct SyscallStack {
/// The FS register
pub fs: usize,
/// The R11 register
pub r11: usize,
......@@ -125,10 +124,7 @@ pub unsafe extern fn syscall() {
push r8
push r9
push r10
push r11
push fs
mov r11, 0x10
mov fs, r11"
push r11"
: : : : "intel", "volatile");
// Get reference to stack variables
......@@ -142,8 +138,7 @@ pub unsafe extern fn syscall() {
// of a function is stored in RAX, so nothing to do!
// Interrupt return
llvm_asm!("pop fs
pop r11
llvm_asm!("pop r11
pop r10
pop r9
pop r8
......@@ -159,7 +154,10 @@ pub unsafe extern fn syscall() {
// --- Syscall numbers ---
const WRITE: usize = 1;
const MMAP: usize = 9;
const BRK: usize = 12;
const EXIT: usize = 60;
const ARCH_PRCTL: usize = 158;
/// A structure used to call the right handler for each syscall
pub struct Syscall<'a> {
......@@ -183,8 +181,14 @@ impl<'a> Syscall<'a> {
match num {
WRITE => self.write(args[0], args[1], args[2]),
MMAP => self.mmap(args[0], args[1], args[2], args[3], args[4], args[5]),
BRK => self.brk(args[0]),
EXIT => self.exit(args[0]),
_ => 0,
ARCH_PRCTL => self.arch_prctl(args[0], args[1]),
_ => {
println!("Unknown syscall: {}", num);
0
},
}
}
}
......@@ -55,14 +55,6 @@ impl ProcessMemory {
let frame = PhysFrame::containing_address(PhysAddr::new(memory::KERNEL_START_PHYS + i as u64 * 4096));
unsafe { mapper.map_to(page, frame, Flags::PRESENT | Flags::WRITABLE, &mut *memory::FRAME_ALLOCATOR.r#try().unwrap().lock()).unwrap().ignore(); }
}
// Map the kernel's page table frame
if let Some(frame) = memory::KERNEL_PAGE_TABLE.r#try() {
unsafe { mapper.identity_map(*frame, Flags::PRESENT | Flags::WRITABLE, &mut *memory::FRAME_ALLOCATOR.r#try().unwrap().lock()).unwrap().ignore(); }
}
// Map the table itself
unsafe { mapper.identity_map(page_table_frame, Flags::PRESENT | Flags::WRITABLE, &mut *memory::FRAME_ALLOCATOR.r#try().unwrap().lock()).unwrap().ignore(); }
});
Self {
......
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "test-std"
version = "0.0.0"
[package]
name = "test-std"
version = "0.0.0"
authors = ["Nifou <nfouquet@mailfence.com>"]
edition = "2018"
all:
@cargo rustc --target x86_64-unknown-linux-musl
@cp target/x86_64-unknown-linux-musl/debug/test-std ../../../build/bins/test-std
fn main() {
println!("Hello, world!");
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment