7
UEFI Booting Fedora 17 UEFI Booting Fedora 17 Finnbarr P. Murphy ([email protected]) This post looks at the state of UEFI booting in Fedora 17(codename Beefy Miracle). By UEFI booting, I mean the ability to boot a Linux operating system without the next for GRUB, efililo or any other boot loader. Here is how Fedora 17 (F17) sets up a 500G disk if you do an F17 default UEFI install: $ df -h Filesystem Size Used Avail Use% Mounted on rootfs 50G 5.6G 42G 12% / devtmpfs 7.8G 0 7.8G 0% /dev tmpfs 7.8G 96K 7.8G 1% /dev/shm tmpfs 7.8G 1.3M 7.8G 1% /run /dev/sda3 50G 5.6G 42G 12% / tmpfs 7.8G 0 7.8G 0% /sys/fs/cgroup tmpfs 7.8G 0 7.8G 0% /media /dev/sda5 398G 6.2G 372G 2% /home /dev/sda2 497M 74M 399M 16% /boot /dev/sda1 200M 27M 173M 14% /boot/efi I am not going to explain how to do a UEFI install. I assume that you know how to do so if you are reading this blog. If not, read the F17 Release Notes. Looking more closely at the contents of /boot, you will see that it contains three sub-directores of interest, i.e. efi, grub and grub2: # cd /boot; ls -al total 47406 dr-xr-xr-x. 6 root root 1024 May 24 12:02 . dr-xr-xr-x. 18 root root 4096 May 26 19:15 .. -rw-r--r--. 1 root root 114861 Mar 18 23:09 config-3.3.0-1.fc17.x86_64 -rw-r--r-- 1 root root 115168 May 16 17:27 config-3.3.6-3.fc17.x86_64 drwx------ 4 root root 16384 Dec 31 1969 efi drwxr-xr-x. 2 root root 1024 May 24 12:02 grub drwxr-xr-x 3 root root 1024 May 24 12:02 grub2 -rw-r--r--. 1 root root 16683967 May 19 18:58 initramfs-3.3.0-1.fc17.x86_64.img -rw-r--r-- 1 root root 17432458 May 21 19:38 initramfs-3.3.6-3.fc17.x86_64.img drwx------. 2 root root 12288 May 19 18:44 lost+found -rw-------. 1 root root 2411498 Mar 18 23:09 System.map-3.3.0-1.fc17.x86_64 -rw------- 1 root root 2412800 May 16 17:27 System.map-3.3.6-3.fc17.x86_64 -rwxr-xr-x. 1 root root 4661840 Mar 18 23:09 vmlinuz-3.3.0-1.fc17.x86_64 -rwxr-xr-x 1 root root 4664080 May 16 17:27 vmlinuz-3.3.6-3.fc17.x86_64 -rw-r--r-- 1 root root 164 May 16 17:27 .vmlinuz-3.3.6-3.fc17.x86_64.hmac # cd grub; ls splash.xpm.gz < -- used by GRUB 0.97 EFI, #cd ../grub2; ls -R .: themes ./themes: system For personnal use only 07-13-2012 Copyright 2004-2012 Finnbarr P. Murphy. All rights reserved. 1/7

UEFI Booting Fedora 17

Embed Size (px)

DESCRIPTION

In this post, I examine how to directly boot Fedora 17 from UEFI firmware. I also discuss a number of non volatile variables which the Linux kernel can create during an kernel crash.Read more: http://blog.fpmurphy.com/2012/06#ixzz20SnsDkBj

Citation preview

UEFI Booting Fedora 17

UEFI Booting Fedora 17Finnbarr P. Murphy

([email protected])

This post looks at the state of UEFI booting in Fedora 17(codename Beefy Miracle). By UEFIbooting, I mean the ability to boot a Linux operating system without the next for GRUB, efililo orany other boot loader.

Here is how Fedora 17 (F17) sets up a 500G disk if you do an F17 default UEFI install:

