mirror of
https://github.com/MintCN/linux-insides-zh.git
synced 2026-04-26 11:41:53 +08:00
Update Booting/linux-bootstrap-2md.md
This commit is contained in:
@@ -326,4 +326,29 @@ ENDPROC(memset)
|
||||
|
||||
接下来的`imull`指令将`eax`寄存器的值乘上`0x01010101`。这么做的原因是代码每次将尝试拷贝4个字节内存的内容。下面让我们来看一个具体的例子,假设我们需要将`0x7`这个数值放到内存中,在执行`imull`指令之前,`eax`寄存器的值是`0x7`,在`imull`指令被执行之后,`eax`寄存器的内容变成了`0x07070707`(4个字节的`0x7`)。在`imull`指令之后,代码使用`rep; stosl`指令将`eax`寄存器的内容拷贝到`es:di`指向的内存。
|
||||
|
||||
在`bisoregs`结构体被`initregs`函数正确填充之后,`bios_putchar` 调用中断 [0x10](http://www.ctyme.com/intr/rb-0106.htm) 在显示器上输出一个字符。接下来`putchar`函数检查是否初始化了串口,如果串口被初始化了,那么将调用[serial_putchar](https://github.com/torvalds/linux/blob/master/arch/x86/boot/tty.c#L30)将字符输出到串口。
|
||||
在`bisoregs`结构体被`initregs`函数正确填充之后,`bios_putchar` 调用中断 [0x10](http://www.ctyme.com/intr/rb-0106.htm) 在显示器上输出一个字符。接下来`putchar`函数检查是否初始化了串口,如果串口被初始化了,那么将调用[serial_putchar](https://github.com/torvalds/linux/blob/master/arch/x86/boot/tty.c#L30)将字符输出到串口。
|
||||
|
||||
堆初始化
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
After the stack and bss section were prepared in [header.S](https://github.com/torvalds/linux/blob/master/arch/x86/boot/header.S) (see previous [part](linux-bootstrap-1.md)), the kernel needs to initialize the [heap](https://github.com/torvalds/linux/blob/master/arch/x86/boot/main.c#L116) with the [`init_heap`](https://github.com/torvalds/linux/blob/master/arch/x86/boot/main.c#L116) function.
|
||||
|
||||
First of all `init_heap` checks the [`CAN_USE_HEAP`](https://github.com/torvalds/linux/blob/master/arch/x86/include/uapi/asm/bootparam.h#L21) flag from the [`loadflags`](https://github.com/torvalds/linux/blob/master/arch/x86/boot/header.S#L321) in the kernel setup header and calculates the end of the stack if this flag was set:
|
||||
|
||||
```C
|
||||
char *stack_end;
|
||||
|
||||
if (boot_params.hdr.loadflags & CAN_USE_HEAP) {
|
||||
asm("leal %P1(%%esp),%0"
|
||||
: "=r" (stack_end) : "i" (-STACK_SIZE));
|
||||
```
|
||||
|
||||
or in other words `stack_end = esp - STACK_SIZE`.
|
||||
|
||||
Then there is the `heap_end` calculation:
|
||||
```c
|
||||
heap_end = (char *)((size_t)boot_params.hdr.heap_end_ptr + 0x200);
|
||||
```
|
||||
which means `heap_end_ptr` or `_end` + `512`(`0x200h`). The last check is whether `heap_end` is greater than `stack_end`. If it is then `stack_end` is assigned to `heap_end` to make them equal.
|
||||
|
||||
Now the heap is initialized and we can use it using the `GET_HEAP` method. We will see how it is used, how to use it and how the it is implemented in the next posts.
|
||||
Reference in New Issue
Block a user