1
Mixing it up with EFI mixed mode
Matt Fleming, SSG/OTC
2
Debian 8 “Jessie” release
“Support for mixed-mode EFI systems like the Intel Bay
Trail: a 64-bit platform crippled with a 32-bit EFI
firmware.”
3
What is EFI mixed mode?
• Fat 64-bit OS on small 32-bit EFI firmware
• Implemented in the x86 kernel
• Translates x86-64 ABI to i386
• Utilises full capabilities of CPU
• Increases virtual address space
4
How does it work?
2 Phases
5
How does it work?
2 Phases
Boot transition Runtime thunking
6
Boot transition
7
Boot transition – Traditional entry point
64-bit kernel image
efi64_stub_entry
• Boot loaders always enter via native entry point
• Legacy +512 bytes for 64-bit loaders
64-bit boot loader
bootx64.efi
8
Boot transition – Mixed mode entry points
64-bit kernel image
efi64_stub_entry
efi32_stub_entry
• 2 entry points are available
• No changes required to Linux boot loaders
• All magic happens in the kernel
• 1 kernel image for both scenarios
32-bit/64-bit boot loaders
bootia32.efi
512bytes
bootx64.efi
9
Runtime transition
(Thunking)
10
Thunking at runtime
• Dedicated kernel page table
• UEFI regions are mapped with VA == PA
• Physical addresses are passed to UEFI
• Luckily never seen address above 4GB
0xffffffffffffffff
0x0
0xffffffff
Virtual AddressesPhysical Addresses
Kernel text/data
11
Thunking at runtime
0x000000fde3c190
1. Convert pointers to physical address
0xffff8800fde3c190
2. Truncate to 32-bits
12
Thunking at runtime
0xfde3c190
3. Push arguments onto stack (convert ABI)
4. Switch to 32-bit CPU mode and call UEFI
0x000000340fdece
0xfde45080
0x000000fde3c190
Stack
0x340fdece
Registers
13
Development gotchas
• “unsigned long” no longer represents natural pointer size
• Some UEFI runtime services not supported (UpdateCapsule())
• If memory existed above 4GB: kaboom!
14
Supported boot loaders
• Grub2
• Used by Debian, Fedora, Ubuntu
• Efilinux
• Kernel support developed using efilinux
• rEFInd
• Support unconfirmed
• Syslinux
15
A quick word on gummiboot
• Gummiboot is an UEFI application loader not a boot loader
• It has no understanding of the different Linux kernel entry points
• It simply uses the UEFI boot services to load and run applications
• Linux kernel masquerades as PE/COFF application
16
Ingredients for rolling your own solution
• 32-bit boot loader from the supported list
• Drop it in EFI System Partition (ESP) at EFIBOOTBOOTIA32.EFI
• Build your x86 kernel with the following options
• CONFIG_EFI_STUB
• CONFIG_EFI_MIXED
• Profit!
17
Q & A

Mixing it up with EFI mixed mode

  • 1.
    1 Mixing it upwith EFI mixed mode Matt Fleming, SSG/OTC
  • 2.
    2 Debian 8 “Jessie”release “Support for mixed-mode EFI systems like the Intel Bay Trail: a 64-bit platform crippled with a 32-bit EFI firmware.”
  • 3.
    3 What is EFImixed mode? • Fat 64-bit OS on small 32-bit EFI firmware • Implemented in the x86 kernel • Translates x86-64 ABI to i386 • Utilises full capabilities of CPU • Increases virtual address space
  • 4.
    4 How does itwork? 2 Phases
  • 5.
    5 How does itwork? 2 Phases Boot transition Runtime thunking
  • 6.
  • 7.
    7 Boot transition –Traditional entry point 64-bit kernel image efi64_stub_entry • Boot loaders always enter via native entry point • Legacy +512 bytes for 64-bit loaders 64-bit boot loader bootx64.efi
  • 8.
    8 Boot transition –Mixed mode entry points 64-bit kernel image efi64_stub_entry efi32_stub_entry • 2 entry points are available • No changes required to Linux boot loaders • All magic happens in the kernel • 1 kernel image for both scenarios 32-bit/64-bit boot loaders bootia32.efi 512bytes bootx64.efi
  • 9.
  • 10.
    10 Thunking at runtime •Dedicated kernel page table • UEFI regions are mapped with VA == PA • Physical addresses are passed to UEFI • Luckily never seen address above 4GB 0xffffffffffffffff 0x0 0xffffffff Virtual AddressesPhysical Addresses Kernel text/data
  • 11.
    11 Thunking at runtime 0x000000fde3c190 1.Convert pointers to physical address 0xffff8800fde3c190 2. Truncate to 32-bits
  • 12.
    12 Thunking at runtime 0xfde3c190 3.Push arguments onto stack (convert ABI) 4. Switch to 32-bit CPU mode and call UEFI 0x000000340fdece 0xfde45080 0x000000fde3c190 Stack 0x340fdece Registers
  • 13.
    13 Development gotchas • “unsignedlong” no longer represents natural pointer size • Some UEFI runtime services not supported (UpdateCapsule()) • If memory existed above 4GB: kaboom!
  • 14.
    14 Supported boot loaders •Grub2 • Used by Debian, Fedora, Ubuntu • Efilinux • Kernel support developed using efilinux • rEFInd • Support unconfirmed • Syslinux
  • 15.
    15 A quick wordon gummiboot • Gummiboot is an UEFI application loader not a boot loader • It has no understanding of the different Linux kernel entry points • It simply uses the UEFI boot services to load and run applications • Linux kernel masquerades as PE/COFF application
  • 16.
    16 Ingredients for rollingyour own solution • 32-bit boot loader from the supported list • Drop it in EFI System Partition (ESP) at EFIBOOTBOOTIA32.EFI • Build your x86 kernel with the following options • CONFIG_EFI_STUB • CONFIG_EFI_MIXED • Profit!
  • 17.