1
0
mirror of https://github.com/systemd/systemd synced 2026-04-04 06:04:51 +02:00

Compare commits

...

12 Commits

Author SHA1 Message Date
Frantisek Sumsal
8b212f3596 ci: take CIFuzz's matrix into consideration
Otherwise the jobs will try to cancel each other out.

Follow-up to 3884837610168e6fb69fc2d5709f6c017a30beb9.
2021-11-10 20:44:24 +00:00
Luca Boccassi
227e2fc1a7
Merge pull request #21290 from poettering/arch-me-harder
some docs/tweaks regarding porting to new archs
2021-11-10 18:37:01 +00:00
Jan Janssen
9cf75222f2 meson: Rework gnu-efi detection
Moving all of the gnu-efi detection into src/boot/efi/meson.build makes
more sense than having it partially split.

And thanks to subdir_done() we can simplify the code a lot.

Fixes: #21258
2021-11-10 18:25:19 +00:00
Luca Boccassi
fe63d890fd
Merge pull request #21293 from mrc0mmand/ci-cancel-old-jobs
ci: cancel previous jobs on ref update
2021-11-10 18:15:21 +00:00
Frantisek Sumsal
3884837610 ci: cancel previous jobs on ref update
Let's save the environment (and reduce the number of jobs in GH Actions
queues) by cancelling old jobs on a ref update (force push).

See: https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#concurrency
2021-11-10 17:15:35 +01:00
Frantisek Sumsal
46573ee131 ci: fix indentation 2021-11-10 17:15:35 +01:00
Frantisek Sumsal
b8c94ee372 Revert "CI: run GCC unit test job on push to main"
This reverts commit c1036042f5aa3369d771776fb6d57fac2543d80d.

Follow-up to 0ad536c16a940b4557322f3f811db73c4b374898.
2021-11-10 17:15:35 +01:00
Lennart Poettering
ec512b9b9d doc: add some docs with a checklist of what to do for new architectures 2021-11-10 15:18:01 +01:00
Lennart Poettering
04ba1bb038 shared: nudge people into sending us patches to make /lib64/ symlink generation work on all archs that need it
This is an attempt to nudge people into sending us patches that fix
bug #14311 for us, given that the original submitter lost interest.
2021-11-10 15:18:01 +01:00
Lennart Poettering
1fb2d8fcb6 docs: invite people to define GPT partition types for all archs now
The discovery partitions spec so far suggested we should define
arch-specific partition type uuids only for archs that have EFI. Let's
change that and invite people to define them for any arch. Why? Even if
GPT is defined as part of the UEFI spec it's quite useful independently
of it, too. Specifically, our image dissection logic makes use of it,
i.e. systemd-nspawn, systemd-gpt-auto-generator, systemd-repart,
RootImage=, portable services, and so on. None of these tools are
related to UEFI in any way.

Hence, let's open this up.
2021-11-10 15:18:01 +01:00
Lennart Poettering
d42e4fa258 shared: start pushing people gently to define GPT partition type UUIDs for missing archs
Let's generate a single gcc `#warning`  message asking people to define
partition type UUIDs for their architectures if they are missing.
2021-11-10 15:18:01 +01:00
Lennart Poettering
3299c293db architecture: drop __riscv__ checks, it's obsolete since 2018 2021-11-10 12:38:32 +01:00
13 changed files with 429 additions and 384 deletions

View File

@ -15,6 +15,9 @@ on:
jobs: jobs:
build: build:
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
concurrency:
group: ${{ github.workflow }}-${{ matrix.env.COMPILER }}-${{ matrix.env.COMPILER_VERSION }}-${{ github.ref }}
cancel-in-progress: true
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:

View File

@ -17,32 +17,35 @@ on:
branches: branches:
- main - main
jobs: jobs:
Fuzzing: Fuzzing:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.repository == 'systemd/systemd' if: github.repository == 'systemd/systemd'
strategy: concurrency:
fail-fast: false group: ${{ github.workflow }}-${{ matrix.sanitizer }}-${{ github.ref }}
matrix: cancel-in-progress: true
sanitizer: [address, undefined, memory] strategy:
steps: fail-fast: false
- name: Build Fuzzers (${{ matrix.sanitizer }}) matrix:
id: build sanitizer: [address, undefined, memory]
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master steps:
with: - name: Build Fuzzers (${{ matrix.sanitizer }})
oss-fuzz-project-name: 'systemd' id: build
dry-run: false uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
allowed-broken-targets-percentage: 0 with:
sanitizer: ${{ matrix.sanitizer }} oss-fuzz-project-name: 'systemd'
- name: Run Fuzzers (${{ matrix.sanitizer }}) dry-run: false
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master allowed-broken-targets-percentage: 0
with: sanitizer: ${{ matrix.sanitizer }}
oss-fuzz-project-name: 'systemd' - name: Run Fuzzers (${{ matrix.sanitizer }})
fuzz-seconds: 600 uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
dry-run: false with:
sanitizer: ${{ matrix.sanitizer }} oss-fuzz-project-name: 'systemd'
- name: Upload Crash fuzz-seconds: 600
uses: actions/upload-artifact@v1 dry-run: false
if: failure() && steps.build.outcome == 'success' sanitizer: ${{ matrix.sanitizer }}
with: - name: Upload Crash
name: ${{ matrix.sanitizer }}-artifacts uses: actions/upload-artifact@v1
path: ./out/artifacts if: failure() && steps.build.outcome == 'success'
with:
name: ${{ matrix.sanitizer }}-artifacts
path: ./out/artifacts

