重写rust核心库,构建中断处理框架 #6

Merged
pointer-to-bios merged 18 commits from pointer-to-bios/metaverse-dev:main into main 2024-05-03 05:45:43 +08:00
12 changed files with 511 additions and 297 deletions
Showing only changes of commit 3762b0245c - Show all commits

View File

@ -11,6 +11,7 @@ extern "C" {
pub struct SystemTimeError(Duration);
#[derive(Clone, Copy, Hash)]
#[derive(Default)]
pub struct SystemTime {
unix_time: usize,
ns_time: usize,

View File

@ -1,5 +1,4 @@
use alloc::vec;
use alloc::vec::Vec;
use crate::libk::alloc::vec::Vec;
use super::{
clock::time::SystemTime,
@ -28,12 +27,12 @@ pub struct KernelLogger {
impl KernelLogger {
pub fn new() -> Self {
Self {
fatal_queue: vec![],
error_queue: vec![],
warning_queue: vec![],
info_queue: vec![],
debug_queue: vec![],
trace_queue: vec![],
fatal_queue: Vec::new(),
error_queue: Vec::new(),
warning_queue: Vec::new(),
info_queue: Vec::new(),
debug_queue: Vec::new(),
trace_queue: Vec::new(),
}
}
@ -91,105 +90,18 @@ impl KernelLogger {
self.trace_queue.push((SystemTime::now(), msg));
}
pub fn iter(&self, level: LoggerLevel) -> LogIterator {
let mut logs = vec![];
match level {
LoggerLevel::Fatal => {
logs.push(&self.fatal_queue);
}
LoggerLevel::Error => {
logs.push(&self.fatal_queue);
logs.push(&self.error_queue);
}
LoggerLevel::Warning => {
logs.push(&self.fatal_queue);
logs.push(&self.error_queue);
logs.push(&self.warning_queue);
}
LoggerLevel::Info => {
logs.push(&self.fatal_queue);
logs.push(&self.error_queue);
logs.push(&self.warning_queue);
logs.push(&self.info_queue);
}
LoggerLevel::Debug => {
logs.push(&self.fatal_queue);
logs.push(&self.error_queue);
logs.push(&self.warning_queue);
logs.push(&self.info_queue);
logs.push(&self.debug_queue);
}
LoggerLevel::Trace => {
logs.push(&self.fatal_queue);
logs.push(&self.error_queue);
logs.push(&self.warning_queue);
logs.push(&self.info_queue);
logs.push(&self.debug_queue);
logs.push(&self.trace_queue);
}
}
let mut res = vec![];
let mut indeces = Vec::new();
for _ in 0..logs.len() {
indeces.push(0usize);
}
let all_end = |indeces: &Vec<usize>, logs: &Vec<&Vec<(SystemTime, Message)>>| {
for i in 0..indeces.len() {
if indeces[i] < logs.len() {
return false;
}
}
true
};
while !all_end(&indeces, &logs) {
let mut min_ind = None;
let mut min = None;
for i in 0..indeces.len() {
if indeces[i] >= logs[i].len() {
continue;
}
if let Some(minx) = min.as_mut() {
if logs[i][indeces[i]].0 < *minx {
*minx = logs[i][indeces[i]].0;
min_ind = Some(i);
}
} else {
min = Some(logs[i][indeces[i]].0);
min_ind = Some(i);
}
}
if let Some(mini) = min_ind {
res.push(&logs[mini][indeces[mini]]);
indeces[mini] += 1;
} else {
break;
}
}
LogIterator { logs: res }
pub fn iter(&self, _level: LoggerLevel) -> LogIterator {
todo!()
}
}
pub struct LogIterator<'a> {
logs: Vec<&'a (SystemTime, Message)>,
pub struct LogIterator {
}
impl<'a> Iterator for LogIterator<'a> {
impl Iterator for LogIterator {
type Item = Message;
fn next(&mut self) -> Option<Self::Item> {
let res = if let Some((time, msg)) = self.logs.first() {
Some(
MessageBuilder::new()
.message(time)
.append(MessageBuilder::from_message(msg.clone()))
.build(),
)
} else {
None
};
if let Some(_) = res {
self.logs.remove(0);
}
res
todo!()
}
}

View File

@ -1 +0,0 @@
pub mod rwlock;

View File

@ -1,129 +0,0 @@
use core::{ops::{Deref, DerefMut}, ptr::null_mut};
use alloc::{vec, vec::Vec};
/// ## RwLock<T>
/// 读写锁
///
/// * 对于写入操作:
///
/// 锁没有占用时,获取锁,并执行闭包。
///
/// 当锁已经被占用,将闭包悬挂。
///
/// 释放锁时,将所有悬挂的闭包都执行。
///
/// 正在释放锁时,`write`方法返回`Err(())`
///
/// ```
/// let num = 6;
/// let num = RwLock::new(num);
/// if let Err(()) = num.write(
/// |n| *n = 10
/// ) {}
/// let numstr = format!("{}", num.read());
/// ````
pub struct RwLock<'a, T> {
obj: T,
locked: bool,
dealing_hanged: bool,
ptr: *mut RwLockWriteGuard<'a, T>,
hanging: Vec<&'a dyn Fn(&mut T)>,
}
unsafe impl<T> Send for RwLock<'_, T> {}
unsafe impl<T> Sync for RwLock<'_, T> {}
impl<'a, T> RwLock<'a, T> {
pub fn new(obj: T) -> Self {
Self {
obj,
locked: false,
dealing_hanged: false,
ptr: null_mut(),
hanging: vec![],
}
}
pub fn read(&self) -> RwLockReadGuard<T> {
RwLockReadGuard { obj: &self.obj }
}
pub fn write(&'a mut self, f: &'a dyn Fn(&mut T)) -> Result<RwLockWriteGuard<T>, ()> {
if self.dealing_hanged {
Err(())
} else if !self.locked {
self.locked = true;
f(&mut self.obj);
let ptr = { self as *mut RwLock<'a, T> };
let obj = &mut self.obj;
let mut res = RwLockWriteGuard {
obj,
ptr,
must_deal_hang: false,
};
self.ptr = &mut res as *mut RwLockWriteGuard<'_, T>;
Ok(res)
} else {
self.hanging.push(f);
let ptr = { self as *mut RwLock<'a, T> };
let obj = &mut self.obj;
Ok(RwLockWriteGuard {
obj,
ptr,
must_deal_hang: false,
})
}
}
}
pub struct RwLockReadGuard<'a, T> {
obj: &'a T,
}
impl<'a, T> Deref for RwLockReadGuard<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.obj
}
}
impl<'a, T> Drop for RwLockReadGuard<'a, T> {
fn drop(&mut self) {}
}
pub struct RwLockWriteGuard<'a, T> {
obj: &'a mut T,
ptr: *mut RwLock<'a, T>,
must_deal_hang: bool,
}
impl<'a, T> Deref for RwLockWriteGuard<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.obj
}
}
impl<'a, T> DerefMut for RwLockWriteGuard<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.obj
}
}
impl<'a, T> Drop for RwLockWriteGuard<'a, T> {
fn drop(&mut self) {
if self.must_deal_hang {
let p = unsafe { &mut *self.ptr };
p.dealing_hanged = true;
for f in p.hanging.iter() {
f(self.obj);
}
p.hanging.clear();
p.dealing_hanged = false;
p.locked = false;
}
}
}

