mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-20 16:07:49 +00:00
Compare commits
3 Commits
e69c4a59c8
...
13e1034ca7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
13e1034ca7 | ||
|
|
3d337e5f80 | ||
|
|
9691bd5dc8 |
@@ -296,13 +296,13 @@ bootloader = { version = "0.9.23", features = ["map_physical_memory"]}
|
||||
### 启动信息
|
||||
|
||||
|
||||
`Bootloader` 板块定义了一个[`BootInfo`]结构,包含了它传递给我们内核的所有信息。这个结构还处于早期阶段,所以在更新到未来的[semver-incompatible] bootloader版本时,可能会出现一些故障。在启用 "map_physical_memory" 功能后,它目前有两个字段 "memory_map" 和 "physical_memory_offset"。
|
||||
`Bootloader` 板块定义了一个[`BootInfo`]结构,包含了它传递给我们内核的所有信息。这个结构还处于早期阶段,所以在更新到未来的 [semver-incompatible] bootloader 版本时,可能会出现一些故障。在启用 "map_physical_memory" 功能后,它目前有两个字段 "memory_map" 和 "physical_memory_offset"。
|
||||
|
||||
[`BootInfo`]: https://docs.rs/bootloader/0.9.3/bootloader/bootinfo/struct.BootInfo.html
|
||||
[semver-incompatible]: https://doc.rust-lang.org/stable/cargo/reference/specifying-dependencies.html#caret-requirements
|
||||
|
||||
- `memory_map`字段包含了可用物理内存的概览。它告诉我们的内核,系统中有多少物理内存可用,哪些内存区域被保留给设备,如VGA硬件。内存图可以从BIOS或UEFI固件中查询,但只能在启动过程的早期查询。由于这个原因,它必须由引导程序提供,因为内核没有办法在以后检索到它。在这篇文章的后面我们将需要内存图。
|
||||
- physical_memory_offset`告诉我们物理内存映射的虚拟起始地址。通过把这个偏移量加到物理地址上,我们得到相应的虚拟地址。这使得我们可以从我们的内核中访问任意的物理内存。
|
||||
- `physical_memory_offset`告诉我们物理内存映射的虚拟起始地址。通过把这个偏移量加到物理地址上,我们得到相应的虚拟地址。这使得我们可以从我们的内核中访问任意的物理内存。
|
||||
- 这个物理内存偏移可以通过在Cargo.toml中添加一个`[package.metadata.bootloader]`表并设置`physical-memory-offset = "0x0000f00000000000"`(或任何其他值)来定制。然而,请注意,如果bootloader遇到物理地址值开始与偏移量以外的空间重叠,也就是说,它以前会映射到其他早期的物理地址的区域,就会出现恐慌。所以一般来说,这个值越高(>1 TiB)越好。
|
||||
|
||||
Bootloader将 `BootInfo` 结构以 `&'static BootInfo`参数的形式传递给我们的内核,并传递给我们的`_start`函数。我们的函数中还没有声明这个参数,所以让我们添加它。
|
||||
@@ -621,11 +621,11 @@ fn kernel_main(boot_info: &'static BootInfo) -> ! {
|
||||
[`translate_addr`]: https://docs.rs/x86_64/0.14.2/x86_64/structures/paging/mapper/trait.Translate.html#method.translate_addr
|
||||
[`translate`]: https://docs.rs/x86_64/0.14.2/x86_64/structures/paging/mapper/trait.Translate.html#tymethod.translate
|
||||
|
||||
特质只定义接口,不提供任何实现。`x86_64`板块目前提供了三种类型来实现不同要求的特征。[`OffsetPageTable`] 类型假设完整的物理内存被映射到虚拟地址空间的某个偏移处。[`MappedPageTable`]更灵活一些。它只要求每个页表帧在一个可计算的地址处被映射到虚拟地址空间。最后,[递归页表]类型可以用来通过[递归页表](#di-gui-ye-biao)访问页表框架。
|
||||
特质只定义接口,不提供任何实现。`x86_64`板块目前提供了三种类型来实现不同要求的特征。[`OffsetPageTable`] 类型假设完整的物理内存被映射到虚拟地址空间的某个偏移处。[`MappedPageTable`]更灵活一些。它只要求每个页表帧在一个可计算的地址处被映射到虚拟地址空间。最后,[`递归页表`]类型可以用来通过[递归页表](#di-gui-ye-biao)访问页表框架。
|
||||
|
||||
[`OffsetPageTable`]: https://docs.rs/x86_64/0.14.2/x86_64/structures/paging/mapper/struct.OffsetPageTable.html
|
||||
[`MappedPageTable`]: https://docs.rs/x86_64/0.14.2/x86_64/structures/paging/mapper/struct.MappedPageTable.html
|
||||
[`RecursivePageTable`]: https://docs.rs/x86_64/0.14.2/x86_64/structures/paging/mapper/struct.RecursivePageTable.html
|
||||
[`递归页表`]: https://docs.rs/x86_64/0.14.2/x86_64/structures/paging/mapper/struct.RecursivePageTable.html
|
||||
|
||||
在我们的例子中,bootloader在`physical_memory_offset`变量指定的虚拟地址上映射完整的物理内存,所以我们可以使用`OffsetPageTable`类型。为了初始化它,我们在`memory`模块中创建一个新的`init`函数。
|
||||
|
||||
@@ -961,7 +961,7 @@ unsafe impl FrameAllocator<Size4KiB> for BootInfoFrameAllocator {
|
||||
|
||||
[`Iterator::nth`]: https://doc.rust-lang.org/core/iter/trait.Iterator.html#method.nth
|
||||
|
||||
这个实现不是很理想,因为它在每次分配时都会重新创建`usable_frame`分配器。最好的办法是直接将迭代器存储为一个结构域。这样我们就不需要`nth`方法了,可以在每次分配时直接调用[`next`]。这种方法的问题是,目前不可能将 "impl Trait "类型存储在一个结构字段中。当[_name existential types_]完全实现时,它可能会在某一天发挥作用。
|
||||
这个实现不是很理想,因为它在每次分配时都会重新创建`usable_frame`分配器。最好的办法是直接将迭代器存储为一个结构域。这样我们就不需要`nth`方法了,可以在每次分配时直接调用[`next`]。这种方法的问题是,目前不可能将 "impl Trait "类型存储在一个结构字段中。当[_named existential types_]完全实现时,它可能会在某一天发挥作用。
|
||||
|
||||
[`next`]: https://doc.rust-lang.org/core/iter/trait.Iterator.html#tymethod.next
|
||||
[_named existential types_]: https://github.com/rust-lang/rfcs/pull/2071
|
||||
|
||||
Reference in New Issue
Block a user