View File

@ -13,6 +13,9 @@ jobs:
build: build:
name: Lint Code Base name: Lint Code Base
runs-on: ubuntu-latest runs-on: ubuntu-latest
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
steps: steps:
- name: Repo checkout - name: Repo checkout

View File

@ -15,6 +15,9 @@ on:
jobs: jobs:
ci: ci:
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
concurrency:
group: ${{ github.workflow }}-${{ matrix.distro }}-${{ github.ref }}
cancel-in-progress: true
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:

View File

@ -4,10 +4,6 @@
# #
name: Unit tests name: Unit tests
on: on:
# On push/merge to main we only run the GCC job, to get coverage data uploaded to coveralls.io
push:
branches:
- main
pull_request: pull_request:
branches: branches:
- main - main
@ -15,6 +11,9 @@ on:
jobs: jobs:
build: build:
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
concurrency:
group: ${{ github.workflow }}-${{ matrix.run_phase }}-${{ github.ref }}
cancel-in-progress: true
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@ -22,10 +21,7 @@ jobs:
steps: steps:
- name: Repository checkout - name: Repository checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
if: github.event_name == 'pull_request' || matrix.run_phase == 'GCC'
- name: Install build dependencies - name: Install build dependencies
run: sudo -E .github/workflows/unit_tests.sh SETUP run: sudo -E .github/workflows/unit_tests.sh SETUP
if: github.event_name == 'pull_request' || matrix.run_phase == 'GCC'
- name: Build & test (${{ matrix.run_phase }}) - name: Build & test (${{ matrix.run_phase }})
run: sudo -E .github/workflows/unit_tests.sh RUN_${{ matrix.run_phase }} run: sudo -E .github/workflows/unit_tests.sh RUN_${{ matrix.run_phase }}
if: github.event_name == 'pull_request' || matrix.run_phase == 'GCC'

View File

@ -306,11 +306,9 @@ installation processes of Linux a bit more robust and self-descriptive.
### Why did you only define the root partition for these listed architectures? ### Why did you only define the root partition for these listed architectures?
The automatic discovery of the root partition is defined to operate on the disk Please submit a patch that adds appropriate partition type UUIDs for the
containing the current EFI System Partition (ESP). Since EFI only exists on architecture of your choice should they be missing so far. The only reason they
x86, x86-64, ia64, ARM, LoongArch and RISC-V so far, we only defined root aren't defined yet is that nobody submitted them yet.
partition UUIDs for these architectures. Should EFI become more common on
other architectures, we can define additional UUIDs for them.
### Why define distinct root partition UUIDs for the various architectures? ### Why define distinct root partition UUIDs for the various architectures?

View File

