From e0cb85d230a14df628ba361b09999dc90c6d3cbe Mon Sep 17 00:00:00 2001 From: "Andreas J. Reichel" Date: Fri, 13 Mar 2020 17:54:43 +0100 Subject: [PATCH 1/2] Fix description of 'rep stosl' in bootstrap-4 rep stosl does not modify 'edi' but the memory, where 'edi' points to. Signed-off-by: Andreas J. Reichel --- Booting/linux-bootstrap-4.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Booting/linux-bootstrap-4.md b/Booting/linux-bootstrap-4.md index 72de9e7..012b96a 100644 --- a/Booting/linux-bootstrap-4.md +++ b/Booting/linux-bootstrap-4.md @@ -480,7 +480,7 @@ Let's look at how this is implemented. First, we clear the buffer for the page t We put the address of `pgtable` with an offset of `ebx` (remember that `ebx` points to the location in memory where the kernel will be decompressed later) into the `edi` register, clear the `eax` register and set the `ecx` register to `6144`. -The `rep stosl` instruction will write the value of `eax` to `edi`, add `4` to `edi` and decrement `ecx` by `1`. This operation will be repeated while the value of the `ecx` register is greater than zero. That's why we put `6144` or `BOOT_INIT_PGT_SIZE/4` in `ecx`. +The `rep stosl` instruction will write the value of `eax` to the memory location where `edi` points to, increment `edi` by `4`, and decrement `ecx` by `1`. This operation will be repeated while the value of the `ecx` register is greater than zero. That's why we put `6144` or `BOOT_INIT_PGT_SIZE/4` in `ecx`. `pgtable` is defined at the end of the [arch/x86/boot/compressed/head_64.S](https://github.com/torvalds/linux/blob/v4.16/arch/x86/boot/compressed/head_64.S) assembly file: From 8be1e44662c16ef4425eee09d4e428b1a70ec3dc Mon Sep 17 00:00:00 2001 From: "Andreas J. Reichel" Date: Fri, 13 Mar 2020 18:06:50 +0100 Subject: [PATCH 2/2] Correct description of btsl $_EFER_LME, %eax The btsl not only tests the bit, it tests the bit by transfering it into the carry flag and then sets it as well. Otherwise the wrmsr would not make sense. Signed-off-by: Andreas J. Reichel --- Booting/linux-bootstrap-4.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Booting/linux-bootstrap-4.md b/Booting/linux-bootstrap-4.md index 012b96a..539a544 100644 --- a/Booting/linux-bootstrap-4.md +++ b/Booting/linux-bootstrap-4.md @@ -568,7 +568,7 @@ First of all we need to set the `EFER.LME` flag in the [MSR](http://en.wikipedia wrmsr ``` -Here we put the `MSR_EFER` flag (which is defined in [arch/x86/include/asm/msr-index.h](https://github.com/torvalds/linux/blob/v4.16/arch/x86/include/asm/msr-index.h)) in the `ecx` register and execute the `rdmsr` instruction which reads the [MSR](http://en.wikipedia.org/wiki/Model-specific_register) register. After `rdmsr` executes, the resulting data is stored in `edx:eax` according to the `MSR` register specified in `ecx`. We check the `EFER_LME` bit with the `btsl` instruction and write data from `edx:eax` back to the `MSR` register with the `wrmsr` instruction. +Here we put the `MSR_EFER` flag (which is defined in [arch/x86/include/asm/msr-index.h](https://github.com/torvalds/linux/blob/v4.16/arch/x86/include/asm/msr-index.h)) in the `ecx` register and execute the `rdmsr` instruction which reads the [MSR](http://en.wikipedia.org/wiki/Model-specific_register) register. After `rdmsr` executes, the resulting data is stored in `edx:eax` according to the `MSR` register specified in `ecx`. We check the current `EFER_LME` bit, transfer it into the carry flag and update the bit, all with the `btsl` instruction. Then we write data from `edx:eax` back to the `MSR` register with the `wrmsr` instruction. In the next step, we push the address of the kernel segment code to the stack (we defined it in the GDT) and put the address of the `startup_64` routine in `eax`.