You've got it wrong sorry
The processor always starts in 16 bit mode, for backwards compatibly. In 16bit you don't have the full 4gb address space of 32bit or the 2^64 space of x64. The memory addressing in x16 is very different too. To access an address you need to multiply the segment selector by 16d (ROL 1) and add the offset. For example to jump to address 0x1000 you could do this:
jmp 0:1000
But this will also produce the same effect:
jmp 100:0 ; 100:0 == 0:1000 while 10:100 = 200
Once you've got your 16bit boot loader up and running, you can switch to x86. When x86 is up and running you switch (for the last time) to x64, you need to be in protected mode first, since certain functions of the processor can't be accessed in realmode and you need to functions to make the switch. The problem is that any paging related exceptions that occur during the switch to x64 must be handled by a handler in the IDT, if you have no handler yet your processor will triple fault.
So what you need to do is:
[BOOT]
Change the a21 line for extra memory
Load kernel
Switch to x86
Fix IDT
Enable paging
Switch to x64
relocate kernel
run kernel
And that's it!
You can of course use grub to load your kernel. Everyone uses grub
