uefi: Import the fwupd.efi sources from the fwupdate project

This commit is contained in:
Richard Hughes 2018-06-23 10:26:59 +01:00
parent 44367e707d
commit b1e0ab98d1
13 changed files with 1751 additions and 3 deletions

View File

@ -339,6 +339,24 @@
<package />
</distro>
</dependency>
<dependency type="build" id="gnu-efi-devel">
<distro id="arch">
<package>gnu-efi-libs</package>
</distro>
<distro id="centos">
<package />
</distro>
<distro id="fedora">
<package />
</distro>
<distro id="debian">
<package variant="x86_64">gnu-efi</package>
<package variant="i386">gnu-efi</package>
</distro>
<distro id="ubuntu">
<package variant="x86_64">gnu-efi</package>
</distro>
</dependency>
<dependency type="build" id="gir1.2-appstreamglib-1.0">
<distro id="debian">
<package variant="x86_64" />

View File

@ -9,6 +9,7 @@ usr/share/locale
usr/share/metainfo/*
usr/lib/*/fwupd
usr/lib/*/fwupdtool
usr/lib/*/efi
usr/share/man/man1/*
lib/systemd/system/*
var/lib/fwupd

View File

@ -63,6 +63,7 @@ BuildRequires: freetype
BuildRequires: fontconfig
BuildRequires: dejavu-sans-fonts
BuildRequires: adobe-source-han-sans-cn-fonts
BuildRequires: gnu-efi-devel
%endif
%if 0%{?have_dell}
@ -191,6 +192,9 @@ mkdir -p --mode=0700 $RPM_BUILD_ROOT%{_localstatedir}/lib/fwupd/gnupg
%dir %{_libexecdir}/fwupd
%{_libexecdir}/fwupd/fwupd
%{_libexecdir}/fwupd/fwupdtool
%if 0%{?have_uefi}
%{_libexecdir}/fwupd/efi/*.efi
%endif
%{_bindir}/dfu-tool
%{_bindir}/fwupdmgr
%dir %{_sysconfdir}/fwupd

View File

@ -144,6 +144,21 @@
}
]
},
{
"name": "gnu-efi",
"buildsystem": "simple",
"build-commands": ["make", "make PREFIX=/app install"],
"cleanup": [
"/bin/efivar"
],
"sources": [
{
"type": "archive",
"url": "http://superb-dca2.dl.sourceforge.net/project/gnu-efi/gnu-efi-3.0.5.tar.bz2",
"sha256": "bd8fcd5914f18fc0e4ba948ab03b00013e528504f529c60739b748f6ef130b22"
}
]
},
{
"name": "fwupd",
"buildsystem": "meson",
@ -157,6 +172,9 @@
"-Dplugin_uefi_labels=false",
"-Dsystemd=false",
"-Dtests=false",
"-Defi-includedir=/app/include/efi",
"-Defi-ldsdir=/app/lib",
"-Defi-libdir=/app/lib",
"--sysconfdir=/app/etc",
"--localstatedir=/var/data"],
"cleanup": [

View File

@ -187,10 +187,22 @@ parts:
- -usr/lib/*/pkgconfig
- -usr/lib/*/girepository-1.0
after: [libusb]
gnu-efi:
plugin: make
source: http://superb-dca2.dl.sourceforge.net/project/gnu-efi/gnu-efi-3.0.5.tar.bz2
make-parameters:
- PREFIX=/usr
make-install-var: INSTALLROOT
prime:
- -usr/include/
- -usr/lib
fwupd:
plugin: meson
meson-parameters: [--prefix=/usr,
--libexecdir=/usr/lib,
-Defi-includedir=$SNAPCRAFT_STAGE/usr/include/efi,
-Defi-ldsdir=$SNAPCRAFT_STAGE/usr/lib,
-Defi-libdir=$SNAPCRAFT_STAGE/usr/lib,
-Dtests=false,
-Ddaemon=false,
-Dgtkdoc=false,
@ -263,7 +275,7 @@ parts:
- -usr/share/upstart
- -usr/lib/*/glib-2.0
- -usr/lib/*/pkgconfig
after: [appstream-glib-dev, libfwup-dev, gudev, gusb]
after: [appstream-glib-dev, libfwup-dev, gudev, gusb, gnu-efi, libsmbios, libefivar-fixpkgconfig]
fix-bash-completion:
plugin: make
source: contrib/snap/fix-bash-completion

View File

@ -183,10 +183,22 @@ parts:
- -usr/lib/*/pkgconfig
- -usr/lib/*/girepository-1.0
after: [libusb]
gnu-efi:
plugin: make
source: http://superb-dca2.dl.sourceforge.net/project/gnu-efi/gnu-efi-3.0.5.tar.bz2
make-parameters:
- PREFIX=/usr
make-install-var: INSTALLROOT
prime:
- -usr/include/
- -usr/lib
fwupd:
plugin: meson
meson-parameters: [--prefix=/usr,
--libexecdir=/usr/lib,
-Defi-includedir=$SNAPCRAFT_STAGE/usr/include/efi,
-Defi-ldsdir=$SNAPCRAFT_STAGE/usr/lib,
-Defi-libdir=$SNAPCRAFT_STAGE/usr/lib,
-Dtests=false,
-Ddaemon=false,
-Dgtkdoc=false,
@ -259,7 +271,7 @@ parts:
- -usr/share/upstart
- -usr/lib/*/glib-2.0
- -usr/lib/*/pkgconfig
after: [appstream-glib-dev, libfwup-dev, gudev, gusb]
after: [appstream-glib-dev, libfwup-dev, gudev, gusb, gnu-efi, libefivar-fixpkgconfig, libsmbios]
fix-bash-completion:
plugin: make
source: contrib/snap/fix-bash-completion

View File

@ -214,9 +214,34 @@ if get_option('plugin_uefi')
if fwup.version().version_compare('>= 12')
conf.set('HAVE_FWUP_VERSION', '1')
endif
conf.set_quoted('LIBFWUP_LIBRARY_VERSION', fwup.version())
efivar = dependency('efivar')
conf.set_quoted('EFIVAR_LIBRARY_VERSION', efivar.version())
conf.set_quoted('LIBFWUP_LIBRARY_VERSION', fwup.version())
objcopy = find_program ('objcopy')
readelf = find_program ('readelf')
efi_app_location = join_paths(libexecdir, 'fwupd', 'efi')
conf.set_quoted ('EFI_APP_LOCATION', efi_app_location)
efi_arch = host_machine.cpu_family()
if efi_arch == 'x86'
EFI_MACHINE_TYPE_NAME = 'ia32'
gnu_efi_arch = 'ia32'
elif efi_arch == 'x86_64'
EFI_MACHINE_TYPE_NAME = 'x64'
gnu_efi_arch = 'x86_64'
elif efi_arch == 'arm'
EFI_MACHINE_TYPE_NAME = 'arm'
gnu_efi_arch = 'arm'
elif efi_arch == 'aarch64'
EFI_MACHINE_TYPE_NAME = 'aa64'
gnu_efi_arch = 'aarch64'
else
EFI_MACHINE_TYPE_NAME = ''
gnu_efi_arch = ''
endif
conf.set_quoted('EFI_MACHINE_TYPE_NAME', EFI_MACHINE_TYPE_NAME)
endif
if get_option('plugin_dell')

View File

@ -19,3 +19,8 @@ option('systemd', type : 'boolean', value : true, description : 'enable systemd
option('systemdunitdir', type: 'string', value: '', description: 'Directory for systemd units')
option('tests', type : 'boolean', value : true, description : 'enable tests')
option('udevdir', type: 'string', value: '', description: 'Directory for udev rules')
option('efi-cc', type : 'string', value : 'gcc', description : 'the compiler to use for EFI modules')
option('efi-ld', type : 'string', value : 'ld', description : 'the linker to use for EFI modules')
option('efi-libdir', type : 'string', description : 'path to the EFI lib directory')
option('efi-ldsdir', type : 'string', description : 'path to the EFI lds directory')
option('efi-includedir', type : 'string', value : '/usr/include/efi', description : 'path to the EFI header directory')

View File

@ -0,0 +1,51 @@
/*
* Copyright (C) 2015-2017 Peter Jones <pjones@redhat.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#ifndef _FWUP_EFI_H
#define _FWUP_EFI_H
#define FWUPDATE_ATTEMPT_UPDATE 0x00000001
#define FWUPDATE_ATTEMPTED 0x00000002
#define UPDATE_INFO_VERSION 7
#ifdef _EFI_INCLUDE_
#define efidp_header EFI_DEVICE_PATH
#define efi_guid_t EFI_GUID
#endif /* _EFI_INCLUDE_ */
typedef struct {
uint8_t version;
uint8_t checksum;
uint8_t image_type;
uint8_t reserved;
uint32_t mode;
uint32_t x_offset;
uint32_t y_offset;
} ux_capsule_header_t;
typedef struct update_info_s {
uint32_t update_info_version;
/* stuff we need to apply an update */
efi_guid_t guid;
uint32_t capsule_flags;
uint64_t hw_inst;
EFI_TIME time_attempted;
/* our metadata */
uint32_t status;
/* variadic device path */
union {
efidp_header *dp_ptr;
efidp_header dp;
uint8_t dp_buf[0];
};
} __attribute__((__packed__)) update_info;
#endif /* _FWUP_EFI_H */

