找回密码
 立即注册
首页 业界区 安全 [rCore学习笔记 019]在main中测试本章实现

[rCore学习笔记 019]在main中测试本章实现

神泱 前天 12:45
写在前面

本随笔是非常菜的菜鸡写的。如有问题请及时提出。
可以联系:1160712160@qq.com
GitHhub:https://github.com/WindDevil (目前啥也没有
批处理操作系统的启动和运行流程

要想把本章实现的那些模块全部都串联在一起以实现运行一个批处理操作系统,回顾本章内容,思考批处理操作系统的运行流程.
可以看到本章完成的内容大概如图所示:
1.png

可以看到在内核层,最重要的就是实现了batch来加载程序和切换程序,以及trap用来处理用户层的请求.
因此,我们只需要在main.rs中添加这两个模块的初始化即可.
编写main.rs

主要是三部分:

  • 引入上述编写模块

    • 嵌入link_app.S
    • 引入batch,trap,syscall

  • 初始化模块
  • 开始运行用户态APP
需要添加的内容就这么多:
  1. pub mod batch;
  2. pub mod syscall;
  3. pub mod trap;
  4. global_asm!(include_str!("link_app.S"));
  5. pub fn rust_main() -> ! {
  6.         trap::init();
  7.     batch::init();
  8.     batch::run_next_app();
  9. }
复制代码
最终实现的main.rs:
  1. //! The main module and entrypoint
  2. //!
  3. //! Various facilities of the kernels are implemented as submodules. The most
  4. //! important ones are:
  5. //!
  6. //! - [`trap`]: Handles all cases of switching from userspace to the kernel
  7. //! - [`syscall`]: System call handling and implementation
  8. //!
  9. //! The operating system also starts in this module. Kernel code starts
  10. //! executing from `entry.asm`, after which [`rust_main()`] is called to
  11. //! initialize various pieces of functionality. (See its source code for
  12. //! details.)
  13. //!
  14. //! We then call [`batch::run_next_app()`] and for the first time go to
  15. //! userspace.
  16. #![deny(missing_docs)]
  17. #![deny(warnings)]
  18. #![no_std]
  19. #![no_main]
  20. #![feature(panic_info_message)]
  21. use core::arch::global_asm;
  22. use log::*;
  23. #[macro_use]
  24. mod console;
  25. pub mod batch;
  26. mod lang_items;
  27. mod logging;
  28. mod sbi;
  29. mod sync;
  30. pub mod syscall;
  31. pub mod trap;
  32. global_asm!(include_str!("entry.asm"));
  33. global_asm!(include_str!("link_app.S"));
  34. /// clear BSS segment
  35. fn clear_bss() {
  36.     extern "C" {
  37.         fn sbss();
  38.         fn ebss();
  39.     }
  40.     unsafe {
  41.         core::slice::from_raw_parts_mut(sbss as usize as *mut u8, ebss as usize - sbss as usize)
  42.             .fill(0);
  43.     }
  44. }
  45. /// the rust entry-point of os
  46. #[no_mangle]
  47. pub fn rust_main() -> ! {
  48.     extern "C" {
  49.         fn stext(); // begin addr of text segment
  50.         fn etext(); // end addr of text segment
  51.         fn srodata(); // start addr of Read-Only data segment
  52.         fn erodata(); // end addr of Read-Only data ssegment
  53.         fn sdata(); // start addr of data segment
  54.         fn edata(); // end addr of data segment
  55.         fn sbss(); // start addr of BSS segment
  56.         fn ebss(); // end addr of BSS segment
  57.         fn boot_stack_lower_bound(); // stack lower bound
  58.         fn boot_stack_top(); // stack top
  59.     }
  60.     clear_bss();
  61.     logging::init();
  62.     println!("[kernel] Hello, world!");
  63.     trace!(
  64.         "[kernel] .text [{:#x}, {:#x})",
  65.         stext as usize,
  66.         etext as usize
  67.     );
  68.     debug!(
  69.         "[kernel] .rodata [{:#x}, {:#x})",
  70.         srodata as usize, erodata as usize
  71.     );
  72.     info!(
  73.         "[kernel] .data [{:#x}, {:#x})",
  74.         sdata as usize, edata as usize
  75.     );
  76.     warn!(
  77.         "[kernel] boot_stack top=bottom={:#x}, lower_bound={:#x}",
  78.         boot_stack_top as usize, boot_stack_lower_bound as usize
  79.     );
  80.     error!("[kernel] .bss [{:#x}, {:#x})", sbss as usize, ebss as usize);
  81.     trap::init();
  82.     batch::init();
  83.     batch::run_next_app();
  84. }
