From UEFI Shell to Linux - UEFI Linux BootLoader Zhang Rui Software Engineer Sep 28th 2011 Agenda BootLoader Tridition Linux BootLoader UEFI BootLoader UEFI Linux BootLoader Elilo – the standard UEFI Linux BootLoader 2 BootLoader • The program invoked by the BIOS to load the image of an operating system kernel into RAM • Why BootLoader - 3 CPU can only execute program code found in ROM, RAM. Modern operating systems and application program code and data are stored on nonvolatile data storage devices, such as hard disk, CD, DVD, flash memory cards, USB, foppy, etc… Traditional Linux Bootloader 4 UEFI BootLoader • UEFI application – Loaded by Boot Manager/Other UEFI applications. – Firmware allocates memory and copies the image. – Unloaded when the application returns from its entry points or when it calls the boot service Exit(). • UEFI driver – Same as UEFI application but • Optionally unloaded unless EFI_SUCCESS is not returned. • UEFI OS loader – A special type of UEFI application that normally takes over control of the system from firmware. – Never unloaded unless something bad happens – If success, take control of the system by using ExitBootService(). 5 UEFI conceptual overview 6 UEFI Linux BootLoader • • • • • • 7 A UEFI OS loader A Linux BootLoader No MBR involved Single stage Follows Linux/X86 Boot Protocol Elilo/Grub EFI/efiLinux, etc. Elilo – the uEfi LInux LOader • Elilo is the standard Linux boot loader for UEFI-based PC hardware • Elilo is a UEFI OS loader that can be launched in EFI shell • Source code : http://elilo.sourceforge.net/cgi-bin/blosxom • Can be built directly in Linux 8 How to launch Elilo • Build a UEFI system partition • Copy elilo.efi, Linux kernel image, init ramdisk, and elilo configure file to the system partition • Boot into UEFI shell • “elilo.efi –C elilo.conf” 9 How Elilo works • • • • • • • • • • • 10 Get Boot services table and RuntimeServices table. Get application options, “-C elilo.conf” <- LoadedImageProtocol Parse the options Install the FileSystem <- FileSystemProtocol Read elilo configuration file, “elilo.conf”. Parse config file Load kernel image (bzImage) Load init ramdisk Setup boot parameters for Linux kernel Uninstall the FileSystem Jump to Linux kernel Linux kernel image • bzImage. – setup.bin • .bstext + .bsdata + .header + .entrytext + … – .bstext & .bsdata : legacy code for booting from floppy – .header : setup_header (kernel attributes, used by setup) – .entrytext: start_of_setup – the real mode kernel entry • Boot sector : the first 512 bytes of setup.bin – vmlinux.bin • Protect mode kernel entry + Compressed Linux kernel 11 bzImage Code for floppy .header(setup_header) Setup.bin Real mode entry: start_of_setup bzImage … Protect mode entry: startup_32 Vmlinux.bin Compressed kernel: start_kernel 12 Linux Boot process start_of_setup: arch/x86/boot/header.S main: arch/x86/boot/main.c startup_32: arch/x86/boot/compress/header_32.S decompress_kernel: arch/x86/boot/compress/misc.c start_kernel: init/main.c mount rootfs : 13 /init boot_params structure • Every field in it has a story – kernel_src/Documentation/x86/boot.txt • struct boot_params – APM BIOS information – EFI information • System table • Memory map – Setup header (offset 0x1F1) – E820 entries – … 14 Loading Linux kernel image • • • • • • • 15 Read boot sector Check if it is bzImage If no, fail Read setup data Get the kernel protect mode entry in setup data Allocate memory for kernel image Copy kernel image to Memory Initializing boot_params • create new boot_params for Linux kernel – Allocate memory for boot_params – Copy kernel command line – Get setup header from setup data – Set loader type – Set the kernel start address in boot_params – Set initrd start address in boot_params – Set cmdline address in boot_params – Set EFI system table pointer in boot_params – Set Memory Map <- GetMemoryMap() 16 Jumping to Linux • • • • • • • Now we are ready! • Kernel image/initrd image/cmdline/boot_params are all in memory now • Jump to kernel image right now? NO! Invoke ExitBootServices Save boot_params so that the kernel can get it (esi) Initialize GDT asm volatile ( “movl %0, %%ecx” : : “m” (kernel_entry) ); asm volatile ( “jmp *%%ecx” : : ); startup_32() – the protect mode kernel entry Yeah! 17 References • Unified Extensible Firmware Interface Specification 2.3.1 • Understanding Linux kernel, 3rd Edition • http://en.wikipedia.org/wiki/Bootloader#Boot_l oader Q&A 19