change images url

This commit is contained in:
Xin Qiu
2020-03-17 15:53:41 +08:00
committed by GitHub
parent dcbefa1981
commit 807d1e0d71

View File

@@ -245,7 +245,7 @@ X+08000 +------------------------+
上面的公式中, `X` 是 kernel bootsector 被引导入内存的位置。在我的机器上, `X` 的值是 `0x10000`,我们可以通过 memory dump 来检查这个地址:
![kernel first address](http://oi57.tinypic.com/16bkco2.jpg)
![kernel first address](https://github.com/0xAX/linux-insides/raw/master/Booting/images/kernel_first_address.png)
到这里,引导程序完成它的使命,并将控制权移交给了 Linux kernel。下面我们就来看看 kernel setup code 都做了些什么。
@@ -260,7 +260,7 @@ X+08000 +------------------------+
qemu-system-x86_64 vmlinuz-3.18-generic
```
![Try vmlinuz in qemu](http://oi60.tinypic.com/r02xkz.jpg)
![Try vmlinuz in qemu](https://github.com/0xAX/linux-insides/raw/master/Booting/images/try_vmlinuz_in_qemu.png)
为了能够作为 bootloader 来使用, `header.S` 开始处定义了 [MZ] [MZ](https://en.wikipedia.org/wiki/DOS_MZ_executable) 魔术数字, 并且定义了 [PE](https://en.wikipedia.org/wiki/Portable_Executable) 头,在 PE 头中定义了输出的字符串:
@@ -387,7 +387,7 @@ cs = 0x1020
这段代码首先将 `dx` 寄存器的值(就是当前`sp` 寄存器的值4字节对齐然后检查是否为0如果是0堆栈就不对了因为堆栈是从大地址向小地址发展的如果是0那么就将 `dx` 寄存器的值设置成 `0xfffc` 64KB地址段的最后一个4字节地址。如果不是0那么就保持当前值不变。接下来就将 `ax` 寄存器的值( 0x10000 )设置到 `ss` 寄存器,并根据 `dx` 寄存器的值设置正确的 `sp`。这样我们就得到了正确的堆栈设置,具体请参考下图:
![stack](http://oi58.tinypic.com/16iwcis.jpg)
![stack](https://github.com/0xAX/linux-insides/raw/master/Booting/images/stack1.png)
* 下面让我们来看 `ss` != `ds`的情况,首先将 setup code 的结束地址 [_end](http://lxr.free-electrons.com/source/arch/x86/boot/setup.ld?v=3.18#L52) 写入 `dx` 寄存器。然后检查 `loadflags` 中是否设置了 `CAN_USE_HEAP` 标志。 根据 kernel boot protocol 的定义,[loadflags](http://lxr.free-electrons.com/source/arch/x86/boot/header.S?v=3.18#L321) 是一个标志字段。这个字段的 `Bit 7` 就是 `CAN_USE_HEAP` 标志:
@@ -413,11 +413,11 @@ Field name: loadflags
如果 `CAN_USE_HEAP` 被置位,那么将 `heap_end_ptr` 放入 `dx` 寄存器,然后加上 `STACK_SIZE` (最小堆栈大小是 512 bytes。在加法完成之后如果结果没有溢出CF flag 没有置位,如果置位那么程序就出错了),那么就跳转到标号为 `2` 的代码处继续执行这段代码的逻辑在1中已经详细介绍了接着我们就得到了如下图所示的堆栈
![stack](http://oi62.tinypic.com/dr7b5w.jpg)
![stack](https://github.com/0xAX/linux-insides/raw/master/Booting/images/stack2.png)
* 最后一种情况就是 `CAN_USE_HEAP` 没有置位, 那么我们就将 `dx` 寄存器的值加上 `STACK_SIZE`,然后跳转到标号为 `2` 的代码处继续执行,接着我们就得到了如下图所示的堆栈:
![minimal stack](http://oi60.tinypic.com/28w051y.jpg)
![minimal stack](https://github.com/0xAX/linux-insides/raw/master/Booting/images/minimal_stack.png)
BSS段设置
--------------------------------------------------------------------------------
@@ -444,7 +444,7 @@ BSS 段用来存储那些没有被初始化的静态变量。对于这个段使
在这段代码中,首先将 [__bss_start](http://lxr.free-electrons.com/source/arch/x86/boot/setup.ld?v=3.18#L47) 地址放入 `di` 寄存器,然后将 `_end + 3` 4字节对齐 地址放入 `cx`,接着使用 `xor` 指令将 `ax` 寄存器清零,接着计算 BSS 段的大小 `cx` - `di` ),然后将大小放入 `cx` 寄存器。接下来将 `cx` 寄存器除4最后使用 `rep; stosl` 指令将 `ax` 寄存器的值0写入 寄存器整个 BSS 段。 代码执行完成之后,我们将得到如下图所示的 BSS 段:
![bss](http://oi59.tinypic.com/29m2eyr.jpg)
![bss](https://github.com/0xAX/linux-insides/raw/master/Booting/images/bss.png)
跳转到 main 函数
--------------------------------------------------------------------------------