@ -0,0 +1,61 @@
---
title: Porting to New Architectures
category: Contributing
layout: default
SPDX-License-Identifier: LGPL-2.1-or-later
---
# Porting systemd to New Architectures
Here's a brief checklist of things to implement when porting systemd to a new
architecture.
1. Patch
[src/basic/architecture.h](https://github.com/systemd/systemd/blob/main/src/basic/architecture.h)
and
[src/basic/architecture.c](https://github.com/systemd/systemd/blob/main/src/basic/architecture.c)
to make your architecture known to systemd. Besides an `ARCHITECTURE_XYZ`
enumeration entry you need to provide an implementation of
`native_architecture()` and `uname_architecture()`.
2. Patch
[src/shared/gpt.h](https://github.com/systemd/systemd/blob/main/src/shared/gpt.h)
and
[src/shared/gpt.c](https://github.com/systemd/systemd/blob/main/src/shared/gpt.c)
and define a new set of GPT partition type UUIDs for the root file system,
`/usr/` file system, and the matching Verity and Verity signature
partitions. Use `systemd-id128 new -p` to generate new suitable UUIDs you
can use for this. Make sure to register your new types in the various
functions in `gpt.c`. Also make sure to update the tables in
`docs/DISCOVERABLE_PARTITIONS.md` and `man/systemd-gpt-auto-generator.xml`
accordingly.
3. If your architecture supports UEFI, make sure to update the `efi_arch`
variable logic in `meson.build` to be set to the right architecture string
as defined by the UEFI specification. (This ensures that `systemd-boot` will
be built as the appropriately named `BOOT<arch>.EFI` binary.) Also, if your
architecture uses a special boot protocol for the Linux kernel make sure to
implement it in `src/boot/efi/linux*.c`, so that the `systemd-stub` EFI stub
can work.
4. Make sure to register the right system call numbers for your architecture in
`src/basic/missing_syscall_def.h`. systemd uses various system calls the
Linux kernel provides that are currently not wrapped by glibc (or are only
in very new glibc), and we need to know the right numbers for them. It might
also be necessary to tweak `src/basic/raw-clone.h`.
5. Make sure the code in `src/shared/seccomp-util.c` properly understands the
local architecture and its system call quirks.
6. If your architecture uses a `/lib64/` library directory, then make sure that
the `BaseFilesystem` table in `src/shared/base-filesystem.c` has an entry
for it so that it can be set up automatically if missing. This is useful to
support booting into OS trees that have an empty root directory with only
`/usr/` mounted in.
7. If your architecture has a CPU opcode similar to x86' RDRAND consider adding
native support for it to `src/basic/random-util.c`'s `rdrand()` function.
8. If your architecture supports VM virtualization and provides CPU opcodes
similar to x86' CPUID consider adding native support for detecting VMs this
way to `src/basic/virt.c`.

View File

@ -1641,39 +1641,8 @@ conf.set10('SYSTEMD_SLOW_TESTS_DEFAULT', slow_tests)
##################################################################### #####################################################################
if get_option('efi')
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'
elif efi_arch == 'riscv64'
EFI_MACHINE_TYPE_NAME = 'riscv64'
gnu_efi_arch = 'riscv64'
else
EFI_MACHINE_TYPE_NAME = ''
gnu_efi_arch = ''
endif
have = true
conf.set_quoted('EFI_MACHINE_TYPE_NAME', EFI_MACHINE_TYPE_NAME)
else
have = false
endif
conf.set10('ENABLE_EFI', have)
subdir('src/fundamental') subdir('src/fundamental')
subdir('src/boot/efi') subdir('src/boot/efi')
conf.set10('HAVE_GNU_EFI', have_gnu_efi)
############################################################ ############################################################
@ -3887,19 +3856,14 @@ summary({
# CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS} # CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS}
# LDFLAGS: ${OUR_LDFLAGS} ${LDFLAGS} # LDFLAGS: ${OUR_LDFLAGS} ${LDFLAGS}
if conf.get('ENABLE_EFI') == 1 if conf.get('ENABLE_EFI') == 1 and conf.get('HAVE_GNU_EFI') == 1
summary({'EFI arch' : efi_arch}, summary({
'EFI machine type' : efi_arch[0],
'EFI CC' : '@0@'.format(' '.join(efi_cc)),
'EFI lds' : efi_lds,
'EFI crt0' : efi_crt0,
'EFI include directory' : efi_incdir},
section : 'Extensible Firmware Interface') section : 'Extensible Firmware Interface')
if have_gnu_efi
summary({
'EFI machine type' : EFI_MACHINE_TYPE_NAME,
'EFI CC' : '@0@'.format(' '.join(efi_cc)),
'EFI lds' : efi_lds,
'EFI crt0' : efi_crt0,
'EFI include directory' : efi_incdir},
section : 'Extensible Firmware Interface')
endif
endif endif
found = [] found = []
@ -3947,11 +3911,11 @@ foreach tuple : [
# components # components
['backlight'], ['backlight'],
['binfmt'], ['binfmt'],
['bpf-framework', conf.get('BPF_FRAMEWORK') == 1], ['bpf-framework'],
['coredump'], ['coredump'],
['environment.d'], ['environment.d'],
['efi'], ['efi'],
['gnu-efi', have_gnu_efi], ['gnu-efi'],
['firstboot'], ['firstboot'],
['hibernate'], ['hibernate'],
['homed'], ['homed'],
@ -4008,7 +3972,7 @@ foreach tuple : [
['debug hashmap'], ['debug hashmap'],
['debug mmap cache'], ['debug mmap cache'],
['debug siphash'], ['debug siphash'],
['valgrind', conf.get('VALGRIND') == 1], ['valgrind'],
['trace logging', conf.get('LOG_TRACE') == 1], ['trace logging', conf.get('LOG_TRACE') == 1],
['install tests', install_tests], ['install tests', install_tests],
['link-udev-shared', get_option('link-udev-shared')], ['link-udev-shared', get_option('link-udev-shared')],

View File

@ -106,8 +106,7 @@ int uname_architecture(void) {
{ "crisv32", ARCHITECTURE_CRIS }, { "crisv32", ARCHITECTURE_CRIS },
#elif defined(__nios2__) #elif defined(__nios2__)
{ "nios2", ARCHITECTURE_NIOS2 }, { "nios2", ARCHITECTURE_NIOS2 },
#elif defined(__riscv__) || defined(__riscv) #elif defined(__riscv)
/* __riscv__ is obsolete, remove in 2018 */
{ "riscv32", ARCHITECTURE_RISCV32 }, { "riscv32", ARCHITECTURE_RISCV32 },
{ "riscv64", ARCHITECTURE_RISCV64 }, { "riscv64", ARCHITECTURE_RISCV64 },
# if __SIZEOF_POINTER__ == 4 # if __SIZEOF_POINTER__ == 4

View File

@ -210,8 +210,7 @@ int uname_architecture(void);
#elif defined(__nios2__) #elif defined(__nios2__)
# define native_architecture() ARCHITECTURE_NIOS2 # define native_architecture() ARCHITECTURE_NIOS2
# define LIB_ARCH_TUPLE "nios2-linux-gnu" # define LIB_ARCH_TUPLE "nios2-linux-gnu"
#elif defined(__riscv__) || defined(__riscv) #elif defined(__riscv)
/* __riscv__ is obsolete, remove in 2018 */
# if __SIZEOF_POINTER__ == 4 # if __SIZEOF_POINTER__ == 4
# define native_architecture() ARCHITECTURE_RISCV32 # define native_architecture() ARCHITECTURE_RISCV32
# define LIB_ARCH_TUPLE "riscv32-linux-gnu" # define LIB_ARCH_TUPLE "riscv32-linux-gnu"

View File

@ -1,5 +1,102 @@
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
conf.set10('ENABLE_EFI', get_option('efi'))
conf.set10('HAVE_GNU_EFI', false)
if not get_option('efi') or get_option('gnu-efi') == 'false'
if get_option('gnu-efi') == 'true'
error('gnu-efi support requested, but general efi support is disabled')
endif
subdir_done()
endif
efi_arch = {
# host_cc_arch: [efi_arch (see Table 3-2 in UEFI spec), gnu_efi_inc_arch]
'x86': ['ia32', 'ia32'],
'x86_64': ['x64', 'x86_64'],
'arm': ['arm', 'arm'],
'aarch64': ['aa64', 'aarch64'],
'riscv64': ['riscv64', 'riscv64'],
}.get(host_machine.cpu_family(), [])
efi_incdir = get_option('efi-includedir')
if efi_arch.length() > 0 and not cc.has_header('@0@/@1@/efibind.h'.format(efi_incdir, efi_arch[1]))
efi_arch = []
endif
if efi_arch.length() == 0
if get_option('gnu-efi') == 'true'
error('gnu-efi support requested, but headers not found or efi arch is unkown')
endif
warning('gnu-efi headers not found or efi arch is unkown, disabling gnu-efi support')
subdir_done()
endif
if not cc.has_header_symbol('efi.h', 'EFI_IMAGE_MACHINE_X64',
include_directories: include_directories(efi_incdir, efi_incdir / efi_arch[1]))
if get_option('gnu-efi') == 'true'
error('gnu-efi support requested, but found headers are too old (3.0.5+ required)')
endif
warning('gnu-efi headers are too old (3.0.5+ required), disabling gnu-efi support')
subdir_done()
endif
objcopy = find_program('objcopy')
efi_cc = get_option('efi-cc')
if efi_cc.length() == 0
efi_cc = cc.cmd_array()
endif
efi_ld = find_program(get_option('efi-ld'))
efi_ld_name = efi_ld.path().split('/')[-1]
if efi_ld_name == 'lld' or efi_ld_name == 'ld.lld'
# LLVM/LLD does not support PE/COFF relocations
# https://lists.llvm.org/pipermail/llvm-dev/2021-March/149234.html
error('LLVM/lld does not support PE/COFF relocations. Use different linker for EFI image.')
endif
efi_libdir = ''
foreach dir : [get_option('efi-libdir'),
'/usr/lib/gnuefi' / efi_arch[0],
run_command('realpath', '-e',
'/usr/lib' / run_command(efi_cc, '-print-multi-os-directory').stdout().strip()).stdout().strip()]
if run_command(test, '-d', dir).returncode() == 0
efi_libdir = dir
break
endif
endforeach
if efi_libdir == ''
if get_option('gnu-efi') == 'true'
error('gnu-efi support requested, but efi-libdir was not found')
endif
warning('efi-libdir was not found, disabling gnu-efi support')
subdir_done()
endif
efi_lds = ''
foreach location : [ # New locations first introduced with gnu-efi 3.0.11
[efi_libdir / 'efi.lds',
efi_libdir / 'crt0.o'],
# Older locations...
[efi_libdir / 'gnuefi' / 'elf_@0@_efi.lds'.format(efi_arch[1]),
efi_libdir / 'gnuefi' / 'crt0-efi-@0@.o'.format(efi_arch[1])],
[efi_libdir / 'elf_@0@_efi.lds'.format(efi_arch[1]),
efi_libdir / 'crt0-efi-@0@.o'.format(efi_arch[1])]]
if run_command(test, '-f', location[0], '-a', '-f', location[1]).returncode() == 0
efi_lds = location[0]
efi_crt0 = location[1]
break
endif
endforeach
if efi_lds == ''
if get_option('gnu-efi') == 'true'
error('gnu-efi support requested, but cannot find efi.lds')
endif
warning('efi.lds was not found, disabling gnu-efi support')
subdir_done()
endif
efi_headers = files(''' efi_headers = files('''
console.h console.h
cpio.h cpio.h
@ -39,312 +136,206 @@ systemd_boot_sources = '''
'''.split() '''.split()
stub_sources = ''' stub_sources = '''
cpio.c
initrd.c initrd.c
splash.c splash.c
stub.c stub.c
cpio.c
'''.split() '''.split()
if efi_arch in ['x86', 'x86_64'] if efi_arch[1] in ['ia32', 'x86_64']
stub_sources += 'linux_x86.c' stub_sources += 'linux_x86.c'
else else
stub_sources += 'linux.c' stub_sources += 'linux.c'
endif endif
if conf.get('ENABLE_EFI') == 1 and get_option('gnu-efi') != 'false' conf.set10('HAVE_GNU_EFI', true)
efi_cc = get_option('efi-cc') conf.set_quoted('EFI_MACHINE_TYPE_NAME', efi_arch[0])
if efi_cc.length() == 0
efi_cc = cc.cmd_array() efi_conf = configuration_data()
efi_conf.set_quoted('EFI_MACHINE_TYPE_NAME', efi_arch[0])
efi_conf.set10('ENABLE_TPM', get_option('tpm'))
foreach ctype : ['color-normal', 'color-entry', 'color-highlight', 'color-edit']
c = get_option('efi-' + ctype).split(',')
efi_conf.set(ctype.underscorify().to_upper(), 'EFI_TEXT_ATTR(@0@, @1@)'.format(
'EFI_' + c[0].strip().underscorify().to_upper(),
'EFI_' + c[1].strip().underscorify().to_upper()))
endforeach
if get_option('sbat-distro') != ''
efi_conf.set_quoted('SBAT_PROJECT', meson.project_name())
efi_conf.set_quoted('PROJECT_VERSION', meson.project_version())
efi_conf.set('PROJECT_URL', conf.get('PROJECT_URL'))
if get_option('sbat-distro-generation') < 1
error('SBAT Distro Generation must be a positive integer')
endif endif
efi_conf.set('SBAT_DISTRO_GENERATION', get_option('sbat-distro-generation'))
efi_ld = find_program(get_option('efi-ld'), required: true) foreach sbatvar : [['sbat-distro', 'ID'],
efi_ld_name = efi_ld.path().split('/')[-1] ['sbat-distro-summary', 'NAME'],
if efi_ld_name == 'lld' or efi_ld_name == 'ld.lld' ['sbat-distro-url', 'BUG_REPORT_URL']]
# LLVM/LLD does not support PE/COFF relocations value = get_option(sbatvar[0])
# https://lists.llvm.org/pipermail/llvm-dev/2021-March/149234.html if (value == '' and not meson.is_cross_build()) or value == 'auto'
error('LLVM/lld does not support PE/COFF relocations. Use different linker for EFI image.') cmd = 'if [ -e /etc/os-release ]; then . /etc/os-release; else . /usr/lib/os-release; fi; echo $@0@'.format(sbatvar[1])
endif value = run_command(sh, '-c', cmd).stdout().strip()
message('@0@ (from @1@): @2@'.format(sbatvar[0], sbatvar[1], value))
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 endif
if value == ''
error('Required @0@ option not set and autodetection failed'.format(sbatvar[0]))
endif
efi_conf.set_quoted(sbatvar[0].underscorify().to_upper(), value)
endforeach endforeach
if gnu_efi_path_arch != '' and EFI_MACHINE_TYPE_NAME == '' pkgname = get_option('sbat-distro-pkgname')
error('gnu-efi is available, but EFI_MACHINE_TYPE_NAME is unknown') if pkgname == ''
pkgname = meson.project_name()
endif endif
efi_conf.set_quoted('SBAT_DISTRO_PKGNAME', pkgname)
efi_libdir = get_option('efi-libdir') pkgver = get_option('sbat-distro-version')
if efi_libdir == '' if pkgver == ''
# New location first introduced with gnu-efi 3.0.11 efi_conf.set('SBAT_DISTRO_VERSION', 'GIT_VERSION')
efi_libdir = '/usr/lib/gnuefi' / EFI_MACHINE_TYPE_NAME
cmd = run_command(test, '-e', efi_libdir)
if cmd.returncode() != 0
# Fall back to the old approach
cmd = run_command(efi_cc + ['-print-multi-os-directory'])
if cmd.returncode() == 0
path = '/usr/lib' / cmd.stdout().strip()
cmd = run_command(env, 'realpath', '-e', path)
if cmd.returncode() == 0
efi_libdir = cmd.stdout().strip()
endif
endif
endif
endif
have_gnu_efi = gnu_efi_path_arch != '' and efi_libdir != ''
if have_gnu_efi and not cc.has_header_symbol('efi.h', 'EFI_IMAGE_MACHINE_X64',
include_directories: include_directories(efi_incdir, efi_incdir / gnu_efi_path_arch))
have_gnu_efi = false
if get_option('gnu-efi') == 'true'
error('gnu-efi support requested, but found headers are too old (3.0.5+ required)')
endif
endif
else
have_gnu_efi = false
endif
if get_option('gnu-efi') == 'true' and not have_gnu_efi
error('gnu-efi support requested, but headers were not found')
endif
if have_gnu_efi
efi_conf = configuration_data()
efi_conf.set_quoted('EFI_MACHINE_TYPE_NAME', EFI_MACHINE_TYPE_NAME)
efi_conf.set10('ENABLE_TPM', get_option('tpm'))
foreach ctype : ['color-normal', 'color-entry', 'color-highlight', 'color-edit']
c = get_option('efi-' + ctype).split(',')
fg = 'EFI_' + c[0].strip().underscorify().to_upper()
bg = 'EFI_BACKGROUND_' + c[1].strip().underscorify().to_upper()
efi_conf.set(ctype.underscorify().to_upper(), '(' + fg + '|' + bg + ')')
endforeach
if get_option('sbat-distro') != ''
efi_conf.set_quoted('SBAT_PROJECT', meson.project_name())
efi_conf.set_quoted('PROJECT_VERSION', meson.project_version())
efi_conf.set('PROJECT_URL', conf.get('PROJECT_URL'))
if get_option('sbat-distro-generation') < 1
error('SBAT Distro Generation must be a positive integer')
endif
efi_conf.set('SBAT_DISTRO_GENERATION', get_option('sbat-distro-generation'))
sbatvars = [['sbat-distro', 'ID'],
['sbat-distro-summary', 'NAME'],
['sbat-distro-url', 'BUG_REPORT_URL']]
foreach sbatvar : sbatvars
value = get_option(sbatvar[0])
if (value == '' and not meson.is_cross_build()) or value == 'auto'
cmd = 'if [ -e /etc/os-release ]; then . /etc/os-release; else . /usr/lib/os-release; fi; echo $@0@'.format(sbatvar[1])
value = run_command(sh, '-c', cmd).stdout().strip()
message('@0@ (from @1@): @2@'.format(sbatvar[0], sbatvar[1], value))
endif
if value == ''
error('Required @0@ option not set and autodetection failed'.format(sbatvar[0]))
endif
efi_conf.set_quoted(sbatvar[0].underscorify().to_upper(), value)
endforeach
pkgname = get_option('sbat-distro-pkgname')
if pkgname == ''
pkgname = meson.project_name()
endif
efi_conf.set_quoted('SBAT_DISTRO_PKGNAME', pkgname)
pkgver = get_option('sbat-distro-version')
if pkgver == ''
efi_conf.set('SBAT_DISTRO_VERSION', 'GIT_VERSION')
else
efi_conf.set_quoted('SBAT_DISTRO_VERSION', pkgver)
endif
endif
efi_config_h = configure_file(
output : 'efi_config.h',
configuration : efi_conf)
objcopy = find_program('objcopy')
efi_location_map = [
# New locations first introduced with gnu-efi 3.0.11
[efi_libdir / 'efi.lds',
efi_libdir / 'crt0.o'],
# Older locations...
[efi_libdir / 'gnuefi' / 'elf_@0@_efi.lds'.format(gnu_efi_path_arch),
efi_libdir / 'gnuefi' / 'crt0-efi-@0@.o'.format(gnu_efi_path_arch)],
[efi_libdir / 'elf_@0@_efi.lds'.format(gnu_efi_path_arch),
efi_libdir / 'crt0-efi-@0@.o'.format(gnu_efi_path_arch)]]
efi_lds = ''
foreach location : efi_location_map
if efi_lds == ''
cmd = run_command(test, '-f', location[0])
if cmd.returncode() == 0
efi_lds = location[0]
efi_crt0 = location[1]
endif
endif
endforeach
if efi_lds == ''
if get_option('gnu-efi') == 'true'
error('gnu-efi support requested, but cannot find efi.lds')
else
have_gnu_efi = false
endif
endif
endif
if have_gnu_efi
compile_args = cc.get_supported_arguments(
basic_disabled_warnings +
possible_common_cc_flags + [
'-fno-stack-protector',
'-fno-strict-aliasing',
'-fpic',
'-fwide-exec-charset=UCS2',
'-Wall',
'-Wextra',
'-Wsign-compare',
]
) + [
'-nostdlib',
'-std=gnu99',
'-ffreestanding',
'-fshort-wchar',
'-isystem', efi_incdir,
'-isystem', efi_incdir / gnu_efi_path_arch,
'-I', fundamental_path,
'-DSD_BOOT',
'-DGNU_EFI_USE_MS_ABI',
'-include', efi_config_h,
'-include', version_h,
]
if efi_arch == 'x86_64'
compile_args += ['-mno-red-zone',
'-mno-sse',
'-mno-mmx']
elif efi_arch == 'x86'
compile_args += ['-mno-sse',
'-mno-mmx']
elif efi_arch == 'arm'
compile_args += cc.get_supported_arguments([
'-mgeneral-regs-only',
'-mfpu=none'
])
endif
# We are putting the efi_cc command line together ourselves, so make sure to pull any
# relevant compiler flags from meson/CFLAGS as povided by the user or distro.
if get_option('werror')
compile_args += ['-Werror']
endif
if get_option('debug')
compile_args += ['-ggdb', '-DEFI_DEBUG']
endif
if get_option('optimization') != '0'
compile_args += ['-O' + get_option('optimization')]
endif
if get_option('b_ndebug') == 'true' or (
get_option('b_ndebug') == 'if-release' and ['plain', 'release'].contains(get_option('buildtype')))
compile_args += ['-DNDEBUG']
endif
foreach arg : get_option('c_args')
if arg in ['-Werror', '-g', '-ggdb', '-O1', '-O2', '-O3', '-Og', '-Os', '-DNDEBUG']
message('Using "@0@" from c_args for EFI compiler'.format(arg))
compile_args += arg
endif
endforeach
efi_ldflags = ['-T', efi_lds,
'-shared',
'-Bsymbolic',
'-nostdlib',
'--no-undefined',
'--warn-common',
'--fatal-warnings',
'-znocombreloc',
'--build-id=sha1',
'-L', efi_libdir,
efi_crt0]
if ['aarch64', 'arm', 'riscv64'].contains(efi_arch)
# Aarch64, ARM32 and 64bit RISC-V 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 else
efi_format = ['--target=efi-app-@0@'.format(gnu_efi_arch)] efi_conf.set_quoted('SBAT_DISTRO_VERSION', pkgver)
endif endif
systemd_boot_objects = []
stub_objects = []
foreach file : fundamental_source_paths + common_sources + systemd_boot_sources + stub_sources
o_file = custom_target(file.split('/')[-1] + '.o',
input : file,
output : file.split('/')[-1] + '.o',
command : efi_cc + ['-c', '@INPUT@', '-o', '@OUTPUT@']
+ compile_args,
depend_files : efi_headers + fundamental_headers)
if (fundamental_source_paths + common_sources + systemd_boot_sources).contains(file)
systemd_boot_objects += o_file
endif
if (fundamental_source_paths + common_sources + stub_sources).contains(file)
stub_objects += o_file
endif
endforeach
libgcc_file_name = run_command(efi_cc + ['-print-libgcc-file-name']).stdout().strip()
systemd_boot_efi_name = 'systemd-boot@0@.efi'.format(EFI_MACHINE_TYPE_NAME)
stub_elf_name = 'linux@0@.elf.stub'.format(EFI_MACHINE_TYPE_NAME)
stub_efi_name = 'linux@0@.efi.stub'.format(EFI_MACHINE_TYPE_NAME)
efi_stubs = []
foreach tuple : [['systemd_boot.so', systemd_boot_efi_name, systemd_boot_objects, false],
[stub_elf_name, stub_efi_name, stub_objects, true]]
so = custom_target(
tuple[0],
input : tuple[2],
output : tuple[0],
command : [efi_ld, '-o', '@OUTPUT@',
efi_ldflags, tuple[2],
'-lefi', '-lgnuefi', libgcc_file_name],
install : tuple[3],
install_dir : bootlibdir)
stub = custom_target(
tuple[1],
input : so,
output : tuple[1],
command : [objcopy,
'-j', '.data',
'-j', '.dynamic',
'-j', '.dynsym',
'-j', '.osrel',
'-j', '.rel*',
'-j', '.sbat',
'-j', '.sdata',
'-j', '.sdmagic',
'-j', '.text',
efi_format,
'@INPUT@', '@OUTPUT@'],
install : true,
install_dir : bootlibdir)
efi_stubs += [[so, stub]]
endforeach
############################################################
test_efi_disk_img = custom_target(
'test-efi-disk.img',
input : [efi_stubs[0][0], efi_stubs[1][1]],
output : 'test-efi-disk.img',
command : [test_efi_create_disk_sh, '@OUTPUT@','@INPUT@', splash_bmp])
endif endif
efi_config_h = configure_file(
output : 'efi_config.h',
configuration : efi_conf)
compile_args = cc.get_supported_arguments(
basic_disabled_warnings +
possible_common_cc_flags + [
'-fno-stack-protector',
'-fno-strict-aliasing',
'-fpic',
'-fwide-exec-charset=UCS2',
'-Wall',
'-Wextra',
'-Wsign-compare',
]
) + [
'-nostdlib',
'-std=gnu99',
'-ffreestanding',
'-fshort-wchar',
'-isystem', efi_incdir,
'-isystem', efi_incdir / efi_arch[1],
'-I', fundamental_path,
'-DSD_BOOT',
'-DGNU_EFI_USE_MS_ABI',
'-include', efi_config_h,
'-include', version_h,
]
compile_args += cc.get_supported_arguments({
'ia32': ['-mno-sse', '-mno-mmx'],
'x86_64': ['-mno-red-zone', '-mno-sse', '-mno-mmx'],
'arm': ['-mgeneral-regs-only', '-mfpu=none'],
}.get(efi_arch[1], []))
# We are putting the efi_cc command line together ourselves, so make sure to pull any
# relevant compiler flags from meson/CFLAGS as povided by the user or distro.
if get_option('werror')
compile_args += ['-Werror']
endif
if get_option('debug')
compile_args += ['-ggdb', '-DEFI_DEBUG']
endif
if get_option('optimization') != '0'
compile_args += ['-O' + get_option('optimization')]
endif
if get_option('b_ndebug') == 'true' or (
get_option('b_ndebug') == 'if-release' and get_option('buildtype') in ['plain', 'release'])
compile_args += ['-DNDEBUG']
endif
foreach arg : get_option('c_args')
if arg in ['-Werror', '-g', '-ggdb', '-O1', '-O2', '-O3', '-Og', '-Os', '-DNDEBUG']
message('Using "@0@" from c_args for EFI compiler'.format(arg))
compile_args += arg
endif
endforeach
efi_ldflags = ['-T', efi_lds,
'-shared',
'-Bsymbolic',
'-nostdlib',
'--no-undefined',
'--warn-common',
'--fatal-warnings',
'-znocombreloc',
'--build-id=sha1',
'-L', efi_libdir,
efi_crt0]
if efi_arch[1] in ['aarch64', 'arm', 'riscv64']
# Aarch64, ARM32 and 64bit RISC-V 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(efi_arch[1])]
endif
systemd_boot_objects = []
stub_objects = []
foreach file : fundamental_source_paths + common_sources + systemd_boot_sources + stub_sources
o_file = custom_target(file.split('/')[-1] + '.o',
input : file,
output : file.split('/')[-1] + '.o',
command : [efi_cc, '-c', '@INPUT@', '-o', '@OUTPUT@', compile_args],
depend_files : efi_headers + fundamental_headers)
if (fundamental_source_paths + common_sources + systemd_boot_sources).contains(file)
systemd_boot_objects += o_file
endif
if (fundamental_source_paths + common_sources + stub_sources).contains(file)
stub_objects += o_file
endif
endforeach
libgcc_file_name = run_command(efi_cc + ['-print-libgcc-file-name']).stdout().strip()
systemd_boot_efi_name = 'systemd-boot@0@.efi'.format(efi_arch[0])
stub_elf_name = 'linux@0@.elf.stub'.format(efi_arch[0])
stub_efi_name = 'linux@0@.efi.stub'.format(efi_arch[0])
efi_stubs = []
foreach tuple : [['systemd_boot.so', systemd_boot_efi_name, systemd_boot_objects, false],
[stub_elf_name, stub_efi_name, stub_objects, true]]
so = custom_target(
tuple[0],
input : tuple[2],
output : tuple[0],
command : [efi_ld, '-o', '@OUTPUT@', efi_ldflags, tuple[2], '-lefi', '-lgnuefi', libgcc_file_name],
install : tuple[3],
install_dir : bootlibdir)
stub = custom_target(
tuple[1],
input : so,
output : tuple[1],
command : [objcopy,
'-j', '.data',
'-j', '.dynamic',
'-j', '.dynsym',
'-j', '.osrel',
'-j', '.rel*',
'-j', '.sbat',
'-j', '.sdata',
'-j', '.sdmagic',
'-j', '.text',
efi_format,
'@INPUT@', '@OUTPUT@'],
install : true,
install_dir : bootlibdir)
efi_stubs += [[so, stub]]
endforeach
############################################################
test_efi_disk_img = custom_target(
'test-efi-disk.img',
input : [efi_stubs[0][0], efi_stubs[1][1]],
output : 'test-efi-disk.img',
command : [test_efi_create_disk_sh, '@OUTPUT@','@INPUT@', splash_bmp])

View File

@ -20,10 +20,10 @@
#include "user-util.h" #include "user-util.h"
typedef struct BaseFilesystem { typedef struct BaseFilesystem {
const char *dir; const char *dir; /* directory or symlink to create */
mode_t mode; mode_t mode;
const char *target; const char *target; /* if non-NULL create as symlink to this target */
const char *exists; const char *exists; /* conditionalize this entry on existance of this file */
bool ignore_failure; bool ignore_failure;
} BaseFilesystem; } BaseFilesystem;
@ -39,11 +39,26 @@ static const BaseFilesystem table[] = {
{ "sys", 0755, NULL, NULL, true }, { "sys", 0755, NULL, NULL, true },
{ "dev", 0755, NULL, NULL, true }, { "dev", 0755, NULL, NULL, true },
#if defined(__i386__) || defined(__x86_64__) #if defined(__i386__) || defined(__x86_64__)
/* Various architecture ABIs define the path to the dynamic loader via the /lib64/ subdirectory of
* the root directory. When booting from an otherwise empty root file system (where only /usr/ has
* been mounted into) it is thus necessary to create a symlink pointing to the right subdirectory of
* /usr/ first otherwise we couldn't invoke any dynamic binary. Let's detect this case here, and
* create the symlink as needed should it be missing. We prefer doing this consistently with Debian's
* multiarch logic, but support Fedora-style multilib too.*/
{ "lib64", 0, "usr/lib/x86_64-linux-gnu\0" { "lib64", 0, "usr/lib/x86_64-linux-gnu\0"
"usr/lib64\0", "ld-linux-x86-64.so.2" }, "usr/lib64\0", "ld-linux-x86-64.so.2" },
#else
/* gcc doesn't allow pragma to be used within constructs, hence log about this separately below */
# define WARN_LIB64 1
#endif #endif
}; };
#ifdef WARN_LIB64
#pragma message "If your architecture knows a /lib64/ or /lib32/ directory, please add an entry creating it here."
/* And if your architecture doesn't know these directories, make sure to add ifdeffery here to
* suppress this pragma message. */
#endif
int base_filesystem_create(const char *root, uid_t uid, gid_t gid) { int base_filesystem_create(const char *root, uid_t uid, gid_t gid) {
_cleanup_close_ int fd = -1; _cleanup_close_ int fd = -1;
int r; int r;

View File

@ -4,6 +4,16 @@
#include "string-util.h" #include "string-util.h"
#include "utf8.h" #include "utf8.h"
/* Gently push people towards defining GPT type UUIDs for all architectures we know */
#if !defined(GPT_ROOT_NATIVE) || \
!defined(GPT_ROOT_NATIVE_VERITY) || \
!defined(GPT_ROOT_NATIVE_VERITY_SIG) || \
!defined(GPT_USR_NATIVE) || \
!defined(GPT_USR_NATIVE_VERITY) || \
!defined(GPT_USR_NATIVE_VERITY_SIG)
#pragma message "Please define GPT partition types for your architecture."
#endif
const GptPartitionType gpt_partition_type_table[] = { const GptPartitionType gpt_partition_type_table[] = {
{ GPT_ROOT_X86, "root-x86" }, { GPT_ROOT_X86, "root-x86" },
{ GPT_ROOT_X86_VERITY, "root-x86-verity" }, { GPT_ROOT_X86_VERITY, "root-x86-verity" },