efibootmgr 32bit build must run on 32bit kernel and 64bit build must run on 64bit kernel. This raise problems when 32bit userland run on 64bit (x86_64) kernel via chroot environment or 64bit kernel was use to boot 32bit linux system. (Such as SystemRescueCD) According to changelog of 5.2.2 commit 0ee8ecc10109b91d0a77098d5596f56780c862d8 Author: Matt Domsch <Matt_Domsch@dell.com> Date: Thu Aug 11 17:37:04 2005 +0000 v0.5.2.2 * Thu Aug 11 2005 Matt Domsch <Matt_Domsch@dell.com> - applied patch from Rogerio Timmers which adds a new option -@ <file>, which takes extra variable parameters from <file>, or - from stdin. This lets you pass binary (non-unicode, non-ascii) formatted options to your bootloader. - cleaned up Rogerio's patch some. - moved definition of _FILE_OFFSET_BITS=64 into Makefile and out of the individual .c files. This fixes a bug reported by Red Flag, where variable data was getting incorrectly set with a 32-bit copy of efibootmgr on a 32-bit kernel. - made efi_variable_t.DataSize be an unsigned long to match the kernel. This lets a 32-bit copy of efibootmgr run on a 32-bit kernel. This means you've got to have a 32-bit efibootmgr on a 32-bit kernel, and a 64-bit efibootmgr on a 64-bit kernel, but since efi_status_t is also a long, this was really going to be the case anyway. - valgrind caught the app exiting without freeing some malloc'd structures, fix that. - v0.5.2.2 released for testing efibootmgr 64bit run on 64bit kernel xwing ~ # uname -a Linux xwing 3.5.2-gentoo #10 SMP PREEMPT Sat Aug 18 18:30:49 ICT 2012 x86_64 Intel(R) Core(TM) i5-2467M CPU @ 1.60GHz GenuineIntel GNU/Linux xwing ~ # file /usr/sbin/efibootmgr /usr/sbin/efibootmgr: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, stripped xwing ~ # efibootmgr -v BootCurrent: 0000 BootOrder: 0000,0001,0002,0003,0004,0005,0006,0007,0008,0009,000A,000B,000C,000D,000E Boot0000* 0 ACPI(a0341d0,0)PCI(1,1)ATAPI(0,0,0) Boot0001* 1 ACPI(a0341d0,0)PCI(1,1)ATAPI(0,1,0) Boot0002* 2 ACPI(a0341d0,0)PCI(1,1)ATAPI(1,0,0) Boot0003* 0 ACPI(a0341d0,0)PCI(1,1)ATAPI(0,0,0)HD(1,800,ff800,7c1b0800) Boot0004* 1 ACPI(a0341d0,0)PCI(1,1)ATAPI(0,0,0)HD(2,100000,f00000,7c1b0800) Boot0005* 2 ACPI(a0341d0,0)PCI(1,1)ATAPI(0,0,0)HD(3,1000000,8000000,7c1b0800) Boot0006* 3 ACPI(a0341d0,0)PCI(1,1)ATAPI(0,0,0)HD(4,9000000,31386030,7c1b0800) Boot0007* 4 ACPI(a0341d0,0)PCI(1,1)ATAPI(0,0,0)HD(4,9000000,31386030,7c1b0800)HD(1,9000800,4000000,00000000) Boot0008* 5 ACPI(a0341d0,0)PCI(1,1)ATAPI(0,0,0)HD(4,9000000,31386030,7c1b0800)HD(2,d001000,1000000,00000000) Boot0009* 6 ACPI(a0341d0,0)PCI(1,1)ATAPI(0,0,0)HD(4,9000000,31386030,7c1b0800)HD(3,e001800,2c384800,00000000) Boot000A* 7 ACPI(a0341d0,0)PCI(1,1)ATAPI(0,1,0)HD(1,800,7800,2b5f0a55-a8b0-4af0-8cec-6a629a8efdbc) Boot000B* 8 ACPI(a0341d0,0)PCI(1,1)ATAPI(0,1,0)HD(2,8000,f8000,7200f787-52f7-46df-8ba1-17b86a65cb32) Boot000C* 9 ACPI(a0341d0,0)PCI(1,1)ATAPI(0,1,0)HD(3,100000,f00000,fcc49bcf-b9dd-4305-9ce0-01db1979df67) Boot000D* 10 ACPI(a0341d0,0)PCI(1,1)ATAPI(0,1,0)HD(4,1000000,850f88f,35e9d7e5-86d4-4156-8b60-8c284e010d4d) Boot000E* EFI Internal Shell MM(b,5fa55000,5fea4fff) efibootmgr 32bit run on 64bit kernel on same machine weird and different output xwing doc # uname -a Linux xwing 3.5.2-gentoo #10 SMP PREEMPT Sat Aug 18 18:30:49 ICT 2012 x86_64 Intel(R) Core(TM) i5-2467M CPU @ 1.60GHz GenuineIntel GNU/Linux xwing doc # file /usr/sbin/efibootmgr /usr/sbin/efibootmgr: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, stripped xwing doc # efibootmgr -v BootCurrent: 0000 BootOrder: 0000,0000,0000,0001,0002,0003,0004,0005,0006,0007,0008,0009,000A,000B,000C Boot0000 wierd path1e 00 30 00 ..0. .0........A.................... Boot0001 wierd path1e 00 31 00 ..1. .1........A.................... Boot0002 wierd path1e 00 32 00 ..2. .2........A.................... Boot0003 wierd path48 00 30 00 H.0. .0........A......................*........................|.............. Boot0004 wierd path48 00 31 00 H.1. .1........A......................*........................|.............. Boot0005 wierd path48 00 32 00 H.2. .2........A......................*........................|.............. Boot0006 wierd path48 00 33 00 H.3. .3........A......................*.............0`81.......|.............. Boot0007 wierd path72 00 34 00 r.4. .4........A......................*.............0`81.......|................*....................................... Boot0008 wierd path72 00 35 00 r.5. .5........A......................*.............0`81.......|................*....................................... Boot0009 wierd path72 00 36 00 r.6. .6........A......................*.............0`81.......|................*..............H8,...................... Boot000A wierd path48 00 37 00 H.7. .7........A......................*..............x......U._+...J..jb...... Boot000B wierd path48 00 38 00 H.8. .8........A......................*........................r.R.F....je.2.. Boot000C wierd path48 00 39 00 H.9. .9........A......................*............................C.....y.g.. Boot000D wierd path48 00 31 00 H.1. .1.0........A......................*...............P........5..VA.`.(N..M.. Boot000E wierd path30 00 45 00 0.E. .E.F.I. .I.n.t.e.r.n.a.l. .S.h.e.l.l............P._.....O._..........z....@.!U.R.N7 For now seems no easy solution here, because x64_64 build is not possible on 32bit userland, so wrapper and eselect is not a viable solution. This may affected x32 ABI too. So a patch may needed to allow efibootmgr use match data structure for running kernel when reading/writing EFI variable. Note: Will send a copy of this bug to Matt_Domsch@dell.com
This was an intentional design decision when the kernel EFI Variables module (efivars) was first written in ~2001. There are EFI spec-defined fields which are of type LONG which differs between 32-bit and 64-bit EFI environments and kernels, and therefore userspace. Matthew Garrett (Red Hat) was working on a new efivars kernel module that also removes the restriction on variables being only 1024 bytes max which was in a pre-1.0 spec but was removed by EFI 1.0, but which unfortunately lives on in both efivars and efibootmgr today. I don't know the status there. With that complete, it may be possible that the new userspace interface would not be 32-bit or 64-bit specific, at which point efibootmgr could be updated to use the new interface. For now I'd say either "working as designed", or "feel free to fix efivars, and then fix efibootmgr, but you can't fix efibootmgr without fixing efivars first."
Created attachment 321730 [details, diff] efibootmgr efivars read/write workaround patch Attached (dirty) fixes on efivars reading/writing of efibootmgr when running kernel architecture is different from userland.
Since current efivars have no mechanism to detect if it use 64bit or 32bit long variable. I think we just leave it as is. It will work as long as userland (efibootmgr) and kernel match. So specific case require updated efibootmgr to check what correct data structure to use when read/write sysfs, which my patch does by uname(), but patch does not correct data write by --test option. I seems to lucky because I use recent kernels, it was updated to do more strict validation. Writing invalid values to efivars to older kernel may corrupt firmware, and therefore may cause by this case.
I also found that booting 32bit kernel in 64bit UEFI results kernel OOPs on efivars module. I guess 32bit kernel try to use 32bit EFI data structure when booting UEFI 64bit, if it do so it definitely a kernel BUG. So efivars need to be fixed, anyway and at least provide some variables to detect what UEFI platform is using. And efibootmgr will determinate how to handle it.
If this is still a problem, please re-open.