diff options
Diffstat (limited to 'scripts/lib/wic/plugins/source/bootimg-efi.py')
-rw-r--r-- | scripts/lib/wic/plugins/source/bootimg-efi.py | 360 |
1 files changed, 0 insertions, 360 deletions
diff --git a/scripts/lib/wic/plugins/source/bootimg-efi.py b/scripts/lib/wic/plugins/source/bootimg-efi.py deleted file mode 100644 index cdc72543c2..0000000000 --- a/scripts/lib/wic/plugins/source/bootimg-efi.py +++ /dev/null | |||
@@ -1,360 +0,0 @@ | |||
1 | # | ||
2 | # Copyright (c) 2014, Intel Corporation. | ||
3 | # | ||
4 | # SPDX-License-Identifier: GPL-2.0-only | ||
5 | # | ||
6 | # DESCRIPTION | ||
7 | # This implements the 'bootimg-efi' source plugin class for 'wic' | ||
8 | # | ||
9 | # AUTHORS | ||
10 | # Tom Zanussi <tom.zanussi (at] linux.intel.com> | ||
11 | # | ||
12 | |||
13 | import logging | ||
14 | import os | ||
15 | import shutil | ||
16 | import re | ||
17 | |||
18 | from glob import glob | ||
19 | |||
20 | from wic import WicError | ||
21 | from wic.engine import get_custom_config | ||
22 | from wic.pluginbase import SourcePlugin | ||
23 | from wic.misc import (exec_cmd, exec_native_cmd, | ||
24 | get_bitbake_var, BOOTDD_EXTRA_SPACE) | ||
25 | |||
26 | logger = logging.getLogger('wic') | ||
27 | |||
28 | class BootimgEFIPlugin(SourcePlugin): | ||
29 | """ | ||
30 | Create EFI boot partition. | ||
31 | This plugin supports GRUB 2 and systemd-boot bootloaders. | ||
32 | """ | ||
33 | |||
34 | name = 'bootimg-efi' | ||
35 | |||
36 | @classmethod | ||
37 | def do_configure_grubefi(cls, hdddir, creator, cr_workdir, source_params): | ||
38 | """ | ||
39 | Create loader-specific (grub-efi) config | ||
40 | """ | ||
41 | configfile = creator.ks.bootloader.configfile | ||
42 | custom_cfg = None | ||
43 | if configfile: | ||
44 | custom_cfg = get_custom_config(configfile) | ||
45 | if custom_cfg: | ||
46 | # Use a custom configuration for grub | ||
47 | grubefi_conf = custom_cfg | ||
48 | logger.debug("Using custom configuration file " | ||
49 | "%s for grub.cfg", configfile) | ||
50 | else: | ||
51 | raise WicError("configfile is specified but failed to " | ||
52 | "get it from %s." % configfile) | ||
53 | |||
54 | initrd = source_params.get('initrd') | ||
55 | |||
56 | if initrd: | ||
57 | bootimg_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") | ||
58 | if not bootimg_dir: | ||
59 | raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting") | ||
60 | |||
61 | initrds = initrd.split(';') | ||
62 | for rd in initrds: | ||
63 | cp_cmd = "cp %s/%s %s" % (bootimg_dir, rd, hdddir) | ||
64 | exec_cmd(cp_cmd, True) | ||
65 | else: | ||
66 | logger.debug("Ignoring missing initrd") | ||
67 | |||
68 | if not custom_cfg: | ||
69 | # Create grub configuration using parameters from wks file | ||
70 | bootloader = creator.ks.bootloader | ||
71 | title = source_params.get('title') | ||
72 | |||
73 | grubefi_conf = "" | ||
74 | grubefi_conf += "serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1\n" | ||
75 | grubefi_conf += "default=boot\n" | ||
76 | grubefi_conf += "timeout=%s\n" % bootloader.timeout | ||
77 | grubefi_conf += "menuentry '%s'{\n" % (title if title else "boot") | ||
78 | |||
79 | kernel = get_bitbake_var("KERNEL_IMAGETYPE") | ||
80 | if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1": | ||
81 | if get_bitbake_var("INITRAMFS_IMAGE"): | ||
82 | kernel = "%s-%s.bin" % \ | ||
83 | (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME")) | ||
84 | |||
85 | label = source_params.get('label') | ||
86 | label_conf = "root=%s" % creator.rootdev | ||
87 | if label: | ||
88 | label_conf = "LABEL=%s" % label | ||
89 | |||
90 | grubefi_conf += "linux /%s %s rootwait %s\n" \ | ||
91 | % (kernel, label_conf, bootloader.append) | ||
92 | |||
93 | if initrd: | ||
94 | initrds = initrd.split(';') | ||
95 | grubefi_conf += "initrd" | ||
96 | for rd in initrds: | ||
97 | grubefi_conf += " /%s" % rd | ||
98 | grubefi_conf += "\n" | ||
99 | |||
100 | grubefi_conf += "}\n" | ||
101 | |||
102 | logger.debug("Writing grubefi config %s/hdd/boot/EFI/BOOT/grub.cfg", | ||
103 | cr_workdir) | ||
104 | cfg = open("%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir, "w") | ||
105 | cfg.write(grubefi_conf) | ||
106 | cfg.close() | ||
107 | |||
108 | @classmethod | ||
109 | def do_configure_systemdboot(cls, hdddir, creator, cr_workdir, source_params): | ||
110 | """ | ||
111 | Create loader-specific systemd-boot/gummiboot config | ||
112 | """ | ||
113 | install_cmd = "install -d %s/loader" % hdddir | ||
114 | exec_cmd(install_cmd) | ||
115 | |||
116 | install_cmd = "install -d %s/loader/entries" % hdddir | ||
117 | exec_cmd(install_cmd) | ||
118 | |||
119 | bootloader = creator.ks.bootloader | ||
120 | |||
121 | loader_conf = "" | ||
122 | loader_conf += "default boot\n" | ||
123 | loader_conf += "timeout %d\n" % bootloader.timeout | ||
124 | |||
125 | initrd = source_params.get('initrd') | ||
126 | |||
127 | if initrd: | ||
128 | # obviously we need to have a common common deploy var | ||
129 | bootimg_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") | ||
130 | if not bootimg_dir: | ||
131 | raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting") | ||
132 | |||
133 | initrds = initrd.split(';') | ||
134 | for rd in initrds: | ||
135 | cp_cmd = "cp %s/%s %s" % (bootimg_dir, rd, hdddir) | ||
136 | exec_cmd(cp_cmd, True) | ||
137 | else: | ||
138 | logger.debug("Ignoring missing initrd") | ||
139 | |||
140 | logger.debug("Writing systemd-boot config " | ||
141 | "%s/hdd/boot/loader/loader.conf", cr_workdir) | ||
142 | cfg = open("%s/hdd/boot/loader/loader.conf" % cr_workdir, "w") | ||
143 | cfg.write(loader_conf) | ||
144 | cfg.close() | ||
145 | |||
146 | configfile = creator.ks.bootloader.configfile | ||
147 | custom_cfg = None | ||
148 | if configfile: | ||
149 | custom_cfg = get_custom_config(configfile) | ||
150 | if custom_cfg: | ||
151 | # Use a custom configuration for systemd-boot | ||
152 | boot_conf = custom_cfg | ||
153 | logger.debug("Using custom configuration file " | ||
154 | "%s for systemd-boots's boot.conf", configfile) | ||
155 | else: | ||
156 | raise WicError("configfile is specified but failed to " | ||
157 | "get it from %s.", configfile) | ||
158 | |||
159 | if not custom_cfg: | ||
160 | # Create systemd-boot configuration using parameters from wks file | ||
161 | kernel = get_bitbake_var("KERNEL_IMAGETYPE") | ||
162 | if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1": | ||
163 | if get_bitbake_var("INITRAMFS_IMAGE"): | ||
164 | kernel = "%s-%s.bin" % \ | ||
165 | (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME")) | ||
166 | |||
167 | title = source_params.get('title') | ||
168 | |||
169 | boot_conf = "" | ||
170 | boot_conf += "title %s\n" % (title if title else "boot") | ||
171 | boot_conf += "linux /%s\n" % kernel | ||
172 | |||
173 | label = source_params.get('label') | ||
174 | label_conf = "LABEL=Boot root=%s" % creator.rootdev | ||
175 | if label: | ||
176 | label_conf = "LABEL=%s" % label | ||
177 | |||
178 | boot_conf += "options %s %s\n" % \ | ||
179 | (label_conf, bootloader.append) | ||
180 | |||
181 | if initrd: | ||
182 | initrds = initrd.split(';') | ||
183 | for rd in initrds: | ||
184 | boot_conf += "initrd /%s\n" % rd | ||
185 | |||
186 | logger.debug("Writing systemd-boot config " | ||
187 | "%s/hdd/boot/loader/entries/boot.conf", cr_workdir) | ||
188 | cfg = open("%s/hdd/boot/loader/entries/boot.conf" % cr_workdir, "w") | ||
189 | cfg.write(boot_conf) | ||
190 | cfg.close() | ||
191 | |||
192 | |||
193 | @classmethod | ||
194 | def do_configure_partition(cls, part, source_params, creator, cr_workdir, | ||
195 | oe_builddir, bootimg_dir, kernel_dir, | ||
196 | native_sysroot): | ||
197 | """ | ||
198 | Called before do_prepare_partition(), creates loader-specific config | ||
199 | """ | ||
200 | hdddir = "%s/hdd/boot" % cr_workdir | ||
201 | |||
202 | install_cmd = "install -d %s/EFI/BOOT" % hdddir | ||
203 | exec_cmd(install_cmd) | ||
204 | |||
205 | try: | ||
206 | if source_params['loader'] == 'grub-efi': | ||
207 | cls.do_configure_grubefi(hdddir, creator, cr_workdir, source_params) | ||
208 | elif source_params['loader'] == 'systemd-boot': | ||
209 | cls.do_configure_systemdboot(hdddir, creator, cr_workdir, source_params) | ||
210 | else: | ||
211 | raise WicError("unrecognized bootimg-efi loader: %s" % source_params['loader']) | ||
212 | except KeyError: | ||
213 | raise WicError("bootimg-efi requires a loader, none specified") | ||
214 | |||
215 | if get_bitbake_var("IMAGE_EFI_BOOT_FILES") is None: | ||
216 | logger.debug('No boot files defined in IMAGE_EFI_BOOT_FILES') | ||
217 | else: | ||
218 | boot_files = None | ||
219 | for (fmt, id) in (("_uuid-%s", part.uuid), ("_label-%s", part.label), (None, None)): | ||
220 | if fmt: | ||
221 | var = fmt % id | ||
222 | else: | ||
223 | var = "" | ||
224 | |||
225 | boot_files = get_bitbake_var("IMAGE_EFI_BOOT_FILES" + var) | ||
226 | if boot_files: | ||
227 | break | ||
228 | |||
229 | logger.debug('Boot files: %s', boot_files) | ||
230 | |||
231 | # list of tuples (src_name, dst_name) | ||
232 | deploy_files = [] | ||
233 | for src_entry in re.findall(r'[\w;\-\./\*]+', boot_files): | ||
234 | if ';' in src_entry: | ||
235 | dst_entry = tuple(src_entry.split(';')) | ||
236 | if not dst_entry[0] or not dst_entry[1]: | ||
237 | raise WicError('Malformed boot file entry: %s' % src_entry) | ||
238 | else: | ||
239 | dst_entry = (src_entry, src_entry) | ||
240 | |||
241 | logger.debug('Destination entry: %r', dst_entry) | ||
242 | deploy_files.append(dst_entry) | ||
243 | |||
244 | cls.install_task = []; | ||
245 | for deploy_entry in deploy_files: | ||
246 | src, dst = deploy_entry | ||
247 | if '*' in src: | ||
248 | # by default install files under their basename | ||
249 | entry_name_fn = os.path.basename | ||
250 | if dst != src: | ||
251 | # unless a target name was given, then treat name | ||
252 | # as a directory and append a basename | ||
253 | entry_name_fn = lambda name: \ | ||
254 | os.path.join(dst, | ||
255 | os.path.basename(name)) | ||
256 | |||
257 | srcs = glob(os.path.join(kernel_dir, src)) | ||
258 | |||
259 | logger.debug('Globbed sources: %s', ', '.join(srcs)) | ||
260 | for entry in srcs: | ||
261 | src = os.path.relpath(entry, kernel_dir) | ||
262 | entry_dst_name = entry_name_fn(entry) | ||
263 | cls.install_task.append((src, entry_dst_name)) | ||
264 | else: | ||
265 | cls.install_task.append((src, dst)) | ||
266 | |||
267 | @classmethod | ||
268 | def do_prepare_partition(cls, part, source_params, creator, cr_workdir, | ||
269 | oe_builddir, bootimg_dir, kernel_dir, | ||
270 | rootfs_dir, native_sysroot): | ||
271 | """ | ||
272 | Called to do the actual content population for a partition i.e. it | ||
273 | 'prepares' the partition to be incorporated into the image. | ||
274 | In this case, prepare content for an EFI (grub) boot partition. | ||
275 | """ | ||
276 | if not kernel_dir: | ||
277 | kernel_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") | ||
278 | if not kernel_dir: | ||
279 | raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting") | ||
280 | |||
281 | staging_kernel_dir = kernel_dir | ||
282 | |||
283 | hdddir = "%s/hdd/boot" % cr_workdir | ||
284 | |||
285 | kernel = get_bitbake_var("KERNEL_IMAGETYPE") | ||
286 | if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1": | ||
287 | if get_bitbake_var("INITRAMFS_IMAGE"): | ||
288 | kernel = "%s-%s.bin" % \ | ||
289 | (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME")) | ||
290 | |||
291 | install_cmd = "install -m 0644 %s/%s %s/%s" % \ | ||
292 | (staging_kernel_dir, kernel, hdddir, kernel) | ||
293 | exec_cmd(install_cmd) | ||
294 | |||
295 | if get_bitbake_var("IMAGE_EFI_BOOT_FILES"): | ||
296 | for src_path, dst_path in cls.install_task: | ||
297 | install_cmd = "install -m 0644 -D %s %s" \ | ||
298 | % (os.path.join(kernel_dir, src_path), | ||
299 | os.path.join(hdddir, dst_path)) | ||
300 | exec_cmd(install_cmd) | ||
301 | |||
302 | try: | ||
303 | if source_params['loader'] == 'grub-efi': | ||
304 | shutil.copyfile("%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir, | ||
305 | "%s/grub.cfg" % cr_workdir) | ||
306 | for mod in [x for x in os.listdir(kernel_dir) if x.startswith("grub-efi-")]: | ||
307 | cp_cmd = "cp %s/%s %s/EFI/BOOT/%s" % (kernel_dir, mod, hdddir, mod[9:]) | ||
308 | exec_cmd(cp_cmd, True) | ||
309 | shutil.move("%s/grub.cfg" % cr_workdir, | ||
310 | "%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir) | ||
311 | elif source_params['loader'] == 'systemd-boot': | ||
312 | for mod in [x for x in os.listdir(kernel_dir) if x.startswith("systemd-")]: | ||
313 | cp_cmd = "cp %s/%s %s/EFI/BOOT/%s" % (kernel_dir, mod, hdddir, mod[8:]) | ||
314 | exec_cmd(cp_cmd, True) | ||
315 | else: | ||
316 | raise WicError("unrecognized bootimg-efi loader: %s" % | ||
317 | source_params['loader']) | ||
318 | except KeyError: | ||
319 | raise WicError("bootimg-efi requires a loader, none specified") | ||
320 | |||
321 | startup = os.path.join(kernel_dir, "startup.nsh") | ||
322 | if os.path.exists(startup): | ||
323 | cp_cmd = "cp %s %s/" % (startup, hdddir) | ||
324 | exec_cmd(cp_cmd, True) | ||
325 | |||
326 | du_cmd = "du -bks %s" % hdddir | ||
327 | out = exec_cmd(du_cmd) | ||
328 | blocks = int(out.split()[0]) | ||
329 | |||
330 | extra_blocks = part.get_extra_block_count(blocks) | ||
331 | |||
332 | if extra_blocks < BOOTDD_EXTRA_SPACE: | ||
333 | extra_blocks = BOOTDD_EXTRA_SPACE | ||
334 | |||
335 | blocks += extra_blocks | ||
336 | |||
337 | logger.debug("Added %d extra blocks to %s to get to %d total blocks", | ||
338 | extra_blocks, part.mountpoint, blocks) | ||
339 | |||
340 | # dosfs image, created by mkdosfs | ||
341 | bootimg = "%s/boot.img" % cr_workdir | ||
342 | |||
343 | label = part.label if part.label else "ESP" | ||
344 | |||
345 | dosfs_cmd = "mkdosfs -n %s -i %s -C %s %d" % \ | ||
346 | (label, part.fsuuid, bootimg, blocks) | ||
347 | exec_native_cmd(dosfs_cmd, native_sysroot) | ||
348 | |||
349 | mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (bootimg, hdddir) | ||
350 | exec_native_cmd(mcopy_cmd, native_sysroot) | ||
351 | |||
352 | chmod_cmd = "chmod 644 %s" % bootimg | ||
353 | exec_cmd(chmod_cmd) | ||
354 | |||
355 | du_cmd = "du -Lbks %s" % bootimg | ||
356 | out = exec_cmd(du_cmd) | ||
357 | bootimg_size = out.split()[0] | ||
358 | |||
359 | part.size = int(bootimg_size) | ||
360 | part.source_file = bootimg | ||