diff --git a/blog/content/edition-2/posts/05-cpu-exceptions/index.fa.md b/blog/content/edition-2/posts/05-cpu-exceptions/index.fa.md index 77bd8385..1704e596 100644 --- a/blog/content/edition-2/posts/05-cpu-exceptions/index.fa.md +++ b/blog/content/edition-2/posts/05-cpu-exceptions/index.fa.md @@ -129,7 +129,7 @@ pub struct InterruptDescriptorTable { بیایید ابتدا به نوع `HandlerFunc` نگاه کنیم: ```rust -type HandlerFunc = extern "x86-interrupt" fn(_: &mut InterruptStackFrame); +type HandlerFunc = extern "x86-interrupt" fn(_: InterruptStackFrame); ``` این یک [نوع مستعار(type alias)] برای نوع "`extern "x86-interrupt" fn` است. کلمه کلیدی `extern` تابعی را با یک [قرارداد فراخوانی خارجی] تعریف می کند و اغلب برای برقراری ارتباط با کد C استفاده می شود(`extern "C" fn`) . اما قرارداد فراخوانی `x86-interrupt` چیست؟ @@ -255,7 +255,7 @@ pub fn init_idt() { } extern "x86-interrupt" fn breakpoint_handler( - stack_frame: &mut InterruptStackFrame) + stack_frame: InterruptStackFrame) { println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame); } @@ -269,7 +269,7 @@ extern "x86-interrupt" fn breakpoint_handler( error[E0658]: x86-interrupt ABI is experimental and subject to change (see issue #40180) --> src/main.rs:53:1 | -53 | / extern "x86-interrupt" fn breakpoint_handler(stack_frame: &mut InterruptStackFrame) { +53 | / extern "x86-interrupt" fn breakpoint_handler(stack_frame: InterruptStackFrame) { 54 | | println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame); 55 | | } | |_^ diff --git a/blog/content/edition-2/posts/05-cpu-exceptions/index.ja.md b/blog/content/edition-2/posts/05-cpu-exceptions/index.ja.md index 79b9930b..689f589d 100644 --- a/blog/content/edition-2/posts/05-cpu-exceptions/index.ja.md +++ b/blog/content/edition-2/posts/05-cpu-exceptions/index.ja.md @@ -127,7 +127,7 @@ pub struct InterruptDescriptorTable { まず`HandlerFunc`型を見てみましょう: ```rust -type HandlerFunc = extern "x86-interrupt" fn(_: &mut InterruptStackFrame); +type HandlerFunc = extern "x86-interrupt" fn(_: InterruptStackFrame); ``` これは、`extern "x86-interrupt" fn`型への[型エイリアス][type alias]です。`extern`は[外部呼び出し規約][foreign calling convention]に従う関数を定義するのに使われ、おもにC言語のコードと連携したいときに使われます (`extern "C" fn`) 。しかし、`x86-interrupt`呼び出し規約とは何なのでしょう? @@ -253,7 +253,7 @@ pub fn init_idt() { } extern "x86-interrupt" fn breakpoint_handler( - stack_frame: &mut InterruptStackFrame) + stack_frame: InterruptStackFrame) { println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame); } @@ -267,7 +267,7 @@ extern "x86-interrupt" fn breakpoint_handler( error[E0658]: x86-interrupt ABI is experimental and subject to change (see issue #40180) --> src/main.rs:53:1 | -53 | / extern "x86-interrupt" fn breakpoint_handler(stack_frame: &mut InterruptStackFrame) { +53 | / extern "x86-interrupt" fn breakpoint_handler(stack_frame: InterruptStackFrame) { 54 | | println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame); 55 | | } | |_^ diff --git a/blog/content/edition-2/posts/06-double-faults/index.fa.md b/blog/content/edition-2/posts/06-double-faults/index.fa.md index a749a2ba..ad68b869 100644 --- a/blog/content/edition-2/posts/06-double-faults/index.fa.md +++ b/blog/content/edition-2/posts/06-double-faults/index.fa.md @@ -89,7 +89,7 @@ lazy_static! { // new extern "x86-interrupt" fn double_fault_handler( - stack_frame: &mut InterruptStackFrame, _error_code: u64) -> ! + stack_frame: InterruptStackFrame, _error_code: u64) -> ! { panic!("EXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame); } @@ -543,7 +543,7 @@ use blog_os::{exit_qemu, QemuExitCode, serial_println}; use x86_64::structures::idt::InterruptStackFrame; extern "x86-interrupt" fn test_double_fault_handler( - _stack_frame: &mut InterruptStackFrame, + _stack_frame: InterruptStackFrame, _error_code: u64, ) -> ! { serial_println!("[ok]"); diff --git a/blog/content/edition-2/posts/06-double-faults/index.ja.md b/blog/content/edition-2/posts/06-double-faults/index.ja.md index 62f24fe9..5adcaaf0 100644 --- a/blog/content/edition-2/posts/06-double-faults/index.ja.md +++ b/blog/content/edition-2/posts/06-double-faults/index.ja.md @@ -84,7 +84,7 @@ lazy_static! { // new extern "x86-interrupt" fn double_fault_handler( - stack_frame: &mut InterruptStackFrame, _error_code: u64) -> ! + stack_frame: InterruptStackFrame, _error_code: u64) -> ! { panic!("EXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame); } @@ -488,7 +488,7 @@ fn stack_overflow() { しかし、ここではスタックオーバーフローを起こしたいので、コンパイラに削除されない、ダミーのvolatile読み込み文を関数の末尾に追加します。その結果、関数は**末尾再帰**ではなくなり、ループへの変換は防がれます。更に関数が無限に再帰することに対するコンパイラの警告をなくすために`allow(unconditional_recursion)`属性を追加します。 -### IDTのテスト +### IDTのテスト 上で述べたように、テストはカスタムしたダブルフォルトハンドラを含む専用のIDTが必要です。実装はこのようになります: @@ -529,7 +529,7 @@ use blog_os::{exit_qemu, QemuExitCode, serial_println}; use x86_64::structures::idt::InterruptStackFrame; extern "x86-interrupt" fn test_double_fault_handler( - _stack_frame: &mut InterruptStackFrame, + _stack_frame: InterruptStackFrame, _error_code: u64, ) -> ! { serial_println!("[ok]"); diff --git a/blog/content/edition-2/posts/07-hardware-interrupts/index.fa.md b/blog/content/edition-2/posts/07-hardware-interrupts/index.fa.md index 60c9634f..089c60c0 100644 --- a/blog/content/edition-2/posts/07-hardware-interrupts/index.fa.md +++ b/blog/content/edition-2/posts/07-hardware-interrupts/index.fa.md @@ -205,7 +205,7 @@ lazy_static! { } extern "x86-interrupt" fn timer_interrupt_handler( - _stack_frame: &mut InterruptStackFrame) + _stack_frame: InterruptStackFrame) { print!("."); } @@ -230,7 +230,7 @@ extern "x86-interrupt" fn timer_interrupt_handler( // in src/interrupts.rs extern "x86-interrupt" fn timer_interrupt_handler( - _stack_frame: &mut InterruptStackFrame) + _stack_frame: InterruptStackFrame) { print!("."); @@ -543,7 +543,7 @@ lazy_static! { } extern "x86-interrupt" fn keyboard_interrupt_handler( - _stack_frame: &mut InterruptStackFrame) + _stack_frame: InterruptStackFrame) { print!("k"); @@ -568,7 +568,7 @@ extern "x86-interrupt" fn keyboard_interrupt_handler( // in src/interrupts.rs extern "x86-interrupt" fn keyboard_interrupt_handler( - _stack_frame: &mut InterruptStackFrame) + _stack_frame: InterruptStackFrame) { use x86_64::instructions::port::Port; @@ -609,7 +609,7 @@ extern "x86-interrupt" fn keyboard_interrupt_handler( // in src/interrupts.rs extern "x86-interrupt" fn keyboard_interrupt_handler( - _stack_frame: &mut InterruptStackFrame) + _stack_frame: InterruptStackFrame) { use x86_64::instructions::port::Port; @@ -668,7 +668,7 @@ pc-keyboard = "0.5.0" // in/src/interrupts.rs extern "x86-interrupt" fn keyboard_interrupt_handler( - _stack_frame: &mut InterruptStackFrame) + _stack_frame: InterruptStackFrame) { use pc_keyboard::{layouts, DecodedKey, HandleControl, Keyboard, ScancodeSet1}; use spin::Mutex; diff --git a/blog/content/edition-2/posts/08-paging-introduction/index.fa.md b/blog/content/edition-2/posts/08-paging-introduction/index.fa.md index 731882f5..89cbcf19 100644 --- a/blog/content/edition-2/posts/08-paging-introduction/index.fa.md +++ b/blog/content/edition-2/posts/08-paging-introduction/index.fa.md @@ -166,7 +166,7 @@ rtl = true ![An example 4-level page hierarchy with each page table shown in physical memory](x86_64-page-table-translation.svg) آدرس فیزیکی جدول صفحه سطح 4 که در حال حاضر فعال می‌باشد، و ریشه جدول صفحه سطح 4 است، در ثبات `CR3` ذخیره می‌شود. سپس هر ورودی جدول صفحه به قاب فیزیکی جدول سطح بعدی اشاره می‌کند. سپس ورودی جدول سطح 1 به قاب نگاشت شده اشاره می‌کند. توجه داشته باشید که تمام آدرس‌های موجود در جدول‌های صفحه فیزیکی هستند، به جای این‌که مجازی باشند، زیرا در غیر این‌صورت CPU نیاز به ترجمه آن آدرس‌ها نیز دارد (که این امر می‌تواند باعث بازگشت بی‌پایان شود). - + سلسله مراتب جدول صفحه بالا، دو صفحه را نگاشت می‌کند (به رنگ آبی). از اندیس‌های جدول صفحه می‌توان نتیجه گرفت که آدرس‌های مجازی این دو صفحه `0x803FE7F000` و `0x803FE00000` است. بیایید ببینیم چه اتفاقی می‌افتد وقتی برنامه سعی می‌کند از آدرس `0x803FE7F5CE` بخواند. ابتدا آدرس را به باینری تبدیل می‌کنیم و اندیس‌های جدول صفحه و آفست صفحه را برای آدرس تعیین می‌کنیم: ![The sign extension bits are all 0, the level 4 index is 1, the level 3 index is 0, the level 2 index is 511, the level 1 index is 127, and the page offset is 0x5ce](x86_64-page-table-translation-addresses.png) @@ -244,7 +244,7 @@ Bit(s) | Name | Meaning ### بافر ترجمه Lookaside -یک جدول صفحه 4 سطحی، ترجمه آدرس‌های مجازی را پُر هزینه‌ می‌کند، زیرا هر ترجمه به 4 دسترسی حافظه نیاز دارد. برای بهبود عملکرد، معماری x86_64 آخرین ترجمه‌ها را در _translation lookaside buffer_ یا به اختصار TLB ذخیره می‌کند. و این به ما اجازه می‌دهد تا از ترجمه کردن مجدد ترجمه‌هایی که در حافظه پنهان قرار دارند خودداری کنیم. +یک جدول صفحه 4 سطحی، ترجمه آدرس‌های مجازی را پُر هزینه‌ می‌کند، زیرا هر ترجمه به 4 دسترسی حافظه نیاز دارد. برای بهبود عملکرد، معماری x86_64 آخرین ترجمه‌ها را در _translation lookaside buffer_ یا به اختصار TLB ذخیره می‌کند. و این به ما اجازه می‌دهد تا از ترجمه کردن مجدد ترجمه‌هایی که در حافظه پنهان قرار دارند خودداری کنیم. برخلاف سایر حافظه‌های پنهان پردازنده، TLB کاملاً شفاف نبوده و با تغییر محتوای جدول‌های صفحه، ترجمه‌ها را به‌روز و حذف نمی‌کند. این بدان معنی است که هسته هر زمان که جدول صفحه را تغییر می‌دهد باید TLB را به صورت دستی به‌روز کند. برای انجام این کار، یک دستورالعمل ویژه پردازنده وجود دارد به نام [`invlpg`] ("صفحه نامعتبر") که ترجمه برای صفحه مشخص شده را از TLB حذف می‌کند، بنابراین دوباره از جدول صفحه در دسترسی بعدی بارگیری می‌شود. TLB همچنین می‌تواند با بارگیری مجدد رجیستر `CR3`، که یک تعویض فضای آدرس را شبیه‌سازی می‌کند، کاملاً فلاش (کلمه: flush) شود. کریت `x86_64` توابع راست را برای هر دو نوع در [ماژول `tlb`] فراهم می‌کند. @@ -288,7 +288,7 @@ use x86_64::structures::idt::PageFaultErrorCode; use crate::hlt_loop; extern "x86-interrupt" fn page_fault_handler( - stack_frame: &mut InterruptStackFrame, + stack_frame: InterruptStackFrame, error_code: PageFaultErrorCode, ) { use x86_64::registers::control::Cr2; diff --git a/blog/content/edition-2/posts/08-paging-introduction/index.ja.md b/blog/content/edition-2/posts/08-paging-introduction/index.ja.md index 09a14d57..321627a7 100644 --- a/blog/content/edition-2/posts/08-paging-introduction/index.ja.md +++ b/blog/content/edition-2/posts/08-paging-introduction/index.ja.md @@ -295,7 +295,7 @@ use x86_64::structures::idt::PageFaultErrorCode; use crate::hlt_loop; extern "x86-interrupt" fn page_fault_handler( - stack_frame: &mut InterruptStackFrame, + stack_frame: InterruptStackFrame, error_code: PageFaultErrorCode, ) { use x86_64::registers::control::Cr2; diff --git a/blog/content/edition-2/posts/12-async-await/index.ja.md b/blog/content/edition-2/posts/12-async-await/index.ja.md index 8d25ef22..a60ec6a0 100644 --- a/blog/content/edition-2/posts/12-async-await/index.ja.md +++ b/blog/content/edition-2/posts/12-async-await/index.ja.md @@ -1144,7 +1144,7 @@ pub(crate) fn add_scancode(scancode: u8) { // in src/interrupts.rs extern "x86-interrupt" fn keyboard_interrupt_handler( - _stack_frame: &mut InterruptStackFrame + _stack_frame: InterruptStackFrame ) { use x86_64::instructions::port::Port;