boot-4: Improve description for kernel relocation and paging#904
boot-4: Improve description for kernel relocation and paging#904
Conversation
|
E-books generated for this pull request available at: https://github.com/0xAX/linux-insides/actions/runs/22018627185 |
8eef110 to
95bb0d5
Compare
|
E-books generated for this pull request available at: https://github.com/0xAX/linux-insides/actions/runs/22018847289 |
95bb0d5 to
09af390
Compare
|
E-books generated for this pull request available at: https://github.com/0xAX/linux-insides/actions/runs/22020648645 |
09af390 to
2b95b75
Compare
|
E-books generated for this pull request available at: https://github.com/0xAX/linux-insides/actions/runs/22035098613 |
2b95b75 to
73bd829
Compare
Signed-off-by: Alexander Kuleshov <kuleshovmail@gmail.com>
73bd829 to
771204b
Compare
|
E-books generated for this pull request available at: https://github.com/0xAX/linux-insides/actions/runs/22070033196 |
|
E-books generated for this pull request available at: https://github.com/0xAX/linux-insides/actions/runs/22070119113 |
| ### CPU verification | ||
|
|
||
| Before we the kernel can switch to long mode, it needs to check that it runs on the suitable `x86_64` processor. This is done by the next piece of code: | ||
| Before the the kernel can switch to long mode, it needs to check that it runs on the suitable `x86_64` processor. This is done by the next piece of code: |
There was a problem hiding this comment.
| Before the the kernel can switch to long mode, it needs to check that it runs on the suitable `x86_64` processor. This is done by the next piece of code: | |
| Before the kernel can switch to long mode, it checks that it runs on a suitable `x86_64` processor by running this piece of code: |
| ``` | ||
|
|
||
| The `verify_cpu` function defined in the [arch/x86/kernel/verify_cpu.S](https://github.com/torvalds/linux/blob/master/arch/x86/kernel/verify_cpu.S) and executes the [cpuid](https://en.wikipedia.org/wiki/CPUID) instruction to check the details of the processors on which kernel is running on. In our case, the most crucial check is for `long mode` and [SSE](http://en.wikipedia.org/wiki/Streaming_SIMD_Extensions) support. and sets the `eax` register to `0` on success and `1` on failure. If the long mode is not supported by the current processor, the kernel jumps to the `no_longmode` label which just stops the CPU with the `hlt` instruction: | ||
| The `verify_cpu` function defined in the [arch/x86/kernel/verify_cpu.S](https://github.com/torvalds/linux/blob/master/arch/x86/kernel/verify_cpu.S) and executes the [cpuid](https://en.wikipedia.org/wiki/CPUID) instruction to check the details of the processors on which kernel is running on. In our case, the most crucial check is for `long mode` and [SSE](http://en.wikipedia.org/wiki/Streaming_SIMD_Extensions) support. This function returns the result in the `eax` register which value will be `0` on success and `1` on failure. If the long mode is not supported by the current processor, the kernel jumps to the `no_longmode` label which just stops the CPU with the `hlt` instruction: |
There was a problem hiding this comment.
| The `verify_cpu` function defined in the [arch/x86/kernel/verify_cpu.S](https://github.com/torvalds/linux/blob/master/arch/x86/kernel/verify_cpu.S) and executes the [cpuid](https://en.wikipedia.org/wiki/CPUID) instruction to check the details of the processors on which kernel is running on. In our case, the most crucial check is for `long mode` and [SSE](http://en.wikipedia.org/wiki/Streaming_SIMD_Extensions) support. This function returns the result in the `eax` register which value will be `0` on success and `1` on failure. If the long mode is not supported by the current processor, the kernel jumps to the `no_longmode` label which just stops the CPU with the `hlt` instruction: | |
| The `verify_cpu` function is defined in [arch/x86/kernel/verify_cpu.S](https://github.com/torvalds/linux/blob/master/arch/x86/kernel/verify_cpu.S) and executes the [CPUID](https://en.wikipedia.org/wiki/CPUID) instruction to check the details of the processors on which the kernel is running. In our case, the most crucial check is for long mode and [SSE](http://en.wikipedia.org/wiki/Streaming_SIMD_Extensions) support. This function returns the result in the `eax` register. Its value is `0` on success and `1` on failure. If long mode is not supported by the current processor, the kernel jumps to the `no_longmode` label, which stops the CPU with the `hlt` instruction: |
| - Chunk of compressed kernel code | ||
|
|
||
| Obviously, the final decompressed kernel code will be bigger than compressed image. The memory area where the decompressed kernel should locate may overlap with the area where the compressed image is located. In this case, the compressed image could be overwritten during decompression process. To avoid this, the the kernel will copy the compressed part for safe decompression. This is done by the following code: | ||
| We may see it looking at the [arch/x86/boot/compressed/vmlinux.lds.S](https://github.com/torvalds/linux/blob/master/arch/x86/boot/compressed/vmlinux.lds.S) linker script: |
There was a problem hiding this comment.
| We may see it looking at the [arch/x86/boot/compressed/vmlinux.lds.S](https://github.com/torvalds/linux/blob/master/arch/x86/boot/compressed/vmlinux.lds.S) linker script: | |
| We can see it looking at the [arch/x86/boot/compressed/vmlinux.lds.S](https://github.com/torvalds/linux/blob/master/arch/x86/boot/compressed/vmlinux.lds.S) linker script: |
| } | ||
| ``` | ||
|
|
||
| There are three sections in the beginning of the linker script above: |
There was a problem hiding this comment.
| There are three sections in the beginning of the linker script above: | |
| There are three sections at the beginning of the linker script above: |
| - `.rodaya..compressed` - section with the compressed kernel image | ||
| - `.text` - section with the decompressor code | ||
|
|
||
| The kernel decompression happens in place. This means that the parts of the decompressed kernel image will overwrite the parts of the compressed image during the decompression process. It may sound dangerous as if the decompressed part will overwrite the decompressor code or the part of the compressed kernel image which is not decompressed yet, this will lead to the code or image corruption. |
There was a problem hiding this comment.
| The kernel decompression happens in place. This means that the parts of the decompressed kernel image will overwrite the parts of the compressed image during the decompression process. It may sound dangerous as if the decompressed part will overwrite the decompressor code or the part of the compressed kernel image which is not decompressed yet, this will lead to the code or image corruption. | |
| The kernel decompression happens in-place, which is the same place where the compressed kernel is. This means that the parts of the decompressed kernel image will overwrite the parts of the compressed image during the decompression process. It may sound dangerous – if the decompressed part overwrites the decompressor code or the part of the compressed kernel image that is not decompressed yet, this will lead to code or image corruption. |
| ``` | ||
|
|
||
| This is the `Long Mode Enable` bit and it is mandatory action to set this bit to enable `64-bit` mode. | ||
| This is the `Long Mode Enable` bit and it is mandatory action to set this bit to enable long mode. |
There was a problem hiding this comment.
| This is the `Long Mode Enable` bit and it is mandatory action to set this bit to enable long mode. | |
| This is the `Long Mode Enable` bit, and it is mandatory to set this bit to enable long mode. |
| This is the `Long Mode Enable` bit and it is mandatory action to set this bit to enable `64-bit` mode. | ||
| This is the `Long Mode Enable` bit and it is mandatory action to set this bit to enable long mode. | ||
|
|
||
| In the next step, we may see the preparation of the jump on the long mode entrypoint. To do this jump, the kernel stores the base address of the kernel segment code along with the address of the long mode entrypoint on the stack: |
There was a problem hiding this comment.
| In the next step, we may see the preparation of the jump on the long mode entrypoint. To do this jump, the kernel stores the base address of the kernel segment code along with the address of the long mode entrypoint on the stack: | |
| In the next step, we can see the preparation for the jump on the long mode entrypoint. To do this jump, the kernel stores the base address of the kernel segment code along with the address of the long mode entrypoint on the stack: |
| ``` | ||
|
|
||
| Everything is ready. Since our stack contains the base of the kernel code segment and the address of the entrypoint, kernel executes the last instruction in protected mode: | ||
| Since the stack contains the base of the kernel code segment and the address of the entrypoint, kernel executes the last instruction in protected mode: |
There was a problem hiding this comment.
| Since the stack contains the base of the kernel code segment and the address of the entrypoint, kernel executes the last instruction in protected mode: | |
| Since the stack contains the base of the kernel code segment and the address of the entrypoint, the kernel executes the last instruction in protected mode: |
| ``` | ||
|
|
||
| The CPU extracts the address of the `startup_64` from the stack and jumps there: | ||
| The CPU extracts the address of the `startup_64` which is the long mode entrypoint from the stack and jumps there: |
There was a problem hiding this comment.
| The CPU extracts the address of the `startup_64` which is the long mode entrypoint from the stack and jumps there: | |
| The CPU extracts the address of `startup_64`, which is the long mode entrypoint from the stack, and jumps there: |
|
|
||
| The Linux kernel now in 64-bit mode 🎉 | ||
|
|
||
| The Linux kernel now is in 64-bit mode 🎉 |
There was a problem hiding this comment.
| The Linux kernel now is in 64-bit mode 🎉 | |
| The Linux kernel is now in 64-bit mode! 🎉 |
klaudiagrz
left a comment
There was a problem hiding this comment.
Please see the comments
Description
The PR should provide way more better description of the preparation for kernel relocation and some tries to improve paging description.