mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 14:16:47 +00:00
port kmalloc and printk to rust (#83)
* 暂时移除cbindgen * 将lib文件夹更名为libs文件夹(解决rust的冲突) * 实现了全局的allocator * 实现了printk宏 * new: 完善了printk的颜色
This commit is contained in:
parent
82d2e446a4
commit
fb6c29d01d
@ -2,7 +2,7 @@
|
||||
target = "src/arch/x86_64/x86_64-unknown-none.json"
|
||||
|
||||
[unstable]
|
||||
build-std = ["core", "compiler_builtins"]
|
||||
build-std = ["core", "compiler_builtins", "alloc"]
|
||||
build-std-features = ["compiler-builtins-mem"]
|
||||
|
||||
[target.'cfg(target_os = "none")']
|
||||
|
@ -11,7 +11,7 @@ fn main() {
|
||||
println!("cargo:rustc-link-search=src");
|
||||
println!("cargo:rerun-if-changed=src/include/bindings/wrapper.h");
|
||||
|
||||
let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||
// let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||
let out_path = PathBuf::from(String::from("src/include/bindings/"));
|
||||
|
||||
// The bindgen::Builder is the main entry point
|
||||
|
@ -3,7 +3,7 @@ DIRS := . $(shell find $(SUBDIR_ROOTS) -type d)
|
||||
GARBAGE_PATTERNS := *.o *.s~ *.s *.S~ *.c~ *.h~ kernel
|
||||
GARBAGE := $(foreach DIR,$(DIRS),$(addprefix $(DIR)/,$(GARBAGE_PATTERNS)))
|
||||
|
||||
DIR_LIB=lib
|
||||
DIR_LIB=libs
|
||||
lib_patterns := *.a
|
||||
LIB_FILES := $(foreach DIR,$(DIR_LIB),$(addprefix $(DIR)/,$(lib_patterns)))
|
||||
|
||||
@ -17,7 +17,7 @@ export ASFLAGS := --64
|
||||
LD_LIST := head.o
|
||||
|
||||
|
||||
kernel_subdirs := common driver process debug filesystem time arch exception mm smp sched syscall ktest lib ipc
|
||||
kernel_subdirs := common driver process debug filesystem time arch exception mm smp sched syscall ktest libs ipc
|
||||
|
||||
|
||||
|
||||
@ -34,8 +34,9 @@ main.o: main.c
|
||||
kernel_rust:
|
||||
rustup default nightly
|
||||
cargo +nightly build --release --target ./arch/x86_64/x86_64-unknown-none.json
|
||||
all: kernel_rust
|
||||
$(MAKE) kernel || exit 1
|
||||
|
||||
all: kernel
|
||||
|
||||
@echo "Linking kernel..."
|
||||
ld -b elf64-x86-64 -z muldefs -o kernel head.o main.o $(shell find . -name "*.o") ../target/x86_64-unknown-none/release/libdragonos_kernel.a -T link.lds
|
||||
# 生成kallsyms
|
||||
@ -53,6 +54,7 @@ all: kernel_rust
|
||||
|
||||
# 重新链接
|
||||
@echo "Re-Linking kernel..."
|
||||
@echo $(shell find . -name "*.o")
|
||||
ld -b elf64-x86-64 -z muldefs -o kernel head.o main.o $(shell find . -name "*.o") ../target/x86_64-unknown-none/release/libdragonos_kernel.a ./debug/kallsyms.o -T link.lds
|
||||
@echo "Generating kernel ELF file..."
|
||||
# 生成内核文件
|
||||
@ -66,7 +68,7 @@ $(kernel_subdirs): ECHO
|
||||
|
||||
$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" PIC="$(PIC)" kernel_root_path="$(shell pwd)"
|
||||
|
||||
kernel: head.o main.o $(kernel_subdirs)
|
||||
kernel: head.o main.o $(kernel_subdirs) kernel_rust
|
||||
|
||||
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
#include "font.h"
|
||||
#include "glib.h"
|
||||
#include <lib/libUI/screen_manager.h>
|
||||
#include <libs/libUI/screen_manager.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
extern unsigned char font_ascii[256][16]; //导出ascii字体的bitmap(8*16大小) ps:位于font.h中
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include <common/glib.h>
|
||||
#include <stdbool.h>
|
||||
#include <lib/libUI/screen_manager.h>
|
||||
#include <libs/libUI/screen_manager.h>
|
||||
|
||||
/**
|
||||
* @brief 重新初始化显示驱动,需先低级初始化才能高级初始化
|
||||
|
@ -15,12 +15,14 @@
|
||||
#include <common/crc64.h>
|
||||
#include <common/crc7.h>
|
||||
#include <common/crc8.h>
|
||||
#include <common/gfp.h>
|
||||
#include <common/kfifo.h>
|
||||
#include <common/list.h>
|
||||
#include <common/lz4.h>
|
||||
#include <common/printk.h>
|
||||
#include <common/spinlock.h>
|
||||
#include <common/unistd.h>
|
||||
#include <driver/uart/uart.h>
|
||||
#include <mm/mm.h>
|
||||
#include <mm/slab.h>
|
||||
#include <sched/cfs.h>
|
||||
|
5
kernel/src/include/gfp.rs
Normal file
5
kernel/src/include/gfp.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use crate::include::bindings::bindings::gfp_t;
|
||||
|
||||
#[allow(unused_parens)]
|
||||
/// 定义__GFP_ZERO
|
||||
pub const __GFP_ZERO: gfp_t = (1 << 0);
|
@ -1 +1,4 @@
|
||||
pub mod bindings;
|
||||
pub mod bindings;
|
||||
pub mod gfp;
|
||||
pub mod printk;
|
||||
|
||||
|
45
kernel/src/include/printk.rs
Normal file
45
kernel/src/include/printk.rs
Normal file
@ -0,0 +1,45 @@
|
||||
#![allow(unused)]
|
||||
// ====== 定义颜色 ======
|
||||
/// 白色
|
||||
pub const COLOR_WHITE: u32 = 0x00ffffff;
|
||||
/// 黑色
|
||||
pub const COLOR_BLACK: u32 = 0x00000000;
|
||||
/// 红色
|
||||
pub const COLOR_RED:u32 = 0x00ff0000;
|
||||
/// 橙色
|
||||
pub const COLOR_ORANGE:u32 = 0x00ff8000;
|
||||
/// 黄色
|
||||
pub const COLOR_YELLOW:u32 = 0x00ffff00;
|
||||
/// 绿色
|
||||
pub const COLOR_GREEN:u32 = 0x0000ff00;
|
||||
/// 蓝色
|
||||
pub const COLOR_BLUE:u32 = 0x000000ff;
|
||||
/// 靛色
|
||||
pub const COLOR_INDIGO:u32 = 0x0000ffff;
|
||||
/// 紫色
|
||||
pub const COLOR_PURPLE:u32 = 0x008000ff;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! print {
|
||||
($($arg:tt)*) => ($crate::libs::printk::__printk(format_args!($($arg)*)));
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! println {
|
||||
() => {
|
||||
$crate::print!("\n");
|
||||
};
|
||||
($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*)));
|
||||
}
|
||||
|
||||
/// 指定颜色,彩色输出
|
||||
/// @param FRcolor 前景色
|
||||
/// @param BKcolor 背景色
|
||||
#[macro_export]
|
||||
macro_rules! printk_color {
|
||||
|
||||
($FRcolor:expr, $BKcolor:expr, $($arg:tt)*) => {
|
||||
use alloc;
|
||||
$crate::libs::printk::PrintkWriter.__write_string_color($FRcolor, $BKcolor, alloc::fmt::format(format_args!($($arg)*)).as_str())
|
||||
};
|
||||
}
|
@ -1,32 +1,44 @@
|
||||
#![no_std] // <1>
|
||||
#![no_main] // <1>
|
||||
#![feature(core_intrinsics)] // <2>
|
||||
#![no_std] // <1>
|
||||
#![no_main] // <1>
|
||||
#![feature(core_intrinsics)] // <2>
|
||||
#![feature(alloc_error_handler)]
|
||||
|
||||
#[allow(non_upper_case_globals)]
|
||||
#[allow(non_camel_case_types)]
|
||||
#[allow(non_snake_case)]
|
||||
|
||||
use core::intrinsics; // <2>
|
||||
use core::panic::PanicInfo;
|
||||
|
||||
|
||||
#[macro_use]
|
||||
mod mm;
|
||||
mod include;
|
||||
mod libs;
|
||||
|
||||
use crate::mm::allocator;
|
||||
use core::ffi::c_char;
|
||||
use core::intrinsics; // <2>
|
||||
use core::panic::PanicInfo; // <3>
|
||||
use crate::include::bindings::bindings::{printk_color, GREEN, BLACK};
|
||||
extern crate alloc;
|
||||
|
||||
use mm::allocator::KernelAllocator;
|
||||
|
||||
// <3>
|
||||
use crate::include::bindings::bindings::{BLACK, GREEN};
|
||||
|
||||
// 声明全局的slab分配器
|
||||
#[cfg_attr(not(test), global_allocator)]
|
||||
pub static KERNEL_ALLOCATOR: KernelAllocator = KernelAllocator {};
|
||||
|
||||
/// 全局的panic处理函数
|
||||
#[panic_handler]
|
||||
#[no_mangle]
|
||||
pub fn panic(_info: &PanicInfo) -> ! {
|
||||
intrinsics::abort(); // <4>
|
||||
intrinsics::abort(); // <4>
|
||||
}
|
||||
|
||||
/// 该函数用作测试,在process.c的initial_kernel_thread()中调用了此函数
|
||||
#[no_mangle]
|
||||
pub extern "C" fn __rust_demo_func() -> i32 {
|
||||
unsafe{
|
||||
let f = b"\nDragonOS's Rust lib called printk_color()\n".as_ptr() as *const c_char;
|
||||
printk_color(GREEN, BLACK, f);
|
||||
}
|
||||
return 0;
|
||||
|
||||
printk_color!(GREEN, BLACK, "__rust_demo_func()\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
1
kernel/src/libs/mod.rs
Normal file
1
kernel/src/libs/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod printk;
|
@ -5,7 +5,7 @@
|
||||
#include <common/printk.h>
|
||||
|
||||
#include <common/spinlock.h>
|
||||
#include <lib/libUI/textui.h>
|
||||
#include <libs/libUI/textui.h>
|
||||
#include <mm/mm.h>
|
||||
|
||||
#include <common/math.h>
|
54
kernel/src/libs/printk.rs
Normal file
54
kernel/src/libs/printk.rs
Normal file
@ -0,0 +1,54 @@
|
||||
use crate::include::bindings::bindings::{printk_color, BLACK, WHITE};
|
||||
use ::core::ffi::c_char;
|
||||
use alloc::vec::Vec;
|
||||
use core::fmt;
|
||||
pub struct PrintkWriter;
|
||||
|
||||
impl PrintkWriter {
|
||||
/// 调用C语言编写的printk_color,并输出白底黑字(暂时只支持ascii字符)
|
||||
/// @param str: 要写入的字符
|
||||
pub fn __write_string(&mut self, s: &str) {
|
||||
let str_to_print = self.__utf8_to_ascii(s);
|
||||
unsafe {
|
||||
printk_color(WHITE, BLACK, str_to_print.as_ptr() as *const c_char);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn __write_string_color(&self, fr_color: u32, bk_color: u32, s: &str) {
|
||||
let str_to_print = self.__utf8_to_ascii(s);
|
||||
unsafe {
|
||||
printk_color(fr_color, bk_color, str_to_print.as_ptr() as *const c_char);
|
||||
}
|
||||
}
|
||||
|
||||
/// 将s这个utf8字符串,转换为ascii字符串
|
||||
/// @param s 待转换的utf8字符串
|
||||
/// @return Vec<u8> 转换结束后的Ascii字符串
|
||||
pub fn __utf8_to_ascii(&self, s: &str) -> Vec<u8> {
|
||||
let mut ascii_str: Vec<u8> = Vec::with_capacity(s.len() + 1);
|
||||
for byte in s.bytes() {
|
||||
match byte {
|
||||
0..=127 => {
|
||||
ascii_str.push(byte);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
ascii_str.push(b'\0');
|
||||
return ascii_str;
|
||||
}
|
||||
}
|
||||
|
||||
/// 为Printk Writer实现core::fmt::Write, 使得能够借助Rust自带的格式化组件,格式化字符并输出
|
||||
impl fmt::Write for PrintkWriter {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
self.__write_string(s);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn __printk(args: fmt::Arguments) {
|
||||
use fmt::Write;
|
||||
PrintkWriter.write_fmt(args).unwrap();
|
||||
}
|
@ -47,6 +47,7 @@ SECTIONS
|
||||
{
|
||||
_rodata = .;
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
_erodata = .;
|
||||
}
|
||||
|
||||
@ -62,6 +63,7 @@ SECTIONS
|
||||
{
|
||||
_bss = .;
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
_ebss = .;
|
||||
}
|
||||
|
||||
|
@ -14,8 +14,8 @@
|
||||
#include "smp/smp.h"
|
||||
#include "syscall/syscall.h"
|
||||
#include <exception/softirq.h>
|
||||
#include <lib/libUI/screen_manager.h>
|
||||
#include <lib/libUI/textui.h>
|
||||
#include <libs/libUI/screen_manager.h>
|
||||
#include <libs/libUI/textui.h>
|
||||
#include <sched/sched.h>
|
||||
#include <smp/ipi.h>
|
||||
|
||||
@ -209,7 +209,7 @@ void Start_Kernel(void)
|
||||
// 如果调用的时候,启用了中断,则hlt。否则认为是bug
|
||||
if (get_rflags() & 0x200)
|
||||
{
|
||||
kdebug("hlt");
|
||||
// kdebug("hlt");
|
||||
hlt();
|
||||
}
|
||||
else
|
||||
|
@ -1,22 +1,55 @@
|
||||
use crate::include::bindings::bindings::{gfp_t, PAGE_2M_SIZE, kmalloc};
|
||||
use crate::include::bindings::bindings::{gfp_t, kfree, kmalloc, PAGE_2M_SIZE};
|
||||
use crate::include::gfp::__GFP_ZERO;
|
||||
|
||||
use core::alloc::{GlobalAlloc, Layout};
|
||||
|
||||
/// 类kmalloc的分配器应当实现的trait
|
||||
pub trait LocalAlloc {
|
||||
unsafe fn alloc(&mut self, layout: Layout, gfp: gfp_t) -> *mut u8;
|
||||
unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout);
|
||||
unsafe fn local_alloc(&self, layout: Layout, gfp: gfp_t) -> *mut u8;
|
||||
unsafe fn local_alloc_zeroed(&self, layout: Layout, gfp: gfp_t) -> *mut u8;
|
||||
unsafe fn local_dealloc(&self, ptr: *mut u8, layout: Layout);
|
||||
}
|
||||
|
||||
pub struct KernelAllocator {}
|
||||
|
||||
/// 为内核SLAB分配器实现LocalAlloc的trait
|
||||
impl LocalAlloc for KernelAllocator {
|
||||
unsafe fn alloc(&mut self, layout: Layout, gfp: gfp_t) -> *mut u8 {
|
||||
unsafe fn local_alloc(&self, layout: Layout, gfp: gfp_t) -> *mut u8 {
|
||||
if layout.size() > (PAGE_2M_SIZE as usize / 2) {
|
||||
return core::ptr::null_mut();
|
||||
}
|
||||
return kmalloc(layout.size() as u64, gfp) as *mut u8;
|
||||
}
|
||||
unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout){
|
||||
// todo:
|
||||
|
||||
unsafe fn local_alloc_zeroed(&self, layout: Layout, gfp: gfp_t) -> *mut u8 {
|
||||
if layout.size() > (PAGE_2M_SIZE as usize / 2) {
|
||||
return core::ptr::null_mut();
|
||||
}
|
||||
return kmalloc(layout.size() as u64, gfp | __GFP_ZERO) as *mut u8;
|
||||
}
|
||||
#[allow(unused_variables)]
|
||||
unsafe fn local_dealloc(&self, ptr: *mut u8, layout: Layout) {
|
||||
kfree(ptr as *mut ::core::ffi::c_void);
|
||||
}
|
||||
}
|
||||
|
||||
/// 为内核slab分配器实现GlobalAlloc特性
|
||||
unsafe impl GlobalAlloc for KernelAllocator {
|
||||
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
||||
self.local_alloc(layout, 0)
|
||||
}
|
||||
|
||||
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
|
||||
self.local_alloc_zeroed(layout, 0)
|
||||
}
|
||||
|
||||
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
|
||||
self.local_dealloc(ptr, layout);
|
||||
}
|
||||
}
|
||||
|
||||
/// 内存分配错误处理函数
|
||||
#[alloc_error_handler]
|
||||
pub fn global_alloc_err_handler(_layout: Layout) -> ! {
|
||||
panic!("global_alloc_error");
|
||||
}
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include <mm/mmio.h>
|
||||
|
||||
#include <common/lz4.h>
|
||||
|
||||
extern int __rust_demo_func();
|
||||
// #pragma GCC push_options
|
||||
// #pragma GCC optimize("O0")
|
||||
|
||||
@ -499,21 +499,21 @@ ul initial_kernel_thread(ul arg)
|
||||
// int usb_pid = kernel_thread(usb_init, 0, 0);
|
||||
|
||||
kinfo("LZ4 lib Version=%s", LZ4_versionString());
|
||||
|
||||
__rust_demo_func();
|
||||
// 对completion完成量进行测试
|
||||
__test_completion();
|
||||
// __test_completion();
|
||||
|
||||
// 对一些组件进行单元测试
|
||||
uint64_t tpid[] = {
|
||||
ktest_start(ktest_test_bitree, 0), ktest_start(ktest_test_kfifo, 0), ktest_start(ktest_test_mutex, 0),
|
||||
ktest_start(ktest_test_idr, 0),
|
||||
// usb_pid,
|
||||
};
|
||||
kinfo("Waiting test thread exit...");
|
||||
// 等待测试进程退出
|
||||
for (int i = 0; i < sizeof(tpid) / sizeof(uint64_t); ++i)
|
||||
waitpid(tpid[i], NULL, NULL);
|
||||
kinfo("All test done.");
|
||||
// // 对一些组件进行单元测试
|
||||
// uint64_t tpid[] = {
|
||||
// ktest_start(ktest_test_bitree, 0), ktest_start(ktest_test_kfifo, 0), ktest_start(ktest_test_mutex, 0),
|
||||
// ktest_start(ktest_test_idr, 0),
|
||||
// // usb_pid,
|
||||
// };
|
||||
// kinfo("Waiting test thread exit...");
|
||||
// // 等待测试进程退出
|
||||
// for (int i = 0; i < sizeof(tpid) / sizeof(uint64_t); ++i)
|
||||
// waitpid(tpid[i], NULL, NULL);
|
||||
// kinfo("All test done.");
|
||||
|
||||
// 准备切换到用户态
|
||||
struct pt_regs *regs;
|
||||
|
Loading…
x
Reference in New Issue
Block a user