Merge branch 'fix-warnings' into 'master'

Fix warnings

See merge request redox-os/kernel!114
This commit is contained in:
Jeremy Soller
2020-03-06 20:46:01 +00:00
3 changed files with 210 additions and 83 deletions

View File

@@ -1,9 +1,8 @@
use std::collections::HashMap;
use std::env;
use std::fs;
use std::io::{Error, Write};
use std::path::Path;
use std::collections::HashMap;
// View loc folder with subfolders, get listings
// Returns touple (folder_map, file_list)
@@ -36,7 +35,9 @@ fn scan_folder(loc: &Path) -> (HashMap<String, Vec<String>>, Vec<String>) {
}
current.sort();
folders.entry(String::from(loc.to_str().unwrap()).replace("\\", "/")).or_insert(current);
folders
.entry(String::from(loc.to_str().unwrap()).replace("\\", "/"))
.or_insert(current);
} else {
panic!("{:?} is not a folder!", loc);
}
@@ -45,9 +46,9 @@ fn scan_folder(loc: &Path) -> (HashMap<String, Vec<String>>, Vec<String>) {
}
// Write folder/file information to output file
fn fill_from_location(f: &mut fs::File, loc: &Path ) -> Result<(), (Error)> {
fn fill_from_location(f: &mut fs::File, loc: &Path) -> Result<(), Error> {
let (folders, mut files) = scan_folder(loc);
let mut folder_it:Vec<_> = folders.keys().collect();
let mut folder_it: Vec<_> = folders.keys().collect();
let loc_str = loc.to_str().unwrap();
let mut idx = loc_str.len();
@@ -80,7 +81,11 @@ fn fill_from_location(f: &mut fs::File, loc: &Path ) -> Result<(), (Error)> {
for name in files.iter() {
let (_, strip) = name.split_at(idx);
write!(f, " files.insert(b\"{}\", (include_bytes!(\"{}\"), false));\n", strip, name)?;
write!(
f,
" files.insert(b\"{}\", (include_bytes!(\"{}\"), false));\n",
strip, name
)?;
}
Ok(())
@@ -96,29 +101,39 @@ fn main() {
let src = env::var("INITFS_FOLDER");
// Write header
f.write_all(b"
f.write_all(
b"
mod gen {
use alloc::collections::BTreeMap;
pub fn gen() -> BTreeMap<&'static [u8], (&'static [u8], bool)> {
let mut files: BTreeMap<&'static [u8], (&'static [u8], bool)> = BTreeMap::new();
").unwrap();
",
)
.unwrap();
match src {
Ok(v) => {
println!("cargo:rerun-if-changed={}", v);
fill_from_location(&mut f, Path::new(&v)).unwrap()
},
}
Err(e) => {
f.write_all(
b" files.clear();" // Silence mutability warning
).unwrap();
println!("cargo:warning=location not found: {}, please set proper INITFS_FOLDER.", e);
b" files.clear();", // Silence mutability warning
)
.unwrap();
println!(
"cargo:warning=location not found: {}, please set proper INITFS_FOLDER.",
e
);
}
}
f.write_all(b"
f.write_all(
b"
files
}
}
").unwrap();
",
)
.unwrap();
}

View File

@@ -1,8 +1,8 @@
//! # Paging
//! Some code was borrowed from [Phil Opp's Blog](http://os.phil-opp.com/modifying-page-tables.html)
use core::{mem, ptr};
use core::ops::{Deref, DerefMut};
use core::{mem, ptr};
use spin::Mutex;
use x86::shared::{control_regs, msr, tlb};
@@ -45,9 +45,7 @@ fn page_table_lock() {
return;
}
}
unsafe {
crate::arch::interrupt::pause();
}
crate::arch::interrupt::pause();
}
}
@@ -75,13 +73,22 @@ unsafe fn init_pat() {
let pat6 = pat2;
let pat7 = pat3;
msr::wrmsr(msr::IA32_PAT, pat7 << 56 | pat6 << 48 | pat5 << 40 | pat4 << 32
| pat3 << 24 | pat2 << 16 | pat1 << 8 | pat0);
msr::wrmsr(
msr::IA32_PAT,
pat7 << 56
| pat6 << 48
| pat5 << 40
| pat4 << 32
| pat3 << 24
| pat2 << 16
| pat1 << 8
| pat0,
);
}
/// Copy tdata, clear tbss, set TCB self pointer
unsafe fn init_tcb(cpu_id: usize) -> usize {
extern {
extern "C" {
/// The starting byte of the thread data segment
static mut __tdata_start: u8;
/// The ending byte of the thread data segment
@@ -94,14 +101,14 @@ unsafe fn init_tcb(cpu_id: usize) -> usize {
let tcb_offset;
{
let size = & __tbss_end as *const _ as usize - & __tdata_start as *const _ as usize;
let tbss_offset = & __tbss_start as *const _ as usize - & __tdata_start as *const _ as usize;
let size = &__tbss_end as *const _ as usize - &__tdata_start as *const _ as usize;
let tbss_offset = &__tbss_start as *const _ as usize - &__tdata_start as *const _ as usize;
let start = crate::KERNEL_PERCPU_OFFSET + crate::KERNEL_PERCPU_SIZE * cpu_id;
let end = start + size;
tcb_offset = end - mem::size_of::<usize>();
ptr::copy(& __tdata_start as *const u8, start as *mut u8, tbss_offset);
ptr::copy(&__tdata_start as *const u8, start as *mut u8, tbss_offset);
ptr::write_bytes((start + tbss_offset) as *mut u8, 0, size - tbss_offset);
*(tcb_offset as *mut usize) = end;
@@ -112,8 +119,14 @@ unsafe fn init_tcb(cpu_id: usize) -> usize {
/// Initialize paging
///
/// Returns page table and thread control block offset
pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_start: usize, stack_end: usize) -> (ActivePageTable, usize) {
extern {
pub unsafe fn init(
cpu_id: usize,
kernel_start: usize,
kernel_end: usize,
stack_start: usize,
stack_end: usize,
) -> (ActivePageTable, usize) {
extern "C" {
/// The starting byte of the text (code) data segment.
static mut __text_start: u8;
/// The ending byte of the text (code) data segment.
@@ -144,7 +157,9 @@ pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_
let mut active_table = ActivePageTable::new_unlocked();
let mut temporary_page = TemporaryPage::new(Page::containing_address(VirtualAddress::new(crate::USER_TMP_MISC_OFFSET)));
let mut temporary_page = TemporaryPage::new(Page::containing_address(VirtualAddress::new(
crate::USER_TMP_MISC_OFFSET,
)));
let mut new_table = {
let frame = allocate_frames(1).expect("no more frames in paging::init new_table");
@@ -154,13 +169,28 @@ pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_
active_table.with(&mut new_table, &mut temporary_page, |mapper| {
// Remap stack writable, no execute
{
let start_frame = Frame::containing_address(PhysicalAddress::new(stack_start - crate::KERNEL_OFFSET));
let end_frame = Frame::containing_address(PhysicalAddress::new(stack_end - crate::KERNEL_OFFSET - 1));
let start_frame =
Frame::containing_address(PhysicalAddress::new(stack_start - crate::KERNEL_OFFSET));
let end_frame = Frame::containing_address(PhysicalAddress::new(
stack_end - crate::KERNEL_OFFSET - 1,
));
for frame in Frame::range_inclusive(start_frame, end_frame) {
let page = Page::containing_address(VirtualAddress::new(frame.start_address().get() + crate::KERNEL_OFFSET));
let result = mapper.map_to(page, frame, EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE);
let page = Page::containing_address(VirtualAddress::new(
frame.start_address().get() + crate::KERNEL_OFFSET,
));
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(); }
/* unsafe */
{
result.ignore();
}
}
}
@@ -173,10 +203,10 @@ pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_
let virt_addr = phys_addr + crate::KERNEL_OFFSET;
macro_rules! in_section {
($n: ident) => (
virt_addr >= & concat_idents!(__, $n, _start) as *const u8 as usize &&
virt_addr < & concat_idents!(__, $n, _end) as *const u8 as usize
);
($n: ident) => {
virt_addr >= &concat_idents!(__, $n, _start) as *const u8 as usize
&& virt_addr < &concat_idents!(__, $n, _end) as *const u8 as usize
};
}
let flags = if in_section!(text) {
@@ -187,13 +217,19 @@ pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_
EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE
} else if in_section!(data) {
// Remap data writable, no execute
EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE
EntryFlags::PRESENT
| EntryFlags::GLOBAL
| EntryFlags::NO_EXECUTE
| EntryFlags::WRITABLE
} else if in_section!(tdata) {
// Remap tdata master read-only, no execute
EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE
} else if in_section!(bss) {
// Remap bss writable, no execute
EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE
EntryFlags::PRESENT
| EntryFlags::GLOBAL
| EntryFlags::NO_EXECUTE
| EntryFlags::WRITABLE
} else {
// Remap anything else read-only, no execute
EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE
@@ -202,13 +238,16 @@ pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_
let page = Page::containing_address(VirtualAddress::new(virt_addr));
let result = mapper.map_to(page, frame, flags);
// The flush can be ignored as this is not the active table. See later active_table.switch
/* unsafe */ { result.ignore(); }
/* unsafe */
{
result.ignore();
}
}
}
// Map tdata and tbss
{
let size = & __tbss_end as *const _ as usize - & __tdata_start as *const _ as usize;
let size = &__tbss_end as *const _ as usize - &__tdata_start as *const _ as usize;
let start = crate::KERNEL_PERCPU_OFFSET + crate::KERNEL_PERCPU_SIZE * cpu_id;
let end = start + size;
@@ -216,7 +255,13 @@ 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, EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE | EntryFlags::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();
}
@@ -230,8 +275,13 @@ pub unsafe fn init(cpu_id: usize, kernel_start: usize, kernel_end: usize, stack_
(active_table, init_tcb(cpu_id))
}
pub unsafe fn init_ap(cpu_id: usize, bsp_table: usize, stack_start: usize, stack_end: usize) -> usize {
extern {
pub unsafe fn init_ap(
cpu_id: usize,
bsp_table: usize,
stack_start: usize,
stack_end: usize,
) -> usize {
extern "C" {
/// The starting byte of the thread data segment
static mut __tdata_start: u8;
/// The ending byte of the thread data segment
@@ -248,12 +298,14 @@ pub unsafe fn init_ap(cpu_id: usize, bsp_table: usize, stack_start: usize, stack
let mut new_table = InactivePageTable::from_address(bsp_table);
let mut temporary_page = TemporaryPage::new(Page::containing_address(VirtualAddress::new(crate::USER_TMP_MISC_OFFSET)));
let mut temporary_page = TemporaryPage::new(Page::containing_address(VirtualAddress::new(
crate::USER_TMP_MISC_OFFSET,
)));
active_table.with(&mut new_table, &mut temporary_page, |mapper| {
// Map tdata and tbss
{
let size = & __tbss_end as *const _ as usize - & __tdata_start as *const _ as usize;
let size = &__tbss_end as *const _ as usize - &__tdata_start as *const _ as usize;
let start = crate::KERNEL_PERCPU_OFFSET + crate::KERNEL_PERCPU_SIZE * cpu_id;
let end = start + size;
@@ -261,7 +313,13 @@ 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, EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE | EntryFlags::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();
}
@@ -272,7 +330,9 @@ pub unsafe fn init_ap(cpu_id: usize, bsp_table: usize, stack_start: usize, stack
let start_frame = Frame::containing_address(PhysicalAddress::new(start));
let end_frame = Frame::containing_address(PhysicalAddress::new(end - 1));
for frame in Frame::range_inclusive(start_frame, end_frame) {
let page = Page::containing_address(VirtualAddress::new(frame.start_address().get() + crate::KERNEL_OFFSET));
let page = Page::containing_address(VirtualAddress::new(
frame.start_address().get() + crate::KERNEL_OFFSET,
));
let result = mapper.map_to(page, frame, flags);
// The flush can be ignored as this is not the active table. See later active_table.switch
result.ignore();
@@ -281,7 +341,14 @@ pub unsafe fn init_ap(cpu_id: usize, bsp_table: usize, stack_start: usize, stack
};
// Remap stack writable, no execute
remap(stack_start - crate::KERNEL_OFFSET, stack_end - crate::KERNEL_OFFSET, EntryFlags::PRESENT | EntryFlags::GLOBAL | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE);
remap(
stack_start - crate::KERNEL_OFFSET,
stack_end - crate::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
@@ -328,9 +395,9 @@ impl ActivePageTable {
pub fn switch(&mut self, new_table: InactivePageTable) -> InactivePageTable {
let old_table = InactivePageTable {
p4_frame: Frame::containing_address(
PhysicalAddress::new(unsafe { control_regs::cr3() } as usize)
),
p4_frame: Frame::containing_address(PhysicalAddress::new(
unsafe { control_regs::cr3() } as usize,
)),
};
unsafe {
control_regs::cr3_write(new_table.p4_frame.start_address().get() as u64);
@@ -339,31 +406,52 @@ impl ActivePageTable {
}
pub fn flush(&mut self, page: Page) {
unsafe { tlb::flush(page.start_address().get()); }
unsafe {
tlb::flush(page.start_address().get());
}
}
pub fn flush_all(&mut self) {
unsafe { tlb::flush_all(); }
unsafe {
tlb::flush_all();
}
}
pub fn with<F>(&mut self, table: &mut InactivePageTable, temporary_page: &mut TemporaryPage, f: F)
where F: FnOnce(&mut Mapper)
pub fn with<F>(
&mut self,
table: &mut InactivePageTable,
temporary_page: &mut TemporaryPage,
f: F,
) where
F: FnOnce(&mut Mapper),
{
{
let backup = Frame::containing_address(PhysicalAddress::new(unsafe { control_regs::cr3() as usize }));
let backup = Frame::containing_address(PhysicalAddress::new(unsafe {
control_regs::cr3() as usize
}));
// map temporary_page to current p4 table
let p4_table = temporary_page.map_table_frame(backup.clone(), EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::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()[crate::RECURSIVE_PAGE_PML4].set(table.p4_frame.clone(), EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE);
self.p4_mut()[crate::RECURSIVE_PAGE_PML4].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[crate::RECURSIVE_PAGE_PML4].set(backup, EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE);
p4_table[crate::RECURSIVE_PAGE_PML4].set(
backup,
EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE,
);
self.flush_all();
}
@@ -389,13 +477,24 @@ pub struct InactivePageTable {
}
impl InactivePageTable {
pub fn new(frame: Frame, active_table: &mut ActivePageTable, temporary_page: &mut TemporaryPage) -> InactivePageTable {
pub fn new(
frame: Frame,
active_table: &mut ActivePageTable,
temporary_page: &mut TemporaryPage,
) -> InactivePageTable {
{
let table = temporary_page.map_table_frame(frame.clone(), EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::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[crate::RECURSIVE_PAGE_PML4].set(frame.clone(), EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE);
table[crate::RECURSIVE_PAGE_PML4].set(
frame.clone(),
EntryFlags::PRESENT | EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE,
);
}
temporary_page.unmap(active_table);
@@ -403,7 +502,9 @@ impl InactivePageTable {
}
pub unsafe fn from_address(cr3: usize) -> InactivePageTable {
InactivePageTable { p4_frame: Frame::containing_address(PhysicalAddress::new(cr3)) }
InactivePageTable {
p4_frame: Frame::containing_address(PhysicalAddress::new(cr3)),
}
}
pub unsafe fn address(&self) -> usize {
@@ -442,7 +543,7 @@ impl VirtualAddress {
/// Page
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Page {
number: usize
number: usize,
}
impl Page {
@@ -469,7 +570,9 @@ impl Page {
pub fn containing_address(address: VirtualAddress) -> Page {
//TODO assert!(address.get() < 0x0000_8000_0000_0000 || address.get() >= 0xffff_8000_0000_0000,
// "invalid address: 0x{:x}", address.get());
Page { number: address.get() / PAGE_SIZE }
Page {
number: address.get() / PAGE_SIZE,
}
}
pub fn range_inclusive(start: Page, end: Page) -> PageIter {
@@ -477,7 +580,9 @@ impl Page {
}
pub fn next(self) -> Page {
Self { number: self.number + 1 }
Self {
number: self.number + 1,
}
}
}

View File

@@ -1,6 +1,6 @@
use core::convert::TryInto;
use crate::syscall::io::{Io, Pio, Mmio, ReadOnly};
use crate::syscall::io::{Io, Mmio, Pio, ReadOnly};
bitflags! {
/// Interrupt enable flags
@@ -51,7 +51,7 @@ impl SerialPort<Pio<u8>> {
line_ctrl: Pio::new(base + 3),
modem_ctrl: Pio::new(base + 4),
line_sts: ReadOnly::new(Pio::new(base + 5)),
modem_sts: ReadOnly::new(Pio::new(base + 6))
modem_sts: ReadOnly::new(Pio::new(base + 6)),
}
}
}
@@ -63,30 +63,37 @@ impl SerialPort<Mmio<u32>> {
}
impl<T: Io> SerialPort<T>
where T::Value: From<u8> + TryInto<u8>
where
T::Value: From<u8> + TryInto<u8>,
{
pub fn init(&mut self) {
//TODO: Cleanup
self.int_en.write(0x00.into());
self.line_ctrl.write(0x80.into());
self.data.write(0x01.into());
self.int_en.write(0x00.into());
self.line_ctrl.write(0x03.into());
self.fifo_ctrl.write(0xC7.into());
self.modem_ctrl.write(0x0B.into());
self.int_en.write(0x01.into());
unsafe {
self.int_en.write(0x00.into());
self.line_ctrl.write(0x80.into());
self.data.write(0x01.into());
self.int_en.write(0x00.into());
self.line_ctrl.write(0x03.into());
self.fifo_ctrl.write(0xC7.into());
self.modem_ctrl.write(0x0B.into());
self.int_en.write(0x01.into());
}
}
fn line_sts(&self) -> LineStsFlags {
LineStsFlags::from_bits_truncate(
(self.line_sts.read() & 0xFF.into()).try_into().unwrap_or(0)
(unsafe { self.line_sts.read() } & 0xFF.into())
.try_into()
.unwrap_or(0),
)
}
pub fn receive(&mut self) -> Option<u8> {
if self.line_sts().contains(LineStsFlags::INPUT_FULL) {
Some(
(self.data.read() & 0xFF.into()).try_into().unwrap_or(0)
(unsafe { self.data.read() } & 0xFF.into())
.try_into()
.unwrap_or(0),
)
} else {
None
@@ -94,8 +101,8 @@ impl<T: Io> SerialPort<T>
}
pub fn send(&mut self, data: u8) {
while ! self.line_sts().contains(LineStsFlags::OUTPUT_EMPTY) {}
self.data.write(data.into());
while !self.line_sts().contains(LineStsFlags::OUTPUT_EMPTY) {}
unsafe { self.data.write(data.into()) }
}
pub fn write(&mut self, buf: &[u8]) {
@@ -105,11 +112,11 @@ impl<T: Io> SerialPort<T>
self.send(8);
self.send(b' ');
self.send(8);
},
}
b'\n' => {
self.send(b'\r');
self.send(b'\n');
},
}
_ => {
self.send(b);
}