$ df -hFilesystem Size Used Avail Use% Mounted onrootfs 50G 5.6G 42G 12% /devtmpfs 7.8G 0 7.8G 0% /devtmpfs 7.8G 96K 7.8G 1% /dev/shmtmpfs 7.8G 1.3M 7.8G 1% /run/dev/sda3 50G 5.6G 42G 12% /tmpfs 7.8G 0 7.8G 0% /sys/fs/cgrouptmpfs 7.8G 0 7.8G 0% /media/dev/sda5 398G 6.2G 372G 2% /home/dev/sda2 497M 74M 399M 16% /boot/dev/sda1 200M 27M 173M 14% /boot/efi

I am not going to explain how to do a UEFI install. I assume that you know how to do so if you arereading this blog. If not, read the F17 Release Notes.

Looking more closely at the contents of /boot, you will see that it contains three sub-directores ofinterest, i.e. efi, grub and grub2:

# cd /boot; ls -altotal 47406dr-xr-xr-x. 6 root root 1024 May 24 12:02 .dr-xr-xr-x. 18 root root 4096 May 26 19:15 ..-rw-r--r--. 1 root root 114861 Mar 18 23:09 config-3.3.0-1.fc17.x86_64-rw-r--r-- 1 root root 115168 May 16 17:27 config-3.3.6-3.fc17.x86_64drwx------ 4 root root 16384 Dec 31 1969 efidrwxr-xr-x. 2 root root 1024 May 24 12:02 grubdrwxr-xr-x 3 root root 1024 May 24 12:02 grub2-rw-r--r--. 1 root root 16683967 May 19 18:58 initramfs-3.3.0-1.fc17.x86_64.img-rw-r--r-- 1 root root 17432458 May 21 19:38 initramfs-3.3.6-3.fc17.x86_64.imgdrwx------. 2 root root 12288 May 19 18:44 lost+found-rw-------. 1 root root 2411498 Mar 18 23:09 System.map-3.3.0-1.fc17.x86_64-rw------- 1 root root 2412800 May 16 17:27 System.map-3.3.6-3.fc17.x86_64-rwxr-xr-x. 1 root root 4661840 Mar 18 23:09 vmlinuz-3.3.0-1.fc17.x86_64-rwxr-xr-x 1 root root 4664080 May 16 17:27 vmlinuz-3.3.6-3.fc17.x86_64-rw-r--r-- 1 root root 164 May 16 17:27 .vmlinuz-3.3.6-3.fc17.x86_64.hmac

# cd grub; lssplash.xpm.gz < -- used by GRUB 0.97 EFI,

#cd ../grub2; ls -R.:themes

./themes:system

For p

erson

nal u

se on

ly

07-13-2012 Copyright 2004-2012 Finnbarr P. Murphy. All rights reserved. 1/7

UEFI Booting Fedora 17

./themes/system:background.png

# cd /boot/efi/EFI/redhat; ls -l-rwx------ 1 root root 64 May 19 15:02 device.map-rwx------ 1 root root 1050 May 21 19:38 grub.conf-rwx------ 1 root root 246697 Apr 27 11:45 grub.efi

The hardware platoform that I UEFI-installed F17 on was a Biostar TZ77MXE which has AMIAptio (UEFI 2.3) firmware. The UEFI install completed without incident or failure but the systemwould not boot after installation was completed. I traced the problem to a boot flag on theprotective MBR. Once I removed the boot flag, the firmware had no difficulty UEFI-booting F17.Intel UEFI firmware seems to want the boot flag, other firmware such as the AMI Aptio appear torequire the boot flag not to be set. The firmware boots a modified version of Legacy GRUB v0.97 (grub.efi) which in turn boots F17. Note that the GRUB Legacy upstream source does not haveUEFI support. Redhat's fork of GRUB Legacy, which is maintained by Peter Jones, contains anumber of UEFI patches provided by Intel. See here for the gory details.

EFI runtime services support was recently added to the Linux Kernel (3.3.1 and later) to enablebooting the kernel directly from a UEFI shell or a UEFI boot manager. To build the kernel withEFISTUB (EFI runtime services) support, the following kernel configuration is necessary:

