Rename the src directory to kernel
.
This commit is contained in:
parent
7b8ba1a118
commit
f8bd171efd
16 changed files with 0 additions and 0 deletions
7
kernel/arch/mod.rs
Normal file
7
kernel/arch/mod.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
//! Architecture specific items
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub use self::x86_64::*;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub mod x86_64;
|
31
kernel/arch/x86_64/gdt.rs
Normal file
31
kernel/arch/x86_64/gdt.rs
Normal file
|
@ -0,0 +1,31 @@
|
|||
pub const GDT_NULL: usize = 0;
|
||||
pub const GDT_KERNEL_CODE: usize = 1;
|
||||
pub const GDT_KERNEL_DATA: usize = 2;
|
||||
pub const GDT_USER_CODE: usize = 3;
|
||||
pub const GDT_USER_DATA: usize = 4;
|
||||
pub const GDT_USER_TLS: usize = 5;
|
||||
pub const GDT_TSS: usize = 6;
|
||||
|
||||
#[repr(packed)]
|
||||
pub struct GdtDescriptor {
|
||||
pub size: u16,
|
||||
pub ptr: u64
|
||||
}
|
||||
|
||||
#[repr(packed)]
|
||||
pub struct GdtEntry {
|
||||
pub limitl: u16,
|
||||
pub basel: u16,
|
||||
pub basem: u8,
|
||||
pub attribute: u8,
|
||||
pub flags_limith: u8,
|
||||
pub baseh: u8
|
||||
}
|
||||
|
||||
impl GdtEntry {
|
||||
pub fn set_base(&mut self, base: usize) {
|
||||
self.basel = base as u16;
|
||||
self.basem = (base >> 16) as u8;
|
||||
self.baseh = (base >> 24) as u8;
|
||||
}
|
||||
}
|
75
kernel/arch/x86_64/idt.rs
Normal file
75
kernel/arch/x86_64/idt.rs
Normal file
|
@ -0,0 +1,75 @@
|
|||
use core::mem;
|
||||
|
||||
pub static mut IDTR: IdtDescriptor = IdtDescriptor {
|
||||
size: 0,
|
||||
offset: 0
|
||||
};
|
||||
|
||||
pub static mut IDT: [IdtEntry; 256] = [IdtEntry::new(); 256];
|
||||
|
||||
bitflags! {
|
||||
pub flags IdtFlags: u8 {
|
||||
const IDT_PRESENT = 1 << 7,
|
||||
const IDT_RING_0 = 0 << 5,
|
||||
const IDT_RING_1 = 1 << 5,
|
||||
const IDT_RING_2 = 2 << 5,
|
||||
const IDT_RING_3 = 3 << 5,
|
||||
const IDT_SS = 1 << 4,
|
||||
const IDT_INTERRUPT = 0xE,
|
||||
const IDT_TRAP = 0xF,
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(packed)]
|
||||
pub struct IdtDescriptor {
|
||||
size: u16,
|
||||
offset: u64
|
||||
}
|
||||
|
||||
impl IdtDescriptor {
|
||||
pub fn set_slice(&mut self, slice: &'static [IdtEntry]) {
|
||||
self.size = (slice.len() * mem::size_of::<IdtEntry>() - 1) as u16;
|
||||
self.offset = slice.as_ptr() as u64;
|
||||
}
|
||||
|
||||
pub unsafe fn load(&self) {
|
||||
asm!("lidt [rax]" : : "{rax}"(self as *const _ as usize) : : "intel", "volatile");
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[repr(packed)]
|
||||
pub struct IdtEntry {
|
||||
offsetl: u16,
|
||||
selector: u16,
|
||||
zero: u8,
|
||||
attribute: u8,
|
||||
offsetm: u16,
|
||||
offseth: u32,
|
||||
zero2: u32
|
||||
}
|
||||
|
||||
impl IdtEntry {
|
||||
pub const fn new() -> IdtEntry {
|
||||
IdtEntry {
|
||||
offsetl: 0,
|
||||
selector: 0,
|
||||
zero: 0,
|
||||
attribute: 0,
|
||||
offsetm: 0,
|
||||
offseth: 0,
|
||||
zero2: 0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_flags(&mut self, flags: IdtFlags) {
|
||||
self.attribute = flags.bits;
|
||||
}
|
||||
|
||||
pub fn set_offset(&mut self, selector: u16, base: usize) {
|
||||
self.selector = selector;
|
||||
self.offsetl = base as u16;
|
||||
self.offsetm = (base >> 16) as u16;
|
||||
self.offseth = (base >> 32) as u32;
|
||||
}
|
||||
}
|
61
kernel/arch/x86_64/io/io.rs
Normal file
61
kernel/arch/x86_64/io/io.rs
Normal file
|
@ -0,0 +1,61 @@
|
|||
use core::cmp::PartialEq;
|
||||
use core::ops::{BitAnd, BitOr, Not};
|
||||
|
||||
pub trait Io {
|
||||
type Value: Copy + PartialEq + BitAnd<Output = Self::Value> + BitOr<Output = Self::Value> + Not<Output = Self::Value>;
|
||||
|
||||
fn read(&self) -> Self::Value;
|
||||
fn write(&mut self, value: Self::Value);
|
||||
|
||||
fn readf(&self, flags: Self::Value) -> bool {
|
||||
(self.read() & flags) as Self::Value == flags
|
||||
}
|
||||
|
||||
fn writef(&mut self, flags: Self::Value, value: bool) {
|
||||
let tmp: Self::Value = match value {
|
||||
true => self.read() | flags,
|
||||
false => self.read() & !flags,
|
||||
};
|
||||
self.write(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ReadOnly<I: Io> {
|
||||
inner: I
|
||||
}
|
||||
|
||||
impl<I: Io> ReadOnly<I> {
|
||||
pub fn new(inner: I) -> ReadOnly<I> {
|
||||
ReadOnly {
|
||||
inner: inner
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read(&self) -> I::Value {
|
||||
self.inner.read()
|
||||
}
|
||||
|
||||
pub fn readf(&self, flags: I::Value) -> bool {
|
||||
self.inner.readf(flags)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WriteOnly<I: Io> {
|
||||
inner: I
|
||||
}
|
||||
|
||||
impl<I: Io> WriteOnly<I> {
|
||||
pub fn new(inner: I) -> WriteOnly<I> {
|
||||
WriteOnly {
|
||||
inner: inner
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write(&mut self, value: I::Value) {
|
||||
self.inner.write(value)
|
||||
}
|
||||
|
||||
pub fn writef(&mut self, flags: I::Value, value: bool) {
|
||||
self.inner.writef(flags, value)
|
||||
}
|
||||
}
|
31
kernel/arch/x86_64/io/mmio.rs
Normal file
31
kernel/arch/x86_64/io/mmio.rs
Normal file
|
@ -0,0 +1,31 @@
|
|||
use core::intrinsics::{volatile_load, volatile_store};
|
||||
use core::mem::uninitialized;
|
||||
use core::ops::{BitAnd, BitOr, Not};
|
||||
|
||||
use super::io::Io;
|
||||
|
||||
#[repr(packed)]
|
||||
pub struct Mmio<T> {
|
||||
value: T,
|
||||
}
|
||||
|
||||
impl<T> Mmio<T> {
|
||||
/// Create a new Mmio without initializing
|
||||
pub fn new() -> Self {
|
||||
Mmio {
|
||||
value: unsafe { uninitialized() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Io for Mmio<T> where T: Copy + PartialEq + BitAnd<Output = T> + BitOr<Output = T> + Not<Output = T> {
|
||||
type Value = T;
|
||||
|
||||
fn read(&self) -> T {
|
||||
unsafe { volatile_load(&self.value) }
|
||||
}
|
||||
|
||||
fn write(&mut self, value: T) {
|
||||
unsafe { volatile_store(&mut self.value, value) };
|
||||
}
|
||||
}
|
9
kernel/arch/x86_64/io/mod.rs
Normal file
9
kernel/arch/x86_64/io/mod.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
/// I/O functions
|
||||
|
||||
pub use self::io::*;
|
||||
pub use self::mmio::*;
|
||||
pub use self::pio::*;
|
||||
|
||||
mod io;
|
||||
mod mmio;
|
||||
mod pio;
|
83
kernel/arch/x86_64/io/pio.rs
Normal file
83
kernel/arch/x86_64/io/pio.rs
Normal file
|
@ -0,0 +1,83 @@
|
|||
use core::marker::PhantomData;
|
||||
|
||||
use super::io::Io;
|
||||
|
||||
/// Generic PIO
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Pio<T> {
|
||||
port: u16,
|
||||
value: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> Pio<T> {
|
||||
/// Create a PIO from a given port
|
||||
pub fn new(port: u16) -> Self {
|
||||
Pio::<T> {
|
||||
port: port,
|
||||
value: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Read/Write for byte PIO
|
||||
impl Io for Pio<u8> {
|
||||
type Value = u8;
|
||||
|
||||
/// Read
|
||||
fn read(&self) -> u8 {
|
||||
let value: u8;
|
||||
unsafe {
|
||||
asm!("in $0, $1" : "={al}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile");
|
||||
}
|
||||
value
|
||||
}
|
||||
|
||||
/// Write
|
||||
fn write(&mut self, value: u8) {
|
||||
unsafe {
|
||||
asm!("out $1, $0" : : "{al}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Read/Write for word PIO
|
||||
impl Io for Pio<u16> {
|
||||
type Value = u16;
|
||||
|
||||
/// Read
|
||||
fn read(&self) -> u16 {
|
||||
let value: u16;
|
||||
unsafe {
|
||||
asm!("in $0, $1" : "={ax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile");
|
||||
}
|
||||
value
|
||||
}
|
||||
|
||||
/// Write
|
||||
fn write(&mut self, value: u16) {
|
||||
unsafe {
|
||||
asm!("out $1, $0" : : "{ax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Read/Write for doubleword PIO
|
||||
impl Io for Pio<u32> {
|
||||
type Value = u32;
|
||||
|
||||
/// Read
|
||||
fn read(&self) -> u32 {
|
||||
let value: u32;
|
||||
unsafe {
|
||||
asm!("in $0, $1" : "={eax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile");
|
||||
}
|
||||
value
|
||||
}
|
||||
|
||||
/// Write
|
||||
fn write(&mut self, value: u32) {
|
||||
unsafe {
|
||||
asm!("out $1, $0" : : "{eax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile");
|
||||
}
|
||||
}
|
||||
}
|
10
kernel/arch/x86_64/irq.rs
Normal file
10
kernel/arch/x86_64/irq.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
//! # IRQ handling
|
||||
//!
|
||||
//! This module defines IRQ handling functions. These functions should all be #[naked],
|
||||
//! unsafe, extern, and end in `iretq`
|
||||
|
||||
/// Interupt Request handler.
|
||||
#[naked]
|
||||
pub unsafe extern fn irq() {
|
||||
|
||||
}
|
78
kernel/arch/x86_64/main.rs
Normal file
78
kernel/arch/x86_64/main.rs
Normal file
|
@ -0,0 +1,78 @@
|
|||
/// This function is where the kernel sets up IRQ handlers
|
||||
/// It is increcibly unsafe, and should be minimal in nature
|
||||
/// It must create the IDT with the correct entries, those entries are
|
||||
/// defined in other files inside of the `arch` module
|
||||
|
||||
use super::idt::{IDTR, IDT, IDT_PRESENT, IDT_RING_0, IDT_INTERRUPT};
|
||||
use super::mem::memset;
|
||||
|
||||
extern {
|
||||
/// The starting byte of the text (code) data segment.
|
||||
static mut __text_start: u8;
|
||||
/// The ending byte of the text (code) data segment.
|
||||
static mut __text_end: u8;
|
||||
/// The starting byte of the _.rodata_ (read-only data) segment.
|
||||
static mut __rodata_start: u8;
|
||||
/// The ending byte of the _.rodata_ (read-only data) segment.
|
||||
static mut __rodata_end: u8;
|
||||
/// The starting byte of the _.data_ segment.
|
||||
static mut __data_start: u8;
|
||||
/// The ending byte of the _.data_ segment.
|
||||
static mut __data_end: u8;
|
||||
/// The starting byte of the _.bss_ (uninitialized data) segment.
|
||||
static mut __bss_start: u8;
|
||||
/// The ending byte of the _.bss_ (uninitialized data) segment.
|
||||
static mut __bss_end: u8;
|
||||
}
|
||||
|
||||
/// Test of zero values in BSS.
|
||||
static BSS_TEST_ZERO: usize = 0;
|
||||
/// Test of non-zero values in BSS.
|
||||
static BSS_TEST_NONZERO: usize = 0xFFFFFFFFFFFFFFFF;
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn kmain() {
|
||||
asm!("xchg bx, bx" : : : : "intel", "volatile");
|
||||
|
||||
// Zero BSS, this initializes statics that are set to 0
|
||||
{
|
||||
let start_ptr = &mut __bss_start as *mut u8;
|
||||
let end_ptr = & __bss_end as *const u8 as usize;
|
||||
|
||||
if start_ptr as usize <= end_ptr {
|
||||
let size = end_ptr - start_ptr as usize;
|
||||
memset(start_ptr, 0, size);
|
||||
}
|
||||
|
||||
//debug_assert_eq!(BSS_TEST_ZERO, 0);
|
||||
//debug_assert_eq!(BSS_TEST_NONZERO, 0xFFFFFFFFFFFFFFFF);
|
||||
}
|
||||
|
||||
asm!("xchg bx, bx" : : : : "intel", "volatile");
|
||||
|
||||
//Set up IDT
|
||||
for entry in IDT.iter_mut() {
|
||||
entry.set_flags(IDT_PRESENT | IDT_RING_0 | IDT_INTERRUPT);
|
||||
entry.set_offset(8, blank as usize);
|
||||
}
|
||||
IDTR.set_slice(&IDT);
|
||||
IDTR.load();
|
||||
|
||||
asm!("xchg bx, bx" : : : : "intel", "volatile");
|
||||
|
||||
asm!("int 0xFF" : : : : "intel", "volatile");
|
||||
|
||||
asm!("xchg bx, bx" : : : : "intel", "volatile");
|
||||
|
||||
print!("TEST\n");
|
||||
|
||||
loop{
|
||||
asm!("hlt" : : : : "intel", "volatile");
|
||||
}
|
||||
}
|
||||
|
||||
#[naked]
|
||||
pub unsafe extern "C" fn blank() {
|
||||
asm!("xchg bx, bx" : : : : "intel", "volatile");
|
||||
asm!("iretq" : : : : "intel", "volatile");
|
||||
}
|
69
kernel/arch/x86_64/mem.rs
Normal file
69
kernel/arch/x86_64/mem.rs
Normal file
|
@ -0,0 +1,69 @@
|
|||
/// Copy memory.
|
||||
///
|
||||
/// Copy N bytes of memory from one location to another.
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 {
|
||||
let mut i = 0;
|
||||
while i < n {
|
||||
*dest.offset(i as isize) = *src.offset(i as isize);
|
||||
i += 1;
|
||||
}
|
||||
|
||||
dest
|
||||
}
|
||||
|
||||
/// Copy (possibly overlapping) memory.
|
||||
///
|
||||
/// Copy N bytes of memory from src to dest. The memory areas may overlap.
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn memmove(dest: *mut u8, src: *const u8,
|
||||
n: usize) -> *mut u8 {
|
||||
if src < dest as *const u8 {
|
||||
let mut i = n;
|
||||
while i != 0 {
|
||||
i -= 1;
|
||||
*dest.offset(i as isize) = *src.offset(i as isize);
|
||||
}
|
||||
} else {
|
||||
let mut i = 0;
|
||||
while i < n {
|
||||
*dest.offset(i as isize) = *src.offset(i as isize);
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
dest
|
||||
}
|
||||
|
||||
/// Set memory.
|
||||
///
|
||||
/// Fill a block of memory with a specified value.
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn memset(s: *mut u8, c: i32, n: usize) -> *mut u8 {
|
||||
let mut i = 0;
|
||||
while i < n {
|
||||
*s.offset(i as isize) = c as u8;
|
||||
i += 1;
|
||||
}
|
||||
|
||||
s
|
||||
}
|
||||
|
||||
/// Compare memory.
|
||||
///
|
||||
/// Compare two blocks of memory.
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 {
|
||||
let mut i = 0;
|
||||
|
||||
while i < n {
|
||||
let a = *s1.offset(i as isize);
|
||||
let b = *s2.offset(i as isize);
|
||||
if a != b {
|
||||
return a as i32 - b as i32
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
|
||||
0
|
||||
}
|
25
kernel/arch/x86_64/mod.rs
Normal file
25
kernel/arch/x86_64/mod.rs
Normal file
|
@ -0,0 +1,25 @@
|
|||
//! X86_64 architecture primitives.
|
||||
|
||||
/// Global descriptor table.
|
||||
pub mod gdt;
|
||||
|
||||
/// Interrupt descriptor table.
|
||||
pub mod idt;
|
||||
|
||||
/// IO handling.
|
||||
pub mod io;
|
||||
|
||||
/// IRQ handling.
|
||||
pub mod irq;
|
||||
|
||||
/// Initialization and main function.
|
||||
pub mod main;
|
||||
|
||||
/// Core memory routines.
|
||||
pub mod mem;
|
||||
|
||||
/// Serial driver and `print!` support.
|
||||
pub mod serial;
|
||||
|
||||
/// Task state segment.
|
||||
pub mod tss;
|
39
kernel/arch/x86_64/serial.rs
Normal file
39
kernel/arch/x86_64/serial.rs
Normal file
|
@ -0,0 +1,39 @@
|
|||
use core::fmt;
|
||||
use super::io::{Io, Pio};
|
||||
|
||||
pub struct SerialConsole {
|
||||
status: Pio<u8>,
|
||||
data: Pio<u8>
|
||||
}
|
||||
|
||||
impl SerialConsole {
|
||||
pub fn new() -> SerialConsole {
|
||||
SerialConsole {
|
||||
status: Pio::new(0x3F8 + 5),
|
||||
data: Pio::new(0x3F8)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write(&mut self, bytes: &[u8]) {
|
||||
for byte in bytes.iter() {
|
||||
while !self.status.readf(0x20) {}
|
||||
self.data.write(*byte);
|
||||
|
||||
if *byte == 8 {
|
||||
while !self.status.readf(0x20) {}
|
||||
self.data.write(0x20);
|
||||
|
||||
while !self.status.readf(0x20) {}
|
||||
self.data.write(8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Write for SerialConsole {
|
||||
fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> {
|
||||
self.write(s.as_bytes());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
22
kernel/arch/x86_64/tss.rs
Normal file
22
kernel/arch/x86_64/tss.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
/// The Task State Segment.
|
||||
#[repr(C, packed)]
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct Tss {
|
||||
/// Reserved.
|
||||
pub _reserved1: u32,
|
||||
/// The stack-pointers (reg RSP) for the IO privilege level 0 through 2.
|
||||
pub rsp: [u64; 3],
|
||||
/// Reserved.
|
||||
pub _reserved2: u32,
|
||||
/// Reserved.
|
||||
pub _reserved3: u32,
|
||||
pub ist: [u64; 7],
|
||||
/// Reserved.
|
||||
pub _reserved4: u32,
|
||||
/// Reserved.
|
||||
pub _reserved5: u32,
|
||||
// Reserved.
|
||||
pub reserved6: u16,
|
||||
/// The offset to the IOPB.
|
||||
pub iomap_base: u16,
|
||||
}
|
108
kernel/lib.rs
Normal file
108
kernel/lib.rs
Normal file
|
@ -0,0 +1,108 @@
|
|||
//! # The Redox OS Kernel, version 2
|
||||
//!
|
||||
//! The Redox OS Kernel is a hybrid kernel that supports X86 systems and
|
||||
//! provides Unix-like syscalls for primarily Rust applications
|
||||
//!
|
||||
//! ## Syscalls
|
||||
//! Syscalls in Redox are often handled by userspace `schemes`.
|
||||
//! The essential syscalls in Redox are as follows:
|
||||
//!
|
||||
//! ### Open
|
||||
//! `open(path: &str, flags: usize) -> Result<file_descriptor: usize>`
|
||||
//!
|
||||
//! Open a file, providing a path as a `&str` and flags, defined elsewhere.
|
||||
//!
|
||||
//! Returns a number, known as a file descriptor, that is passed to other syscalls
|
||||
//!
|
||||
//! ### Close
|
||||
//! `close(file_descriptor: usize) -> Result<()>`
|
||||
//!
|
||||
//! Close a file descriptor, providing the file descriptor from `open`
|
||||
//!
|
||||
//! Returns an error, `EBADF`, if the file descriptor was not found.
|
||||
//!
|
||||
//! This potential error is often ignored by userspace
|
||||
//!
|
||||
//! ### Duplicate
|
||||
//! `dup(file_descriptor: usize) -> Result<file_descriptor: usize>`
|
||||
//!
|
||||
//! Duplicate a file descriptor, providing the file descriptor from `open`
|
||||
//!
|
||||
//! Returns a new file descriptor, or an error
|
||||
//!
|
||||
//! ### Read
|
||||
//! `read(file_descriptor: usize, buffer: &mut [u8]) -> Result<count: usize>`
|
||||
//!
|
||||
//! Read from a file descriptor, providing the file descriptor from `open` and a mutable buffer
|
||||
//!
|
||||
//! Returns the number of bytes actually read, or an error
|
||||
//!
|
||||
//! ### Write
|
||||
//! `write(file_descriptor: usize, buffer: &[u8]) -> Result<count: usize>`
|
||||
//!
|
||||
//! Write to a file descriptor, providing the file descriptor from `open` and a const buffer
|
||||
//!
|
||||
//! Returns the number of bytes actually written, or an error
|
||||
//!
|
||||
//! ### Stat
|
||||
//! `fstat(file_descriptor: usize, stat: &mut Stat) -> Result<()>`
|
||||
//!
|
||||
//! Get information from a file descriptor, providing the file descriptor from `open`
|
||||
//! and a mutable Stat struct, defined elsewhere.
|
||||
//!
|
||||
//! Returns an error if the operation failed
|
||||
//!
|
||||
//! ### Path
|
||||
//! `fpath(file_descriptor: usize, buffer: &mut [u8]) -> Result<count: usize>`
|
||||
//!
|
||||
//! Read the path of a file descriptor, providing the file descriptor from `open` and
|
||||
//! a mutable buffer.
|
||||
//!
|
||||
//! Returns the number of bytes actually read, or an error
|
||||
//!
|
||||
//! The buffer should be 4096 bytes, to ensure that the entire path will fit.
|
||||
//! An error will be returned, `ENOBUFS`, if the buffer is not long enough for the name.
|
||||
//! In this case, it is recommended to add one page, 4096 bytes, to the buffer and retry.
|
||||
|
||||
#![feature(asm)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(lang_items)]
|
||||
#![feature(naked_functions)]
|
||||
#![no_std]
|
||||
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
|
||||
/// Print to console
|
||||
macro_rules! print {
|
||||
($($arg:tt)*) => ({
|
||||
use $crate::core::fmt::Write;
|
||||
let _ = write!($crate::arch::serial::SerialConsole::new(), $($arg)*);
|
||||
});
|
||||
}
|
||||
|
||||
/// Print with new line to console
|
||||
macro_rules! println {
|
||||
($fmt:expr) => (print!(concat!($fmt, "\n")));
|
||||
($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
|
||||
}
|
||||
|
||||
/// Architecture specific items
|
||||
pub mod arch;
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[lang = "eh_personality"]
|
||||
extern "C" fn eh_personality() {}
|
||||
|
||||
#[cfg(not(test))]
|
||||
/// Required to handle panics
|
||||
#[lang = "panic_fmt"]
|
||||
extern "C" fn panic_fmt() -> ! {loop{}}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
/// Required to handle panics
|
||||
pub extern "C" fn _Unwind_Resume() -> ! {
|
||||
loop {}
|
||||
}
|
12
kernel/scheme/mod.rs
Normal file
12
kernel/scheme/mod.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
/// A scheme is a primitive for handling filesystem syscalls in Redox.
|
||||
/// Schemes accept paths from the kernel for `open`, and file descriptors that they generate
|
||||
/// are then passed for operations like `close`, `read`, `write`, etc.
|
||||
///
|
||||
/// The kernel validates paths and file descriptors before they are passed to schemes,
|
||||
/// also stripping the scheme identifier of paths if necessary.
|
||||
pub trait Scheme {
|
||||
/// Open the file at `path` with `flags`.
|
||||
///
|
||||
/// Returns a file descriptor or an error
|
||||
fn open(path: &str, flags: usize) -> Result<usize>;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue