11#! /bin/bash
22set -euo pipefail
33
4- # exit with an error message
5- die () {
6- echo " Error: $* " >&2
7- exit 1
8- }
9-
10- # get the size of the file in bytes
11- get_size () {
12- stat -c %s " $1 "
13- }
14-
15- # convert a number of bytes into MiB (i.e. 1024 * 1024 bytes), rounded to the next value
16- in_mib () {
17- echo $(( ($1 + (1 << 20 ) - 1 ) >> 20 ))
18- }
19-
20- # get the size of the file in mibytes
21- get_size_mib () {
22- in_mib " $( get_size " $1 " ) "
23- }
24-
25- # round the value given in $1 to the next multiple of the value given in $2
26- # e.g. align 9 4 -> 12, align 8 4 -> 8
27- align () {
28- echo " $(( ($1 + $2 - 1 ) / $2 * $2 )) "
29- }
30-
31- # build the EFI executable
32- build_efi () {
33- local size kernel
34-
35- pushd " $build_dir " > /dev/null
36-
37- echo " Building the EFI executable"
38- build_initramfs
39- size=$( get_size_mib initramfs)
40- echo " The size of the initramfs is: $size MiB"
41- kernel=$( find /system/boot -name ' vmlinu*' -print)
42- space_separated < /system/boot/cmdline > cmdline
43- basename /system/lib/modules/* > kernel-release
44-
45- # build the EFI UKI file
46- # TODO: add .dtb section on ARM?
47- build_uki << -EOF
48- .osrel /system/etc/os-release
49- .uname kernel-release
50- .cmdline cmdline
51- .initrd initramfs
52- .linux $kernel
53- EOF
54-
55- # delete all the temporary files
56- find . ! -name ' *.efi' -delete
57-
58- popd > /dev/null
59- }
60-
61- # build the initramfs
62- build_initramfs () {
63- mkdir initramfs_files
64-
65- # copy the init script
66- cp /usr/share/claylinux/init initramfs_files
67-
68- # copy /etc/hosts.target as /etc/hosts
69- if [[ -f /system/etc/hosts.target ]]; then
70- mkdir -p initramfs_files/etc
71- cp /system/etc/hosts.target initramfs_files/etc/hosts
72- fi
73-
74- # copy etc/resolv.conf.target as etc/resolv.conf
75- if [[ -f /system/etc/resolv.conf.target ]]; then
76- mkdir -p initramfs_files/etc
77- cp /system/etc/resolv.conf.target initramfs_files/etc/resolv.conf
78- fi
79-
80- # create an initramfs with these files
81- find initramfs_files -mindepth 1 -printf ' %P\0' \
82- | cpio --quiet -o0H newc -D initramfs_files -F initramfs.img
83-
84- # append the system files into the initramfs image, except /boot, /etc/hosts.target and /etc/resolv.conf.target
85- find /system \
86- -path /system/boot -prune -o \
87- ! -path /system/init \
88- ! -path /system/etc/hosts.target \
89- ! -path /system/etc/resolv.conf.target \
90- -mindepth 1 -printf ' %P\0' \
91- | cpio --quiet -o0AH newc -D /system -F initramfs.img
92-
93- # compress the initramfs
94- compress initramfs.img
95-
96- # build the final initramfs by concatenating the ucode images & our compressed initramfs image
97- # see https://docs.kernel.org/arch/x86/microcode.html
98- echo " $( find /system/boot/ -name ' *-ucode.img' ) initramfs.img" | xargs cat > initramfs
99-
100- # remove the temporary files
101- find . ! -name initramfs -delete
102- }
103-
104- # create a Unified Kernel Image from the sections passed in the standard input
105- build_uki () {
106- # the sections addresses should be aligned to PAGE_ALIGN(), i.e. 2<<12 == 4096 bytes
107- local args=() alignment=4096 size offset
108-
109- # compute the start offset of the new sections
110- offset=" $( objdump -h -w " $efi_stub " | awk ' END { offset=("0x"$4)+0; size=("0x"$3)+0; print offset + size }' ) "
111- offset=$( align " $offset " $alignment )
112-
113- # compute the objcopy arguments
114- while read -r section file
115- do
116- # add the section to the parameters
117- args+=(
118- --add-section
119- " $section =$file "
120- --change-section-vma
121- " $section =$offset "
122- )
123-
124- # compute the offset for the next section
125- size=" $( get_size " $file " ) "
126- size=$( align " $size " $alignment )
127- offset=$(( offset + size ))
128- done
129-
130- objcopy " ${args[@]} " " $efi_stub " " $efi_file "
131- }
132-
1334# detect the current EFI architecture
1345get_efi_arch () {
1356 local machine_arch
@@ -153,34 +24,6 @@ get_efi_arch() {
15324 esac
15425}
15526
156- # convert a multi-line input into a space separated list
157- space_separated () {
158- paste -d' ' -s
159- }
160-
161- # compress the initramfs with the specified scheme
162- compress () {
163- case " $compression " in
164- none)
165- ;;
166- gz)
167- pigz -9 " $1 "
168- mv " $1 " .gz " $1 "
169- ;;
170- xz)
171- xz -C crc32 -9 -T0 " $1 "
172- mv " $1 " .xz " $1 "
173- ;;
174- zstd)
175- zstd -19 -T0 --rm " $1 "
176- mv " $1 " .zstd " $1 "
177- ;;
178- * )
179- die " invalid compression scheme '$compression '"
180- ;;
181- esac
182- }
183-
18427# just copy the build files to the output directory
18528generate_efi () {
18629 echo " Copying the OS files to the output directory"
@@ -312,7 +155,6 @@ format=raw
312155volume=CLAYLINUX
313156compression=gz
314157efi_arch=$( get_efi_arch)
315- efi_stub=" /usr/lib/systemd/boot/efi/linux${efi_arch} .efi.stub"
316158
317159usage=$( cat << -EOF
318160 Usage: $( basename " $0 " ) [OPTIONS ...]
373215build_dir=$( mktemp -d)
374216efi_file=" $build_dir " /claylinux.efi
375217esp_file=" $build_dir " /claylinux.esp
376- build_efi
218+ imager " $build_dir "
377219mkdir -p " $( dirname " $output " ) "
378220generate_" $format "
379221rmdir " $build_dir "
0 commit comments