CONFIG_EFI=yCONFIG_EFI_VARS=y

Rather than trying to write my own explanation of how to do this, read the the following text,written by Matt Fleming, that was added to the Linux Kernel codebase by H. Peter Anvin on June1st 2012.

The EFI Boot Stub ---------------------------

On the x86 platform, a bzImage can masquerade as a PE/COFF image,thereby convincing EFI firmware loaders to load it as an EFIexecutable. The code that modifies the bzImage header, along with theEFI-specific entry point that the firmware loader jumps to arecollectively known as the "EFI boot stub", and live inarch/x86/boot/header.S and arch/x86/boot/compressed/eboot.c,respectively.

By using the EFI boot stub it's possible to boot a Linux kernelwithout the use of a conventional EFI boot loader, such as grub orelilo. Since the EFI boot stub performs the jobs of a boot loader, ina certain sense it *IS* the boot loader.

The EFI boot stub is enabled with the CONFIG_EFI_STUB kernel option.

**** How to install bzImage.efi

The bzImage located in arch/x86/boot/bzImage must be copied to the EFISystem Partiion (ESP) and renamed with the extension ".efi". Withoutthe extension the EFI firmware loader will refuse to execute it. It'snot possible to execute bzImage.efi from the usual Linux file systemsbecause EFI firmware doesn't have support for them.

**** Passing kernel parameters from the EFI shell

Arguments to the kernel can be passed after bzImage.efi, e.g.

For p

erson

nal u

se on

ly

07-13-2012 Copyright 2004-2012 Finnbarr P. Murphy. All rights reserved. 2/7

UEFI Booting Fedora 17

fs0:> bzImage.efi console=ttyS0 root=/dev/sda4

**** The "initrd=" option

Like most boot loaders, the EFI stub allows the user to specifymultiple initrd files using the "initrd=" option. This is the only EFIstub-specific command line parameter, everything else is passed to thekernel when it boots.

The path to the initrd file must be an absolute path from thebeginning of the ESP, relative path names do not work. Also, the pathis an EFI-style path and directory elements must be separated withbackslashes (\). For example, given the following directory layout,

fs0:> Kernels\ bzImage.efi initrd-large.img

Ramdisks\ initrd-small.img initrd-medium.img

to boot with the initrd-large.img file if the current workingdirectory is fs0:\Kernels, the following command must be used,

fs0:\Kernels> bzImage.efi initrd=\Kernels\initrd-large.img

Notice how bzImage.efi can be specified with a relative path. That'sbecause the image we're executing is interpreted by the EFI shell,which understands relative paths, whereas the rest of the command lineis passed to bzImage.efi.

Usually there is an option on your firmware configuration screen, to boot to an EFI shell. An EFIshell is simply another EFI application (executable image) as far as the firmware is concerned.

If your firmware does not come with a built-in EFI shell, you need to install a X64 EFI shell at(typically) /boot/efi and name it either shell.efi or shellx64.efi. If you need an X64 EFI shell, youcan download one from my website.

All EFI executable images contain a PE/COFF header defining the format of the executable code.The code may be one of the following:

IA-32●

X64●

IA-64 (Itaninum)●

EFI byte code (Processor agnostic)●

Once you get to the EFI shell prompt, you need to copy your kernel and initramfs images to yourESP (EFI System Partition) and give the kernel an .EFI extension. It does not matter whether it islowercase or uppercase as the ESP is a FAT filesystem and thus case agnostic. You should then beable to boot F17 from the EFI shell command line.

# cd /boot/efi; ls -ldrwx------ 3 root root 4096 May 20 01:36 EFI-rwx------ 1 root root 17432458 May 23 21:49 initramfs-3.3.6-3.fc17.x86_64.img-rwx------ 1 root root 214 May 26 12:14 f17.nsh-rwx------ 1 root root 1240192 May 26 22:53 Shell.efi-rwx------ 1 root root 4664080 May 23 21:49 vmlinuz-3.3.6-3.fc17.x86_64.efi

