diff --git a/src/gdt.rs b/src/gdt.rs index 84758ec..2807cc3 100644 --- a/src/gdt.rs +++ b/src/gdt.rs @@ -1,8 +1,8 @@ -use x86_64::VirtAddr; -use x86_64::structures::tss::TaskStateSegment; use lazy_static::lazy_static; -use x86_64::structures::gdt::{GlobalDescriptorTable, Descriptor}; use x86_64::structures::gdt::SegmentSelector; +use x86_64::structures::gdt::{Descriptor, GlobalDescriptorTable}; +use x86_64::structures::tss::TaskStateSegment; +use x86_64::VirtAddr; pub const DOUBLE_FAULT_IST_INDEX: u16 = 0; @@ -25,7 +25,13 @@ lazy_static! { let mut gdt = GlobalDescriptorTable::new(); let code_selector = gdt.add_entry(Descriptor::kernel_code_segment()); let tss_selector = gdt.add_entry(Descriptor::tss_segment(&TSS)); - (gdt, Selectors { code_selector, tss_selector }) + ( + gdt, + Selectors { + code_selector, + tss_selector, + }, + ) }; } diff --git a/src/interrupts.rs b/src/interrupts.rs index 652888c..66a8d53 100644 --- a/src/interrupts.rs +++ b/src/interrupts.rs @@ -1,23 +1,22 @@ -use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame, PageFaultErrorCode}; -use crate::{println, print}; -use lazy_static::lazy_static; use crate::gdt; +use crate::hlt_loop; +use crate::{print, println}; +use lazy_static::lazy_static; use pic8259::ChainedPics; use spin; -use crate::hlt_loop; +use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame, PageFaultErrorCode}; lazy_static! { static ref IDT: InterruptDescriptorTable = { let mut idt = InterruptDescriptorTable::new(); idt.breakpoint.set_handler_fn(breakpoint_handler); unsafe { - idt.double_fault.set_handler_fn(double_fault_handler) + idt.double_fault + .set_handler_fn(double_fault_handler) .set_stack_index(gdt::DOUBLE_FAULT_IST_INDEX); } - idt[InterruptIndex::Timer.as_usize()] - .set_handler_fn(timer_interrupt_handler); - idt[InterruptIndex::Keyboard.as_usize()] - .set_handler_fn(keyboard_interrupt_handler); + idt[InterruptIndex::Timer.as_usize()].set_handler_fn(timer_interrupt_handler); + idt[InterruptIndex::Keyboard.as_usize()].set_handler_fn(keyboard_interrupt_handler); idt.page_fault.set_handler_fn(page_fault_handler); idt }; @@ -31,7 +30,10 @@ extern "x86-interrupt" fn breakpoint_handler(stack_frame: InterruptStackFrame) { println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame); } -extern "x86-interrupt" fn double_fault_handler(stack_frame: InterruptStackFrame, _error_code: u64) -> ! { +extern "x86-interrupt" fn double_fault_handler( + stack_frame: InterruptStackFrame, + _error_code: u64, +) -> ! { panic!("EXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame); } @@ -70,8 +72,9 @@ extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStac use x86_64::instructions::port::Port; lazy_static! { - static ref KEYBOARD: Mutex> = - Mutex::new(Keyboard::new(layouts::Us104Key, ScancodeSet1, HandleControl::Ignore)); + static ref KEYBOARD: Mutex> = Mutex::new( + Keyboard::new(layouts::Us104Key, ScancodeSet1, HandleControl::Ignore) + ); } let mut keyboard = KEYBOARD.lock(); @@ -92,7 +95,10 @@ extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStac } } -extern "x86-interrupt" fn page_fault_handler(stack_frame: InterruptStackFrame, error_code: PageFaultErrorCode) { +extern "x86-interrupt" fn page_fault_handler( + stack_frame: InterruptStackFrame, + error_code: PageFaultErrorCode, +) { use x86_64::registers::control::Cr2; println!("EXCEPTION: PAGE FAULT"); println!("Accessed Address: {:?}", Cr2::read()); diff --git a/src/lib.rs b/src/lib.rs index 852eee4..bff9277 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,11 +6,11 @@ #![feature(abi_x86_interrupt)] use core::panic::PanicInfo; +pub mod gdt; +pub mod interrupts; +pub mod memory; pub mod serial; pub mod vga_buffer; -pub mod interrupts; -pub mod gdt; -pub mod memory; pub trait Testable { fn run(&self) -> (); @@ -21,9 +21,9 @@ where T: Fn(), { fn run(&self) { - serial_print!("{}...\t", core::any::type_name::()); // 打印函数名 - self(); // 执行这个函数。由于 T 具有 Fn() trait 所以它能够作为一个函数被直接调用 - serial_println!("[ok]"); // 打印 "[ok]" + serial_print!("{}...\t", core::any::type_name::()); // 打印函数名 + self(); // 执行这个函数。由于 T 具有 Fn() trait 所以它能够作为一个函数被直接调用 + serial_println!("[ok]"); // 打印 "[ok]" } } @@ -80,7 +80,7 @@ pub fn exit_qemu(exit_code: QemuExitCode) { use x86_64::instructions::port::Port; unsafe { - let mut port = Port::new(0xf4); // iobase port + let mut port = Port::new(0xf4); // iobase port port.write(exit_code as u32); } } diff --git a/src/main.rs b/src/main.rs index ceab20d..5e16bf0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,18 +1,18 @@ -#![no_std] // 不链接 Rust 标准库 -#![no_main] // 禁用 main 入口点,因为没有运行时 +#![no_std] // 不链接 Rust 标准库 +#![no_main] // 禁用 main 入口点,因为没有运行时 #![feature(custom_test_frameworks)] #![test_runner(anos::test_runner)] #![reexport_test_harness_main = "test_main"] -use core::panic::PanicInfo; use anos::println; -use bootloader::{BootInfo, entry_point}; +use bootloader::{entry_point, BootInfo}; +use core::panic::PanicInfo; entry_point!(kernel_main); fn kernel_main(boot_info: &'static BootInfo) -> ! { - use anos::memory::{ self, BootInfoFrameAllocator }; - use x86_64::{ structures::paging::Page, VirtAddr }; + use anos::memory::{self, BootInfoFrameAllocator}; + use x86_64::{structures::paging::Page, VirtAddr}; println!("Hello World{}", "!"); anos::init(); @@ -25,7 +25,7 @@ fn kernel_main(boot_info: &'static BootInfo) -> ! { memory::create_example_mapping(page, &mut mapper, &mut frame_allocator); let page_ptr: *mut u64 = page.start_address().as_mut_ptr(); - unsafe { page_ptr.offset(400).write_volatile(0x_f021_f077_f065_f04e)}; + unsafe { page_ptr.offset(400).write_volatile(0x_f021_f077_f065_f04e) }; // 触发一个中断 x86_64::instructions::interrupts::int3(); diff --git a/src/memory.rs b/src/memory.rs index 275a117..a9bd5b6 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -33,9 +33,7 @@ pub fn create_example_mapping( let frame = PhysFrame::containing_address(PhysAddr::new(0xb8000)); let flags = Flags::PRESENT | Flags::WRITABLE; - let map_to_result = unsafe { - mapper.map_to(page, frame, flags, frame_allocator) - }; + let map_to_result = unsafe { mapper.map_to(page, frame, flags, frame_allocator) }; map_to_result.expect("map_to failed").flush(); } diff --git a/src/serial.rs b/src/serial.rs index 353b13a..919ad95 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -1,6 +1,6 @@ -use uart_16550::SerialPort; -use spin::Mutex; use lazy_static::lazy_static; +use spin::Mutex; +use uart_16550::SerialPort; lazy_static! { pub static ref SERIAL1: Mutex = { diff --git a/src/vga_buffer.rs b/src/vga_buffer.rs index 83df5b0..848b8c6 100644 --- a/src/vga_buffer.rs +++ b/src/vga_buffer.rs @@ -3,14 +3,14 @@ // 这实际上是通过内存操作的副作用来实现的 // 但由于我们从未访问过这段内存,所以它可能会在未来的 Rust 编译器中被优化掉 // 为了告诉编译器,这部分针对内存的操作是我们故意的,就需要用到 volatile crate -use volatile::Volatile; use core::fmt; use lazy_static::lazy_static; use spin::Mutex; +use volatile::Volatile; #[allow(dead_code)] // 允许未使用的代码 -#[derive(Debug, Clone, Copy, PartialEq, Eq)] // 启用 copy 语义 -#[repr(u8)] // 每个 enum variant 都以 u8 存储 +#[derive(Debug, Clone, Copy, PartialEq, Eq)] // 启用 copy 语义 +#[repr(u8)] // 每个 enum variant 都以 u8 存储 pub enum Color { Black = 0, Blue = 1, @@ -31,7 +31,7 @@ pub enum Color { } #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[repr(transparent)] // 为了保证 ColorCode 和 u8 有同样的数据布局 +#[repr(transparent)] // 为了保证 ColorCode 和 u8 有同样的数据布局 struct ColorCode(u8); impl ColorCode { @@ -41,7 +41,7 @@ impl ColorCode { } #[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[repr(C)] // 使数据结构的布局和 C 一样,这样才能保证每个成员的顺序一致 +#[repr(C)] // 使数据结构的布局和 C 一样,这样才能保证每个成员的顺序一致 struct ScreenChar { ascii_character: u8, color_code: ColorCode, @@ -56,9 +56,9 @@ struct Buffer { } pub struct Writer { - column_position: usize, // 当前光标所在列 - color_code: ColorCode, // 当前颜色代码 - buffer: &'static mut Buffer, // VGA Buffer 的引用,生命周期是 'static + column_position: usize, // 当前光标所在列 + color_code: ColorCode, // 当前颜色代码 + buffer: &'static mut Buffer, // VGA Buffer 的引用,生命周期是 'static } impl Writer { @@ -71,7 +71,7 @@ impl Writer { if self.column_position >= BUFFER_WIDTH { self.new_line(); } - let row = BUFFER_HEIGHT -1; + let row = BUFFER_HEIGHT - 1; let col = self.column_position; let color_code = self.color_code; // 将 ScreenChar 写入到 Buffer 的相应位置 @@ -88,11 +88,11 @@ impl Writer { for row in 1..BUFFER_HEIGHT { for col in 0..BUFFER_WIDTH { let character = self.buffer.chars[row][col].read(); - self.buffer.chars[row -1][col].write(character); + self.buffer.chars[row - 1][col].write(character); } } // 清空最下面的一行 - self.clear_row(BUFFER_HEIGHT -1); + self.clear_row(BUFFER_HEIGHT - 1); // 将当前列的位置设为 0 self.column_position = 0; } @@ -161,19 +161,22 @@ pub fn _print(args: fmt::Arguments) { } #[test_case] -fn test_println_simple() { // 测试单行 println! +fn test_println_simple() { + // 测试单行 println! println!("test_println_simple output"); } #[test_case] -fn test_println_many() { // 测试多行 println! +fn test_println_many() { + // 测试多行 println! for _ in 0..10 { println!("test_println_many output"); } } #[test_case] -fn test_println_output() { // 测试字符是否真的打印到了屏幕上 +fn test_println_output() { + // 测试字符是否真的打印到了屏幕上 use core::fmt::Write; use x86_64::instructions::interrupts; diff --git a/tests/basic_boot.rs b/tests/basic_boot.rs index 7477812..6b716b7 100644 --- a/tests/basic_boot.rs +++ b/tests/basic_boot.rs @@ -4,8 +4,8 @@ #![test_runner(anos::test_runner)] #![reexport_test_harness_main = "test_main"] -use core::panic::PanicInfo; use anos::println; +use core::panic::PanicInfo; #[no_mangle] pub extern "C" fn _start() -> ! { diff --git a/tests/should_panic.rs b/tests/should_panic.rs index 36d4d0c..8eed418 100644 --- a/tests/should_panic.rs +++ b/tests/should_panic.rs @@ -1,8 +1,8 @@ #![no_std] #![no_main] +use anos::{exit_qemu, serial_print, serial_println, QemuExitCode}; use core::panic::PanicInfo; -use anos::{QemuExitCode, exit_qemu, serial_println, serial_print}; #[panic_handler] fn panic(_info: &PanicInfo) -> ! { diff --git a/tests/stack_overflow.rs b/tests/stack_overflow.rs index d46c760..9cdb43e 100644 --- a/tests/stack_overflow.rs +++ b/tests/stack_overflow.rs @@ -2,8 +2,8 @@ #![no_main] #![feature(abi_x86_interrupt)] +use anos::{exit_qemu, serial_print, serial_println, QemuExitCode}; use core::panic::PanicInfo; -use anos::{exit_qemu, QemuExitCode, serial_println, serial_print}; use lazy_static::lazy_static; use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame}; @@ -43,7 +43,10 @@ pub fn init_test_idt() { TEST_IDT.load(); } -extern "x86-interrupt" fn test_double_fault_handler(_stack_frame: InterruptStackFrame, _error_code: u64) -> ! { +extern "x86-interrupt" fn test_double_fault_handler( + _stack_frame: InterruptStackFrame, + _error_code: u64, +) -> ! { serial_println!("[ok]"); exit_qemu(QemuExitCode::Success); loop {}