Translate

Archives

Image of Operating System Concepts
Image of Modern Operating Systems (3rd Edition)
Image of Linux Kernel Development (3rd Edition)
Image of RHCE Red Hat Certified Engineer Linux Study Guide (Exam RH302) (Certification Press)

UEFI Boot Fedora 17

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

./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 AMI Aptio (UEFI 2.3) firmware. The UEFI install completed without incident or failure but the system would not boot after installation was completed. I traced the problem to a boot flag on the protective 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 to require 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 have UEFI support. Redhat’s fork of GRUB Legacy, which is maintained by Peter Jones, contains a number 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 enable booting the kernel directly from a UEFI shell or a UEFI boot manager. To build the kernel with EFISTUB (EFI runtime services) support, the following kernel configuration is necessary:

CONFIG_EFI=y
CONFIG_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 June 1st 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 EFI
executable. The code that modifies the bzImage header, along with the
EFI-specific entry point that the firmware loader jumps to are
collectively known as the "EFI boot stub", and live in
arch/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 kernel
without the use of a conventional EFI boot loader, such as grub or
elilo. Since the EFI boot stub performs the jobs of a boot loader, in
a 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 EFI
System Partiion (ESP) and renamed with the extension ".efi". Without
the extension the EFI firmware loader will refuse to execute it. It's
not possible to execute bzImage.efi from the usual Linux file systems
because 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.

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


**** The "initrd=" option

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

The path to the initrd file must be an absolute path from the
beginning of the ESP, relative path names do not work. Also, the path
is an EFI-style path and directory elements must be separated with
backslashes (\). 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 working
directory 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's
because the image we're executing is interpreted by the EFI shell,
which understands relative paths, whereas the rest of the command line
is passed to bzImage.efi.


Usually there is an option on your firmware configuration screen, to boot to an EFI shell. An EFI shell 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, you can 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 your ESP (EFI System Partition) and give the kernel an .EFI extension. It does not matter whether it is lowercase or uppercase as the ESP is a FAT filesystem and thus case agnostic. You should then be able to boot F17 from the EFI shell command line.

# cd /boot/efi; ls -l
drwx------  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


In older versions of Fedora, you had to boot the kernel using a UEFI-enabled verion of GRUB Legacy which came with the release or you could download and build a UEFI-enabled version of GRUB2. With EFI runtime services availbale in the Linux kernel, you can boot the kernel directly from 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 the 3.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 simply type f17.

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

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

# efibootmgr
Timeout: 2 seconds
BootOrder: 0000,0001,0002
Boot0000* Fedora
Boot0001  CD/DVD Drive 
Boot0002  Hard Drive 
[root@ultra vars]# efibootmgr -v
Timeout: 2 seconds
BootOrder: 0000,0001,0002
Boot0000* 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. . . . . . . . . . . . . . . . . . . . ......AMBO
Boot0002  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 by efibootmgr. 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 following directories which I had never seen before.

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


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

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

</ffffffff815f52a0></ffffffff81aedc0b></ffffffff815f52a4></ffffffff81087b77>
</ffffffff81aedd60></ffffffff81aee23b></ffffffff81aee0fa></ffffffff81aedfe0>
</ffffffff81b14c64></ffffffff810566bb></ffffffff81b14c64></ffffffff815e27dd>