For p

erson

nal u

se on

ly

07-13-2012 Copyright 2004-2012 Finnbarr P. Murphy. All rights reserved. 3/7

UEFI Booting Fedora 17

In older versions of Fedora, you had to boot the kernel using a UEFI-enabled verion of GRUBLegacy which came with the release or you could download and build a UEFI-enabled version ofGRUB2. With EFI runtime services availbale in the Linux kernel, you can boot the kernel directlyfrom an EFI Shell without the need to use GRUB,

Here is a copy of the EFI shell script which I created to simplify booting Fedora 17 with the3.3.6-3 kernel:

# cat f17.nsh vmlinuz-3.3.6-3.fc17.x86_64.efi root=UUID=1d3092fc-265e-4860-a609-d6a16c1a6458 rd.lvm=0 rd.dm=0 KEYTABLE=us SYSFONT=True rd.md=0 rd.luks=0 ro LANG=en_US.UTF-8 rhgb quiet initrd=.\initramfs-3.3.6-3.fc17.x86_64.img

EFI shell scripts have to have an extension of .nsh, i.e new shell script. To boot F17, I then simplytype f17.

Turning now to related UEFI topic, let us examine what UEFI-related information is available ormodifiable from within F17.

The efibootmgr utility can be used to change the UEFI boot variables, i.e. Timeout,BootOrder, andthe BootXXXX variables.

# efibootmgrTimeout: 2 secondsBootOrder: 0000,0001,0002Boot0000* FedoraBoot0001 CD/DVD Drive Boot0002 Hard Drive [root@ultra vars]# efibootmgr -vTimeout: 2 secondsBootOrder: 0000,0001,0002Boot0000* Fedora HD(1,800,64000,a2b4a2ac-5677-43cf-a820-b97975015f20)File(\EFI\redhat\grub.efi)Boot0001 CD/DVD Drive BIOS(3,0,00)AMGOAMNO........o.H.P. .D.V.D. .W.r.i.t.e.r. .1.0.7.0.d............�........A......................�.....>..Gd-.;.A..MQ..L. . . . . . . . . . . . . . . . . . . . ...�...AMBOBoot0002 Hard Drive BIOS(2,0,00)AMGOAMNO........o.S.T.3.5.0.0.4.1.3.A.S............�........A......................�.....>..Gd-.;.A..MQ..L. . . . . . . . . . . . .2.Z.8.A.Q.J.8.N...�...AMBOAMNO........o.S.T.3.5.0.0.4.1.8.A.S............�........A......................�.....>..Gd-.;.A..MQ..L. . . . . . . . . . . . .V.9.J.M.P.4.7.7...�...AMBOAMNO........o.S.T.3.5.0.0.3.2.0.A.S............�........A......................�.....>..Gd-.;.A..MQ..L. . . . . . . . . . . . .Q.9.4.M.N.9.Q.M...�...AMBO

By the way, it is possible to directly embed the kernel parameters within the boot entry created byefibootmgr. For example,

# echo "root=/dev/sdaX ro rootfstype=ext4 add_efi_memmap initrd=\\EFI\\arch\\initramfs-linux.img" | iconv -f asc

FPM >>>>>> https://wiki.archlinux.org/index.php/UEFI_Bootloaders

While examining the contents of the /sys/firmware/efi/vars sub-directory, I noticed the followingdirectories which I had never seen before.

For p

erson

nal u

se on

ly

07-13-2012 Copyright 2004-2012 Finnbarr P. Murphy. All rights reserved. 4/7

UEFI Booting Fedora 17

dump-type0-10-1337811289-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0dump-type0-11-1337811290-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0dump-type0-1-1337864078-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0dump-type0-2-1337864079-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0dump-type0-3-1337864080-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0dump-type0-4-1337864081-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0dump-type0-5-1337864082-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0dump-type0-6-1337864083-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0dump-type0-7-1337864084-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0dump-type0-8-1337864085-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0dump-type0-9-1337864086-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0

