Skip to content

Commit

Permalink
Use ukify instead of llvm-objcopy
Browse files Browse the repository at this point in the history
  • Loading branch information
valentindavid committed Apr 29, 2024
1 parent 4f18fdf commit a0ef0e0
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 54 deletions.
26 changes: 9 additions & 17 deletions HACKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,28 +264,20 @@ that, to repack everything, run these commands:
$ cd initrd
$ find . | cpio --create --quiet --format=newc --owner=0:0 | lz4 -l -7 > ../initrd.img
$ cd -
$ apt download systemd-boot-efi
$ dpkg --fsys-tarfile systemd-boot-efi_*.deb |
tar xf - ./usr/lib/systemd/boot/efi/linuxx64.efi.stub
$ apt install systemd-boot-efi systemd-ukify
$ objcopy -O binary -j .linux pc-kernel/kernel.efi linux
$ llvm-objcopy --add-section .linux=linux --set-section-flags .linux=readonly,data \
--add-section .initrd=initrd.img --set-section-flags .initrd=readonly,data \
usr/lib/systemd/boot/efi/linuxx64.efi.stub \
pc-kernel/kernel.efi
$ /usr/lib/systemd/ukify build --linux linux \
--initrd initrd.img \
--output pc-kernel/kernel.efi
$ snap pack pc-kernel
```

Here we use llvm-objcopy as it can automatically adjust section
addresses as necessary (objcopy does not do that), while for
retrieving the section data we use objcopy (llvm-objcopy unfortunately
adds a PE header to the extracted files that would need manual
removal).

Note that the systemd-boot-efi package should match the Ubuntu release
of the kernel being modified. You can use this new kernel snap while
building image, or copy it over to your device and install. The new
`kernel.efi` won't be signed, so Secure Boot will not be possible
anymore, unless signed again with a key accepted by the system.
of the kernel being modified (both version and architecture). You can
use this new kernel snap while building image, or copy it over to your
device and install. The new `kernel.efi` won't be signed, so Secure
Boot will not be possible anymore, unless signed again with a key
accepted by the system.

# Hacking with rebuilding

Expand Down
64 changes: 28 additions & 36 deletions bin/ubuntu-core-initramfs
Original file line number Diff line number Diff line change
Expand Up @@ -714,9 +714,10 @@ def create_initrd(parser, args):


def create_efi(parser, args):
if not args.stub:
parser.error("--stub is required, and one was not automatically detected")
if args.root:
if not args.stub:
parser.error("--stub is mandatory when --root is given")
args.os_release = path_join_make_rel_paths(args.root, args.os_release)
args.stub = path_join_make_rel_paths(args.root, args.stub)
args.kernel = path_join_make_rel_paths(args.root, args.kernel)
args.initrd = path_join_make_rel_paths(args.root, args.initrd)
Expand All @@ -739,35 +740,32 @@ def create_efi(parser, args):
except gzip.BadGzipFile:
pass

# kernel.efi sections will be aligned to the page size by llvm-objcopy
# (which is the default value for SectionAlignment in the PE header).
# --set-section-flags are such so added COFF sections have flags:
# CONTENTS, ALLOC, LOAD, READONLY, DATA
# (see llvm-objcopy man page for details)
# To see more details, run 'objdump --all-headers kernel.efi'
# (objdump gives a bit more of information than llvm-objdump in this case)
objcopy_cmd = [
"llvm-objcopy",
# TODO: add --splash
ukify_cmd = [
'/usr/lib/systemd/ukify', 'build',
'--linux', args.kernel,
'--initrd', args.initrd,
'--output', args.output,
'--os-release', '@{}'.format(args.os_release),
]

if args.kernelver:
ukify_cmd += [
'--uname', args.kernelver,
]
if args.stub:
ukify_cmd += [
'--stub', args.stub,
]
if args.efi_arch:
ukify_cmd += [
'--efi-arch', args.efi_arch,
]
# TODO add .osrel
if args.cmdline:
cmdline = tempfile.NamedTemporaryFile(mode='w')
cmdline.write('%s' % args.cmdline)
cmdline.flush()
objcopy_cmd += [
"--add-section", ".cmdline=%s" % cmdline.name,
"--set-section-flags", ".cmdline=readonly,data",
]
# TODO add .splash
objcopy_cmd += [
"--add-section", ".linux=%s" % args.kernel,
"--set-section-flags", ".linux=readonly,data",
"--add-section", ".initrd=%s" % args.initrd,
"--set-section-flags", ".initrd=readonly,data",
args.stub,
args.output,
ukify_cmd += [
'--cmdline', args.cmdline,
]
check_call(objcopy_cmd)
check_call(ukify_cmd)
if not args.unsigned:
check_call(
[
Expand All @@ -788,10 +786,6 @@ def main():
kernelver = check_output(
["uname", "-r"], universal_newlines=True
).strip()
suffix = {"x86_64": "x64",
"aarch64": "aa64",
"arm": "arm",
"riscv64": "riscv64"}.get(platform.machine())
features = {"x86_64": "main server"}.get(platform.machine(), "main")
parser = argparse.ArgumentParser()
subparser = parser.add_subparsers(dest="subcmd", required=True)
Expand All @@ -800,10 +794,8 @@ def main():
)
efi_parser.add_argument("--root", help="path to root")
efi_parser.add_argument("--stub", help="path to stub")
if suffix:
efi_parser.set_defaults(
stub="/usr/lib/systemd/boot/efi/linux%s.efi.stub" % suffix
)
efi_parser.add_argument("--efi-arch", help="efi architecture name")
efi_parser.add_argument("--os-release", help="path to os-release", default="/etc/os-release")
efi_parser.add_argument("--kernel", help="path to kernel", default="/boot/vmlinuz")
efi_parser.add_argument(
"--kernelver", help="kernel version suffix", default=kernelver
Expand Down
2 changes: 1 addition & 1 deletion debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ Depends: ${python3:Depends}, ${misc:Depends}, dracut-core (>= 051-1),
sbsigntool,
snapd (>= 2.50+20.04),
linux-firmware,
llvm,
kcapi-tools (>= 1.4.0-1ubuntu3),
dbus,
dmsetup,
Expand All @@ -39,6 +38,7 @@ Depends: ${python3:Depends}, ${misc:Depends}, dracut-core (>= 051-1),
squashfs-tools,
systemd,
systemd-boot-efi,
systemd-ukify,
systemd-bootchart,
cryptsetup-bin,
systemd-sysv,
Expand Down

0 comments on commit a0ef0e0

Please sign in to comment.