This commit is contained in:
Jeremy Soller
2017-10-21 20:30:26 -06:00
20 changed files with 125 additions and 108 deletions

8
Cargo.lock generated
View File

@@ -3,7 +3,7 @@ name = "kernel"
version = "0.1.0"
dependencies = [
"alloc_kernel 0.1.0",
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"goblin 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
"raw-cpuid 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.31",
@@ -24,6 +24,11 @@ name = "bitflags"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bitflags"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "gcc"
version = "0.3.54"
@@ -92,6 +97,7 @@ dependencies = [
[metadata]
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
"checksum bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5cde24d1b2e2216a726368b2363a273739c91f4e3eb4e0dd12d672d396ad989"
"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb"
"checksum goblin 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "81af14056c25d33759862c5ae2035452acb1255bfb1b16db57819f183921e259"
"checksum linked_list_allocator 0.4.1 (git+https://github.com/redox-os/linked-list-allocator.git)" = "<none>"

View File

@@ -10,7 +10,7 @@ crate-type = ["staticlib"]
[dependencies]
alloc_kernel = { path = "alloc_kernel" }
bitflags = "0.7"
bitflags = "1"
spin = "0.4"
raw-cpuid = "3.0"
redox_syscall = { path = "syscall" }

View File

@@ -3,7 +3,8 @@ use core::mem;
use super::sdt::Sdt;
use self::drhd::Drhd;
use memory::Frame;
use paging::{entry, ActivePageTable, PhysicalAddress};
use paging::{ActivePageTable, PhysicalAddress};
use paging::entry::EntryFlags;
use super::{find_sdt, load_table, get_sdt_signature};
@@ -93,7 +94,7 @@ pub struct DmarDrhd {
impl DmarDrhd {
pub fn get(&self, active_table: &mut ActivePageTable) -> &'static mut Drhd {
let result = active_table.identity_map(Frame::containing_address(PhysicalAddress::new(self.base as usize)), entry::PRESENT | entry::WRITABLE | entry::NO_EXECUTE);
let result = active_table.identity_map(Frame::containing_address(PhysicalAddress::new(self.base as usize)), EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE);
result.flush(active_table);
unsafe { &mut *(self.base as *mut Drhd) }
}

View File

@@ -3,7 +3,8 @@ use core::{mem, ptr};
use core::intrinsics::{volatile_load, volatile_store};
use memory::Frame;
use paging::{entry, ActivePageTable, PhysicalAddress, Page, VirtualAddress};
use paging::{ActivePageTable, PhysicalAddress, Page, VirtualAddress};
use paging::entry::EntryFlags;
use super::sdt::Sdt;
use super::{ACPI_TABLE, find_sdt, load_table, get_sdt_signature};
@@ -68,7 +69,7 @@ impl GenericAddressStructure {
pub unsafe fn init(&self, active_table: &mut ActivePageTable) {
let page = Page::containing_address(VirtualAddress::new(self.address as usize));
let frame = Frame::containing_address(PhysicalAddress::new(self.address as usize));
let result = active_table.map_to(page, frame, entry::PRESENT | entry::WRITABLE | entry::NO_EXECUTE);
let result = active_table.map_to(page, frame, EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE);
result.flush(active_table);
}

View File

@@ -1,7 +1,8 @@
use core::mem;
use memory::{allocate_frames, Frame};
use paging::{entry, ActivePageTable, Page, PhysicalAddress, VirtualAddress};
use paging::{ActivePageTable, Page, PhysicalAddress, VirtualAddress};
use paging::entry::EntryFlags;
use super::sdt::Sdt;
use super::{AP_STARTUP, TRAMPOLINE, find_sdt, load_table, get_sdt_signature};
@@ -49,7 +50,7 @@ impl Madt {
let trampoline_page = Page::containing_address(VirtualAddress::new(TRAMPOLINE));
// Map trampoline
let result = active_table.map_to(trampoline_page, trampoline_frame, entry::PRESENT | entry::WRITABLE);
let result = active_table.map_to(trampoline_page, trampoline_frame, EntryFlags::PRESENT | EntryFlags::WRITABLE);
result.flush(active_table);
for madt_entry in madt.iter() {

View File

@@ -13,7 +13,8 @@ use spin::RwLock;
use stop::kstop;
use memory::Frame;
use paging::{entry, ActivePageTable, Page, PhysicalAddress, VirtualAddress};
use paging::{ActivePageTable, Page, PhysicalAddress, VirtualAddress};
use paging::entry::EntryFlags;
use self::dmar::Dmar;
use self::fadt::Fadt;
@@ -46,7 +47,7 @@ fn get_sdt(sdt_address: usize, active_table: &mut ActivePageTable) -> &'static S
let page = Page::containing_address(VirtualAddress::new(sdt_address));
if active_table.translate_page(page).is_none() {
let frame = Frame::containing_address(PhysicalAddress::new(page.start_address().get()));
let result = active_table.map_to(page, frame, entry::PRESENT | entry::NO_EXECUTE);
let result = active_table.map_to(page, frame, EntryFlags::PRESENT | EntryFlags::NO_EXECUTE);
result.flush(active_table);
}
}
@@ -60,7 +61,7 @@ fn get_sdt(sdt_address: usize, active_table: &mut ActivePageTable) -> &'static S
for page in Page::range_inclusive(start_page, end_page) {
if active_table.translate_page(page).is_none() {
let frame = Frame::containing_address(PhysicalAddress::new(page.start_address().get()));
let result = active_table.map_to(page, frame, entry::PRESENT | entry::NO_EXECUTE);
let result = active_table.map_to(page, frame, EntryFlags::PRESENT | EntryFlags::NO_EXECUTE);
result.flush(active_table);
}
}

View File

@@ -1,5 +1,6 @@
use memory::Frame;
use paging::{entry, ActivePageTable, Page, PhysicalAddress, VirtualAddress};
use paging::{ActivePageTable, Page, PhysicalAddress, VirtualAddress};
use paging::entry::EntryFlags;
/// RSDP
#[derive(Copy, Clone, Debug)]
@@ -28,7 +29,7 @@ impl RSDP {
let end_frame = Frame::containing_address(PhysicalAddress::new(end_addr));
for frame in Frame::range_inclusive(start_frame, end_frame) {
let page = Page::containing_address(VirtualAddress::new(frame.start_address().get()));
let result = active_table.map_to(page, frame, entry::PRESENT | entry::NO_EXECUTE);
let result = active_table.map_to(page, frame, EntryFlags::PRESENT | EntryFlags::NO_EXECUTE);
result.flush(active_table);
}
}

View File

@@ -3,7 +3,8 @@ use x86::cpuid::CpuId;
use x86::msr::*;
use memory::Frame;
use paging::{entry, ActivePageTable, PhysicalAddress, Page, VirtualAddress};
use paging::{ActivePageTable, PhysicalAddress, Page, VirtualAddress};
use paging::entry::EntryFlags;
pub static mut LOCAL_APIC: LocalApic = LocalApic {
address: 0,
@@ -32,7 +33,7 @@ impl LocalApic {
if ! self.x2 {
let page = Page::containing_address(VirtualAddress::new(self.address));
let frame = Frame::containing_address(PhysicalAddress::new(self.address - ::KERNEL_OFFSET));
let result = active_table.map_to(page, frame, entry::PRESENT | entry::WRITABLE | entry::NO_EXECUTE);
let result = active_table.map_to(page, frame, EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE);
result.flush(active_table);
}

View File

@@ -63,21 +63,21 @@ pub unsafe fn init() {
// Set syscall function
IDT[0x80].set_func(syscall::syscall);
IDT[0x80].set_flags(IDT_PRESENT | IDT_RING_3 | IDT_INTERRUPT);
IDT[0x80].set_flags(IdtFlags::PRESENT | IdtFlags::RING_3 | IdtFlags::INTERRUPT);
dtables::lidt(&IDTR);
}
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,
pub struct IdtFlags: u8 {
const PRESENT = 1 << 7;
const RING_0 = 0 << 5;
const RING_1 = 1 << 5;
const RING_2 = 2 << 5;
const RING_3 = 3 << 5;
const SS = 1 << 4;
const INTERRUPT = 0xE;
const TRAP = 0xF;
}
}
@@ -119,7 +119,7 @@ impl IdtEntry {
// A function to set the offset more easily
pub fn set_func(&mut self, func: unsafe extern fn()) {
self.set_flags(IDT_PRESENT | IDT_RING_0 | IDT_INTERRUPT);
self.set_flags(IdtFlags::PRESENT | IdtFlags::RING_0 | IdtFlags::INTERRUPT);
self.set_offset(8, func as usize);
}
}

View File

@@ -9,17 +9,17 @@ use super::PhysicalAddress;
pub struct Entry(u64);
bitflags! {
pub flags EntryFlags: u64 {
const PRESENT = 1 << 0,
const WRITABLE = 1 << 1,
const USER_ACCESSIBLE = 1 << 2,
const WRITE_THROUGH = 1 << 3,
const NO_CACHE = 1 << 4,
const ACCESSED = 1 << 5,
const DIRTY = 1 << 6,
const HUGE_PAGE = 1 << 7,
const GLOBAL = 1 << 8,
const NO_EXECUTE = 1 << 63,
pub struct EntryFlags: u64 {
const PRESENT = 1 << 0;
const WRITABLE = 1 << 1;
const USER_ACCESSIBLE = 1 << 2;
const WRITE_THROUGH = 1 << 3;
const NO_CACHE = 1 << 4;
const ACCESSED = 1 << 5;
const DIRTY = 1 << 6;
const HUGE_PAGE = 1 << 7;
const GLOBAL = 1 << 8;
const NO_EXECUTE = 1 << 63;
}
}
@@ -48,7 +48,7 @@ impl Entry {
/// Get the associated frame, if available
pub fn pointed_frame(&self) -> Option<Frame> {
if self.flags().contains(PRESENT) {
if self.flags().contains(EntryFlags::PRESENT) {
Some(Frame::containing_address(self.address()))
} else {
None

View File

@@ -4,7 +4,7 @@ use core::ptr::Unique;
use memory::{allocate_frames, deallocate_frames, Frame};
use super::{ActivePageTable, Page, PAGE_SIZE, PhysicalAddress, VirtualAddress};
use super::entry::{self, EntryFlags};
use super::entry::EntryFlags;
use super::table::{self, Table, Level4};
/// In order to enforce correct paging operations in the kernel, these types
@@ -107,7 +107,7 @@ impl Mapper {
page.start_address().get(),
p1[page.p1_index()].address().get(), p1[page.p1_index()].flags(),
frame.start_address().get(), flags);
p1[page.p1_index()].set(frame, flags | entry::PRESENT);
p1[page.p1_index()].set(frame, flags | EntryFlags::PRESENT);
MapperFlush::new(page)
}
@@ -123,7 +123,7 @@ impl Mapper {
let p2 = p3.next_table_mut(page.p3_index()).expect("failed to remap: no p2");
let p1 = p2.next_table_mut(page.p2_index()).expect("failed to remap: no p1");
let frame = p1[page.p1_index()].pointed_frame().expect("failed to remap: not mapped");
p1[page.p1_index()].set(frame, flags | entry::PRESENT);
p1[page.p1_index()].set(frame, flags | EntryFlags::PRESENT);
MapperFlush::new(page)
}

View File

@@ -7,7 +7,7 @@ use x86::{msr, tlb};
use memory::{allocate_frames, Frame};
use self::entry::{EntryFlags, PRESENT, GLOBAL, WRITABLE, NO_EXECUTE};
use self::entry::EntryFlags;
use self::mapper::Mapper;
use self::temporary_page::TemporaryPage;
@@ -124,7 +124,7 @@ pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_
let end_frame = Frame::containing_address(PhysicalAddress::new(stack_end - ::KERNEL_OFFSET - 1));
for frame in Frame::range_inclusive(start_frame, end_frame) {
let page = Page::containing_address(VirtualAddress::new(frame.start_address().get() + ::KERNEL_OFFSET));
let result = mapper.map_to(page, frame, PRESENT | GLOBAL | NO_EXECUTE | WRITABLE);
let result = mapper.map_to(page, frame, EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE);
// The flush can be ignored as this is not the active table. See later active_table.switch
unsafe { result.ignore(); }
}
@@ -147,22 +147,22 @@ pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_
let flags = if in_section!(text) {
// Remap text read-only
PRESENT | GLOBAL
EntryFlags::PRESENT | EntryFlags::GLOBAL
} else if in_section!(rodata) {
// Remap rodata read-only, no execute
PRESENT | GLOBAL | NO_EXECUTE
EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE
} else if in_section!(data) {
// Remap data writable, no execute
PRESENT | GLOBAL | NO_EXECUTE | WRITABLE
EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE
} else if in_section!(tdata) {
// Remap tdata master read-only, no execute
PRESENT | GLOBAL | NO_EXECUTE
EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE
} else if in_section!(bss) {
// Remap bss writable, no execute
PRESENT | GLOBAL | NO_EXECUTE | WRITABLE
EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE
} else {
// Remap anything else read-only, no execute
PRESENT | GLOBAL | NO_EXECUTE
EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE
};
let page = Page::containing_address(VirtualAddress::new(virt_addr));
@@ -182,7 +182,7 @@ pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_
let start_page = Page::containing_address(VirtualAddress::new(start));
let end_page = Page::containing_address(VirtualAddress::new(end - 1));
for page in Page::range_inclusive(start_page, end_page) {
let result = mapper.map(page, PRESENT | GLOBAL | NO_EXECUTE | WRITABLE);
let result = mapper.map(page, EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE);
// The flush can be ignored as this is not the active table. See later active_table.switch
result.ignore();
}
@@ -227,7 +227,7 @@ pub unsafe fn init_ap(cpu_id: usize, bsp_table: usize, stack_start: usize, stack
let start_page = Page::containing_address(VirtualAddress::new(start));
let end_page = Page::containing_address(VirtualAddress::new(end - 1));
for page in Page::range_inclusive(start_page, end_page) {
let result = mapper.map(page, PRESENT | GLOBAL | NO_EXECUTE | WRITABLE);
let result = mapper.map(page, EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE);
// The flush can be ignored as this is not the active table. See later active_table.switch
result.ignore();
}
@@ -247,7 +247,7 @@ pub unsafe fn init_ap(cpu_id: usize, bsp_table: usize, stack_start: usize, stack
};
// Remap stack writable, no execute
remap(stack_start - ::KERNEL_OFFSET, stack_end - ::KERNEL_OFFSET, PRESENT | GLOBAL | NO_EXECUTE | WRITABLE);
remap(stack_start - ::KERNEL_OFFSET, stack_end - ::KERNEL_OFFSET, EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE);
});
// This switches the active table, which is setup by the bootloader, to a correct table
@@ -313,17 +313,17 @@ impl ActivePageTable {
let backup = Frame::containing_address(PhysicalAddress::new(unsafe { controlregs::cr3() as usize }));
// map temporary_page to current p4 table
let p4_table = temporary_page.map_table_frame(backup.clone(), PRESENT | WRITABLE | NO_EXECUTE, self);
let p4_table = temporary_page.map_table_frame(backup.clone(), EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE, self);
// overwrite recursive mapping
self.p4_mut()[511].set(table.p4_frame.clone(), PRESENT | WRITABLE | NO_EXECUTE);
self.p4_mut()[511].set(table.p4_frame.clone(), EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE);
self.flush_all();
// execute f in the new context
f(self);
// restore recursive mapping to original p4 table
p4_table[511].set(backup, PRESENT | WRITABLE | NO_EXECUTE);
p4_table[511].set(backup, EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE);
self.flush_all();
}
@@ -343,11 +343,11 @@ pub struct InactivePageTable {
impl InactivePageTable {
pub fn new(frame: Frame, active_table: &mut ActivePageTable, temporary_page: &mut TemporaryPage) -> InactivePageTable {
{
let table = temporary_page.map_table_frame(frame.clone(), PRESENT | WRITABLE | NO_EXECUTE, active_table);
let table = temporary_page.map_table_frame(frame.clone(), EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE, active_table);
// now we are able to zero the table
table.zero();
// set up recursive mapping for the table
table[511].set(frame.clone(), PRESENT | WRITABLE | NO_EXECUTE);
table[511].set(frame.clone(), EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE);
}
temporary_page.unmap(active_table);

View File

@@ -6,7 +6,7 @@ use core::ops::{Index, IndexMut};
use memory::allocate_frames;
use super::entry::*;
use super::entry::{EntryFlags, Entry};
use super::ENTRY_COUNT;
pub const P4: *mut Table<Level4> = 0xffff_ffff_ffff_f000 as *mut _;
@@ -73,10 +73,10 @@ impl<L> Table<L> where L: HierarchicalLevel {
pub fn next_table_create(&mut self, index: usize) -> &mut Table<L::NextLevel> {
if self.next_table(index).is_none() {
assert!(!self[index].flags().contains(HUGE_PAGE),
assert!(!self[index].flags().contains(EntryFlags::HUGE_PAGE),
"next_table_create does not support huge pages");
let frame = allocate_frames(1).expect("no frames available");
self[index].set(frame, PRESENT | WRITABLE | USER_ACCESSIBLE /* Allow users to go down the page table, implement permissions at the page level */);
self[index].set(frame, EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::USER_ACCESSIBLE /* Allow users to go down the page table, implement permissions at the page level */);
self.next_table_mut(index).unwrap().zero();
}
self.next_table_mut(index).unwrap()
@@ -84,7 +84,7 @@ impl<L> Table<L> where L: HierarchicalLevel {
fn next_table_address(&self, index: usize) -> Option<usize> {
let entry_flags = self[index].flags();
if entry_flags.contains(PRESENT) && !entry_flags.contains(HUGE_PAGE) {
if entry_flags.contains(EntryFlags::PRESENT) && !entry_flags.contains(EntryFlags::HUGE_PAGE) {
let table_address = self as *const _ as usize;
Some((table_address << 9) | (index << 12))
} else {

View File

@@ -13,7 +13,8 @@ use gdt;
use idt;
use interrupt;
use memory;
use paging::{self, entry, Page, VirtualAddress};
use paging::{self, Page, VirtualAddress};
use paging::entry::EntryFlags;
use paging::mapper::MapperFlushAll;
/// Test of zero values in BSS.
@@ -104,7 +105,7 @@ pub unsafe extern fn kstart(args_ptr: *const KernelArgs) -> ! {
let heap_start_page = Page::containing_address(VirtualAddress::new(::KERNEL_HEAP_OFFSET));
let heap_end_page = Page::containing_address(VirtualAddress::new(::KERNEL_HEAP_OFFSET + ::KERNEL_HEAP_SIZE-1));
for page in Page::range_inclusive(heap_start_page, heap_end_page) {
let result = active_table.map(page, entry::PRESENT | entry::GLOBAL | entry::WRITABLE | entry::NO_EXECUTE);
let result = active_table.map(page, EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE);
flush_all.consume(result);
}

View File

@@ -5,7 +5,7 @@ use spin::Mutex;
use memory::Frame;
use paging::{ActivePageTable, InactivePageTable, Page, PageIter, PhysicalAddress, VirtualAddress};
use paging::entry::{self, EntryFlags};
use paging::entry::EntryFlags;
use paging::mapper::MapperFlushAll;
use paging::temporary_page::TemporaryPage;
@@ -212,7 +212,7 @@ impl Memory {
flush_all.flush(&mut active_table);
if clear {
assert!(self.flags.contains(entry::WRITABLE));
assert!(self.flags.contains(EntryFlags::WRITABLE));
unsafe {
intrinsics::write_bytes(self.start_address().get() as *mut u8, 0, self.size);
}

View File

@@ -5,21 +5,21 @@ use syscall::io::{Io, Pio, Mmio, ReadOnly};
bitflags! {
/// Interrupt enable flags
flags IntEnFlags: u8 {
const RECEIVED = 1,
const SENT = 1 << 1,
const ERRORED = 1 << 2,
const STATUS_CHANGE = 1 << 3,
struct IntEnFlags: u8 {
const RECEIVED = 1;
const SENT = 1 << 1;
const ERRORED = 1 << 2;
const STATUS_CHANGE = 1 << 3;
// 4 to 7 are unused
}
}
bitflags! {
/// Line status flags
flags LineStsFlags: u8 {
const INPUT_FULL = 1,
struct LineStsFlags: u8 {
const INPUT_FULL = 1;
// 1 to 4 unknown
const OUTPUT_EMPTY = 1 << 5,
const OUTPUT_EMPTY = 1 << 5;
// 6 and 7 unknown
}
}
@@ -88,7 +88,7 @@ impl<T: Io<Value = u8>> SerialPort<T> {
}
pub fn receive(&mut self) {
while self.line_sts().contains(INPUT_FULL) {
while self.line_sts().contains(LineStsFlags::INPUT_FULL) {
debug_input(self.data.read());
}
}
@@ -96,15 +96,15 @@ impl<T: Io<Value = u8>> SerialPort<T> {
pub fn send(&mut self, data: u8) {
match data {
8 | 0x7F => {
while ! self.line_sts().contains(OUTPUT_EMPTY) {}
while ! self.line_sts().contains(LineStsFlags::OUTPUT_EMPTY) {}
self.data.write(8);
while ! self.line_sts().contains(OUTPUT_EMPTY) {}
while ! self.line_sts().contains(LineStsFlags::OUTPUT_EMPTY) {}
self.data.write(b' ');
while ! self.line_sts().contains(OUTPUT_EMPTY) {}
while ! self.line_sts().contains(LineStsFlags::OUTPUT_EMPTY) {}
self.data.write(8);
},
_ => {
while ! self.line_sts().contains(OUTPUT_EMPTY) {}
while ! self.line_sts().contains(LineStsFlags::OUTPUT_EMPTY) {}
self.data.write(data);
}
}

View File

@@ -5,7 +5,8 @@ use core::sync::atomic::{AtomicU64, Ordering};
use core::{mem, slice, usize};
use spin::{Mutex, RwLock};
use paging::{InactivePageTable, Page, VirtualAddress, entry};
use paging::{InactivePageTable, Page, VirtualAddress};
use paging::entry::EntryFlags;
use paging::temporary_page::TemporaryPage;
use context::{self, Context};
use context::memory::Grant;
@@ -100,9 +101,9 @@ impl UserInner {
let full_size = ((offset + size + 4095)/4096) * 4096;
let mut to_address = ::USER_GRANT_OFFSET;
let mut flags = entry::PRESENT | entry::NO_EXECUTE | entry::USER_ACCESSIBLE;
let mut flags = EntryFlags::PRESENT | EntryFlags::NO_EXECUTE | EntryFlags::USER_ACCESSIBLE;
if writable {
flags |= entry::WRITABLE;
flags |= EntryFlags::WRITABLE;
}
for i in 0 .. grants.len() {

View File

@@ -1,6 +1,7 @@
use interrupt::syscall::SyscallStack;
use memory::{allocate_frames, deallocate_frames, Frame};
use paging::{entry, ActivePageTable, PhysicalAddress, VirtualAddress};
use paging::{ActivePageTable, PhysicalAddress, VirtualAddress};
use paging::entry::EntryFlags;
use context;
use context::memory::Grant;
use syscall::error::{Error, EFAULT, EINVAL, ENOMEM, EPERM, ESRCH, Result};
@@ -61,12 +62,12 @@ pub fn physmap(physical_address: usize, size: usize, flags: usize) -> Result<usi
let full_size = ((offset + size + 4095)/4096) * 4096;
let mut to_address = ::USER_GRANT_OFFSET;
let mut entry_flags = entry::PRESENT | entry::NO_EXECUTE | entry::USER_ACCESSIBLE;
let mut entry_flags = EntryFlags::PRESENT | EntryFlags::NO_EXECUTE | EntryFlags::USER_ACCESSIBLE;
if flags & MAP_WRITE == MAP_WRITE {
entry_flags |= entry::WRITABLE;
entry_flags |= EntryFlags::WRITABLE;
}
if flags & MAP_WRITE_COMBINE == MAP_WRITE_COMBINE {
entry_flags |= entry::HUGE_PAGE;
entry_flags |= EntryFlags::HUGE_PAGE;
}
for i in 0 .. grants.len() {

View File

@@ -8,7 +8,8 @@ use core::ops::DerefMut;
use spin::Mutex;
use memory::allocate_frames;
use paging::{ActivePageTable, InactivePageTable, Page, VirtualAddress, entry};
use paging::{ActivePageTable, InactivePageTable, Page, VirtualAddress};
use paging::entry::EntryFlags;
use paging::temporary_page::TemporaryPage;
use start::usermode;
use interrupt;
@@ -145,7 +146,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
let mut new_memory = context::memory::Memory::new(
VirtualAddress::new(memory.start_address().get() + ::USER_TMP_OFFSET),
memory.size(),
entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE,
EntryFlags::PRESENT | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE,
false
);
@@ -165,7 +166,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
let mut new_heap = context::memory::Memory::new(
VirtualAddress::new(::USER_TMP_HEAP_OFFSET),
heap.size(),
entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE,
EntryFlags::PRESENT | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE,
false
);
@@ -185,7 +186,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
let mut new_stack = context::memory::Memory::new(
VirtualAddress::new(::USER_TMP_STACK_OFFSET),
stack.size(),
entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE,
EntryFlags::PRESENT | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE,
false
);
@@ -203,7 +204,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
let mut new_sigstack = context::memory::Memory::new(
VirtualAddress::new(::USER_TMP_SIGSTACK_OFFSET),
sigstack.size(),
entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE,
EntryFlags::PRESENT | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE,
false
);
@@ -224,7 +225,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
mem: context::memory::Memory::new(
VirtualAddress::new(::USER_TMP_TLS_OFFSET),
tls.mem.size(),
entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE,
EntryFlags::PRESENT | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE,
true
),
offset: tls.offset,
@@ -418,7 +419,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
for page in Page::range_inclusive(start_page, end_page) {
let frame = active_table.translate_page(page).expect("kernel percpu not mapped");
active_table.with(&mut new_table, &mut temporary_page, |mapper| {
let result = mapper.map_to(page, frame, entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE);
let result = mapper.map_to(page, frame, EntryFlags::PRESENT | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE);
// Ignore result due to operating on inactive table
unsafe { result.ignore(); }
});
@@ -634,7 +635,7 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
let mut memory = context::memory::Memory::new(
VirtualAddress::new(vaddr as usize),
segment.p_memsz as usize + voff as usize,
entry::NO_EXECUTE | entry::WRITABLE,
EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE,
true
);
@@ -645,17 +646,17 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
segment.p_filesz as usize);
}
let mut flags = entry::NO_EXECUTE | entry::USER_ACCESSIBLE;
let mut flags = EntryFlags::NO_EXECUTE | EntryFlags::USER_ACCESSIBLE;
if segment.p_flags & program_header::PF_R == program_header::PF_R {
flags.insert(entry::PRESENT);
flags.insert(EntryFlags::PRESENT);
}
// W ^ X. If it is executable, do not allow it to be writable, even if requested
if segment.p_flags & program_header::PF_X == program_header::PF_X {
flags.remove(entry::NO_EXECUTE);
flags.remove(EntryFlags::NO_EXECUTE);
} else if segment.p_flags & program_header::PF_W == program_header::PF_W {
flags.insert(entry::WRITABLE);
flags.insert(EntryFlags::WRITABLE);
}
memory.remap(flags);
@@ -665,7 +666,7 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
let memory = context::memory::Memory::new(
VirtualAddress::new(::USER_TCB_OFFSET),
4096,
entry::NO_EXECUTE | entry::WRITABLE | entry::USER_ACCESSIBLE,
EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE | EntryFlags::USER_ACCESSIBLE,
true
);
let rounded_size = ((segment.p_memsz + 4095)/4096) * 4096;
@@ -688,7 +689,7 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
context.heap = Some(context::memory::Memory::new(
VirtualAddress::new(::USER_HEAP_OFFSET),
0,
entry::NO_EXECUTE | entry::WRITABLE | entry::USER_ACCESSIBLE,
EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE | EntryFlags::USER_ACCESSIBLE,
true
).to_shared());
@@ -696,7 +697,7 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
context.stack = Some(context::memory::Memory::new(
VirtualAddress::new(::USER_STACK_OFFSET),
::USER_STACK_SIZE,
entry::NO_EXECUTE | entry::WRITABLE | entry::USER_ACCESSIBLE,
EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE | EntryFlags::USER_ACCESSIBLE,
true
));
@@ -704,7 +705,7 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
context.sigstack = Some(context::memory::Memory::new(
VirtualAddress::new(::USER_SIGSTACK_OFFSET),
::USER_SIGSTACK_SIZE,
entry::NO_EXECUTE | entry::WRITABLE | entry::USER_ACCESSIBLE,
EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE | EntryFlags::USER_ACCESSIBLE,
true
));
@@ -716,7 +717,7 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
mem: context::memory::Memory::new(
VirtualAddress::new(::USER_TLS_OFFSET),
size,
entry::NO_EXECUTE | entry::WRITABLE | entry::USER_ACCESSIBLE,
EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE | EntryFlags::USER_ACCESSIBLE,
true
),
offset: offset,
@@ -747,7 +748,7 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
let mut memory = context::memory::Memory::new(
VirtualAddress::new(::USER_ARG_OFFSET),
arg_size,
entry::NO_EXECUTE | entry::WRITABLE,
EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE,
true
);
@@ -762,7 +763,7 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
arg_offset += arg.len();
}
memory.remap(entry::NO_EXECUTE | entry::USER_ACCESSIBLE);
memory.remap(EntryFlags::NO_EXECUTE | EntryFlags::USER_ACCESSIBLE);
context.image.push(memory.to_shared());
}

View File

@@ -1,9 +1,10 @@
use core::{mem, slice};
use paging::{ActivePageTable, Page, VirtualAddress, entry};
use paging::{ActivePageTable, Page, VirtualAddress};
use paging::entry::EntryFlags;
use syscall::error::*;
fn validate(address: usize, size: usize, flags: entry::EntryFlags) -> Result<()> {
fn validate(address: usize, size: usize, flags: EntryFlags) -> Result<()> {
let active_table = unsafe { ActivePageTable::new() };
let start_page = Page::containing_address(VirtualAddress::new(address));
@@ -28,7 +29,7 @@ pub fn validate_slice<T>(ptr: *const T, len: usize) -> Result<&'static [T]> {
if len == 0 {
Ok(&[])
} else {
validate(ptr as usize, len * mem::size_of::<T>(), entry::PRESENT /* TODO | entry::USER_ACCESSIBLE */)?;
validate(ptr as usize, len * mem::size_of::<T>(), EntryFlags::PRESENT /* TODO | EntryFlags::USER_ACCESSIBLE */)?;
Ok(unsafe { slice::from_raw_parts(ptr, len) })
}
}
@@ -38,7 +39,7 @@ pub fn validate_slice_mut<T>(ptr: *mut T, len: usize) -> Result<&'static mut [T]
if len == 0 {
Ok(&mut [])
} else {
validate(ptr as usize, len * mem::size_of::<T>(), entry::PRESENT | entry::WRITABLE /* TODO | entry::USER_ACCESSIBLE */)?;
validate(ptr as usize, len * mem::size_of::<T>(), EntryFlags::PRESENT | EntryFlags::WRITABLE /* TODO | EntryFlags::USER_ACCESSIBLE */)?;
Ok(unsafe { slice::from_raw_parts_mut(ptr, len) })
}
}