summaryrefslogtreecommitdiffstats
path: root/scripts/lib/wic/plugins/source/bootimg_pcbios.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/lib/wic/plugins/source/bootimg_pcbios.py')
-rw-r--r--scripts/lib/wic/plugins/source/bootimg_pcbios.py483
1 files changed, 0 insertions, 483 deletions
diff --git a/scripts/lib/wic/plugins/source/bootimg_pcbios.py b/scripts/lib/wic/plugins/source/bootimg_pcbios.py
deleted file mode 100644
index caabda6318..0000000000
--- a/scripts/lib/wic/plugins/source/bootimg_pcbios.py
+++ /dev/null
@@ -1,483 +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_pcbios' source plugin class for 'wic'
8#
9# AUTHORS
10# Tom Zanussi <tom.zanussi (at] linux.intel.com>
11#
12
13import logging
14import os
15import re
16import shutil
17
18from glob import glob
19from wic import WicError
20from wic.engine import get_custom_config
21from wic.pluginbase import SourcePlugin
22from wic.misc import (exec_cmd, exec_native_cmd,
23 get_bitbake_var, BOOTDD_EXTRA_SPACE)
24
25logger = logging.getLogger('wic')
26
27class BootimgPcbiosPlugin(SourcePlugin):
28 """
29 Creates boot partition that is legacy BIOS firmare bootable with
30 MBR/MSDOS as partition table format. Plugin will install caller
31 selected bootloader directly to resulting wic image.
32
33 Supported Bootloaders:
34 * syslinux (default)
35 * grub
36
37 ****************** Wic Plugin Depends/Vars ******************
38 WKS_FILE_DEPENDS = "grub-native grub"
39 WKS_FILE_DEPENDS = "syslinux-native syslinux"
40
41 # Optional variables
42 # GRUB_MKIMAGE_FORMAT_PC - Used to define target platform.
43 # GRUB_PREFIX_PATH - Used to define which directory
44 # grub config and modules are going
45 # to reside in.
46 GRUB_PREFIX_PATH = '/boot/grub2' # Default: /boot/grub
47 GRUB_MKIMAGE_FORMAT_PC = 'i386-pc' # Default: i386-pc
48
49 WICVARS:append = "\
50 GRUB_PREFIX_PATH \
51 GRUB_MKIMAGE_FORMAT_PC \
52 "
53 ****************** Wic Plugin Depends/Vars ******************
54
55
56 **************** Example kickstart Legacy Bios Grub Boot ****************
57 part boot --label bios_boot --fstype ext4 --offset 1024 --fixed-size 78M
58 --source bootimg_pcbios --sourceparams="loader-bios=grub" --active
59
60 part roots --label rootfs --fstype ext4 --source rootfs --use-uuid
61 bootloader --ptable msdos --source bootimg_pcbios
62 **************** Example kickstart Legacy Bios Grub Boot ****************
63
64
65 *************** Example kickstart Legacy Bios Syslinux Boot ****************
66 part /boot --source bootimg_pcbios --sourceparams="loader-bios=syslinux"
67 --ondisk sda --label boot --fstype vfat --align 1024 --active
68
69 part roots --label rootfs --fstype ext4 --source rootfs --use-uuid
70 bootloader --ptable msdos --source bootimg_pcbios
71 """
72
73 name = 'bootimg_pcbios'
74
75 # Variable required for do_install_disk
76 loader = ''
77
78 @classmethod
79 def _get_bootimg_dir(cls, bootimg_dir, dirname):
80 """
81 Check if dirname exists in default bootimg_dir or in STAGING_DIR.
82 """
83 staging_datadir = get_bitbake_var("STAGING_DATADIR")
84 for result in (bootimg_dir, staging_datadir):
85 if os.path.exists("%s/%s" % (result, dirname)):
86 return result
87
88 # STAGING_DATADIR is expanded with MLPREFIX if multilib is enabled
89 # but dependency syslinux is still populated to original STAGING_DATADIR
90 nonarch_datadir = re.sub('/[^/]*recipe-sysroot', '/recipe-sysroot', staging_datadir)
91 if os.path.exists(os.path.join(nonarch_datadir, dirname)):
92 return nonarch_datadir
93
94 raise WicError("Couldn't find correct bootimg_dir, exiting")
95
96 @classmethod
97 def do_install_disk(cls, disk, disk_name, creator, workdir, oe_builddir,
98 bootimg_dir, kernel_dir, native_sysroot):
99 full_path = creator._full_path(workdir, disk_name, "direct")
100 logger.debug("Installing MBR on disk %s as %s with size %s bytes",
101 disk_name, full_path, disk.min_size)
102
103 if cls.loader == 'grub':
104 cls._do_install_grub(creator, kernel_dir,
105 native_sysroot, full_path)
106 elif cls.loader == 'syslinux':
107 cls._do_install_syslinux(creator, bootimg_dir,
108 native_sysroot, full_path)
109 else:
110 raise WicError("boot loader some how not specified check do_prepare_partition")
111
112 @classmethod
113 def do_configure_partition(cls, part, source_params, creator, cr_workdir,
114 oe_builddir, bootimg_dir, kernel_dir,
115 native_sysroot):
116 try:
117 if source_params['loader-bios'] == 'grub':
118 cls._do_configure_grub(part, creator, cr_workdir)
119 elif source_params['loader-bios'] == 'syslinux':
120 cls._do_configure_syslinux(part, creator, cr_workdir)
121 else:
122 raise WicError("unrecognized bootimg_pcbios loader: %s" % source_params['loader-bios'])
123 except KeyError:
124 cls._do_configure_syslinux(part, creator, cr_workdir)
125
126 @classmethod
127 def do_prepare_partition(cls, part, source_params, creator, cr_workdir,
128 oe_builddir, bootimg_dir, kernel_dir,
129 rootfs_dir, native_sysroot):
130 try:
131 if source_params['loader-bios'] == 'grub':
132 cls._do_prepare_grub(part, cr_workdir, oe_builddir,
133 kernel_dir, rootfs_dir, native_sysroot)
134 elif source_params['loader-bios'] == 'syslinux':
135 cls._do_prepare_syslinux(part, cr_workdir, bootimg_dir,
136 kernel_dir, native_sysroot)
137 else:
138 raise WicError("unrecognized bootimg_pcbios loader: %s" % source_params['loader-bios'])
139
140 # Required by do_install_disk
141 cls.loader = source_params['loader-bios']
142 except KeyError:
143 # Required by do_install_disk
144 cls.loader = 'syslinux'
145 cls._do_prepare_syslinux(part, cr_workdir, bootimg_dir,
146 kernel_dir, native_sysroot)
147
148 @classmethod
149 def _get_staging_libdir(cls):
150 """
151 For unknown reasons when running test with poky
152 STAGING_LIBDIR gets unset when wic create is executed.
153 Bellow is a hack to determine what STAGING_LIBDIR should
154 be if not specified.
155 """
156
157 staging_libdir = get_bitbake_var('STAGING_LIBDIR')
158 staging_dir_target = get_bitbake_var('STAGING_DIR_TARGET')
159
160 if not staging_libdir:
161 staging_libdir = '%s/usr/lib64' % staging_dir_target
162 if not os.path.isdir(staging_libdir):
163 staging_libdir = '%s/usr/lib32' % staging_dir_target
164 if not os.path.isdir(staging_libdir):
165 staging_libdir = '%s/usr/lib' % staging_dir_target
166
167 return staging_libdir
168
169 @classmethod
170 def _get_bootloader_config(cls, bootloader, loader):
171 custom_cfg = None
172
173 if bootloader.configfile:
174 custom_cfg = get_custom_config(bootloader.configfile)
175 if custom_cfg:
176 logger.debug("Using custom configuration file %s "
177 "for %s.cfg", bootloader.configfile,
178 loader)
179 return custom_cfg
180 else:
181 raise WicError("configfile is specified but failed to "
182 "get it from %s." % bootloader.configfile)
183 return custom_cfg
184
185 @classmethod
186 def _do_configure_syslinux(cls, part, creator, cr_workdir):
187 """
188 Called before do_prepare_partition(), creates syslinux config
189 """
190
191 hdddir = "%s/hdd/boot" % cr_workdir
192
193 install_cmd = "install -d %s" % hdddir
194 exec_cmd(install_cmd)
195
196 bootloader = creator.ks.bootloader
197 syslinux_conf = cls._get_bootloader_config(bootloader, 'syslinux')
198
199 if not syslinux_conf:
200 # Create syslinux configuration using parameters from wks file
201 splash = os.path.join(hdddir, "/splash.jpg")
202 if os.path.exists(splash):
203 splashline = "menu background splash.jpg"
204 else:
205 splashline = ""
206
207 # Set a default timeout if none specified to avoid
208 # 'None' being the value placed within the configuration
209 # file.
210 if not bootloader.timeout:
211 bootloader.timeout = 500
212
213 # Set a default kernel params string if none specified
214 # to avoid 'None' being the value placed within the
215 # configuration file.
216 if not bootloader.append:
217 bootloader.append = "rootwait console=ttyS0,115200 console=tty0"
218
219 syslinux_conf = ""
220 syslinux_conf += "PROMPT 0\n"
221 syslinux_conf += "TIMEOUT " + str(bootloader.timeout) + "\n"
222 syslinux_conf += "\n"
223 syslinux_conf += "ALLOWOPTIONS 1\n"
224 syslinux_conf += "SERIAL 0 115200\n"
225 syslinux_conf += "\n"
226 if splashline:
227 syslinux_conf += "%s\n" % splashline
228 syslinux_conf += "DEFAULT boot\n"
229 syslinux_conf += "LABEL boot\n"
230
231 kernel = "/" + get_bitbake_var("KERNEL_IMAGETYPE")
232 syslinux_conf += "KERNEL " + kernel + "\n"
233
234 syslinux_conf += "APPEND label=boot root=%s %s\n" % \
235 (creator.rootdev, bootloader.append)
236
237 logger.debug("Writing syslinux config %s/syslinux.cfg", hdddir)
238 cfg = open("%s/hdd/boot/syslinux.cfg" % cr_workdir, "w")
239 cfg.write(syslinux_conf)
240 cfg.close()
241
242 @classmethod
243 def _do_prepare_syslinux(cls, part, cr_workdir, bootimg_dir,
244 kernel_dir, native_sysroot):
245 """
246 Called to do the actual content population for a partition i.e. it
247 'prepares' the partition to be incorporated into the image.
248 In this case, prepare content for legacy bios boot partition.
249 """
250 bootimg_dir = cls._get_bootimg_dir(bootimg_dir, 'syslinux')
251
252 staging_kernel_dir = kernel_dir
253
254 hdddir = "%s/hdd/boot" % cr_workdir
255
256 kernel = get_bitbake_var("KERNEL_IMAGETYPE")
257 if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1":
258 if get_bitbake_var("INITRAMFS_IMAGE"):
259 kernel = "%s-%s.bin" % \
260 (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME"))
261
262 cmds = ("install -m 0644 %s/%s %s/%s" %
263 (staging_kernel_dir, kernel, hdddir, get_bitbake_var("KERNEL_IMAGETYPE")),
264 "install -m 444 %s/syslinux/ldlinux.sys %s/ldlinux.sys" %
265 (bootimg_dir, hdddir),
266 "install -m 0644 %s/syslinux/vesamenu.c32 %s/vesamenu.c32" %
267 (bootimg_dir, hdddir),
268 "install -m 444 %s/syslinux/libcom32.c32 %s/libcom32.c32" %
269 (bootimg_dir, hdddir),
270 "install -m 444 %s/syslinux/libutil.c32 %s/libutil.c32" %
271 (bootimg_dir, hdddir))
272
273 for install_cmd in cmds:
274 exec_cmd(install_cmd)
275
276 du_cmd = "du -bks %s" % hdddir
277 out = exec_cmd(du_cmd)
278 blocks = int(out.split()[0])
279
280 extra_blocks = part.get_extra_block_count(blocks)
281
282 if extra_blocks < BOOTDD_EXTRA_SPACE:
283 extra_blocks = BOOTDD_EXTRA_SPACE
284
285 blocks += extra_blocks
286
287 logger.debug("Added %d extra blocks to %s to get to %d total blocks",
288 extra_blocks, part.mountpoint, blocks)
289
290 # dosfs image, created by mkdosfs
291 bootimg = "%s/boot%s.img" % (cr_workdir, part.lineno)
292
293 label = part.label if part.label else "boot"
294
295 dosfs_cmd = "mkdosfs -n %s -i %s -S 512 -C %s %d" % \
296 (label, part.fsuuid, bootimg, blocks)
297 exec_native_cmd(dosfs_cmd, native_sysroot)
298
299 mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (bootimg, hdddir)
300 exec_native_cmd(mcopy_cmd, native_sysroot)
301
302 syslinux_cmd = "syslinux %s" % bootimg
303 exec_native_cmd(syslinux_cmd, native_sysroot)
304
305 chmod_cmd = "chmod 644 %s" % bootimg
306 exec_cmd(chmod_cmd)
307
308 du_cmd = "du -Lbks %s" % bootimg
309 out = exec_cmd(du_cmd)
310 bootimg_size = out.split()[0]
311
312 part.size = int(bootimg_size)
313 part.source_file = bootimg
314
315 @classmethod
316 def _do_install_syslinux(cls, creator, bootimg_dir,
317 native_sysroot, full_path):
318 """
319 Called after all partitions have been prepared and assembled into a
320 disk image. In this case, we install the MBR.
321 """
322
323 bootimg_dir = cls._get_bootimg_dir(bootimg_dir, 'syslinux')
324 mbrfile = "%s/syslinux/" % bootimg_dir
325 if creator.ptable_format == 'msdos':
326 mbrfile += "mbr.bin"
327 elif creator.ptable_format == 'gpt':
328 mbrfile += "gptmbr.bin"
329 else:
330 raise WicError("Unsupported partition table: %s" %
331 creator.ptable_format)
332
333 if not os.path.exists(mbrfile):
334 raise WicError("Couldn't find %s. If using the -e option, do you "
335 "have the right MACHINE set in local.conf? If not, "
336 "is the bootimg_dir path correct?" % mbrfile)
337
338 dd_cmd = "dd if=%s of=%s conv=notrunc" % (mbrfile, full_path)
339 exec_cmd(dd_cmd, native_sysroot)
340
341 @classmethod
342 def _do_configure_grub(cls, part, creator, cr_workdir):
343 hdddir = "%s/hdd" % cr_workdir
344 bootloader = creator.ks.bootloader
345
346 grub_conf = cls._get_bootloader_config(bootloader, 'grub')
347
348 grub_prefix_path = get_bitbake_var('GRUB_PREFIX_PATH')
349 if not grub_prefix_path:
350 grub_prefix_path = '/boot/grub'
351
352 grub_path = "%s/%s" %(hdddir, grub_prefix_path)
353 install_cmd = "install -d %s" % grub_path
354 exec_cmd(install_cmd)
355
356 if not grub_conf:
357 # Set a default timeout if none specified to avoid
358 # 'None' being the value placed within the configuration
359 # file.
360 if not bootloader.timeout:
361 bootloader.timeout = 500
362
363 # Set a default kernel params string if none specified
364 # to avoid 'None' being the value placed within the
365 # configuration file.
366 if not bootloader.append:
367 bootloader.append = "rootwait rootfstype=%s " % (part.fstype)
368 bootloader.append += "console=ttyS0,115200 console=tty0"
369
370 kernel = "/boot/" + get_bitbake_var("KERNEL_IMAGETYPE")
371
372 grub_conf = 'serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1\n'
373 grub_conf += 'set gfxmode=auto\n'
374 grub_conf += 'set gfxpayload=keep\n\n'
375 grub_conf += 'set default=0\n\n'
376 grub_conf += '# Boot automatically after %d secs.\n' % (bootloader.timeout)
377 grub_conf += 'set timeout=%d\n\n' % (bootloader.timeout)
378 grub_conf += 'menuentry \'default\' {\n'
379 grub_conf += '\tsearch --no-floppy --set=root --file %s\n' % (kernel)
380 grub_conf += '\tprobe --set partuuid --part-uuid ($root)\n'
381 grub_conf += '\tlinux %s root=PARTUUID=$partuuid %s\n}\n' % \
382 (kernel, bootloader.append)
383
384 logger.debug("Writing grub config %s/grub.cfg", grub_path)
385 cfg = open("%s/grub.cfg" % grub_path, "w")
386 cfg.write(grub_conf)
387 cfg.close()
388
389 @classmethod
390 def _do_prepare_grub(cls, part, cr_workdir, oe_builddir,
391 kernel_dir, rootfs_dir, native_sysroot):
392 """
393 1. Generate embed.cfg that'll later be embedded into core.img.
394 So, that core.img knows where to search for grub.cfg.
395 2. Generate core.img or grub stage 1.5.
396 3. Copy modules into partition.
397 4. Create partition rootfs file.
398 """
399
400 hdddir = "%s/hdd" % cr_workdir
401
402 copy_types = [ '*.mod', '*.o', '*.lst' ]
403
404 builtin_modules = 'boot linux ext2 fat serial part_msdos part_gpt \
405 normal multiboot probe biosdisk msdospart configfile search loadenv test'
406
407 staging_libdir = cls._get_staging_libdir()
408
409 grub_format = get_bitbake_var('GRUB_MKIMAGE_FORMAT_PC')
410 if not grub_format:
411 grub_format = 'i386-pc'
412
413 grub_prefix_path = get_bitbake_var('GRUB_PREFIX_PATH')
414 if not grub_prefix_path:
415 grub_prefix_path = '/boot/grub'
416
417 grub_path = "%s/%s" %(hdddir, grub_prefix_path)
418 core_img = '%s/grub-bios-core.img' % (kernel_dir)
419 grub_mods_path = '%s/grub/%s' % (staging_libdir, grub_format)
420
421 # Generate embedded grub config
422 embed_cfg_str = 'search.file %s/grub.cfg root\n' % (grub_prefix_path)
423 embed_cfg_str += 'set prefix=($root)%s\n' % (grub_prefix_path)
424 embed_cfg_str += 'configfile ($root)%s/grub.cfg\n' % (grub_prefix_path)
425 cfg = open('%s/embed.cfg' % (kernel_dir), 'w+')
426 cfg.write(embed_cfg_str)
427 cfg.close()
428
429 # core.img doesn't get included into boot partition
430 # it's later dd onto the resulting wic image.
431 grub_mkimage = 'grub-mkimage \
432 --prefix=%s \
433 --format=%s \
434 --config=%s/embed.cfg \
435 --directory=%s \
436 --output=%s %s' % \
437 (grub_prefix_path, grub_format, kernel_dir,
438 grub_mods_path, core_img, builtin_modules)
439 exec_native_cmd(grub_mkimage, native_sysroot)
440
441 # Copy grub modules
442 install_dir = '%s/%s/%s' % (hdddir, grub_prefix_path, grub_format)
443 os.makedirs(install_dir, exist_ok=True)
444
445 for ctype in copy_types:
446 files = glob('%s/grub/%s/%s' % \
447 (staging_libdir, grub_format, ctype))
448 for file in files:
449 shutil.copy2(file, install_dir, follow_symlinks=True)
450
451 # Create boot partition
452 logger.debug('Prepare partition using rootfs in %s', hdddir)
453 part.prepare_rootfs(cr_workdir, oe_builddir, hdddir,
454 native_sysroot, False)
455
456 @classmethod
457 def _do_install_grub(cls, creator, kernel_dir,
458 native_sysroot, full_path):
459 core_img = '%s/grub-bios-core.img' % (kernel_dir)
460
461 staging_libdir = cls._get_staging_libdir()
462
463 grub_format = get_bitbake_var('GRUB_MKIMAGE_FORMAT_PC')
464 if not grub_format:
465 grub_format = 'i386-pc'
466
467 boot_img = '%s/grub/%s/boot.img' % (staging_libdir, grub_format)
468 if not os.path.exists(boot_img):
469 raise WicError("Couldn't find %s. Did you include "
470 "do_image_wic[depends] += \"grub:do_populate_sysroot\" "
471 "in your image recipe" % boot_img)
472
473 # Install boot.img or grub stage 1
474 dd_cmd = "dd if=%s of=%s conv=notrunc bs=1 seek=0 count=440" % (boot_img, full_path)
475 exec_cmd(dd_cmd, native_sysroot)
476
477 if creator.ptable_format == 'msdos':
478 # Install core.img or grub stage 1.5
479 dd_cmd = "dd if=%s of=%s conv=notrunc bs=1 seek=512" % (core_img, full_path)
480 exec_cmd(dd_cmd, native_sysroot)
481 else:
482 raise WicError("Unsupported partition table: %s" %
483 creator.ptable_format)