Hi,
I've read the documentation for the x86 boot protocol at
Documentation/arch/x86/boot.rst. It states the following:
> In 64-bit boot protocol, the kernel is started by jumping to the
> 64-bit kernel entry point, which is the start address of loaded
> 64-bit kernel plus 0x200.
When I build a kernel and check the bytes at 0x200, they have the
following disassembly:
0x00000200 eb6a jmp 0x26c
The bytes at 0x26c disassemble as follows:
0x0000026c 8cd8 mov eax, ds
0x0000026e 8ec0 mov es, eax
0x00000270 fc cld
0x00000271 8cd2 mov edx, ss
0x00000273 39c2 cmp edx, eax
0x00000275 89e2 mov edx, esp
0x00000277 7416 je 0x28f
0x00000279 ba204df606 mov edx, 0x6f64d20
0x0000027e 1102 adc dword [rdx], eax
0x00000280 8074048b16 xor byte [rsp + rax - 0x75], 0x16
0x00000285 2402 and al, 2
0x00000287 81c200047302 add edx, 0x2730400
0x0000028d 31d2 xor edx, edx
0x0000028f 83e2fc and edx, 0xfffffffc
0x00000292 7503 jne 0x297
0x00000294 bafcff8ed0 mov edx, 0xd08efffc
0x00000299 660fb7e2 movzx sp, dx
0x0000029d fb sti
0x0000029e 1e invalid
Notice the invalid opcode at 0x29e. In 32-bit mode 0x1e would be PUSH
DS, but it is invalid in 64-bit mode. It appears the 64-bit entrypoint
is invalid. Are the docs out of date?
Thanks,
Yahya Sohail
On Wed, Aug 2, 2023 at 9:50 PM Yahya Sohail <[email protected]> wrote:
>
> Hi,
>
> I've read the documentation for the x86 boot protocol at
> Documentation/arch/x86/boot.rst. It states the following:
> > In 64-bit boot protocol, the kernel is started by jumping to the
> > 64-bit kernel entry point, which is the start address of loaded
> > 64-bit kernel plus 0x200.
>
> When I build a kernel and check the bytes at 0x200, they have the
> following disassembly:
> 0x00000200 eb6a jmp 0x26c
>
> The bytes at 0x26c disassemble as follows:
> 0x0000026c 8cd8 mov eax, ds
> 0x0000026e 8ec0 mov es, eax
> 0x00000270 fc cld
> 0x00000271 8cd2 mov edx, ss
> 0x00000273 39c2 cmp edx, eax
> 0x00000275 89e2 mov edx, esp
> 0x00000277 7416 je 0x28f
> 0x00000279 ba204df606 mov edx, 0x6f64d20
> 0x0000027e 1102 adc dword [rdx], eax
> 0x00000280 8074048b16 xor byte [rsp + rax - 0x75], 0x16
> 0x00000285 2402 and al, 2
> 0x00000287 81c200047302 add edx, 0x2730400
> 0x0000028d 31d2 xor edx, edx
> 0x0000028f 83e2fc and edx, 0xfffffffc
> 0x00000292 7503 jne 0x297
> 0x00000294 bafcff8ed0 mov edx, 0xd08efffc
> 0x00000299 660fb7e2 movzx sp, dx
> 0x0000029d fb sti
> 0x0000029e 1e invalid
>
> Notice the invalid opcode at 0x29e. In 32-bit mode 0x1e would be PUSH
> DS, but it is invalid in 64-bit mode. It appears the 64-bit entrypoint
> is invalid. Are the docs out of date?
>
> Thanks,
> Yahya Sohail
The code you are looking at is from arch/x86/boot/header.S, which is
the 16-bit legacy BIOS entry. The 64-bit entry point the boot docs
are referring to is in arch/x86/boot/compressed/head_64.S. The 0x200
offset is relative to the start of the protected mode setup code,
which is appended to the setup header and legacy BIOS code to form the
bzImage.
Brian Gerst