View File

@ -1,8 +1,8 @@
use core::ptr::null_mut;
use alloc::{
use crate::libk::alloc::{
boxed::Box,
string::{String, ToString},
vec,
vec::Vec,
};
@ -141,7 +141,7 @@ impl Tty {
}
}
#[derive(Clone, Copy)]
#[derive(Clone, Copy, Default)]
pub struct Color(pub u8, pub u8, pub u8);
impl Color {
@ -169,7 +169,7 @@ pub struct Resolution {
pub height: usize,
}
#[derive(Clone)]
#[derive(Clone, Default)]
pub struct MessageSection {
msg: String,
fgcolor: Color,
@ -179,14 +179,14 @@ pub struct MessageSection {
/// ## Message
///
/// 用`MessageBuilder`构造一个`Message`对象
#[derive(Clone)]
#[derive(Clone, Default)]
pub struct Message(Vec<MessageSection>);
impl ToString for Message {
fn to_string(&self) -> String {
let mut res = String::new();
for MessageSection { msg, .. } in self.0.iter() {
res += msg;
res += msg.clone();
}
res
}
@ -212,7 +212,7 @@ impl ToString for Message {
/// ```rust
/// use crate::kernel::tty::tty::BuilderFunctions::*;
///
/// message!(
/// message_raw!(
/// Msg("Hello, "),
/// Msg("Metaverse"),
/// FgColor(Color::GREEN),
@ -242,10 +242,14 @@ pub enum BuilderFunctions<'a> {
impl MessageBuilder {
pub fn new() -> Self {
Self {
msg: Message(vec![]),
msg: Message(Vec::new()),
}
}
pub fn is_empty(&self) -> bool {
self.msg.0.is_empty()
}
pub fn from_message(msg: Message) -> Self {
Self { msg }
}
@ -302,3 +306,82 @@ impl MessageBuilder {
self.msg
}
}
pub enum FmtMeta {
Color(Color),
String(String),
ToStringable(Box<dyn ToString>),
Hex(u8),
Pointer(usize),
}
pub fn format_message(fmt: &mut Vec<char>, meta: FmtMeta) -> MessageBuilder {
let mut msgbuilder = MessageBuilder::new();
let mut fmt_start = None;
let mut fmt_end = None;
for i in 0..fmt.len() {
if fmt[i] == '{' {
fmt_start = Some(i);
}
if fmt[i] == '}' {
fmt_end = Some(i);
break;
}
}
let tohex = |n: u8| {
if n < 10 {
(b'0' + n) as char
} else {
(b'a' + n - 10) as char
}
};
if fmt_start == None || fmt_end == None {
msgbuilder.message_mut(&String::from_iter(fmt.iter()));
} else {
let fmt_start = fmt_start.unwrap();
let fmt_end = fmt_end.unwrap();
let mut formatter = Vec::new();
for _ in fmt_start..=fmt_end {
formatter.push(fmt.remove(fmt_start));
}
formatter.remove(formatter.len() - 1);
formatter.remove(0);
match meta {
FmtMeta::Color(color) => {
let first = fmt.split_at(fmt_start).0;
msgbuilder.message_mut(&String::from_iter(first.iter()));
for _ in 0..fmt_start {
fmt.remove(0);
}
msgbuilder.message_mut(&String::from_iter(formatter.iter()));
msgbuilder.foreground_color_mut(color);
}
FmtMeta::String(s) => {
for c in s.chars().rev() {
fmt.insert(fmt_start, *c);
}
}
FmtMeta::ToStringable(s) => {
for c in s.to_string().chars().rev() {
fmt.insert(fmt_start, *c);
}
}
FmtMeta::Hex(num) => {
fmt.insert(fmt_start, tohex(num >> 4));
fmt.insert(fmt_start, tohex(num & 0xf));
}
FmtMeta::Pointer(mut p) => {
for _ in 0..16 {
fmt.insert(fmt_start, tohex((p & 0xf) as u8));
p >>= 4;
}
}
}
}
let mut rests = Vec::new();
while !fmt.is_empty() && fmt[0] != '{' {
rests.push(fmt.remove(0));
}
msgbuilder.message_mut(&String::from_iter(rests.iter()));
msgbuilder
}

View File

@ -1,69 +1,14 @@
#![no_std]
#![feature(strict_provenance)]
extern crate alloc;
use alloc::{
string::{String, ToString},
vec::Vec,
};
use core::{panic::PanicInfo, ptr::null_mut};
use kernel::tty::tty::{self, tty_enable, tty_text_print, Color};
use core::panic::PanicInfo;
pub mod kernel;
pub mod libk;
#[panic_handler]
unsafe fn kernel_panic_handler(info: &PanicInfo) -> ! {
let line_in_file = if let Some(loca) = info.location() {
loca.line().to_string()
} else {
String::new()
};
let info = {
let mut v = Vec::new();
v.push(("Kernel Panic: ", (Color::RED, Color::BLACK)));
v.push((
if let Some(loca) = info.location() {
loca.file()
} else {
"NoFile"
},
(Color::GREEN, Color::BLACK),
));
v.push((":", (Color::WHITE, Color::BLACK)));
v.push((
if let Some(_) = info.location() {
line_in_file.as_str()
} else {
"NoLine"
},
(Color::WHITE, Color::BLACK),
));
v.push((": ", (Color::WHITE, Color::BLACK)));
v.push((
if let Some(&s) = info.payload().downcast_ref::<&str>() {
s
} else {
"Unknown panic."
},
(Color::BLUE, Color::BLACK),
));
v.push(("\n", (Color::BLACK, Color::BLACK)));
v
};
let tty = tty::tty_get(0);
if tty != null_mut() {
let tty = *tty;
tty_enable(tty);
for (msgo, (fgc, bgc)) in info.into_iter() {
let msg = String::from(msgo).as_bytes_mut() as *mut [u8] as *mut u8;
let p = msg.offset(msgo.len() as isize);
let swp = *p;
*p = 0;
tty_text_print(tty, msg, u32::from(fgc), u32::from(bgc));
*p = swp;
}
}
unsafe fn kernel_panic_handler(_info: &PanicInfo) -> ! {
loop {}
}

38
src/libk/alloc/boxed.rs Normal file
View File

@ -0,0 +1,38 @@
use core::{
alloc::Layout,
mem::transmute,
ops::{Deref, DerefMut},
ptr::addr_of,
};
use alloc::alloc::alloc;
pub struct Box<T: ?Sized> {
inner: *mut T,
}
impl<T> Box<T> {
pub fn new(t: T) -> Self {
unsafe {
let inner = alloc(Layout::for_value(&t));
inner.copy_from(addr_of!(t).cast(), 1);
Self {
inner: transmute(inner),
}
}
}
}
impl<T: ?Sized> Deref for Box<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe { self.inner.as_ref().unwrap() }
}
}
impl<T: ?Sized> DerefMut for Box<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { self.inner.as_mut().unwrap() }
}
}

3
src/libk/alloc/mod.rs Normal file
View File

@ -0,0 +1,3 @@
pub mod boxed;
pub mod string;
pub mod vec;

81
src/libk/alloc/string.rs Normal file
View File

@ -0,0 +1,81 @@
use core::ops::{Add, AddAssign};
use super::vec::{Vec, VecIterator};
#[derive(Clone, Default)]
pub struct String {
data: Vec<char>,
u8data: Vec<u8>,
}
impl String {
pub fn new() -> Self {
Self {
data: Vec::new(),
u8data: Vec::new(),
}
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn chars(&self) -> VecIterator<char> {
self.data.iter()
}
pub fn as_bytes(&self) -> &[u8] {
&self.u8data[..]
}
pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
&mut self.u8data[..]
}
}
impl FromIterator<char> for String {
fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
let data = Vec::from_iter(iter);
let u8data = Vec::from_iter(data.iter().map(|c| *c as u8));
Self { data, u8data }
}
}
impl<'a> FromIterator<&'a char> for String {
fn from_iter<T: IntoIterator<Item = &'a char>>(iter: T) -> Self {
let data = Vec::from_iter(iter.into_iter().map(|c| *c));
let u8data = Vec::from_iter(data.iter().map(|c| *c as u8));
Self { data, u8data }
}
}
impl ToString for String {
fn to_string(&self) -> String {
self.clone()
}
}
impl Add for String {
type Output = Self;
fn add(mut self, rhs: Self) -> Self::Output {
self.data.append(&mut rhs.chars().map(|c| *c).collect());
self
}
}
impl AddAssign for String {
fn add_assign(&mut self, rhs: String) {
*self = self.clone() + rhs;
}
}
pub trait ToString {
fn to_string(&self) -> String;
}
impl ToString for str {
fn to_string(&self) -> String {
String::from_iter(self.chars())
}
}

