测试BP中断,并修复String类型内存泄漏的问题

This commit is contained in:
pointer-to-bios 2024-05-07 04:23:02 +08:00
parent 87f2767499
commit 6913dede05
13 changed files with 263 additions and 119 deletions

View File

@ -1,4 +1,12 @@
use crate::{kernel::tty::tty::Tty, message};
use crate::{
kernel::{
memm::utils::AddressUtils,
tty::tty::{Color, FmtMeta, Tty},
},
message,
};
use super::proc::RegisterTexture;
extern "C" {
pub fn interrupt_open();
@ -9,7 +17,7 @@ extern "C" {
}
#[no_mangle]
unsafe extern "C" fn interrupt_req_UNSUPPORTED(rip: u64, rsp: u64, errcode: u64) -> ! {
unsafe extern "C" fn interrupt_req_UNSUPPORTED(rip: u64, rsp: u64, _errcode: u64) -> ! {
interrupt_rust_enter();
let tty = Tty::from_id(0).unwrap();
tty.enable();
@ -24,25 +32,120 @@ unsafe extern "C" fn interrupt_req_UNSUPPORTED(rip: u64, rsp: u64, errcode: u64)
}
#[no_mangle]
unsafe extern "C" fn interrupt_req_DE(rip: u64, rsp: u64, errcode: u64) {
unsafe extern "C" fn interrupt_req_DE(rip: u64, rsp: u64, _errcode: u64) {
interrupt_rust_enter();
let tty = Tty::from_id(0).unwrap();
tty.enable();
tty.print(message!(
"{Warning}: Kernel hit {Divid Error} on rip=0x{} and rsp=0x{}.\n",
FmtMeta::Color(Color::PURPLE),
FmtMeta::Color(Color::YELLOW),
FmtMeta::Pointer(rip as usize),
FmtMeta::Pointer(rsp as usize)
));
interrupt_rust_leave();
if rip.is_kernel_space() {
let tty = Tty::from_id(0).unwrap();
tty.enable();
tty.print(message!(
"{Warning}: Kernel hit {Divid Error} on rip=0x{} and rsp=0x{}.\n",
FmtMeta::Color(Color::PURPLE),
FmtMeta::Color(Color::YELLOW),
FmtMeta::Pointer(rip as usize),
FmtMeta::Pointer(rsp as usize)
));
loop {}
} else if rip.is_user_space() {
// TODO 处理后返回
interrupt_rust_leave();
}
}
// #[no_mangle]
// unsafe extern "C" fn interrupt_req_NMI(rip: u64, rsp: u64, errcode: u64) {}
#[no_mangle]
unsafe extern "C" fn interrupt_req_BP(rip: u64, rsp: u64, errcode: u64) {
interrupt_rust_enter();
if rip.is_kernel_space() {
let register_texture = errcode as *const RegisterTexture;
let register_texture = &*register_texture;
let tty = Tty::from_id(0).unwrap();
tty.enable();
tty.print(message!(
"{Debug}: Kernel hit breakpoint {0x{}}.\n",
FmtMeta::Color(Color::BLUE),
FmtMeta::Pointer(rip as usize),
FmtMeta::Color(Color::GREEN)
));
tty.print(message!(
"\trax\t{}\n",
FmtMeta::Pointer(register_texture.rax as usize)
));
tty.print(message!(
"\trbx\t{}\n",
FmtMeta::Pointer(register_texture.rbx as usize)
));
tty.print(message!(
"\trcx\t{}\n",
FmtMeta::Pointer(register_texture.rcx as usize)
));
tty.print(message!(
"\trdx\t{}\n",
FmtMeta::Pointer(register_texture.rdx as usize)
));
tty.print(message!(
"\trsi\t{}\n",
FmtMeta::Pointer(register_texture.rsi as usize)
));
tty.print(message!(
"\trdi\t{}\n",
FmtMeta::Pointer(register_texture.rdi as usize)
));
tty.print(message!(
"\trbp\t{}\n",
FmtMeta::Pointer(register_texture.rbp as usize)
));
tty.print(message!(
"\trsp\t{}\n",
FmtMeta::Pointer(register_texture.rsp as usize)
));
tty.print(message!(
"\tr8\t{}\n",
FmtMeta::Pointer(register_texture.r8 as usize)
));
tty.print(message!(
"\tr9\t{}\n",
FmtMeta::Pointer(register_texture.r9 as usize)
));
tty.print(message!(
"\tr10\t{}\n",
FmtMeta::Pointer(register_texture.r10 as usize)
));
tty.print(message!(
"\tr11\t{}\n",
FmtMeta::Pointer(register_texture.r11 as usize)
));
tty.print(message!(
"\tr12\t{}\n",
FmtMeta::Pointer(register_texture.r12 as usize)
));
tty.print(message!(
"\tr13\t{}\n",
FmtMeta::Pointer(register_texture.r13 as usize)
));
tty.print(message!(
"\tr14\t{}\n",
FmtMeta::Pointer(register_texture.r14 as usize)
));
tty.print(message!(
"\tr15\t{}\n",
FmtMeta::Pointer(register_texture.r15 as usize)
));
tty.print(message!(
"\trip\t{}\n",
FmtMeta::Pointer(register_texture.rip as usize)
));
tty.print(message!(
"\trflags\t{}\n",
FmtMeta::Pointer(register_texture.rflags as usize)
));
loop {}
} else if rip.is_user_space() {
// TODO 处理后返回
interrupt_rust_leave();
}
}
#[no_mangle]
unsafe extern "C" fn interrupt_req_NMI(rip: u64, rsp: u64, errcode: u64) {}
#[no_mangle]
unsafe extern "C" fn interrupt_req_BP(rip: u64, rsp: u64, errcode: u64) {}
#[no_mangle]
unsafe extern "C" fn interrupt_req_OF(rip: u64, rsp: u64, errcode: u64) {}

View File

@ -6,6 +6,8 @@
void interrupt_init()
{
gate_descriptor_t gate;
// 用UNSUPPORTED中断处理程序填充所有中断向量
trap_gate_generate(gate, interrupt_entry_sym(UNSUPPORTED));
for (usize i = 4; i < 256; i++)
{
@ -14,7 +16,7 @@ void interrupt_init()
trap_gate_generate(gate, interrupt_entry_sym(DE));
interrupt_register_gate(gate, 0);
trap_gate_generate(gate, interrupt_entry_sym(UNSUPPORTED));
trap_gate_generate(gate, interrupt_entry_sym(UNSUPPORTED)); // Debug Exception (#DB)
interrupt_register_gate(gate, 1);
trap_gate_generate(gate, interrupt_entry_sym(NMI));
interrupt_register_gate(gate, 2);

View File

@ -1,32 +1,30 @@
#[repr(C)]
#[derive(Debug)]
pub struct RegisterTexture {
es: u16,
ds: u16,
reserved: u32,
r15: u64,
r14: u64,
r13: u64,
r12: u64,
r11: u64,
r10: u64,
r9: u64,
r8: u64,
rdi: u64,
rsi: u64,
rdx: u64,
rbx: u64,
rcx: u64,
rax: u64,
rbp: u64,
rip: u64,
cs: u64,
rflags: u64,
rsp: u64,
ss: u64,
pub es: u16,
pub ds: u16,
pub reserved: u32,
pub r15: u64,
pub r14: u64,
pub r13: u64,
pub r12: u64,
pub r11: u64,
pub r10: u64,
pub r9: u64,
pub r8: u64,
pub rdi: u64,
pub rsi: u64,
pub rdx: u64,
pub rbx: u64,
pub rcx: u64,
pub rax: u64,
pub rbp: u64,
pub rip: u64,
pub cs: u64,
pub rflags: u64,
pub rsp: u64,
pub ss: u64,
}
#[derive(Debug)]
pub struct ProcessTexture {
register: RegisterTexture,
}

View File

@ -48,11 +48,11 @@ void kmain(void *mb2_bootinfo)
// 初始化中断管理
interrupt_init();
int i = 1 / 0;
// 初始化系统调用
syscall_init();
asm("int3");
// 为rust准备正确对齐的栈
prepare_stack();

View File

@ -81,12 +81,4 @@ void raw_allocator_free(raw_allocator_t *allocator, void *mem)
cell = raw_allocator_next_cell(cell);
}
allocator->rest_memory += cell->capacity + sizeof(raw_allocator_cell);
allocator->free_count++;
if ( // 可用内存不超过当前allocator的 5% 或调用free次数很多时
allocator->size / allocator->rest_memory > 20 ||
allocator->free_count > RAW_ALLOCATOR_FREE_MAX)
{
raw_allocator_cellmerge(allocator);
allocator->free_count = 0;
}
}

View File

@ -1 +1,2 @@
pub mod memm;
pub mod utils;

24
src/kernel/memm/utils.rs Normal file
View File

@ -0,0 +1,24 @@
mod x86_64 {
pub trait AddressUtils {
fn is_cannonical(self) -> bool;
fn is_user_space(self) -> bool;
fn is_kernel_space(self) -> bool;
}
impl AddressUtils for u64 {
fn is_cannonical(self) -> bool {
self < 0x0000_8000_0000_0000 || self > 0xffff_7fff_ffff_ffff
}
fn is_user_space(self) -> bool {
self > 0xffff_7fff_ffff_ffff
}
fn is_kernel_space(self) -> bool {
self.is_cannonical() && !self.is_user_space()
}
}
}
#[cfg(target_arch = "x86_64")]
pub use x86_64::*;

View File

@ -12,17 +12,12 @@ macro_rules! message {
use crate::{
kernel::tty::tty::{
MessageBuilder,
FmtMeta,
Color,
format_message
},
libk::alloc::vec::Vec,
libk::alloc::{string::ToString, vec::Vec},
};
let mut formatter = $fmtter.chars().collect::<Vec<char>>();
let mut formatter = Vec::from_iter($fmtter.to_string().chars());
let builder = MessageBuilder::new();
$(
let builder = builder.append(format_message(&mut formatter, $e));
)*
builder.build()
builder$(.append(format_message(&mut formatter, $e)))*.build()
}};
}

View File

@ -119,23 +119,18 @@ impl Tty {
pub fn print(&self, msg: Message) {
for MessageSection {
mut msg,
msg,
fgcolor,
bgcolor,
} in msg.0.into_iter()
{
unsafe {
let string = msg.as_bytes_mut() as *mut [u8] as *mut u8;
let string = string.offset(msg.len() as isize);
let swp = *string;
*string = 0;
tty_text_print(
self.tty_pointer,
msg.as_bytes_mut() as *mut [u8] as *mut u8,
msg.to_cstr().get_pointer(),
u32::from(fgcolor),
u32::from(bgcolor),
);
*string = swp;
};
}
}
@ -337,6 +332,7 @@ pub fn format_message(fmt: &mut Vec<char>, meta: FmtMeta) -> MessageBuilder {
};
if fmt_start == None || fmt_end == None {
msgbuilder.message_mut(&String::from_iter(fmt.iter()));
msgbuilder
} else {
let fmt_start = fmt_start.unwrap();
let fmt_end = fmt_end.unwrap();
@ -377,11 +373,11 @@ pub fn format_message(fmt: &mut Vec<char>, meta: FmtMeta) -> MessageBuilder {
}
}
}
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
}
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,6 +1,7 @@
#![no_std]
#![feature(strict_provenance)]
#![feature(layout_for_ptr)]
#![feature(alloc_layout_extra)]
extern crate alloc;
@ -8,6 +9,8 @@ use core::panic::PanicInfo;
use kernel::tty::tty::Tty;
use crate::kernel::tty::tty::{Color, FmtMeta};
pub mod kernel;
pub mod libk;

