mirror of
https://github.com/MintCN/linux-insides-zh.git
synced 2026-04-24 18:50:42 +08:00
fix document style
This commit is contained in:
@@ -521,7 +521,7 @@ per-CPU变量是2.6内核中的特性。顾名思义,当我们创建一个 `pe
|
||||
|
||||
我们需要把 `MSR_GS_BASE` 放入 `ecx` 寄存器,同时利用 `wrmsr` 指令向 `eax` 和 `edx` 处的地址加载数据(即指向 `initial_gs`)。`cs`, `fs`, `ds` 和 `ss` 段寄存器在64位模式下不用来寻址,但 `fs` 和 `gs` 可以使用。 `fs` 和 `gs` 有一个隐含的部分(与实模式下的 `cs` 段寄存器类似),这个隐含部分存储了一个描述符,其指向 [Model Specific Registers](https://en.wikipedia.org/wiki/Model-specific_register)。因此上面的 `0xc0000101` 是一个 `gs.base` MSR 地址。当发生[系统调用](https://en.wikipedia.org/wiki/System_call) 或者 [中断](https://en.wikipedia.org/wiki/Interrupt)时,入口点处并没有内核栈,因此 `MSR_GS_BASE` 将会用来存放中断栈。
|
||||
|
||||
接下来我们把实模式中的 bootparam 结构的地址放入 `rdi`(要记得`rsi`从一开始就保存了这个结构体的指针),然后跳转到C语言代码:
|
||||
接下来我们把实模式中的 bootparam 结构的地址放入 `rdi` (要记得 `rsi` 从一开始就保存了这个结构体的指针),然后跳转到C语言代码:
|
||||
|
||||
```assembly
|
||||
movq initial_code(%rip),%rax
|
||||
@@ -552,7 +552,7 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data) {
|
||||
}
|
||||
```
|
||||
|
||||
这个函数接受一个参数 `real_mode_data`(刚才我们把实模式下数据的地址保存到了`rdi`寄存器中)。
|
||||
这个函数接受一个参数 `real_mode_data`(刚才我们把实模式下数据的地址保存到了 `rdi` 寄存器中)。
|
||||
|
||||
这个函数是内核中第一个执行的C语言代码!
|
||||
|
||||
@@ -574,7 +574,7 @@ BUILD_BUG_ON(!(((MODULES_END - 1) & PGDIR_MASK) == (__START_KERNEL & PGDIR_MASK)
|
||||
BUILD_BUG_ON(__fix_to_virt(__end_of_fixed_addresses) <= MODULES_END);
|
||||
```
|
||||
|
||||
这些检查包括:模块的虚拟地址不能低于内核text段基地址`__START_KERNEL_map`,包含模块的内核text段的空间大小不能小于内核镜像大小等等。`BUILD_BUG_ON` 宏定义如下:
|
||||
这些检查包括:模块的虚拟地址不能低于内核 text 段基地址 `__START_KERNEL_map` ,包含模块的内核 text 段的空间大小不能小于内核镜像大小等等。`BUILD_BUG_ON` 宏定义如下:
|
||||
|
||||
```C
|
||||
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
|
||||
@@ -587,7 +587,7 @@ BUILD_BUG_ON(__fix_to_virt(__end_of_fixed_addresses) <= MODULES_END);
|
||||
|
||||
就是这么简单,通过C语言中某些常量导致编译错误的技巧实现了这一设计。
|
||||
|
||||
接下来 start_kernel 调用了 `cr4_init_shadow` 函数,其中存储了每个CPU中 `cr4` 的Shadow Copy。上下文切换可能会修改 `cr4` 中的位,因此需要保存每个CPU中`cr4` 的内容。在这之后将会调用 `reset_early_page_tables` 函数,它重置了所有的全局页目录项,同时向 `cr3` 中重新写入了的全局页目录表的地址:
|
||||
接下来 start_kernel 调用了 `cr4_init_shadow` 函数,其中存储了每个CPU中 `cr4` 的Shadow Copy。上下文切换可能会修改 `cr4` 中的位,因此需要保存每个CPU中 `cr4` 的内容。在这之后将会调用 `reset_early_page_tables` 函数,它重置了所有的全局页目录项,同时向 `cr3` 中重新写入了的全局页目录表的地址:
|
||||
|
||||
```C
|
||||
for (i = 0; i < PTRS_PER_PGD-1; i++)
|
||||
|
||||
Reference in New Issue
Block a user