From f2240787b6ebdc26a8943de69d5ce6a08c8cc926 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Thu, 25 Apr 2024 17:41:35 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85=E6=9B=B4=E5=A4=9Acore=20crat?= =?UTF-8?q?e=E7=9A=84=E9=87=8D=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- debug/2024-04.txt | 29 ++++++ src/Makefile | 27 +++-- src/kernel/main.rs | 21 ++-- src/kernel/memm/memm.rs | 6 +- src/kernel/memm/mod.rs | 2 +- src/kernel/tty/mod.rs | 33 +++++-- src/kernel/tty/tty.rs | 4 +- src/lib.rs | 1 + src/libk/alloc/alloc.rs | 11 +++ src/libk/alloc/boxed.rs | 13 ++- src/libk/alloc/mod.rs | 1 + src/libk/alloc/string.rs | 209 +++++++++++++++++++++++++++++++++++++++ src/libk/alloc/vec.rs | 9 +- 13 files changed, 326 insertions(+), 40 deletions(-) create mode 100644 debug/2024-04.txt create mode 100644 src/libk/alloc/alloc.rs diff --git a/debug/2024-04.txt b/debug/2024-04.txt new file mode 100644 index 0000000..914d7c4 --- /dev/null +++ b/debug/2024-04.txt @@ -0,0 +1,29 @@ +======== 04-21 16:50 ======== +Hit null pointer at 0x100370a +Stack trace: + 1 0x0000000001007b90 -> interrupt_req_DE + 2 0x00000000010072b0 -> metaverse::kernel::tty::tty::MessageBuilder::message_mut + 3 0x0000000001007e60 -> >::from_iter + 4 0x0000000001005eb0 -> >::from_iter + 5 0x0000000001005d80 -> >::extend + 6 0x0000000001004840 -> alloc::vec::Vec::reserve + 7 0x0000000001005900 -> alloc::raw_vec::RawVec::reserve::{do_reserve_and_handle} + 8 0x00000000010055c0 -> alloc::raw_vec::RawVec::grow_amortized + 9 0x00000000010051e0 -> alloc::raw_vec::finish_grow + 10 0x0000000001005a90 -> ::allocate + 11 0x0000000001004900 -> alloc::alloc::Global::alloc_impl + 12 0x00000000010048a0 -> alloc::alloc::alloc + 13 0x00000000010036e0 -> core::ptr::read_volatile::precondition_check +使用了core crate中的String,导致最终调用了一个含有未正确链接的函数。 + +======== 04-23 13:55 ======== +Hit null pointer as 0x100351a. +Stack trace: + 0x00000000010054d0 -> metaverse::kernel::tty::tty::MessageBuilder::message_mut + 0x0000000001006170 -> ::to_string + 0x0000000001006080 -> >::from_iter + 0x0000000001007450 -> ::from_iter + 0x0000000001006a10 -> metaverse::libk::alloc::vec::Vec::push + 0x0000000001003f60 -> alloc::alloc::alloc + 0x00000000010034f0 -> core::ptr::read_volatile::precondition_check +使用了core crate的alloc函数,其中含有未正确链接的函数。 diff --git a/src/Makefile b/src/Makefile index 7532577..286153c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -31,16 +31,24 @@ endif ################################ # rust语言环境变量 +TARGET_TRIPLE = + +ifeq (${ARCH},x86_64) + TARGET_TRIPLE := x86_64-unknown-none +endif + +RUSTLIB_PATH = ../target/sysroot/lib/rustlib/${TARGET_TRIPLE}/lib +RUST_LIBS = $(shell ls -d ${RUSTLIB_PATH}/lib*.rlib) + RSCFLAGS = --emit obj --crate-type staticlib --verbose \ --crate-name=metaverse \ --edition 2021 \ - -L crate="${PWD}/../rustlib/src/" \ -C code-model=large \ -C relocation-model=static \ - -C embed-bitcode=no + -C embed-bitcode=no \ + -C panic=abort ifeq (${ARCH},x86_64) - RSCFLAGS := ${RSCFLAGS} --target x86_64-unknown-none RSCFLAGS := ${RSCFLAGS} -C target-feature=-sse endif @@ -48,18 +56,14 @@ ifdef release RSCFLAGS := ${RSCFLAGS} -O endif -RUSTLIB_PATH = ../rustlib/${ARCH} -RUST_LIBS = "${RUSTLIB_PATH}/liballoc.rlib" "${RUSTLIB_PATH}/libcompiler_builtins.rlib" \ - "${RUSTLIB_PATH}/libcore.rlib" "${RUSTLIB_PATH}/librustc_std_workspace_core.rlib" - ################################ metaverse.elf: kernel libk rust metaverse.lds font_file.o @echo -e "\e[1;33mld\e[0m \e[1;32m$@\e[0m \e[34m<--\e[0m \e[32m${SUBOBJS}\e[0m" @ld -T metaverse.lds -Map=metaverse.map -unresolved-symbols=ignore-all -o $@ ${SUBOBJS} ${RUST_LIBS} \ - 2>&1 | "${SOURCE}/colorize" "warning:=yellow" "error:=red" "ld=lyellow" + 2>&1 | "${SOURCE}/colorize" "warning:=lpink" "error:=red" "ld=lyellow" -.PHONY: kernel libk all clear postproc rust +.PHONY: kernel libk all clear postproc rust rustlib all: postproc metaverse.elf @echo -e "Build \e[1;32msucceeded\e[0m." @@ -92,7 +96,10 @@ libk: echo -e "\e[33m-------------------------\e[0m"; \ fi -rust: postproc +../target: + @-cargo xbuild --target ${TARGET_TRIPLE} --release + +rust: postproc ../target @echo -e "\e[1m\e[33mrustc\e[0m \e[34m-->\e[0m \e[1m\e[32m$@.o\e[0m" @rustc ${RSCFLAGS} lib.rs -o rust.o diff --git a/src/kernel/main.rs b/src/kernel/main.rs index 4bb1227..2be7822 100644 --- a/src/kernel/main.rs +++ b/src/kernel/main.rs @@ -1,22 +1,13 @@ -use crate::message; - -use super::{ - klog::{KernelLogger, LoggerLevel}, - tty::tty::{BuilderFunctions::*, Color, Tty}, +use crate::{ + kernel::{ + klog::{KernelLogger, LoggerLevel}, + tty::tty::Tty, + }, + message_raw, }; #[no_mangle] extern "C" fn kmain_rust() -> ! { let tty = Tty::from_id(0).unwrap(); - let mut logger = KernelLogger::new(); - logger.info(message!( - Msg("Hello, "), - Msg("Metaverse"), - FgColor(Color::GREEN), - Msg("!\n") - )); - for msg in logger.iter(LoggerLevel::Info) { - tty.print(msg); - } loop {} } diff --git a/src/kernel/memm/memm.rs b/src/kernel/memm/memm.rs index fea17bf..8c5e045 100644 --- a/src/kernel/memm/memm.rs +++ b/src/kernel/memm/memm.rs @@ -6,9 +6,9 @@ use core::{ }; extern "C" { - pub fn memm_kernel_allocate(size: usize) -> *mut u8; + fn memm_kernel_allocate(size: usize) -> *mut u8; // pub fn memm_user_allocate(size: usize, pid: usize); - pub fn memm_free(mem: *mut u8); + fn memm_free(mem: *mut u8); } pub struct KernelAllocator {} @@ -31,4 +31,4 @@ unsafe impl GlobalAlloc for KernelAllocator { } #[global_allocator] -static KERNEL_ALLOCATOR: KernelAllocator = KernelAllocator {}; +pub static KERNEL_ALLOCATOR: KernelAllocator = KernelAllocator {}; diff --git a/src/kernel/memm/mod.rs b/src/kernel/memm/mod.rs index e2c5491..1954ffa 100644 --- a/src/kernel/memm/mod.rs +++ b/src/kernel/memm/mod.rs @@ -1 +1 @@ -mod memm; +pub mod memm; diff --git a/src/kernel/tty/mod.rs b/src/kernel/tty/mod.rs index ed058fa..cebad05 100644 --- a/src/kernel/tty/mod.rs +++ b/src/kernel/tty/mod.rs @@ -25,22 +25,43 @@ macro_rules! message_bgc { } #[macro_export] -macro_rules! message { +macro_rules! message_raw { ( $( $e : expr ),* ) => {{ use crate::{ - kernel::tty::tty::{MessageBuilder, BuilderFunctions}, + kernel::tty::tty::{MessageBuilder, BuilderFunctions::*, Color}, message_msg, message_fgc, message_bgc }; let mut tmp_builder = MessageBuilder::new(); $( - if let BuilderFunctions::Msg(e) = $e { - message_msg!(tmp_builder, e); - } else if let BuilderFunctions::FgColor(c) = $e { + if let Msg(e) = $e { + message_msg!(tmp_builder, &e); + } else if let FgColor(c) = $e { message_fgc!(tmp_builder, c); - } else if let BuilderFunctions::BgColor(c) = $e { + } else if let BgColor(c) = $e { message_bgc!(tmp_builder, c); } )* tmp_builder.build() }}; } + +#[macro_export] +macro_rules! message { + ( $fmtter : expr, $( $e : expr ),* ) => {{ + use crate::{ + kernel::tty::tty::{ + MessageBuilder, + FmtMeta, + Color, + format_message + }, + libk::alloc::vec::Vec, + }; + let mut formatter = $fmtter.chars().collect::>(); + let builder = MessageBuilder::new(); + $( + let builder = builder.append(format_message(&mut formatter, $e)); + )* + builder.build() + }}; +} diff --git a/src/kernel/tty/tty.rs b/src/kernel/tty/tty.rs index 248f6bf..875b222 100644 --- a/src/kernel/tty/tty.rs +++ b/src/kernel/tty/tty.rs @@ -233,8 +233,8 @@ pub struct MessageBuilder { msg: Message, } -pub enum BuilderFunctions<'a> { - Msg(&'a str), +pub enum BuilderFunctions { + Msg(T), FgColor(Color), BgColor(Color), } diff --git a/src/lib.rs b/src/lib.rs index 6872093..642c3f5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ #![no_std] #![feature(strict_provenance)] +#![feature(layout_for_ptr)] extern crate alloc; diff --git a/src/libk/alloc/alloc.rs b/src/libk/alloc/alloc.rs new file mode 100644 index 0000000..ca2ea72 --- /dev/null +++ b/src/libk/alloc/alloc.rs @@ -0,0 +1,11 @@ +use core::alloc::{GlobalAlloc, Layout}; + +use crate::kernel::memm::memm::KERNEL_ALLOCATOR; + +pub unsafe fn alloc(layout: Layout) -> *mut u8 { + KERNEL_ALLOCATOR.alloc(layout) +} + +pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) { + KERNEL_ALLOCATOR.dealloc(ptr, layout); +} diff --git a/src/libk/alloc/boxed.rs b/src/libk/alloc/boxed.rs index c8d448b..baff88d 100644 --- a/src/libk/alloc/boxed.rs +++ b/src/libk/alloc/boxed.rs @@ -5,7 +5,7 @@ use core::{ ptr::addr_of, }; -use alloc::alloc::alloc; +use crate::libk::alloc::alloc::{alloc, dealloc}; pub struct Box { inner: *mut T, @@ -36,3 +36,14 @@ impl DerefMut for Box { unsafe { self.inner.as_mut().unwrap() } } } + +impl Drop for Box { + fn drop(&mut self) { + unsafe { + dealloc( + self.inner.cast(), + Layout::for_value_raw(self.inner.cast_const()), + ) + } + } +} diff --git a/src/libk/alloc/mod.rs b/src/libk/alloc/mod.rs index 2efd480..3acd932 100644 --- a/src/libk/alloc/mod.rs +++ b/src/libk/alloc/mod.rs @@ -1,3 +1,4 @@ +pub mod alloc; pub mod boxed; pub mod string; pub mod vec; diff --git a/src/libk/alloc/string.rs b/src/libk/alloc/string.rs index d365f27..c106e0c 100644 --- a/src/libk/alloc/string.rs +++ b/src/libk/alloc/string.rs @@ -31,6 +31,11 @@ impl String { 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); + } } impl FromIterator for String { @@ -72,6 +77,12 @@ impl AddAssign for String { pub trait ToString { fn to_string(&self) -> String; + fn to_octal_string(&self) -> String { + String::new() + } + fn to_hex_string(&self) -> String { + String::new() + } } impl ToString for str { @@ -79,3 +90,201 @@ impl ToString for str { String::from_iter(self.chars()) } } + +impl ToString for &'static str { + fn to_string(&self) -> String { + (*self).to_string() + } +} + +impl ToString for u8 { + fn to_string(&self) -> String { + let mut num = *self; + let mut res = String::new(); + while num != 0 { + res.insert(0, ((num % 10) as u8 + b'0') as char); + num /= 10; + } + res + } + + fn to_octal_string(&self) -> String { + let mut num = *self; + let mut res = String::new(); + while num != 0 { + res.insert(0, ((num % 8) as u8 + b'0') as char); + num /= 8; + } + res + } + + fn to_hex_string(&self) -> String { + let tohex = |x| { + if x < 10 { + x as u8 + b'0' + } else { + x as u8 - 10 + b'a' + } + }; + let mut num = *self; + let mut res = String::new(); + while num != 0 { + res.insert(0, (tohex(num % 16) + b'0') as char); + num /= 16; + } + res + } +} + +impl ToString for u16 { + fn to_string(&self) -> String { + let mut num = *self; + let mut res = String::new(); + while num != 0 { + res.insert(0, ((num % 10) as u8 + b'0') as char); + num /= 10; + } + res + } + + fn to_octal_string(&self) -> String { + let mut num = *self; + let mut res = String::new(); + while num != 0 { + res.insert(0, ((num % 8) as u8 + b'0') as char); + num /= 8; + } + res + } + + fn to_hex_string(&self) -> String { + let tohex = |x| { + if x < 10 { + x as u8 + b'0' + } else { + x as u8 - 10 + b'a' + } + }; + let mut num = *self; + let mut res = String::new(); + while num != 0 { + res.insert(0, (tohex(num % 16) + b'0') as char); + num /= 16; + } + res + } +} +impl ToString for u32 { + fn to_string(&self) -> String { + let mut num = *self; + let mut res = String::new(); + while num != 0 { + res.insert(0, ((num % 10) as u8 + b'0') as char); + num /= 10; + } + res + } + + fn to_octal_string(&self) -> String { + let mut num = *self; + let mut res = String::new(); + while num != 0 { + res.insert(0, ((num % 8) as u8 + b'0') as char); + num /= 8; + } + res + } + + fn to_hex_string(&self) -> String { + let tohex = |x| { + if x < 10 { + x as u8 + b'0' + } else { + x as u8 - 10 + b'a' + } + }; + let mut num = *self; + let mut res = String::new(); + while num != 0 { + res.insert(0, (tohex(num % 16) + b'0') as char); + num /= 16; + } + res + } +} +impl ToString for u64 { + fn to_string(&self) -> String { + let mut num = *self; + let mut res = String::new(); + while num != 0 { + res.insert(0, ((num % 10) as u8 + b'0') as char); + num /= 10; + } + res + } + + fn to_octal_string(&self) -> String { + let mut num = *self; + let mut res = String::new(); + while num != 0 { + res.insert(0, ((num % 8) as u8 + b'0') as char); + num /= 8; + } + res + } + + fn to_hex_string(&self) -> String { + let tohex = |x| { + if x < 10 { + x as u8 + b'0' + } else { + x as u8 - 10 + b'a' + } + }; + let mut num = *self; + let mut res = String::new(); + while num != 0 { + res.insert(0, (tohex(num % 16) + b'0') as char); + num /= 16; + } + res + } +} +impl ToString for u128 { + fn to_string(&self) -> String { + let mut num = *self; + let mut res = String::new(); + while num != 0 { + res.insert(0, ((num % 10) as u8 + b'0') as char); + num /= 10; + } + res + } + + fn to_octal_string(&self) -> String { + let mut num = *self; + let mut res = String::new(); + while num != 0 { + res.insert(0, ((num % 8) as u8 + b'0') as char); + num /= 8; + } + res + } + + fn to_hex_string(&self) -> String { + let tohex = |x| { + if x < 10 { + x as u8 + b'0' + } else { + x as u8 - 10 + b'a' + } + }; + let mut num = *self; + let mut res = String::new(); + while num != 0 { + res.insert(0, (tohex(num % 16) + b'0') as char); + num /= 16; + } + res + } +} diff --git a/src/libk/alloc/vec.rs b/src/libk/alloc/vec.rs index 1a65451..66df0b2 100644 --- a/src/libk/alloc/vec.rs +++ b/src/libk/alloc/vec.rs @@ -5,7 +5,7 @@ use core::{ slice, }; -use alloc::alloc::{alloc, dealloc}; +use crate::libk::alloc::alloc::{alloc, dealloc}; pub struct Vec { pointer: *mut T, @@ -205,7 +205,12 @@ impl IntoIterator for Vec { type IntoIter = VecIter; fn into_iter(self) -> Self::IntoIter { - todo!() + VecIter { + pointer: self.pointer, + index: 0, + length: self.length, + capacity: self.capacity, + } } }