From fa1a61f950cb59bd53ee5fab3090718cd19fed88 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Sat, 20 Jan 2024 23:50:03 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A0=E5=85=A5=E5=AE=8C=E6=95=B4=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E5=8C=96=E6=94=AF=E6=8C=81=E7=9A=84rust=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 +- Cargo.lock | 7 ++ Cargo.toml | 4 + README.md | 4 +- include/kernel/arch/x86_64/kernel.h | 2 + include/kernel/kernel.h | 2 + include/kernel/tty.h | 19 +++-- src/Makefile | 29 ++++++- src/kernel/Makefile | 19 +---- src/kernel/arch/x86_64/kernel.s | 21 +++++ src/kernel/main.c | 10 +-- src/kernel/main.rs | 14 ++++ src/kernel/memm/mod.rs | 4 +- src/kernel/mod.rs | 4 +- src/kernel/tty/mod.rs | 1 + src/kernel/tty/tty.c | 5 ++ src/kernel/tty/tty.rs | 117 ++++++++++++++++++++++++++++ src/lib.rs | 2 + src/libk/Makefile | 17 +--- test/Makefile | 2 +- 20 files changed, 230 insertions(+), 57 deletions(-) create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/kernel/arch/x86_64/kernel.s create mode 100644 src/kernel/main.rs create mode 100644 src/kernel/tty/mod.rs create mode 100644 src/kernel/tty/tty.rs diff --git a/.gitignore b/.gitignore index 0797d65..d907548 100644 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,7 @@ *.elf metaverse_kernel kerndisass.txt -orgprof +/orgprof /build +/target +/sources diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..ade8ad8 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "metaverse" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..cef59e4 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "metaverse" +version = "0.1.0" +edition = "2021" diff --git a/README.md b/README.md index 5fbad58..42c9a2b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -# Metaverse内核 +# Metaverse + +![logo](https://avatars.githubusercontent.com/u/156706034?s=400&u=d971c0c8990c8c49ff4863e2366ecbebc00cf9ae&v=4) 基于multiboot2引导的64位内核。 diff --git a/include/kernel/arch/x86_64/kernel.h b/include/kernel/arch/x86_64/kernel.h index 450c290..65462a5 100644 --- a/include/kernel/arch/x86_64/kernel.h +++ b/include/kernel/arch/x86_64/kernel.h @@ -3,5 +3,7 @@ #include +// 具有返回值是为了留出一个寄存器用于调整栈顶 +extern usize prepare_stack(); #endif diff --git a/include/kernel/kernel.h b/include/kernel/kernel.h index b3c645c..7d84b16 100644 --- a/include/kernel/kernel.h +++ b/include/kernel/kernel.h @@ -24,6 +24,8 @@ } #define simple_lock_unlock(lock) (lock) = false; +extern void kmain_rust(); + extern void *kend; // 内核结束的标记 #endif diff --git a/include/kernel/tty.h b/include/kernel/tty.h index d68689f..6079eeb 100644 --- a/include/kernel/tty.h +++ b/include/kernel/tty.h @@ -6,13 +6,13 @@ typedef enum __tty_type { - invalid, + invalid = 0, // 用于在内核刚刚被引导,只有bootloader提供的显示功能时使用 - tty_type_raw_framebuffer, + tty_type_raw_framebuffer = 1, // 用于图形功能初始化后,直接连接图形接口 - tty_type_display, + tty_type_display = 2, // 用于图形终端的终端模拟器 - tty_type_vtty, + tty_type_vtty = 3, } tty_type; typedef enum __framebuffer_pixel_type @@ -40,8 +40,8 @@ typedef struct __framebuffer framebuffer; // 文本模式中的字符由tty模块渲染 typedef enum __tty_mode { - tty_mode_text, - tty_mode_graphics, + tty_mode_text = 0, + tty_mode_graphics = 1, } tty_mode; typedef struct __tty_text_state @@ -93,6 +93,13 @@ tty *tty_new(tty_type type, tty_mode mode); */ tty **tty_get(usize id); +/** + * @brief 获取tty的id + * + * @return usize + */ +usize tty_get_id(tty *__tty); + /** * @brief 当type为raw_framebuffer时设置帧缓冲区 * diff --git a/src/Makefile b/src/Makefile index e938645..d300cdd 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,3 +1,5 @@ +.SUFFIXES: + ARCH := $(shell uname -m) PWD := $(shell pwd) SOURCE := ${PWD}/scripts @@ -10,13 +12,27 @@ ifdef release release = 1 endif -SUBOBJS = kernel/kernel.o libk/libk.o +SUBOBJS = kernel/kernel.o libk/libk.o rust.o DEFINES = ARCH="${ARCH}" ASM="${ASM}" ASMFLAGS="${ASMFLAGS}" SOURCE="${SOURCE}" PWD="${PWD}" ifdef release DEFINES := ${DEFINES} release=1 endif +################################ +# rust语言环境变量 + +RSCFLAGS = --emit obj --crate-type lib \ + -L crate="${PWD}/../rustlib/${ARCH}/src/" \ + -C code-model=large \ + -C relocation-model=static \ + -C embed-bitcode=no \ + -C opt-level=z + +ifeq (${ARCH},x86_64) + RSCFLAGS := ${RSCFLAGS} -C target-feature=-sse,-avx +endif + RUSTLIB_PATH = ../rustlib/${ARCH}/lib RUST_LIBS = "${RUSTLIB_PATH}/libaddr2line.rlib" "${RUSTLIB_PATH}/libadler.rlib" \ "${RUSTLIB_PATH}/liballoc.rlib" "${RUSTLIB_PATH}/libcfg_if.rlib" "${RUSTLIB_PATH}/libcompiler_builtins.rlib" \ @@ -29,12 +45,14 @@ RUST_LIBS = "${RUSTLIB_PATH}/libaddr2line.rlib" "${RUSTLIB_PATH}/libadler.rlib" "${RUSTLIB_PATH}/libstd_detect.rlib" "${RUSTLIB_PATH}/libstd.rlib" "${RUSTLIB_PATH}/libsysroot.rlib" \ "${RUSTLIB_PATH}/libtest.rlib" "${RUSTLIB_PATH}/libunicode_width.rlib" "${RUSTLIB_PATH}/libunwind.rlib" -metaverse.elf: kernel libk metaverse.lds +################################ + +metaverse.elf: kernel libk rust metaverse.lds @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" -.PHONY: kernel libk all clear postproc +.PHONY: kernel libk all clear postproc rust all: postproc metaverse.elf @@ -57,7 +75,10 @@ libk: @make -C libk all --no-print-directory ${DEFINES} @echo -e "\e[33m-------------------------\e[0m" +rust: + @rustc ${RSCFLAGS} lib.rs -o rust.o + clear: @make -C kernel clear --no-print-directory ${DEFINES} @make -C libk clear --no-print-directory ${DEFINES} - @-rm metaverse.elf metaverse.map + @-rm metaverse.elf metaverse.map rust.o diff --git a/src/kernel/Makefile b/src/kernel/Makefile index b00ac2d..8a1f78a 100644 --- a/src/kernel/Makefile +++ b/src/kernel/Makefile @@ -16,17 +16,6 @@ C_OBJS = ${C_SRCS:.c=.c.o} ################################ -################################ -# rust语音环境变量 - -RSCFLAGS = --emit obj --crate-type lib \ - -L crate="${PWD}/../rustlib/${ARCH}/src/" - -RS_SRCS = klog.rs memm.rs -RS_OBJS = ${RS_SRCS:.rs=.rs.o} - -################################ - ################################ # 汇编语言环境变量 @@ -37,12 +26,12 @@ endif ASMFLAGS := ${ASMFLAGS} ASMFLAGS32 = -f elf32 -S_SRCS = entry32.s entry.s memm_${ARCH}.s +S_SRCS = entry32.s entry.s memm_${ARCH}.s kernel.s S_OBJS = ${S_SRCS:.s=.s.o} ################################ -OBJS = ${S_OBJS} ${C_OBJS} ${RS_OBJS} +OBJS = ${S_OBJS} ${C_OBJS} STRIP_SECS = -R .note.GNU-stack @@ -55,10 +44,6 @@ VPATH = memm/ memm/allocator tty/ klog/ arch/${ARCH} @echo -e "\e[1m\e[33m${CC}\e[0m \e[32m$<\e[0m \e[34m-->\e[0m \e[1m\e[32m$@\e[0m" @${CC} -c ${CCFLAGS} $< -o $@ -%.rs.o: %.rs - @echo -e "\e[1m\e[33mrustc\e[0m \e[32m$<\e[0m \e[34m-->\e[0m \e[1m\e[32m$@\e[0m" - @rustc ${RSCFLAGS} $< -o $@ - %32.s.o: arch/${ARCH}/%32.s @echo -e "\e[1m\e[33m${ASM}\e[0m \e[32m$<\e[0m \e[34m-->\e[0m \e[1m\e[32m$@\e[0m" @${ASM} ${ASMFLAGS32} -o $@ $< 2>&1 \ diff --git a/src/kernel/arch/x86_64/kernel.s b/src/kernel/arch/x86_64/kernel.s new file mode 100644 index 0000000..ddb5b2b --- /dev/null +++ b/src/kernel/arch/x86_64/kernel.s @@ -0,0 +1,21 @@ + section .text + global prepare_stack +prepare_stack: + push rdx + push rbx + + mov rax, rsp + add rax, 16 + xor rdx, rdx + mov rbx, 16 + div rbx + mov rax, rdx + + pop rbx + pop rdx + sub rsp, rax + add rax, rsp + sub rsp, 16 + mov rax, [rax] + mov [rsp], rax + ret diff --git a/src/kernel/main.c b/src/kernel/main.c index aa211a2..70f8871 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -37,19 +37,15 @@ void kmain(void *mb2_bootinfo) // 初始化tty模块 tty_controller_t *tty_controler = tty_controller_new(); - framebuffer fb; get_frame_buffer_with_bootinfo(&fb, &bootinfo); tty *tty0 = tty_new(tty_type_raw_framebuffer, tty_mode_text); tty_set_framebuffer(tty0, &fb); - tty_text_print(tty0, "Hello ", gen_color(0xee, 0xee, 0xee), gen_color(0, 0, 0)); - tty_text_print(tty0, "Metaverse", gen_color(0x0a, 0xee, 0x0a), gen_color(0, 0, 0)); - tty_text_print(tty0, "!\n", gen_color(0xee, 0xee, 0xee), gen_color(0, 0, 0)); + // 为rust准备正确对齐的栈 + prepare_stack(); - while (true) - { - } + kmain_rust(); } void get_frame_buffer_with_bootinfo(framebuffer *fb, bootinfo_t *bootinfo) diff --git a/src/kernel/main.rs b/src/kernel/main.rs new file mode 100644 index 0000000..4c90f07 --- /dev/null +++ b/src/kernel/main.rs @@ -0,0 +1,14 @@ +use crate::kernel::tty::tty::{Color, MessageBuilder, Tty}; + +#[no_mangle] +extern "C" fn kmain_rust() { + let hello = MessageBuilder::new() + .message("Hello, ".to_string()) + .message("Metaverse".to_string()) + .foreground_color(Color(0xa, 0xee, 0xa)) + .message("!\n".to_string()) + .build(); + let tty = Tty::from_id(0).unwrap(); + tty.print(hello); + loop {} +} diff --git a/src/kernel/memm/mod.rs b/src/kernel/memm/mod.rs index e8e3ff8..e2c5491 100644 --- a/src/kernel/memm/mod.rs +++ b/src/kernel/memm/mod.rs @@ -1,3 +1 @@ -pub mod memm; - - +mod memm; diff --git a/src/kernel/mod.rs b/src/kernel/mod.rs index 4361596..14f7bad 100644 --- a/src/kernel/mod.rs +++ b/src/kernel/mod.rs @@ -1 +1,3 @@ -pub mod memm; \ No newline at end of file +pub mod memm; +pub mod tty; +pub mod main; diff --git a/src/kernel/tty/mod.rs b/src/kernel/tty/mod.rs new file mode 100644 index 0000000..cd8fd47 --- /dev/null +++ b/src/kernel/tty/mod.rs @@ -0,0 +1 @@ +pub mod tty; diff --git a/src/kernel/tty/tty.c b/src/kernel/tty/tty.c index 86a1b46..b7c5b36 100644 --- a/src/kernel/tty/tty.c +++ b/src/kernel/tty/tty.c @@ -41,6 +41,11 @@ tty **tty_get(usize id) return &tty_ctrler.ttys[id]; } +usize tty_get_id(tty *__tty) +{ + return __tty->id; +} + void tty_set_framebuffer(tty *ttyx, framebuffer *fb) { if (ttyx->type != tty_type_raw_framebuffer) diff --git a/src/kernel/tty/tty.rs b/src/kernel/tty/tty.rs new file mode 100644 index 0000000..76d9982 --- /dev/null +++ b/src/kernel/tty/tty.rs @@ -0,0 +1,117 @@ +use std::ptr::null_mut; + +extern "C" { + fn tty_new(tty_type: u8, mode: u8) -> *mut u8; + fn tty_get(id: usize) -> *mut *mut u8; + fn tty_text_print(ttyx: *mut u8, string: *mut u8, color: u32, bgcolor: u32); + fn tty_get_id(tty: *mut u8) -> usize; +} + +pub enum Type { + Invalid = 0, + RawFramebuffer = 1, + Display = 2, + VirtualTty = 3, +} + +pub enum Mode { + Text = 0, + Graphics = 1, +} + +pub struct Tty { + tty_pointer: *mut u8, +} + +impl Tty { + pub fn new(tty_type: Type, tty_mode: Mode) -> Self { + let tty = unsafe { tty_new(tty_type as u8, tty_mode as u8) }; + Self { tty_pointer: tty } + } + + pub fn from_id(id: usize) -> Option { + let tty = unsafe { tty_get(id) }; + if tty == null_mut() { + None + } else { + let tty = unsafe { *tty }; + Some(Self { tty_pointer: tty }) + } + } + + pub fn id(&self) -> usize { + unsafe { tty_get_id(self.tty_pointer) } + } + + pub fn print(&self, msg: Message) { + for MessageSection { + mut msg, + fgcolor, + bgcolor, + } in msg.into_iter() + { + unsafe { + tty_text_print( + self.tty_pointer, + msg.as_bytes_mut() as *mut [u8] as *mut u8, + u32::from(fgcolor), + u32::from(bgcolor), + ) + }; + } + } +} + +pub struct Color(pub u8, pub u8, pub u8); + +impl From for u32 { + fn from(value: Color) -> Self { + let res = (value.0 as u32) << 16 | (value.1 as u32) << 8 | (value.2 as u32); + res + } +} + +pub struct MessageSection { + msg: String, + fgcolor: Color, + bgcolor: Color, +} + +type Message = Vec; + +pub struct MessageBuilder { + msg: Message, +} + +impl MessageBuilder { + pub fn new() -> Self { + Self { msg: vec![] } + } + + pub fn message(mut self, msg: String) -> Self { + self.msg.push(MessageSection { + msg, + fgcolor: Color(0xee, 0xee, 0xee), + bgcolor: Color(0, 0, 0), + }); + self + } + + pub fn background_color(mut self, color: Color) -> Self { + if let Some(msg) = self.msg.last_mut() { + msg.bgcolor = color; + } + self + } + + pub fn foreground_color(mut self, color: Color) -> Self { + if let Some(msg) = self.msg.last_mut() { + msg.fgcolor = color; + } + self + } + + pub fn build(self) -> Message { + self.msg + } +} diff --git a/src/lib.rs b/src/lib.rs index e08d1f9..be290dc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,4 @@ +extern crate core; + pub mod kernel; pub mod libk; diff --git a/src/libk/Makefile b/src/libk/Makefile index e5a5601..6f49226 100644 --- a/src/libk/Makefile +++ b/src/libk/Makefile @@ -16,17 +16,6 @@ C_OBJS = ${C_SRCS:.c=.c.o} ################################ -################################ -# rust语音环境变量 - -RSCFLAGS = --emit obj --crate-type lib \ - -L crate="~/.rustup/toolchains/stable-${ARCH}-unknown-linux-gnu/lib/rustlib/src/rust/library/" - -RS_SRCS = -RS_OBJS = ${RS_SRCS:.rs=.rs.o} - -################################ - ################################ # 汇编语言环境变量 @@ -41,7 +30,7 @@ S_OBJS = ${S_SRCS:.s=.s.o} ################################ -OBJS = ${S_OBJS} ${C_OBJS} ${RS_OBJS} +OBJS = ${S_OBJS} ${C_OBJS} STRIP_SECS = -R .note.GNU-stack @@ -54,10 +43,6 @@ VPATH = multiboot2/ string/ @echo -e "\e[1m\e[33m${CC}\e[0m \e[32m$<\e[0m \e[34m-->\e[0m \e[1m\e[32m$@\e[0m" @${CC} -c ${CCFLAGS} $< -o $@ -%.rs.o: %.rs - @echo -e "\e[1m\e[33mrustc\e[0m \e[32m$<\e[0m \e[34m-->\e[0m \e[1m\e[32m$@\e[0m" - @rustc ${RSCFLAGS} $< -o $@ - %.s.o: arch/${ARCH}/%.s @echo -e "\e[1m\e[33m${ASM}\e[0m \e[32m$<\e[0m \e[34m-->\e[0m \e[1m\e[32m$@\e[0m" @${ASM} ${ASMFLAGS} -o $@ $< 2>&1 | "${SOURCE}/colorize" "warning:=pink" "error:=red" diff --git a/test/Makefile b/test/Makefile index 0b51200..22df149 100644 --- a/test/Makefile +++ b/test/Makefile @@ -8,7 +8,7 @@ BIOS = bios/${ARCH}/OVMF_CODE.fd run: @doas modprobe nbd @make load - @qemu-system-${ARCH} -m 4G metaverse.img -bios ${BIOS} + @qemu-system-${ARCH} -accel kvm -m 4G metaverse.img -bios ${BIOS} debug: @echo "在gdb中连接远程目标'localhost:1234'即可"