View File

@ -24,18 +24,21 @@ impl String {
self.data.iter()
}
pub fn as_bytes(&self) -> &[u8] {
&self.u8data[..]
}
pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
&mut self.u8data[..]
}
pub fn insert(&mut self, index: usize, item: char) {
self.data.insert(index, item);
self.u8data.insert(index, item as u8);
}
pub fn remove(&mut self, index: usize) -> char {
self.u8data.remove(index);
self.data.remove(index)
}
pub unsafe fn to_cstr(&self) -> Vec<u8> {
let mut res = self.u8data.clone();
res.push(0);
res
}
}
impl FromIterator<char> for String {
@ -63,15 +66,17 @@ impl ToString for String {
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());
fn add(mut self, mut rhs: Self) -> Self::Output {
self.data.append(&mut rhs.data);
self.u8data.append(&mut rhs.u8data);
self
}
}
impl AddAssign for String {
fn add_assign(&mut self, rhs: String) {
*self = self.clone() + rhs;
fn add_assign(&mut self, mut rhs: String) {
self.data.append(&mut rhs.data);
self.u8data.append(&mut rhs.u8data);
}
}

View File

@ -1,5 +1,6 @@
use core::{
alloc::Layout,
mem::size_of,
ops::{Index, IndexMut, Range, RangeFull},
ptr::addr_of_mut,
slice,
@ -19,18 +20,24 @@ pub struct Vec<T> {
impl<T: Default> Vec<T> {
pub fn new() -> Self {
Self {
pointer: unsafe { alloc(Layout::array::<T>(4).unwrap()).cast() },
pointer: unsafe {
alloc(Layout::from_size_align_unchecked(4 * size_of::<T>(), 1)).cast()
},
length: 0,
capacity: 4,
}
}
unsafe fn extend_capacity(&mut self) {
let newp: *mut T = alloc(Layout::array::<T>(self.capacity * 2).unwrap()).cast();
let newp: *mut T = alloc(Layout::from_size_align_unchecked(
self.capacity * 2 * size_of::<T>(),
1,
))
.cast();
self.pointer.kcopy_to(newp, self.length);
dealloc(
self.pointer.cast(),
Layout::array::<T>(self.capacity).unwrap(),
Layout::from_size_align_unchecked(self.capacity * size_of::<T>(), 1),
);
self.pointer = newp;
self.capacity *= 2;
@ -51,7 +58,11 @@ impl<T: Default> Vec<T> {
let rearlen = self.length - index;
unsafe {
if rearlen != 0 {
let tmp = alloc(Layout::array::<T>(rearlen).unwrap()).cast();
let tmp = alloc(Layout::from_size_align_unchecked(
rearlen * size_of::<T>(),
1,
))
.cast();
self.pointer.offset(index as isize).kcopy_to(tmp, rearlen);
self.pointer.offset(index as isize).write(item);
self.pointer
@ -116,7 +127,7 @@ impl<T: Default> Vec<T> {
t
}
pub fn iter(&self) -> VecIterator<T> {
pub fn iter<'a, 'b: 'a>(&'a self) -> VecIterator<'b, T> {
VecIterator {
pointer: self.pointer,
index: 0,
@ -124,6 +135,10 @@ impl<T: Default> Vec<T> {
_phantom: &(),
}
}
pub unsafe fn get_pointer(&self) -> *mut T {
self.pointer
}
}
impl<T: Default> Default for Vec<T> {
@ -165,7 +180,13 @@ impl<T: Default> IndexMut<RangeFull> for Vec<T> {
impl<T: Default> Clone for Vec<T> {
fn clone(&self) -> Self {
let res = Self {
pointer: unsafe { alloc(Layout::array::<T>(self.capacity).unwrap()).cast() },
pointer: unsafe {
alloc(Layout::from_size_align_unchecked(
self.capacity * size_of::<T>(),
1,
))
.cast()
},
length: self.length,
capacity: self.capacity,
};
@ -182,7 +203,7 @@ impl<T> Drop for Vec<T> {
unsafe {
dealloc(
self.pointer.cast(),
Layout::array::<T>(self.capacity).unwrap(),
Layout::from_size_align_unchecked(self.capacity * size_of::<T>(), 1),
)
};
}
@ -198,17 +219,33 @@ impl<T: Default> FromIterator<T> for Vec<T> {
}
}
impl<'a> FromIterator<&'a char> for Vec<char> {
fn from_iter<U: IntoIterator<Item = &'a char>>(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 {
/*let pointer = unsafe {
let pointer = alloc(Layout::from_size_align_unchecked(
self.capacity * size_of::<T>(),
1,
));
pointer.copy_from(self.pointer.cast(), self.length);
pointer.cast()
};*/
VecIter {
pointer: self.pointer,
vec: self,
index: 0,
length: self.length,
capacity: self.capacity,
}
}
}
@ -246,22 +283,21 @@ impl<'a, T: 'a> DoubleEndedIterator for VecIterator<'a, T> {
}
pub struct VecIter<T> {
pointer: *mut T,
vec: Vec<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 {
if self.index == self.vec.length {
None
} else {
let mut t = T::default();
let res = unsafe {
self.pointer
self.vec
.pointer
.offset(self.index as isize)
.kcopy_to(addr_of_mut!(t), 1);
Some(t)
@ -271,14 +307,3 @@ impl<T: Default> Iterator for VecIter<T> {
}
}
}
impl<T> Drop for VecIter<T> {
fn drop(&mut self) {
unsafe {
dealloc(
self.pointer.cast(),
Layout::array::<T>(self.capacity).unwrap(),
)
};
}
}

View File

@ -1,4 +1,4 @@
use core::mem::{size_of, transmute};
use core::mem::size_of;
extern "C" {
pub fn memset(des: *const u8, src: u8, len: usize);
@ -14,16 +14,16 @@ pub trait PtrOptions<T> {
impl<T> PtrOptions<T> for *mut T {
unsafe fn kcopy_from(self, src: *const T, count: usize) {
memcpy(
transmute(self.cast_const()),
transmute(src),
self.cast_const() as *const u8,
src.cast(),
count * size_of::<T>(),
);
}
unsafe fn kcopy_to(self, des: *const T, count: usize) {
memcpy(
transmute(des),
transmute(self.cast_const()),
des.cast(),
self.cast_const() as *const u8,
count * size_of::<T>(),
);
}