Looking at the firmware NVRAM using the EFI dmpstore utility showed that the contents of these files are stored as NVRAM variables. For example, here is the contents of dump-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.<6>[    *
  000000A0: 30 2E 35 30 31 34 31 35-5D 20 75 68 63 69 5F 68  *0.501415] uhci_h*
  000000B0: 63 64 3A 20 55 53 42 20-55 6E 69 76 65 72 73 61  *cd: USB Universa*
  000000C0: 6C 20 48 6F 73 74 20 43-6F 6E 74 72 6F 6C 6C 65  *l Host Controlle*
  000000D0: 72 20 49 6E 74 65 72 66-61 63 65 20 64 72 69 76  *r Interface driv*
  000000E0: 65 72 0A 3C 37 3E 5B 20-20 20 20 30 2E 35 30 31  *er.<7>[    0.501*
  000000F0: 38 30 33 5D 20 78 68 63-69 5F 68 63 64 20 30 30  *803] xhci_hcd 00*
  00000100: 30 30 3A 30 30 3A 31 34-2E 30 3A 20 73 65 74 74  *00:00:14.0: sett*
  00000110: 69 6E 67 20 6C 61 74 65-6E 63 79 20 74 69 6D 65  *ing latency time*
  00000120: 72 20 74 6F 20 36 34 0A-3C 36 3E 5B 20 20 20 20  *r to 64.<6>[    *
  00000130: 30 2E 35 30 31 38 30 36-5D 20 78 68 63 69 5F 68  *0.501806] xhci_h*
  00000140: 63 64 20 30 30 30 30 3A-30 30 3A 31 34 2E 30 3A  *cd 0000:00:14.0:*
  00000150: 20 78 48 43 49 20 48 6F-73 74 20 43 6F 6E 74 72  * xHCI Host Contr*
  00000160: 6F 6C 6C 65 72 0A 3C 36-3E 5B 20 20 20 20 30 2E  *oller.<6>[    0.*
  00000170: 35 30 32 31 38 38 5D 20-78 68 63 69 5F 68 63 64  *502188] xhci_hcd*
  00000180: 20 30 30 30 30 3A 30 30-3A 31 34 2E 30 3A 20 6E  * 0000:00:14.0: n*
  00000190: 65 77 20 55 53 42 20 62-75 73 20 72 65 67 69 73  *ew USB bus regis*
  000001A0: 74 65 72 65 64 2C 20 61-73 73 69 67 6E 65 64 20  *tered, assigned *
  000001B0: 62 75 73 20 6E 75 6D 62-65 72 20 33 0A 3C 37 3E  *bus number 3.<7>*
  000001C0: 5B 20 20 20 20 30 2E 35-30 32 36 34 30 5D 20 78  *[    0.502640] x*
  000001D0: 68 63 69 5F 68 63 64 20-30 30 30 30 3A 30 30 3A  *hci_hcd 0000:00:*
  000001E0: 31 34 2E 30 3A 20 63 61-63 68 65 20 6C 69 6E 65  *14.0: cache line*
  000001F0: 20 73 69 7A 65 20 6F 66-20 36 34 20 69 73 20 6E  * size of 64 is n*
  00000200: 6F 74 20 73 75 70 70 6F-72 74 65 64 0A 3C 36 3E  *ot supported.<6>*
  00000210: 5B 20 20 20 20 30 2E 35-30 32 36 34 33 5D 20 78  *[    0.502643] x*
  00000220: 68 63 69 5F 68 63 64 20-30 30 30 30 3A 30 30 3A  *hci_hcd 0000:00:*
  00000230: 31 34 2E 30 3A 20 69 72-71 20 31 36 2C 20 69 6F  *14.0: irq 16, io*
  00000240: 20 6D 65 6D 20 30 78 66-37 63 30 30 30 30 30 0A  * mem 0xf7c00000.*
  00000250: 3C 37 3E 5B 20 20 20 20-30 2E 35 30 33 30 35 37  *<7>[    0.503057*
  00000260: 5D 20 78 68 63 69 5F 68-63 64 20 30 30 30 30 3A  *] xhci_hcd 0000:*
  00000270: 30 30 3A 31 34 2E 30 3A-20 69 72 71 20 34 31 20  *00:14.0: irq 41 *
  00000280: 66 6F 72 20 4D 53 49 2F-4D 53 49 2D 58 0A 3C 36  *for MSI/MSI-X.<6*
  00000290: 3E 5B 20 20 20 20 30 2E-35 30 33 30 39 33 5D 20  *>[    0.503093] *
  000002A0: 75 73 62 20 75 73 62 33-3A 20 4E 65 77 20 55 53  *usb usb3: New US*
  000002B0: 42 20 64 65 76 69 63 65-20 66 6F 75 6E 64 2C 20  *B device found, *
  000002C0: 69 64 56 65 6E 64 6F 72-3D 31 64 36 62 2C 20 69  *idVendor=1d6b, i*
  000002D0: 64 50 72 6F 64 75 63 74-3D 30 30 30 32 0A 3C 36  *dProduct=0002.<6*
  000002E0: 3E 5B 20 20 20 20 30 2E-35 30 33 34 37 32 5D 20  *>[    0.503472] *
  000002F0: 75 73 62 20 75 73 62 33-3A 20 4E 65 77 20 55 53  *usb usb3: New US*
  00000300: 42 20 64 65 76 69 63 65-20 73 74 72 69 6E 67 73  *B device strings*
  00000310: 3A 20 4D 66 72 3D 33 2C-20 50 72 6F 64 75 63 74  *: Mfr=3, Product*
  00000320: 3D 32 2C 20 53 65 72 69-61 6C 4E 75 6D 62 65 72  *=2, SerialNumber*
  00000330: 3D 31 0A 3C 36 3E 5B 20-20 20 20 30 2E 35 30 33  *=1.<6>[    0.503*
  00000340: 38 34 34 5D 20 75 73 62-20 75 73 62 33 3A 20 50  *844] usb usb3: P*
  00000350: 72 6F 64 75 63 74 3A 20-78 48 43 49 20 48 6F 73  *roduct: xHCI Hos*
  00000360: 74 20 43 6F 6E 74 72 6F-6C 6C 65 72 0A 3C 36 3E  *t Controller.<6>*
  00000370: 5B 20 20 20 20 30 2E 35-30 34 32 30 39 5D 20 75  *[    0.504209] u*
  00000380: 73 62 20 75 73 62 33 3A-20 4D 61 6E 75 66 61 63  *sb usb3: Manufac*
  00000390: 74 75 72 65 72 3A 20 4C-69 6E 75 78 20 33 2E 33  *turer: Linux 3.3*
  000003A0: 2E 36 2D 33 2E 66 63 31-37 2E 78 38 36 5F 36 34  *.6-3.fc17.x86_64*
  000003B0: 20 78 68 63 69 5F 68 63-64 0A 3C 36 3E 5B 20 20  * xhci_hcd.<6>[  *
  000003C0: 20 20 30 2E 35 30 34 35-38 31 5D 20 75 73 62 20  *  0.504581] usb *
  000003D0: 75 73 62 33 3A 20 53 65-72 69 61 6C 4E 75 6D 62  *usb3: SerialNumb*
  000003E0: 65 72 3A 20 30 30 30 30-3A 30 30 3A 31 34 2E 30  *er: 0000:00:14.0*
  000003F0: 0A 3C 37 3E 5B 20 20 20-20 30 2E 35 30 34 39 38  *.<7>[    0.50498*


We have to look inside the Linux kernel, specifically …/drivers/firmware/efivars.c, to understand where these UEFI NV (non volatile) variables are being created. The appropriate code is compiled into the Linux kernel, if the kernel is build with CONFIG_PSTORE. The first component of the variable name is always CFC8FC79-BE2E-4DDC-97F0-9F98BFE298A0 which is a GUID defined as LINUX_EFI_CRASH_GUID. The second component is a type designation:

enum pstore_type_id {
   PSTORE_TYPE_DMESG = 0,
   PSTORE_TYPE_MCE = 1,
   PSTORE_TYPE_UNKNOWN = 255
};


The third component is just a sequential number and the final component is the current time in seconds returned from the kernel’s get_secondsfunction.

Tony Luck, author of pstore, writes about pstore in this LWN article.

Some platforms have a small amount of non-volatile storage that can be used to store information useful to diagnose the cause of a system crash. This is the generic part of a file system interface that presents information from the crash as a series of files in
/dev/pstore. Once the information has been seen, the underlying storage is freed by deleting the files.

You can also delete these NV variables when in the EFI shell because the NV variable attributes are set to

(EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS)


Here is a simple EFI application which will erase all the pstore-created NV variables:

#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_ACCESS)

EFI_STATUS
efi_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, 
                                   &size, name, &curGuid);
        if (status != EFI_SUCCESS)
             break;

        val = LibGetVariable(name, &curGuid);
        if (!CompareGuid( &curGuid, &CrashGuid)) {
            status = uefi_call_wrapper(RT->SetVariable, 5,
                                       &name, &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     := /usr
HOSTARCH   = $(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_SOURCE
ASFLAGS    = $(ARCH3264)
LDFLAGS    = -nostdlib
INSTALL    = install

CC         = gcc
AS         = as
LD         = ld.bfd
AR         = ar
RANLIB     = ranlib
OBJCOPY    = objcopy

ifeq ($(ARCH), ia32)
  LIBDIR := $(PREFIX)/lib
  ifeq ($(HOSTARCH), x86_64)
    ARCH3264 := -m32
  endif
endif

ifeq ($(ARCH), x86_64)
  CFLAGS += -mno-red-zone
  LIBDIR := $(PREFIX)/lib64
  ifeq ($(HOSTARCH), ia32)
    ARCH3264 := -m64
  endif
endif

FORMAT=efi-app-$(HOSTARCH)
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-declaration


TARGETS = cer.efi

all : $(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 for dealing with Hardware Error Records. These NV variables are named HwErrRec0001, HwErrRec0002, and so on. Such records are not generated unless the NV variable HwErrRecSupport 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 is concerned. To a certain extent, UEFI support in forthcoming versions of Fedora will be dictated by the actions of Microsoft. For example, it is planned to add support for SecureBoot to Fedora 18 because Microsoft Windows 8 will require it.

Comments are closed.