mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-04 13:58:48 +00:00
uefi: Import the fwupd.efi sources from the fwupdate project
This commit is contained in:
parent
44367e707d
commit
b1e0ab98d1
@ -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" />
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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": [
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
27
meson.build
27
meson.build
@ -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')
|
||||
|
@ -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')
|
||||
|
51
plugins/uefi/efi/fwup-efi.h
Normal file
51
plugins/uefi/efi/fwup-efi.h
Normal 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
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
111
plugins/uefi/efi/hexdump.h
Normal 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
|
155
plugins/uefi/efi/meson.build
Normal file
155
plugins/uefi/efi/meson.build
Normal 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)
|
@ -63,3 +63,4 @@ if get_option('tests')
|
||||
test('uefi-self-test', e)
|
||||
endif
|
||||
|
||||
subdir('efi')
|
||||
|
Loading…
Reference in New Issue
Block a user