UEFI: Going back to 32-bit mode for a bootloader
Posted: Sun Apr 13, 2025 12:15 pm
Hi!
I'm working on a small UEFI bootloader but having problems. I load the kernel image in memory at the requested load address (virtual) but now I'm confused on how to properly start execution.
My 64-bit kernel expects a 32-bit environment so it can craft page tables and transition to long mode, so here's my load process:
- Setup a 32/64-bit GDT/GDTR in low memory and load it, everything is fine
- Disable IRQs
- Use "lretq" to go to a small 32-bit code area that jumps to the kernel
Full code
This works for a short period of time before SP starts pointing to what it was in UEFI mode at a seemingly random instruction.
I have no idea what could possible be going on, but I don't disable paging beforehand so that might be the reason. Does anyone have any good suggestions on what to do or how to solve this?
I'm working on a small UEFI bootloader but having problems. I load the kernel image in memory at the requested load address (virtual) but now I'm confused on how to properly start execution.
My 64-bit kernel expects a 32-bit environment so it can craft page tables and transition to long mode, so here's my load process:
- Setup a 32/64-bit GDT/GDTR in low memory and load it, everything is fine
- Disable IRQs
- Use "lretq" to go to a small 32-bit code area that jumps to the kernel
Full code
Code: Select all
.global platform_bootKernelImage
platform_bootKernelImage:
// Switch stacks
mov %rdx, %rsp
// Push address of kernel
push %rdi
// Load GDT
lgdt (%rsi)
// Disable IRQs
cli
// Can't disable paging
// Go to protected mode
push $0x8
lea .inProtectedMode(%rip), %rax
push %rax
lretq
.code32
.inProtectedMode:
movw $0x10, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
// Load dummy variables
mov $0x2BADB002, %eax
mov $0xDEADDEAD, %ebp
// Jump to kernel
jmpl *0(%esp)
cli
hlt
I have no idea what could possible be going on, but I don't disable paging beforehand so that might be the reason. Does anyone have any good suggestions on what to do or how to solve this?