|
@@ -38,41 +38,36 @@ struct gdt_ptr {
|
|
|
|
|
|
Of course in our case the `gdt_ptr` does not represent the `GDTR` register, but `IDTR` since we set the `Interrupt Descriptor Table`. You will not find an `idt_ptr` structure, because if it had been in the Linux kernel source code, it would have been the same as a `gdt_ptr` but with a different name. It would make no sense to create two structures that only differ in their names. Note here that we do not fill the `Interrupt Descriptor Table` with entries, because it is too early to handle any interrupts or exceptions at this point. That's why we just fill the `IDT` with `NULL`.
|
|
Of course in our case the `gdt_ptr` does not represent the `GDTR` register, but `IDTR` since we set the `Interrupt Descriptor Table`. You will not find an `idt_ptr` structure, because if it had been in the Linux kernel source code, it would have been the same as a `gdt_ptr` but with a different name. It would make no sense to create two structures that only differ in their names. Note here that we do not fill the `Interrupt Descriptor Table` with entries, because it is too early to handle any interrupts or exceptions at this point. That's why we just fill the `IDT` with `NULL`.
|
|
|
|
|
|
-After the setup of the [Interrupt descriptor table](http://en.wikipedia.org/wiki/Interrupt_descriptor_table), [Global Descriptor Table](http://en.wikipedia.org/wiki/GDT) and other stuff we jump into [protected mode](http://en.wikipedia.org/wiki/Protected_mode) in the - [arch/x86/boot/pmjump.S](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/pmjump.S). You can read more about it in the [part](https://0xax.gitbooks.io/linux-insides/content/Booting/linux-bootstrap-3.html) which describes the transition to protected mode.
|
|
|
|
|
|
+After the setup of the [Interrupt descriptor table](http://en.wikipedia.org/wiki/Interrupt_descriptor_table), [Global Descriptor Table](http://en.wikipedia.org/wiki/GDT) and other stuff we jump into [protected mode](http://en.wikipedia.org/wiki/Protected_mode) in the - [arch/x86/boot/pmjump.S](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/pmjump.S) file. You can read more about it in the [part](https://0xax.gitbooks.io/linux-insides/content/Booting/linux-bootstrap-3.html), which describes the transition to protected mode.
|
|
|
|
|
|
-We already know from the earliest parts that entry to protected mode is located in the `boot_params.hdr.code32_start` and you can see that we pass the entry of the protected mode and `boot_params` to the `protected_mode_jump` in the end of the [arch/x86/boot/pm.c](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/pm.c):
|
|
|
|
|
|
+The entry to protected mode is located in the `boot_params.hdr.code32_start` and passed together with the `boot_params` to the `protected_mode_jump` function at the end of [arch/x86/boot/pm.c](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/pm.c):
|
|
|
|
|
|
```C
|
|
```C
|
|
protected_mode_jump(boot_params.hdr.code32_start,
|
|
protected_mode_jump(boot_params.hdr.code32_start,
|
|
(u32)&boot_params + (ds() << 4));
|
|
(u32)&boot_params + (ds() << 4));
|
|
```
|
|
```
|
|
|
|
|
|
-The `protected_mode_jump` is defined in the [arch/x86/boot/pmjump.S](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/pmjump.S) and gets these two parameters in the `ax` and `dx` registers using one of the [8086](http://en.wikipedia.org/wiki/Intel_8086) calling [conventions](http://en.wikipedia.org/wiki/X86_calling_conventions#List_of_x86_calling_conventions):
|
|
|
|
|
|
+The `protected_mode_jump` function is defined at [arch/x86/boot/pmjump.S](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/pmjump.S) and receives these two parameters within the `ax` and `dx` registers, using one of the [8086](http://en.wikipedia.org/wiki/Intel_8086) calling [conventions](http://en.wikipedia.org/wiki/X86_calling_conventions#List_of_x86_calling_conventions):
|
|
|
|
|
|
```assembly
|
|
```assembly
|
|
-GLOBAL(protected_mode_jump)
|
|
|
|
|
|
+SYM_FUNC_START_NOALIGN(protected_mode_jump)
|
|
...
|
|
...
|
|
...
|
|
...
|
|
...
|
|
...
|
|
.byte 0x66, 0xea # ljmpl opcode
|
|
.byte 0x66, 0xea # ljmpl opcode
|
|
-2: .long in_pm32 # offset
|
|
|
|
|
|
+2: .long .Lin_pm32 # offset
|
|
.word __BOOT_CS # segment
|
|
.word __BOOT_CS # segment
|
|
-...
|
|
|
|
-...
|
|
|
|
-...
|
|
|
|
-ENDPROC(protected_mode_jump)
|
|
|
|
|
|
+SYM_FUNC_END(protected_mode_jump)
|
|
```
|
|
```
|
|
|
|
|
|
where `in_pm32` contains a jump to the 32-bit entry point:
|
|
where `in_pm32` contains a jump to the 32-bit entry point:
|
|
|
|
|
|
```assembly
|
|
```assembly
|
|
-GLOBAL(in_pm32)
|
|
|
|
- ...
|
|
|
|
- ...
|
|
|
|
- jmpl *%eax // %eax contains address of the `startup_32`
|
|
|
|
|
|
+SYM_FUNC_START_LOCAL_NOALIGN(.Lin_pm32)
|
|
...
|
|
...
|
|
...
|
|
...
|
|
-ENDPROC(in_pm32)
|
|
|
|
|
|
+ jmpl *%eax # Jump to the 32-bit entrypoint
|
|
|
|
+SYM_FUNC_END(.Lin_pm32)
|
|
```
|
|
```
|
|
|
|
|
|
As you can remember the 32-bit entry point is in the [arch/x86/boot/compressed/head_64.S](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/compressed/head_64.S) assembly file, although it contains `_64` in its name. We can see the two similar files in the `arch/x86/boot/compressed` directory:
|
|
As you can remember the 32-bit entry point is in the [arch/x86/boot/compressed/head_64.S](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/arch/x86/boot/compressed/head_64.S) assembly file, although it contains `_64` in its name. We can see the two similar files in the `arch/x86/boot/compressed` directory:
|