复制代码
编译运行

使用第一章就编写好的Makefile文件实现一键编译运行:
  1. cd os
  2. make run
复制代码
第一次编译运行:
  1. error: expected expression, found keyword `extern`
  2.   --> src/batch.rs:94:13
  3.    |
  4. 94 |             extern "C"
  5.    |             ^^^^^^ expected expression
  6. error: cannot find macro `asm` in this scope
  7.   --> src/batch.rs:84:9
  8.    |
  9. 84 |         asm!("fence.i")
  10.    |         ^^^
  11.    |
  12. help: consider importing this macro
  13.    |
  14. 1  + use core::arch::asm;
  15.    |
  16. error: cannot find macro `global_asm` in this scope
  17. --> src/trap/mod.rs:3:1
  18.   |
  19. 3 | global_asm!(include_str!("trap.S"));
  20.   | ^^^^^^^^^^
  21.   |
  22. help: consider importing one of these items
  23.   |
  24. 3 + use core::arch::global_asm;
  25.   |
  26. 3 + use crate::global_asm;
  27.   |
  28. error[E0412]: cannot find type `TrapContext` in this scope
  29.   --> src/batch.rs:34:36
  30.    |
  31. 34 |     pub fn push_context(&self, cx: TrapContext) -> &'static mut TrapContext {
  32.    |                                    ^^^^^^^^^^^ not found in this scope
  33. error[E0412]: cannot find type `TrapContext` in this scope
  34.   --> src/batch.rs:34:65
  35.    |
  36. 34 |     pub fn push_context(&self, cx: TrapContext) -> &'static mut TrapContext {
  37.    |                                                                 ^^^^^^^^^^^ not found in this scope
  38. error[E0412]: cannot find type `TrapContext` in this scope
  39.   --> src/batch.rs:35:60
  40.    |
  41. 35 |         let cx_ptr = (self.get_sp() - core::mem::size_of::<TrapContext>()) as *mut TrapContext;
  42.    |                                                            ^^^^^^^^^^^ not found in this scope
  43.    |
  44. help: you might be missing a type parameter
  45.    |
  46. 30 | impl<TrapContext> KernelStack {
  47.    |     +++++++++++++
  48. error[E0412]: cannot find type `TrapContext` in this scope
  49.   --> src/batch.rs:35:84
  50.    |
  51. 35 |         let cx_ptr = (self.get_sp() - core::mem::size_of::<TrapContext>()) as *mut TrapContext;
  52.    |                                                                                    ^^^^^^^^^^^ not found in this scope
  53. error[E0412]: cannot find type `RefCell` in this scope
  54. --> src/sync/up.rs:5:12
  55.   |
  56. 5 |     inner: RefCell<T>,
  57.   |            ^^^^^^^ not found in this scope
  58.   |
  59. help: consider importing this struct
  60.   |
  61. 3 + use core::cell::RefCell;
  62.   |
  63. error[E0433]: failed to resolve: use of undeclared type `RefCell`
  64.   --> src/sync/up.rs:14:23
  65.    |
  66. 14 |         Self { inner: RefCell::new(value) }
  67.    |                       ^^^^^^^ use of undeclared type `RefCell`
  68.    |
  69. help: consider importing this struct
  70.    |
  71. 3  + use core::cell::RefCell;
  72.    |
  73. error[E0412]: cannot find type `RefMut` in this scope
  74.   --> src/sync/up.rs:17:39
  75.    |
  76. 17 |     pub fn exclusive_access(&self) -> RefMut<'_, T> {
  77.    |                                       ^^^^^^ not found in this scope
  78.    |
  79. help: consider importing this struct
  80.    |
  81. 3  + use core::cell::RefMut;
  82.    |
  83. error[E0412]: cannot find type `TrapContext` in this scope
  84.   --> src/trap/mod.rs:13:30
  85.    |
  86. 13 | pub fn trap_handler(cx: &mut TrapContext) -> &mut TrapContext {
  87.    |                              ^^^^^^^^^^^ not found in this scope
  88. error[E0412]: cannot find type `TrapContext` in this scope
  89.   --> src/trap/mod.rs:13:51
  90.    |
  91. 13 | pub fn trap_handler(cx: &mut TrapContext) -> &mut TrapContext {
  92.    |                                                   ^^^^^^^^^^^ not found in this scope
  93. error[E0425]: cannot find function `syscall` in this scope
  94.   --> src/trap/mod.rs:19:24
  95.    |
  96. 19 |             cx.x[10] = syscall(cx.x[17], [cx.x[10], cx.x[11], cx.x[12]]) as usize;
  97.    |                        ^^^^^^^ not found in this scope
  98.    |
  99. help: consider importing this function
  100.    |
  101. 3  + use crate::syscall::syscall;
  102.    |
  103. error[E0425]: cannot find function `run_next_app` in this scope
  104.   --> src/trap/mod.rs:24:13
  105.    |
  106. 24 |             run_next_app();
  107.    |             ^^^^^^^^^^^^ not found in this scope
  108.    |
  109. help: consider importing this function
  110.    |
  111. 3  + use crate::batch::run_next_app;
  112.    |
  113. error[E0425]: cannot find function `run_next_app` in this scope
  114.   --> src/trap/mod.rs:28:13
  115.    |
  116. 28 |             run_next_app();
  117.    |             ^^^^^^^^^^^^ not found in this scope
  118.    |
  119. help: consider importing this function
  120.    |
  121. 3  + use crate::batch::run_next_app;
  122.    |
  123. error[E0425]: cannot find function `init` in module `batch`
  124.   --> src/main.rs:88:12
  125.    |
  126. 88 |     batch::init();
  127.    |            ^^^^ not found in `batch`
  128.    |
  129. help: consider importing one of these items
  130.    |
  131. 23 + use crate::logging::init;
  132.    |
  133. 23 + use crate::trap::init;
  134.    |
  135. help: if you import `init`, refer to it directly
  136.    |
  137. 88 -     batch::init();
  138. 88 +     init();
  139.    |
  140. error[E0308]: mismatched types
  141.    --> src/batch.rs:80:41
  142.     |
  143. 80  |         core::slice::from_raw_parts_mut(APP_BASE_ADDRESS as *const u8, APP_SIZE_LIMIT).fill(0);
  144.     |         ------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ in mutability
  145.     |         |
  146.     |         arguments to this function are incorrect
  147.     |
  148.     = note: expected raw pointer `*mut _`
  149.                found raw pointer `*const u8`
  150. note: function defined here
  151.    --> /home/winddevil/.rustup/toolchains/nightly-2024-05-01-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/slice/raw.rs:147:21
  152.     |
  153. 147 | pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] {
  154.     |                     ^^^^^^^^^^^^^^^^^^
  155. error[E0599]: the method `get` exists for struct `Lazy<UPSafeCell>`, but its trait bounds were not satisfied
  156.    --> src/batch.rs:88:1
  157.     |
  158. 88  | / lazy_static!
  159. 89  | | {
  160. 90  | |     static ref APP_MANAGER: UPSafeCell = unsafe
  161. 91  | |     {
  162. ...   |
  163. 110 | |     };
  164. 111 | | }
  165.     | |_^ method cannot be called on `Lazy<UPSafeCell>` due to unsatisfied trait bounds
  166.     |
  167.    ::: src/sync/up.rs:3:1
  168.     |
  169. 3   |   pub struct UPSafeCell<T> {
  170.     |   ------------------------ doesn't satisfy `UPSafeCell: Sized`
  171.     |
  172.     = note: the following trait bounds were not satisfied:
  173.             `{type error}: Sized`
  174.             which is required by `UPSafeCell: Sized`
  175.     = note: this error originates in the macro `__lazy_static_internal` which comes from the expansion of the macro `lazy_static` (in Nightly builds, run with -Z macro-backtrace for more info)
  176. error[E0433]: failed to resolve: use of undeclared type `TrapContext`
  177.    --> src/batch.rs:126:13
  178.     |
  179. 126 |             TrapContext::app_init_context(APP_BASE_ADDRESS, USER_STACK.get_sp())
  180.     |             ^^^^^^^^^^^ use of undeclared type `TrapContext`
  181. error[E0425]: cannot find function `sys_write` in this scope
  182. --> src/syscall/mod.rs:5:26
  183.   |
  184. 5 |         SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]),
  185.   |                          ^^^^^^^^^ not found in this scope
  186. error[E0425]: cannot find function `sys_exit` in this scope
  187. --> src/syscall/mod.rs:6:25
  188.   |
  189. 6 |         SYSCALL_EXIT => sys_exit(args[0] as i32),
  190.   |                         ^^^^^^^^ not found in this scope
  191. error[E0433]: failed to resolve: use of undeclared crate or module `stvec`
  192. --> src/trap/mod.rs:8:9
  193.   |
  194. 8 |         stvec::write(__alltraps as usize, TrapMode::Direct);
  195.   |         ^^^^^ use of undeclared crate or module `stvec`
  196. error[E0433]: failed to resolve: use of undeclared type `TrapMode`
  197. --> src/trap/mod.rs:8:43
  198.   |
  199. 8 |         stvec::write(__alltraps as usize, TrapMode::Direct);
  200.   |                                           ^^^^^^^^ use of undeclared type `TrapMode`
  201. error[E0433]: failed to resolve: use of undeclared crate or module `scause`
  202.   --> src/trap/mod.rs:14:18
  203.    |
  204. 14 |     let scause = scause::read();
  205.    |                  ^^^^^^ use of undeclared crate or module `scause`
  206. error[E0433]: failed to resolve: use of undeclared crate or module `stval`
  207.   --> src/trap/mod.rs:15:17
  208.    |
  209. 15 |     let stval = stval::read();
  210.    |                 ^^^^^ use of undeclared crate or module `stval`
  211. error: unused variable: `metadata`
  212.   --> src/logging.rs:9:23
  213.    |
  214. 9  |     fn enabled(&self, metadata: &Metadata) -> bool
  215.    |                       ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_metadata`
  216.    |
  217. note: the lint level is defined here
  218.   --> src/main.rs:18:9
  219.    |
  220. 18 | #![deny(warnings)]
  221.    |         ^^^^^^^^
  222.    = note: `#[deny(unused_variables)]` implied by `#[deny(warnings)]`
  223. error[E0433]: failed to resolve: use of undeclared type `Exception`
  224.   --> src/trap/mod.rs:26:25
  225.    |
  226. 26 |         Trap::Exception(Exception::IllegalInstruction) => {
  227.    |                         ^^^^^^^^^ use of undeclared type `Exception`
  228. error[E0433]: failed to resolve: use of undeclared type `Trap`
  229.   --> src/trap/mod.rs:26:9
  230.    |
  231. 26 |         Trap::Exception(Exception::IllegalInstruction) => {
  232.    |         ^^^^ use of undeclared type `Trap`
  233. error[E0433]: failed to resolve: use of undeclared type `Exception`
  234.   --> src/trap/mod.rs:22:25
  235.    |
  236. 22 |         Trap::Exception(Exception::StorePageFault) => {
  237.    |                         ^^^^^^^^^ use of undeclared type `Exception`
  238. error[E0433]: failed to resolve: use of undeclared type `Trap`
  239.   --> src/trap/mod.rs:22:9
  240.    |
  241. 22 |         Trap::Exception(Exception::StorePageFault) => {
  242.    |         ^^^^ use of undeclared type `Trap`
  243. error[E0433]: failed to resolve: use of undeclared type `Exception`
  244.   --> src/trap/mod.rs:21:25
  245.    |
  246. 21 |         Trap::Exception(Exception::StoreFault) |
  247.    |                         ^^^^^^^^^ use of undeclared type `Exception`
  248. error[E0433]: failed to resolve: use of undeclared type `Trap`
  249.   --> src/trap/mod.rs:17:9
  250.    |
  251. 17 |         Trap::Exception(Exception::UserEnvCall) => {
  252.    |         ^^^^ use of undeclared type `Trap`
  253. error[E0433]: failed to resolve: use of undeclared type `Exception`
  254.   --> src/trap/mod.rs:17:25
  255.    |
  256. 17 |         Trap::Exception(Exception::UserEnvCall) => {
  257.    |                         ^^^^^^^^^ use of undeclared type `Exception`
  258. error[E0433]: failed to resolve: use of undeclared type `Trap`
  259.   --> src/trap/mod.rs:21:9
  260.    |
  261. 21 |         Trap::Exception(Exception::StoreFault) |
  262.    |         ^^^^ use of undeclared type `Trap`
  263. Some errors have detailed explanations: E0308, E0412, E0425, E0433, E0599.
  264. For more information about an error, try `rustc --explain E0308`.
  265. error: could not compile `os` (bin "os") due to 34 previous errors
  266. make: *** [Makefile:42: kernel] Error 101
复制代码
看到大段的报错不要着急,首先先看容易解决,能够解决的.
首先是在batch.rs里加入use core::arch::asm;:
  1. error: cannot find macro `asm` in this scope
  2.   --> src/batch.rs:84:9
  3.    |
  4. 84 |         asm!("fence.i")
  5.    |         ^^^
  6.    |
  7. help: consider importing this macro
  8.    |
  9. 1  + use core::arch::asm;
  10.    |
复制代码
同样地,在src/trap/mod.rs里边加入use core::arch::global_asm;:
  1. error: cannot find macro `global_asm` in this scope
  2. --> src/trap/mod.rs:3:1
  3.   |
  4. 3 | global_asm!(include_str!("trap.S"));
  5.   | ^^^^^^^^^^
  6.   |
  7. help: consider importing one of these items
  8.   |
  9. 3 + use core::arch::global_asm;
  10.   |
  11. 3 + use crate::global_asm;
  12.   |
复制代码
在batch.rs加入use crate::trap::TrapContext;,这时候我们发现实际上在src/trap/mod.rs里也没有声明TrapContext则在里边声明mod context;:
  1. error[E0412]: cannot find type `TrapContext` in this scope
  2.   --> src/batch.rs:34:36
  3.    |
  4. 34 |     pub fn push_context(&self, cx: TrapContext) -> &'static mut TrapContext {
  5.    |                                    ^^^^^^^^^^^ not found in this scope
复制代码
后续有很多找不到TrapContext的问题,可能都会解决.
在src/sync/up.rs里加入use core::cell::{RefCell, RefMut};:
  1. error[E0412]: cannot find type `RefCell` in this scope
  2. --> src/sync/up.rs:5:12
  3.   |
  4. 5 |     inner: RefCell<T>,
  5.   |            ^^^^^^^ not found in this scope
  6.   |
  7. help: consider importing this struct
  8.   |
  9. 3 + use core::cell::RefCell;
  10.   |
  11. error[E0412]: cannot find type `RefMut` in this scope
  12.   --> src/sync/up.rs:17:39
  13.    |
  14. 17 |     pub fn exclusive_access(&self) -> RefMut<'_, T> {
  15.    |                                       ^^^^^^ not found in this scope
  16.    |
  17. help: consider importing this struct
  18.    |
  19. 3  + use core::cell::RefMut;
  20.    |
复制代码
每次运行之后,

  • 因为触发了异常而退出
  • 直接由exit(main());退出
都会陷入trap,然后在trap_handler里处理,只要不出现没有预期到的Expectation都会调用run_next_app,因此所有的app按顺序运行.
最后完美结束了这一章,我真是一条懒狗,怎么什么坑都要踩一遍.

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册