1335
plugins/uefi/efi/fwupdate.c Normal file

File diff suppressed because it is too large Load Diff

111
plugins/uefi/efi/hexdump.h Normal file
View File

@ -0,0 +1,111 @@
/*
* Copyright (C) 2015-2016 Peter Jones <pjones@redhat.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#ifndef STATIC_HEXDUMP_H
#define STATIC_HEXDUMP_H
static int
__attribute__((__unused__))
isprint(char c)
{
if (c < 0x20)
return 0;
if (c > 0x7e)
return 0;
return 1;
}
static UINTN
__attribute__((__unused__))
format_hex(UINT8 *data, UINTN size, CHAR16 *buf)
{
UINTN sz = (UINTN)data % 16;
CHAR16 hexchars[] = L"0123456789abcdef";
int offset = 0;
unsigned int i;
unsigned int j;
for (i = 0; i < sz; i++) {
buf[offset++] = L' ';
buf[offset++] = L' ';
buf[offset++] = L' ';
if (i == 7)
buf[offset++] = L' ';
}
for (j = sz; j < 16 && j < size; j++) {
UINT8 d = data[j-sz];
buf[offset++] = hexchars[(d & 0xf0) >> 4];
buf[offset++] = hexchars[(d & 0x0f)];
if (j != 15)
buf[offset++] = L' ';
if (j == 7)
buf[offset++] = L' ';
}
for (i = j; i < 16; i++) {
buf[offset++] = L' ';
buf[offset++] = L' ';
if (i != 15)
buf[offset++] = L' ';
if (i == 7)
buf[offset++] = L' ';
}
buf[offset] = L'\0';
return j - sz;
}
static void
__attribute__((__unused__))
format_text(UINT8 *data, UINTN size, CHAR16 *buf)
{
UINTN sz = (UINTN)data % 16;
int offset = 0;
unsigned int i;
unsigned int j;
for (i = 0; i < sz; i++)
buf[offset++] = L' ';
buf[offset++] = L'|';
for (j = sz; j < 16 && j < size; j++) {
if (isprint(data[j-sz]))
buf[offset++] = data[j-sz];
else
buf[offset++] = L'.';
}
buf[offset++] = L'|';
for (i = j; i < 16; i++)
buf[offset++] = L' ';
buf[offset] = L'\0';
}
static void
__attribute__((__unused__))
hexdump(UINT8 *data, UINTN size)
{
UINTN display_offset = (UINTN)data & 0xffffffff;
UINTN offset = 0;
//Print(L"hexdump: data=0x%016x size=0x%x\n", data, size);
while (offset < size) {
CHAR16 hexbuf[49];
CHAR16 txtbuf[19];
UINTN sz;
sz = format_hex(data+offset, size-offset, hexbuf);
if (sz == 0)
return;
uefi_call_wrapper(BS->Stall, 1, 200000);
format_text(data+offset, size-offset, txtbuf);
Print(L"%08x %s %s\n", display_offset, hexbuf, txtbuf);
uefi_call_wrapper(BS->Stall, 1, 200000);
display_offset += sz;
offset += sz;
}
}
#endif

View File

@ -0,0 +1,155 @@
efi_cc = get_option('efi-cc')
efi_ld = get_option('efi-ld')
efi_ldsdir = get_option('efi-ldsdir')
efi_incdir = get_option('efi-includedir')
gnu_efi_path_arch = ''
foreach name : [gnu_efi_arch, EFI_MACHINE_TYPE_NAME]
if (gnu_efi_path_arch == '' and name != '' and
cc.has_header('@0@/@1@/efibind.h'.format(efi_incdir, name)))
gnu_efi_path_arch = name
endif
endforeach
if gnu_efi_path_arch != '' and EFI_MACHINE_TYPE_NAME == ''
error('gnu-efi is available, but EFI_MACHINE_TYPE_NAME is unknown')
endif
efi_libdir = get_option('efi-libdir')
if efi_libdir == ''
cmd = 'cd /usr/lib/$(@0@ -print-multi-os-directory) && pwd'.format(efi_cc)
ret = run_command('sh', '-c', cmd)
if ret.returncode() == 0
efi_libdir = ret.stdout().strip()
endif
endif
have_gnu_efi = gnu_efi_path_arch != '' and efi_libdir != ''
if not have_gnu_efi
error('gnu-efi support requested, but headers were not found')
endif
arch_lds = 'elf_@0@_efi.lds'.format(gnu_efi_path_arch)
if efi_ldsdir == ''
efi_ldsdir = join_paths(efi_libdir, 'gnuefi')
cmd = run_command('test', '-f', join_paths(efi_ldsdir, arch_lds))
if cmd.returncode() != 0
efi_ldsdir = efi_libdir
cmd = run_command('test', '-f', join_paths(efi_ldsdir, arch_lds))
if cmd.returncode() != 0
error('Cannot find @0@'.format(arch_lds))
endif
endif
endif
message('efi-libdir: "@0@"'.format(efi_libdir))
message('efi-ldsdir: "@0@"'.format(efi_ldsdir))
message('efi-includedir: "@0@"'.format(efi_incdir))
debugdir = join_paths (libdir, 'debug')
compile_args = ['-Og',
'-g3',
'-Wp,-D_FORTIFY_SOURCE=2',
'--param=ssp-buffer-size=4',
'-fexceptions',
'-Wall',
'-Werror',
'-Wextra',
'-std=gnu11',
'-fpic',
'-fshort-wchar',
'-ffreestanding',
'-fno-strict-aliasing',
'-fno-stack-protector',
'-fno-stack-check',
'-fno-merge-constants',
'-Wsign-compare',
'-Wno-missing-field-initializers',
'-grecord-gcc-switches',
'-DDEBUGDIR="@0@"'.format(debugdir),
'-isystem', efi_incdir,
'-isystem', join_paths(efi_incdir, gnu_efi_path_arch)]
if efi_arch == 'x86_64'
compile_args += ['-mno-red-zone',
'-mno-sse',
'-mno-mmx',
'-DEFI_FUNCTION_WRAPPER',
'-DGNU_EFI_USE_MS_ABI']
elif efi_arch == 'ia32'
compile_args += ['-mno-sse',
'-mno-mmx',
'-mno-red-zone',
'-m32']
# no special cases for aarch64 or arm
endif
efi_ldflags = ['-T',
join_paths(efi_ldsdir, arch_lds),
'-shared',
'-Bsymbolic',
'-nostdlib',
'-znocombreloc',
'-L', efi_libdir,
join_paths(efi_ldsdir, 'crt0-efi-@0@.o'.format(gnu_efi_path_arch))]
if efi_arch == 'aarch64' or efi_arch == 'arm'
# Aarch64 and ARM32 don't have an EFI capable objcopy. Use 'binary'
# instead, and add required symbols manually.
efi_ldflags += ['--defsym=EFI_SUBSYSTEM=0xa']
efi_format = ['-O', 'binary']
else
efi_format = ['--target=efi-app-@0@'.format(gnu_efi_arch)]
endif
libgcc_file_name = run_command(efi_cc, '-print-libgcc-file-name').stdout().strip()
efi_name = 'fwup@0@.efi'.format(EFI_MACHINE_TYPE_NAME)
o_file = custom_target('fwupdate.o',
input : 'fwupdate.c',
output : 'fwupdate.o',
command : [efi_cc, '-c', '@INPUT@', '-o', '@OUTPUT@']
+ compile_args)
so = custom_target('fwup.so',
input : o_file,
output : 'fwup.so',
command : [efi_ld, '-o', '@OUTPUT@'] +
efi_ldflags + ['@INPUT@'] +
['-lefi', '-lgnuefi', libgcc_file_name])
app = custom_target(efi_name,
input : so,
output : efi_name,
command : [objcopy,
'-j', '.text',
'-j', '.sdata',
'-j', '.data',
'-j', '.dynamic',
'-j', '.dynsym',
'-j', '.rel',
'-j', '.rela',
'-j', '.reloc']
+ efi_format +
['@INPUT@', '@OUTPUT@'],
install : true,
install_dir : efi_app_location)
dbg = custom_target('efi_debug',
input : so,
output : efi_name + '.debug',
command : [objcopy,
'-j', '.text',
'-j', '.sdata',
'-j', '.data',
'-j', '.dynamic',
'-j', '.dynsym',
'-j', '.rel*',
'-j', '.rela*',
'-j', '.reloc',
'-j', '.eh_frame',
'-j', '.debug*',
'-j', '.note.gnu.build-id']
+ efi_format +
['@INPUT@', '@OUTPUT@'],
install : false,
install_dir : debugdir)

View File

@ -63,3 +63,4 @@ if get_option('tests')
test('uefi-self-test', e)
endif
subdir('efi')