From cd6d03d44c10247ac97b36ae5f03883a2137c1ff Mon Sep 17 00:00:00 2001 From: hailin cai Date: Fri, 19 Feb 2016 12:04:58 -0500 Subject: [PATCH] Update Booting/linux-bootstrap-2md.md --- Booting/linux-bootstrap-2md.md | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/Booting/linux-bootstrap-2md.md b/Booting/linux-bootstrap-2md.md index dc623ce..e0b859c 100644 --- a/Booting/linux-bootstrap-2md.md +++ b/Booting/linux-bootstrap-2md.md @@ -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)将字符输出到串口。 \ No newline at end of file +在`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. \ No newline at end of file