@Jester found my problem and answered both questions. The solution was actually in the file that I linked , although I skipped the corresponding section. I include here the relevant material for posterity:
In the 32-bit boot protocol, the first step in booting the Linux kernel is to configure the boot parameters (struct boot_params, traditionally called the "zero page"). The memory for struct boot_params must be allocated and initialized to all zero. Then, the installation header from offset 0x01f1 of the kernel image must be loaded into the boot_params structure and examined. The end of the installation header can be calculated as follows:
0x0202 + byte value with offset 0x0201
In addition to reading / modifying / writing the installation header of the boot_params structure, as with the 16-bit boot protocol, the loader must also fill in the additional struct boot_params fields, as described in the zero-page.txt file.
After configuring struct boot_params, the bootloader can load the 32/64-bit kernel in the same way as for the 16-bit boot protocol.
In the 32-bit boot protocol, the kernel is started by navigating to the 32-bit kernel entry point, which is the starting address of the loaded 32/64-bit kernel.
When entering, the CPU must be in 32-bit protected mode with paging disabled; GDT must be loaded with descriptors for the __BOOT_CS (0x10) and __BOOT_DS (0x18) selectors; both descriptors must be 4G flat segment; __BOOT_CS must have permission to execute / read, and __BOOT_DS must have permission to read / write; CS must be __BOOT_CS and DS, ES, SS must be __BOOT_DS; interruption must be disabled; % esi should contain the base address of the boot_params structure; % ebp,% edi and% ebx must be zero.
64-bit instructions can also be found in the same document.