Examining the first sub-directory revealed that the data file contained therein is some sort of akernel dump facility.

# cd dump-type0-1-1337864078-cfc8fc79-be2e-4ddc-97f0-9f98bfe298a0]# cat dataOops#1 Part1ic - not syncing: stack-protector: Kernel stack is corrupted in: ffffffff81b14c64[ 0.869252] [ 0.871917] Pid: 1, comm: swapper/0 Not tainted 3.3.6-3.fc17.x86_64 #1[ 0.872804] Call Trace:[ 0.873678] [] panic+0xba/0x1c6[ 0.874551] [] ? printk_all_partitions+0x259/0x26b[ 0.875430] [] __stack_chk_fail+0x1b/0x20[ 0.876306] [] printk_all_partitions+0x259/0x26b[ 0.877170] [] mount_block_root+0x1bc/0x27f[ 0.878015] [] mount_root+0x57/0x5b[ 0.878843] [] prepare_namespace+0x13d/0x176[ 0.879660] [] kernel_init+0x155/0x15a[ 0.880477] [] ? schedule_tail+0x27/0xb0[ 0.881286] [] kernel_thread_helper+0x4/0x10[ 0.882082] [] ? start_kernel+0x3c5/0x3c5[ 0.882868] [] ? gs_change+0x13/0x13

Looking at the firmware NVRAM using the EFI dmpstore utility showed that the contents of thesef i les are stored as NVRAM var iables . For example, here is the contents ofdump-type0-10-1337811289 :

Variable NV+RT+BS 'CFC8FC79-BE2E-4DDC-97F0-9F98BFE298A0:dump-type0-10-1337811289' DataSize = 400 00000000: 4F 6F 70 73 23 31 20 50-61 72 74 31 30 0A 30 3A *Oops#1 Part10.0:* 00000010: 20 55 53 42 20 68 75 62-20 66 6F 75 6E 64 0A 3C * USB hub found.< *00000020: 36 3E 5B 20 20 20 20 30-2E 35 30 30 36 39 34 5D *6>[ 0.500694]* 00000030: 20 68 75 62 20 32 2D 30-3A 31 2E 30 3A 20 32 20 * hub 2-0:1.0: 2 * 00000040: 70 6F 72 74 73 20 64 65-74 65 63 74 65 64 0A 3C *ports detected.< *00000050: 36 3E 5B 20 20 20 20 30-2E 35 30 31 30 35 38 5D *6>[ 0.501058]* 00000060: 20 6F 68 63 69 5F 68 63-64 3A 20 55 53 42 20 31 * ohci_hcd: USB 1* 00000070: 2E 31 20 27 4F 70 65 6E-27 20 48 6F 73 74 20 43 *.1 'Open' Host C* 00000080: 6F 6E 74 72 6F 6C 6C 65-72 20 28 4F 48 43 49 29 *ontroller (OHCI)* 00000090: 20 44 72 69 76 65 72 0A-3C 36 3E 5B 20 20 20 20 * Driver.#include <efi.h>#include <efilib.h>#define LINUX_EFI_CRASH_GUID \ (EFI_GUID) { 0xcfc8fc79, 0xbe2e, 0x4ddc, { 0x97, 0xf0, 0x9f, 0x98, 0xbf, 0xe2, 0x98, 0xa0 } }#define PSTORE_EFI_ATTRIBUTES \ (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACC

For p

erson

nal u

se on

ly

07-13-2012 Copyright 2004-2012 Finnbarr P. Murphy. All rights reserved. 5/7

UEFI Booting Fedora 17

