mirror of
https://github.com/MintCN/linux-insides-zh.git
synced 2026-04-25 19:20:28 +08:00
add bootstrap 3
This commit is contained in:
25
Booting/linux-bootstrap-3.md
Normal file → Executable file
25
Booting/linux-bootstrap-3.md
Normal file → Executable file
@@ -86,7 +86,7 @@ vga=<mode>
|
||||
* `__alignof__(type)` 返回对于请求的数据类型需要怎样的对齐方式 ( 根据我的了解这个是 gcc 提供的一个功能 )
|
||||
* `n` 需要分配对少个对应数据类型的对象
|
||||
|
||||
Implementation of `__get_heap` is:
|
||||
下面是 `__get_heap` 函数的实现:
|
||||
|
||||
```C
|
||||
static inline char *__get_heap(size_t s, size_t a, size_t n)
|
||||
@@ -100,15 +100,9 @@ static inline char *__get_heap(size_t s, size_t a, size_t n)
|
||||
}
|
||||
```
|
||||
|
||||
and further we will see its usage, something like:
|
||||
现在让我们来了解这个函数是如何工作的。 这个函数首先根据对齐方式要求(参数 `a` )调整 `HEAP` 的值,然后将 `HEAP` 值赋值给一个临时变量 `tmp`。接下来根据需要分配的对象的个数(参数 `n` ),预留出所需要的内存,然后将 `tmp` 返回给调用端。
|
||||
|
||||
```C
|
||||
saved.data = GET_HEAP(u16, saved.x * saved.y);
|
||||
```
|
||||
|
||||
Let's try to understand how `__get_heap` works. We can see here that `HEAP` (which is equal to `_end` after `RESET_HEAP()`) is the address of aligned memory according to the `a` parameter. After this we save the memory address from `HEAP` to the `tmp` variable, move `HEAP` to the end of the allocated block and return `tmp` which is the start address of allocated memory.
|
||||
|
||||
And the last function is:
|
||||
最后一个关于 heap 的操作是:
|
||||
|
||||
```C
|
||||
static inline bool heap_free(size_t n)
|
||||
@@ -117,11 +111,11 @@ static inline bool heap_free(size_t n)
|
||||
}
|
||||
```
|
||||
|
||||
which subtracts value of the `HEAP` from the `heap_end` (we calculated it in the previous [part](linux-bootstrap-2.md)) and returns 1 if there is enough memory for `n`.
|
||||
这个函数简单做了一个减法 `heap_end - HEAP`,如果相减的结果大于请求的内存,那么就返回真,否则返回假。
|
||||
|
||||
That's all. Now we have a simple API for heap and can setup video mode.
|
||||
我们已经看到了所有可以对 heap 进行操作,下面让我们继续显示模式设置过程。
|
||||
|
||||
Set up video mode
|
||||
设置显示模式
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Now we can move directly to video mode initialization. We stopped at the `RESET_HEAP()` call in the `set_video` function. Next is the call to `store_mode_params` which stores video mode parameters in the `boot_params.screen_info` structure which is defined in [include/uapi/linux/screen_info.h](https://github.com/0xAX/linux/blob/master/include/uapi/linux/screen_info.h).
|
||||
@@ -130,7 +124,7 @@ If we look at the `store_mode_params` function, we can see that it starts with t
|
||||
|
||||
First of all `store_cursor_position` initializes two variables which have type `biosregs` with `AH = 0x3`, and calls `0x10` BIOS interruption. After the interruption is successfully executed, it returns row and column in the `DL` and `DH` registers. Row and column will be stored in the `orig_x` and `orig_y` fields from the the `boot_params.screen_info` structure.
|
||||
|
||||
After `store_cursor_position` is executed, the `store_video_mode` function will be called. It just gets the current video mode and stores it in `boot_params.screen_info.orig_video_mode`.
|
||||
After `store_cursor_position` is executed, the `store_video_mode` function will be called. It just gets the current video mode and stores it in `boot_params.screen_info.orig_video_mode`.
|
||||
|
||||
After this, it checks the current video mode and sets the `video_segment`. After the BIOS transfers control to the boot sector, the following addresses are for video memory:
|
||||
|
||||
@@ -226,9 +220,9 @@ is in the `.videocards` segment. Let's look in the [arch/x86/boot/setup.ld](http
|
||||
|
||||
It means that `video_cards` is just a memory address and all `card_info` structures are placed in this segment. It means that all `card_info` structures are placed between `video_cards` and `video_cards_end`, so we can use it in a loop to go over all of it. After `probe_cards` executes we have all structures like `static __videocard video_vga` with filled `nmodes` (number of video modes).
|
||||
|
||||
After `probe_cards` execution is finished, we move to the main loop in the `set_video` function. There is an infinite loop which tries to set up video mode with the `set_mode` function or prints a menu if we passed `vid_mode=ask` to the kernel command line or video mode is undefined.
|
||||
After `probe_cards` execution is finished, we move to the main loop in the `set_video` function. There is an infinite loop which tries to set up video mode with the `set_mode` function or prints a menu if we passed `vid_mode=ask` to the kernel command line or video mode is undefined.
|
||||
|
||||
The `set_mode` function is defined in [video-mode.c](https://github.com/0xAX/linux/blob/master/arch/x86/boot/video-mode.c#L147) and gets only one parameter, `mode`, which is the number of video modes (we got it from the menu or in the start of `setup_video`, from the kernel setup header).
|
||||
The `set_mode` function is defined in [video-mode.c](https://github.com/0xAX/linux/blob/master/arch/x86/boot/video-mode.c#L147) and gets only one parameter, `mode`, which is the number of video modes (we got it from the menu or in the start of `setup_video`, from the kernel setup header).
|
||||
|
||||
The `set_mode` function checks the `mode` and calls the `raw_set_mode` function. The `raw_set_mode` calls the `set_mode` function for the selected card i.e. `card->set_mode(struct mode_info*)`. We can get access to this function from the `card_info` structure. Every video mode defines this structure with values filled depending upon the video mode (for example for `vga` it is the `video_vga.set_mode` function. See above example of `card_info` structure for `vga`). `video_vga.set_mode` is `vga_set_mode`, which checks the vga mode and calls the respective function:
|
||||
|
||||
@@ -585,4 +579,3 @@ Links
|
||||
* [GCC designated inits](https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html)
|
||||
* [GCC type attributes](https://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html)
|
||||
* [Previous part](linux-bootstrap-2.md)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user