You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 06_Userspace/02_Switching_Modes.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -18,7 +18,7 @@ Changing the flags atomically like this means we can go from having interrupts d
18
18
19
19
### What to Push Onto The Stack
20
20
21
-
Now let's talk about what these values should be.`rflags` is an easy one: set it to `0x202`. Bit 1 is a legacy feature and must always be set, the ninth bit (`0x200`) is the `IF` interrupt enable flag. This means all other flags are cleared, and is what C/C++ and other languages expect flags to look like when starting a program.
21
+
Now let's talk about what these values should be:`rflags` is an easy one, set it to `0x202`. Bit 1 is a legacy feature and must always be set, the ninth bit (`0x200`) is the `IF` interrupt enable flag. This means all other flags are cleared, and is what C/C++ and other languages expect flags to look like when starting a program.
22
22
23
23
For `ss` and `cs` it depends on the layout of your GDT. We'll assume that there are 5 entries in the GDT:
24
24
@@ -28,7 +28,7 @@ For `ss` and `cs` it depends on the layout of your GDT. We'll assume that there
28
28
- 0x18, User Code (ring 3)
29
29
- 0x20, User Data (ring 3)
30
30
31
-
Now `ss` and `cs` are *selectors*, which you'll remember are not just a byte offset into the gdt, but the lowest two bits contain a field called _RPL_ (Requested Privilege Level) is a legacy feature, but it's still enforced by the cpu, so we have to use it. RPL is a sort of 'override' for the target ring, it's useful in some edge cases, but otherwise is best set to the ring we want to jump to.
31
+
Now `ss` and `cs` are *selectors*, which you'll remember are not just a byte offset into the gdt, the lowest two bits contain a field called _RPL_ (Requested Privilege Level) that is a legacy feature, but it's still enforced by the cpu, so we have to use it. _RPL_ is a sort of 'override' for the target ring, it's useful in some edge cases, but otherwise is best set to the ring we want to jump to.
32
32
33
33
So if we're going to ring 0 (supervisor), RPL can be left at 0. If going to ring 3 (user) we'd set it to 3.
| 15:0 | 0xFFFF | Represents the limit field for this segment. Ignored in long mode, but best set to max value in case we support compatibility mode in the future. |
| 15:0 | 0xFFFF | Represents the limit field for this segment. Ignored in long mode, but best set to max value in case we support compatibility mode in the future. |
59
59
| 31:16 | TSS address bits 15:0 | Contains the lowest 16 bits of the tss address. |
60
-
| 39:32 | TSS address bits 23:16 | Contains the next 8 bits of the tss address. |
61
-
| 47:40 | 0b10001001 | Sets the type of GDT descriptor, this magic value indicates it's a valid TSS descriptor. If curious as to how this value was created, see the manual or the section on the GDT. |
62
-
| 55:48 | 0b10000 | Additional fields for the TSS entry. This bit means the TSS is `available`, it's generally unused in long mode, but has some side effects if compatibility mode is enabled. |
63
-
| 63:56 | TSS address bits 31:24 | Contains the next 8 bits of the tss address. |
64
-
| 95:64 | TSS address bits 63:32 | Contains the upper 32 bits of the tss address. |
60
+
| 39:32 | TSS address bits 23:16 | Contains the next 8 bits of the tss address. |
61
+
| 47:40 | 0b10001001 | Sets the type of GDT descriptor, it's DPL (bits 45:46) to 0, marks it as present (bit 47). The rest of this magic value indicates it's a valid TSS descriptor. If curious as to how this value was created, see the manual or our section about the GDT.|
62
+
| 55:48 | 0b10000 | Additional fields for the TSS entry. This bit means the TSS is `available`, it's generally unused in long mode, but has some side effects if compatibility mode is enabled. |
63
+
| 63:56 | TSS address bits 31:24 | Contains the next 8 bits of the tss address. |
64
+
| 95:64 | TSS address bits 63:32 | Contains the upper 32 bits of the tss address. |
65
+
| 96:127 | Reserved | They should be left as 0. |
66
+
67
+
Yes, it's right a TSS descriptor for the GDT is 128 bits. This because we need to specify the 64 bit address containing the TSS data structure.
65
68
66
69
Now for the third step, we need to load the task register. This is similar to the segment registers, in that it has visible and invisible parts. It's loaded in a similar manner, although we use a dedicated instruction instead of a simple `mov`.
0 commit comments