Merge branch 'master' of github.com:0xAX/linux-internals

pull/51/merge
0xAX 9 years ago
commit 96b44f8f77

@ -4,14 +4,14 @@ Kernel booting process. Part 2.
First steps in the kernel setup
--------------------------------------------------------------------------------
We started to dive into linux kernel internals in the previous [part](https://github.com/0xAX/linux-insides/blob/master/Booting/linux-bootstrap-1.md) and saw the initial part of the kernel setup code. We stopped at the first call of the `main` function (which is the first function written in C) from [arch/x86/boot/main.c](https://github.com/torvalds/linux/blob/master/arch/x86/boot/main.c). Here we will continue to research of the kernel setup code and see what is `protected mode`, some preparation for transition to it, the heap and console initialization, memory detection and many many more. So... Let's go ahead.
We started to dive into linux kernel internals in the previous [part](linux-bootstrap-1.md) and saw the initial part of the kernel setup code. We stopped at the first call of the `main` function (which is the first function written in C) from [arch/x86/boot/main.c](https://github.com/torvalds/linux/blob/master/arch/x86/boot/main.c). Here we will continue to research of the kernel setup code and see what is `protected mode`, some preparation for transition to it, the heap and console initialization, memory detection and many many more. So... Let's go ahead.
Protected mode
--------------------------------------------------------------------------------
Before we can move to the native Intel64 [Long mode](http://en.wikipedia.org/wiki/Long_mode), the kernel must switch the CPU into protected mode. What is it protected mode? Protected mode was first added to the x86 architecture in 1982 and was the main mode of Intel processors from [80286](http://en.wikipedia.org/wiki/Intel_80286) processor until Intel 64 and long mode. Main reason to move from the real mode that there is very limited access to the RAM. As you can remember from the previous part, there is only 2^20 bytes or 1 megabyte, or even less 640 kilobytes.
Before we can move to the native Intel64 [Long mode](http://en.wikipedia.org/wiki/Long_mode), the kernel must switch the CPU into protected mode. What is protected mode? Protected mode was first added to the x86 architecture in 1982 and was the main mode of Intel processors from [80286](http://en.wikipedia.org/wiki/Intel_80286) processor until Intel 64 and long mode. Main reason to move from the real mode that there is very limited access to the RAM. As you can remember from the previous part, there is only 2^20 bytes or 1 megabyte, or even less 640 kilobytes.
Protected mode brought many changes, but main is another memory management. 24-bit address bus was replaced with 32-bit address bus. It gives 4 gigabytes of physical address. Also [paging](http://en.wikipedia.org/wiki/Paging) support was added which we will see in the next parts.
Protected mode brought many changes, but main is another memory management. 24-bit address bus was replaced with 32-bit address bus. It gives 4 gigabytes of physical address. Also [paging](http://en.wikipedia.org/wiki/Paging) support was added which we will see in the next parts.
Memory management in the protected mode is divided into two, almost independent parts:
@ -35,7 +35,7 @@ Memory segmentation was completely redone in the protected mode. There are no 64
lgdt gdt
```
where `lgdt` instruction loads base address and limit of global descriptor table to the `GDTR` register. `GDTR` is 48-bit register and consists of two parts:
where the `lgdt` instruction loads base address and limit of global descriptor table to the `GDTR` register. `GDTR` is 48-bit register and consists of two parts:
* size - 16 bit of global descriptor table;
* address - 32-bit of the global descriptor table.
@ -266,7 +266,7 @@ After that `biosregs` structure filled with `memset`, `bios_putchar` calls [0x10
Heap initialization
--------------------------------------------------------------------------------
After the stack and bss section were prepared in the [header.S](https://github.com/torvalds/linux/blob/master/arch/x86/boot/header.S) (see previous [part](https://github.com/0xAX/linux-insides/blob/master/Booting/linux-bootstrap-1.md)), need 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.
After the stack and bss section were prepared in the [header.S](https://github.com/torvalds/linux/blob/master/arch/x86/boot/header.S) (see previous [part](linux-bootstrap-1.md)), need 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 `CAN_USE_HEAP` flag from the `loadflags` kernel setup header and calculates end of the stack if this flag was set:
@ -464,4 +464,4 @@ Links
* [Intel SpeedStep](http://en.wikipedia.org/wiki/SpeedStep)
* [APM](https://en.wikipedia.org/wiki/Advanced_Power_Management)
* [EDD specification](http://www.t13.org/documents/UploadedDocuments/docs2004/d1572r3-EDD3.pdf)
* [Previous part](https://github.com/0xAX/linux-insides/blob/master/Booting/linux-bootstrap-1.md)
* [Previous part](linux-bootstrap-1.md)

@ -4,9 +4,9 @@ Kernel booting process. Part 3.
Video mode initialization and transition to protected mode
--------------------------------------------------------------------------------
This is the third part of the `Kernel booting process` series. In the previous [part](https://github.com/0xAX/linux-insides/blob/master/linux-bootstrap-2.md#kernel-booting-process-part-2), we stopped right before the call of the `set_video` routine from the [main.c](https://github.com/torvalds/linux/blob/master/arch/x86/boot/main.c#L181). We will see video mode initialization in the kernel setup code, preparation before switching into the protected mode and transition into it in this part.
This is the third part of the `Kernel booting process` series. In the previous [part](linux-bootstrap-2.md#kernel-booting-process-part-2), we stopped right before the call of the `set_video` routine from the [main.c](https://github.com/torvalds/linux/blob/master/arch/x86/boot/main.c#L181). We will see video mode initialization in the kernel setup code, preparation before switching into the protected mode and transition into it in this part.
**NOTE** If you don't know anything about protected mode, you can find some information about it in the previous [part](https://github.com/0xAX/linux-insides/blob/master/linux-bootstrap-2.md#protected-mode). Also there are a couple of [links](https://github.com/0xAX/linux-insides/blob/master/linux-bootstrap-2.md#links) which can help you.
**NOTE** If you don't know anything about protected mode, you can find some information about it in the previous [part](linux-bootstrap-2.md#protected-mode). Also there are a couple of [links](linux-bootstrap-2.md#links) which can help you.
As i wrote above, we will start from the `set_video` function which defined in the [arch/x86/boot/video.c](https://github.com/torvalds/linux/blob/master/arch/x86/boot/video.c#L315) source code file. We can see that it starts with getting of video mode from the `boot_params.hdr` structure:
@ -118,7 +118,7 @@ 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](https://github.com/0xAX/linux-insides/blob/master/linux-bootstrap-2.md)) and returns 1 if there is enough memory for `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`.
That's all. Now we have simple API for heap and can setup video mode.
@ -265,7 +265,7 @@ We can see the last function call - `go_to_protected_mode` in the [main.c](https
`go_to_protected_mode` defined in the [arch/x86/boot/pm.c](https://github.com/torvalds/linux/blob/master/arch/x86/boot/pm.c#L104). It contains some functions which make last preparations before we can jump into protected mode, so let's look on it and try to understand what they do and how it works.
At first we see call of `realmode_switch_hook` function in the `go_to_protected_mode`. This function invokes real mode switch hook if it is present and disables [NMI](http://en.wikipedia.org/wiki/Non-maskable_interrupt). Hooks are used if bootloader runs in a hostile environment More about hooks you can read in the [boot protocol](https://www.kernel.org/doc/Documentation/x86/boot.txt) (see **ADVANCED BOOT LOADER HOOKS**). `readlmode_swtich` hook presents pointer to the 16-bit real mode far subroutine which disables non-maskable interruptions. After we checked `realmode_switch` hook (it doesn't present for me), there is disabling of non-maskable interruptions:
At first we see call of `realmode_switch_hook` function in the `go_to_protected_mode`. This function invokes real mode switch hook if it is present and disables [NMI](http://en.wikipedia.org/wiki/Non-maskable_interrupt). Hooks are used if bootloader runs in a hostile environment. More about hooks you can read in the [boot protocol](https://www.kernel.org/doc/Documentation/x86/boot.txt) (see **ADVANCED BOOT LOADER HOOKS**). `readlmode_swtich` hook presents pointer to the 16-bit real mode far subroutine which disables non-maskable interruptions. After we checked `realmode_switch` hook (it doesn't present for me), there is disabling of non-maskable interruptions:
```assembly
asm volatile("cli");
@ -351,7 +351,7 @@ where we can see - 16-bit length of IDT and 32-bit pointer to it (More details a
Setup Global Descriptor Table
--------------------------------------------------------------------------------
The next point is setup of the Global Descriptor Table (GDT). We can see `setup_gdt` function which setups GDT (you can read about it in the [Kernel booting process. Part 2.](https://github.com/0xAX/linux-insides/blob/master/linux-bootstrap-2.md#protected-mode)). There is definition of the `boot_gdt` array in this function, which contains definition of the three segments:
The next point is setup of the Global Descriptor Table (GDT). We can see `setup_gdt` function which setups GDT (you can read about it in the [Kernel booting process. Part 2.](linux-bootstrap-2.md#protected-mode)). There is definition of the `boot_gdt` array in this function, which contains definition of the three segments:
```C
static const u64 boot_gdt[] __attribute__((aligned(16))) = {
@ -389,7 +389,7 @@ int main(void)
Technically structure which contains one `int` field, must be 4 bytes, but here `aligned` structure will be 16 bytes:
```
$ gcc test.c -o test && ./test
$ gcc test.c -o test && test
Not aligned - 4
Aligned - 16
```
@ -421,7 +421,7 @@ in binary. Let's try to understand what every bit means. We will go through all
* 101 - segment type execute/read/
* 1 - accessed bit
You can know more about every bit in the previous [post](https://github.com/0xAX/linux-insides/blob/master/linux-bootstrap-2.md) or in the [Intel® 64 and IA-32 Architectures Software Developers Manuals 3A](http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html).
You can know more about every bit in the previous [post](linux-bootstrap-2.md) or in the [Intel® 64 and IA-32 Architectures Software Developers Manuals 3A](http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html).
After this we get length of GDT with:
@ -538,4 +538,4 @@ Links
* [A20](http://en.wikipedia.org/wiki/A20_line)
* [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](https://github.com/0xAX/linux-insides/blob/master/Booting/linux-bootstrap-2.md)
* [Previous part](linux-bootstrap-2.md)

@ -1,7 +1,7 @@
Contributing
================================================================================
If you want to contribute to the [linux-insides](https://github.com/0xAX/linux-insides), you can do it with following simple rules:
If you want to contribute to [linux-insides](https://github.com/0xAX/linux-insides), please follow these simple rules:
1. Press fork button:
@ -25,6 +25,6 @@ If you want to contribute to the [linux-insides](https://github.com/0xAX/linux-i
**IMPORTANT**
Please, do the actual changes. While you made your changes, I can merge changes from somebody else and your changes can conflict with `master` branch content. Please rebase on master everytime before you're going to push your changes and check that your branch doesn't conflict with `master`.
Please, make the actual changes. While you made your changes, I can merge changes from somebody else and your changes can conflict with `master` branch content. Please rebase on master everytime before you're going to push your changes and check that your branch doesn't conflict with `master`.
Thank you.

@ -1,15 +1,15 @@
linux-internals
===============
Series of posts about linux kernel.
A series of posts about the linux kernel.
**Goal is simple** - to share my modest knowledge about linux kernel internals and help people who are interested in low-level stuff and linux kernel as me.
**The goal is simple** - to share my modest knowledge about the internals of the linux kernel and help people who are interested in the linux kernel, and other low-level subject matter.
**Questions/Suggestions**: Feel free about any questions or suggestions by pinging me at twitter [@0xAX](https://twitter.com/0xAX), adding [issue](https://github.com/0xAX/linux-internals/issues/new) or just drop me [email](anotherworldofworld@gmail.com).
**Contributions**: Feel free to create issues or create pull-requests if you find issues or my English is poor.
**Contributions**: Feel free to create issues or create pull-requests if you find any issues or my English is poor.
**Please read [CONTRIBUTING.md](https://github.com/0xAX/linux-insides/blob/master/CONTRIBUTING.md) before you pushed your changes.**
**Please read [CONTRIBUTING.md](https://github.com/0xAX/linux-insides/blob/master/CONTRIBUTING.md) before pushing any changes.**
![image](http://oi58.tinypic.com/23upobq.jpg)

@ -22,3 +22,4 @@ Thank you to all contributors:
* [Guillaume Gomez](https://github.com/GuillaumeGomez)
* [Leandro Moreira](https://github.com/leandromoreira)
* [Jonatan Pålsson](https://github.com/jonte)
* [George Horrell](https://github.com/georgehorrell)

Loading…
Cancel
Save