280
src/libk/alloc/vec.rs Normal file
View File

@ -0,0 +1,280 @@
use core::{
alloc::Layout,
ops::{Index, IndexMut, Range, RangeFull},
ptr::{addr_of_mut, null_mut},
slice,
};
use alloc::alloc::{alloc, dealloc};
pub struct Vec<T> {
pointer: *mut T,
length: usize,
capacity: usize,
}
impl<T: Default> Vec<T> {
pub fn new() -> Self {
Self {
pointer: null_mut(),
length: 0,
capacity: 0,
}
}
unsafe fn extend_capacity(&mut self) {
let newp = alloc(Layout::array::<T>(self.capacity * 2).unwrap()).cast();
self.pointer.copy_to(newp, self.length);
dealloc(
self.pointer.cast(),
Layout::array::<T>(self.capacity).unwrap(),
);
self.pointer = newp;
self.capacity *= 2;
}
pub fn push(&mut self, item: T) {
if self.pointer.is_null() {
self.pointer = unsafe { alloc(Layout::array::<T>(4).unwrap()).cast() };
self.capacity = 4;
self.length = 0;
}
if self.capacity == self.length {
unsafe { self.extend_capacity() }
}
unsafe { self.pointer.offset(self.length as isize).write(item) };
self.length += 1;
}
pub fn insert(&mut self, index: usize, item: T) {
if self.capacity == self.length {
unsafe { self.extend_capacity() }
}
let rearlen = self.length - index;
unsafe {
if rearlen != 0 {
let tmp = alloc(Layout::array::<T>(rearlen).unwrap()).cast();
self.pointer.offset(index as isize).copy_to(tmp, rearlen);
self.pointer.offset(index as isize).write(item);
self.pointer
.offset(index as isize + 1)
.copy_from(tmp, rearlen);
} else {
self.pointer.offset(self.length as isize).write(item);
}
}
self.length += 1;
}
pub fn append(&mut self, v: &mut Self) {
while self.capacity < self.length + v.length {
unsafe { self.extend_capacity() }
}
unsafe {
self.pointer
.offset(self.length as isize)
.copy_from(v.pointer.cast_const(), v.length)
};
self.length += v.length;
}
pub fn split_at(&self, index: usize) -> (&[T], &[T]) {
if index >= self.length {
panic!("Index out of bound.");
}
(&self[0..index], &self[index..self.length])
}
pub fn len(&self) -> usize {
self.length
}
pub fn is_empty(&self) -> bool {
self.length == 0
}
pub fn last_mut(&mut self) -> Option<&mut T> {
unsafe { self.pointer.offset(self.length as isize - 1).as_mut() }
}
pub fn last(&self) -> Option<&T> {
unsafe { self.pointer.offset(self.length as isize - 1).as_ref() }
}
pub fn remove(&mut self, index: usize) -> T {
if index >= self.length {
panic!("Index out of bound.");
}
let mut t: T = T::default();
let pt = addr_of_mut!(t);
unsafe {
pt.copy_from(self.pointer.offset(index as isize).cast_const(), 1);
self.pointer.offset(index as isize).copy_from(
self.pointer.offset(index as isize + 1),
self.length - index - 1,
);
}
t
}
pub fn iter(&self) -> VecIterator<T> {
VecIterator {
pointer: self.pointer,
index: 0,
length: self.length,
_phantom: &(),
}
}
}
impl<T: Default> Default for Vec<T> {
fn default() -> Self {
Self::new()
}
}
impl<T: Default> Index<usize> for Vec<T> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
unsafe { self.pointer.offset(index as isize).as_ref().unwrap() }
}
}
impl<T: Default> Index<Range<usize>> for Vec<T> {
type Output = [T];
fn index(&self, index: Range<usize>) -> &Self::Output {
unsafe { &slice::from_raw_parts_mut(self.pointer, self.length)[index] }
}
}
impl<T: Default> Index<RangeFull> for Vec<T> {
type Output = [T];
fn index(&self, _: RangeFull) -> &Self::Output {
unsafe { slice::from_raw_parts(self.pointer.cast(), self.length) }
}
}
impl<T: Default> IndexMut<RangeFull> for Vec<T> {
fn index_mut(&mut self, _: RangeFull) -> &mut Self::Output {
unsafe { slice::from_raw_parts_mut(self.pointer.cast(), self.length) }
}
}
impl<T: Default> Clone for Vec<T> {
fn clone(&self) -> Self {
let res = Self {
pointer: unsafe { alloc(Layout::array::<T>(self.capacity).unwrap()).cast() },
length: self.length,
capacity: self.capacity,
};
unsafe {
res.pointer
.copy_from(self.pointer.cast_const(), self.length)
};
res
}
}
impl<T> Drop for Vec<T> {
fn drop(&mut self) {
unsafe {
dealloc(
self.pointer.cast(),
Layout::array::<T>(self.capacity).unwrap(),
)
};
}
}
impl<T: Default> FromIterator<T> for Vec<T> {
fn from_iter<U: IntoIterator<Item = T>>(iter: U) -> Self {
let mut res = Vec::new();
for i in iter {
res.push(i);
}
res
}
}
impl<T: Default> IntoIterator for Vec<T> {
type Item = T;
type IntoIter = VecIter<T>;
fn into_iter(self) -> Self::IntoIter {
todo!()
}
}
pub struct VecIterator<'a, T> {
pointer: *mut T,
index: usize,
length: usize,
_phantom: &'a (),
}
impl<'a, T: 'a> Iterator for VecIterator<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
if self.index == self.length {
None
} else {
let res = unsafe { Some(self.pointer.offset(self.index as isize).as_ref().unwrap()) };
self.index += 1;
res
}
}
}
impl<'a, T: 'a> DoubleEndedIterator for VecIterator<'a, T> {
fn next_back(&mut self) -> Option<Self::Item> {
if self.index == 0 {
None
} else {
self.index -= 1;
unsafe { Some(self.pointer.offset(self.index as isize).as_ref().unwrap()) }
}
}
}
pub struct VecIter<T> {
pointer: *mut T,
index: usize,
length: usize,
capacity: usize,
}
impl<T: Default> Iterator for VecIter<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
if self.index == self.length {
None
} else {
let mut t = T::default();
let res = unsafe {
self.pointer
.offset(self.index as isize)
.copy_to(addr_of_mut!(t), 1);
Some(t)
};
self.index += 1;
res
}
}
}
impl<T> Drop for VecIter<T> {
fn drop(&mut self) {
unsafe {
dealloc(
self.pointer.cast(),
Layout::array::<T>(self.capacity).unwrap(),
)
};
}
}

View File

@ -1 +1,2 @@
pub mod string;
pub mod alloc;
pub mod core;