ESS)EFI_STATUSefi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab){ EFI_STATUS status = EFI_SUCCESS; CHAR16 name[256], *val; EFI_GUID curGuid= NullGuid; UINTN size; UINTN valsize = 100; EFI_GUID CrashGuid = LINUX_EFI_CRASH_GUID ; InitializeLib(image, systab); name[0] = 0; while (1) { size = sizeof(name); status = uefi_call_wrapper(RT->GetNextVariableName, 3, &amp;size, name, &amp;curGuid); if (status != EFI_SUCCESS) break; val = LibGetVariable(name, &amp;curGuid); if (!CompareGuid( &amp;curGuid, &amp;CrashGuid)) { status = uefi_call_wrapper(RT->SetVariable, 5, &amp;name, &amp;curGuid, PSTORE_EFI_ATTRIBUTES, 0, NULL); if (status != EFI_SUCCESS) { Print(L"ERROR: SetVariable failed: %d\n", status); } } FreePool(val); } return status;}

and here is a suitable Makefile for compiling it on Fedora 17:

SRCDIR = .PREFIX := /usrHOSTARCH = $(shell uname -m | sed s,i[3456789]86,ia32,)ARCH := $(shell uname -m | sed s,i[3456789]86,ia32,)INCDIR = -I.CPPFLAGS = -DCONFIG_$(ARCH)CFLAGS = $(ARCH3264) -g -O0 -fpic -Wall -fshort-wchar -fno-strict-aliasing -fno-merge-constants --std=gnu99 -D_GNU_SOURCEASFLAGS = $(ARCH3264)LDFLAGS = -nostdlibINSTALL = installCC = gccAS = asLD = ld.bfdAR = arRANLIB = ranlibOBJCOPY = objcopyifeq ($(ARCH), ia32) LIBDIR := $(PREFIX)/lib ifeq ($(HOSTARCH), x86_64) ARCH3264 := -m32 endifendififeq ($(ARCH), x86_64) CFLAGS += -mno-red-zone LIBDIR := $(PREFIX)/lib64 ifeq ($(HOSTARCH), ia32) ARCH3264 := -m64 endifendifFORMAT=efi-app-$(HOSTARCH)

For p

erson

nal u

se on

ly

07-13-2012 Copyright 2004-2012 Finnbarr P. Murphy. All rights reserved. 6/7

UEFI Booting Fedora 17

LDFLAGS = -nostdlib -T $(LIBDIR)/gnuefi/elf_$(HOSTARCH)_efi.lds -shared -Bsymbolic $(LIBDIR)/gnuefi/crt0-efi-$(HOSTARCH).o -L$(LIBDIR)LIBS=-lefi -lgnuefi $(shell $(CC) -print-libgcc-file-name)CCLDFLAGS =CFLAGS = -I/usr/include/efi/ -I/usr/include/efi/$(HOSTARCH)/ -I/usr/include/efi/protocol -fpic -fshort-wchar -fno-reorder-functions -fno-strict-aliasing -fno-merge-constants -mno-red-zone -Wimplicit-function-declarationTARGETS = cer.efiall : $(TARGETS)clean : @rm -rf *.o *.a *.so $(TARGETS).PHONY: all clean install%.efi : %.so $(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel \ -j .rela -j .reloc --target=$(FORMAT) $*.so $@%.so: %.o $(LD) $(LDFLAGS) -o $@ $^ $(LIBS)%.o: %.c $(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -D__UEFI__ -c $< -o $@%.S: %.c $(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -D__UEFI__ -S $< -o $@%.E: %.c $(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -D__UEFI__ -E $< -o $@

This is not the same as the mechanism detailed in Appendix P of the latest UEFI Specification fordealing with Hardware Error Records. These NV variables are named HwErrRec0001,HwErrRec0002, and so on. Such records are not generated unless the NV variableHwErrRecSupport is defined. By the way, hardware error records support is optional.

The next release or two of Fedora are going to be very interesting as far as UEFI support isconcerned. To a certain extent, UEFI support in forthcoming versions of Fedora will be dictated bythe actions of Microsoft. For example, it is planned to add support for SecureBoot to Fedora 18because Microsoft Windows 8 will require it.

For p

erson

nal u

se on

ly

07-13-2012 Copyright 2004-2012 Finnbarr P. Murphy. All rights reserved. 7/7