blob: a4734c9b36635328a219c4f260d255e2d110dacc [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3#
4# Copyright (c) 2014, Intel Corporation.
5# All rights reserved.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19#
20# DESCRIPTION
21# This implements the 'bootimg-efi' source plugin class for 'wic'
22#
23# AUTHORS
24# Tom Zanussi <tom.zanussi (at] linux.intel.com>
25#
26
27import os
28import shutil
29
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050030from wic import msger
Patrick Williamsc124f4f2015-09-15 14:41:29 -050031from wic.pluginbase import SourcePlugin
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050032from wic.utils.misc import get_custom_config
Patrick Williamsc124f4f2015-09-15 14:41:29 -050033from wic.utils.oe.misc import exec_cmd, exec_native_cmd, get_bitbake_var, \
34 BOOTDD_EXTRA_SPACE
35
36class BootimgEFIPlugin(SourcePlugin):
37 """
38 Create EFI boot partition.
39 This plugin supports GRUB 2 and gummiboot bootloaders.
40 """
41
42 name = 'bootimg-efi'
43
44 @classmethod
45 def do_configure_grubefi(cls, hdddir, creator, cr_workdir):
46 """
47 Create loader-specific (grub-efi) config
48 """
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050049 configfile = creator.ks.bootloader.configfile
50 custom_cfg = None
51 if configfile:
52 custom_cfg = get_custom_config(configfile)
53 if custom_cfg:
54 # Use a custom configuration for grub
55 grubefi_conf = custom_cfg
56 msger.debug("Using custom configuration file "
57 "%s for grub.cfg" % configfile)
58 else:
59 msger.error("configfile is specified but failed to "
60 "get it from %s." % configfile)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050061
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050062 if not custom_cfg:
63 # Create grub configuration using parameters from wks file
64 bootloader = creator.ks.bootloader
Patrick Williamsc124f4f2015-09-15 14:41:29 -050065
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050066 grubefi_conf = ""
67 grubefi_conf += "serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1\n"
68 grubefi_conf += "default=boot\n"
69 grubefi_conf += "timeout=%s\n" % bootloader.timeout
70 grubefi_conf += "menuentry 'boot'{\n"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050071
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050072 kernel = "/bzImage"
73
74 grubefi_conf += "linux %s root=%s rootwait %s\n" \
75 % (kernel, creator.rootdev, bootloader.append)
76 grubefi_conf += "}\n"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050077
78 msger.debug("Writing grubefi config %s/hdd/boot/EFI/BOOT/grub.cfg" \
79 % cr_workdir)
80 cfg = open("%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir, "w")
81 cfg.write(grubefi_conf)
82 cfg.close()
83
84 @classmethod
85 def do_configure_gummiboot(cls, hdddir, creator, cr_workdir):
86 """
87 Create loader-specific (gummiboot) config
88 """
89 install_cmd = "install -d %s/loader" % hdddir
90 exec_cmd(install_cmd)
91
92 install_cmd = "install -d %s/loader/entries" % hdddir
93 exec_cmd(install_cmd)
94
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050095 bootloader = creator.ks.bootloader
Patrick Williamsc124f4f2015-09-15 14:41:29 -050096
97 loader_conf = ""
98 loader_conf += "default boot\n"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050099 loader_conf += "timeout %d\n" % bootloader.timeout
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500100
101 msger.debug("Writing gummiboot config %s/hdd/boot/loader/loader.conf" \
102 % cr_workdir)
103 cfg = open("%s/hdd/boot/loader/loader.conf" % cr_workdir, "w")
104 cfg.write(loader_conf)
105 cfg.close()
106
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500107 configfile = creator.ks.bootloader.configfile
108 custom_cfg = None
109 if configfile:
110 custom_cfg = get_custom_config(configfile)
111 if custom_cfg:
112 # Use a custom configuration for gummiboot
113 boot_conf = custom_cfg
114 msger.debug("Using custom configuration file "
115 "%s for gummiboots's boot.conf" % configfile)
116 else:
117 msger.error("configfile is specified but failed to "
118 "get it from %s." % configfile)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500119
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500120 if not custom_cfg:
121 # Create gummiboot configuration using parameters from wks file
122 kernel = "/bzImage"
123
124 boot_conf = ""
125 boot_conf += "title boot\n"
126 boot_conf += "linux %s\n" % kernel
127 boot_conf += "options LABEL=Boot root=%s %s\n" % \
128 (creator.rootdev, bootloader.append)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500129
130 msger.debug("Writing gummiboot config %s/hdd/boot/loader/entries/boot.conf" \
131 % cr_workdir)
132 cfg = open("%s/hdd/boot/loader/entries/boot.conf" % cr_workdir, "w")
133 cfg.write(boot_conf)
134 cfg.close()
135
136
137 @classmethod
138 def do_configure_partition(cls, part, source_params, creator, cr_workdir,
139 oe_builddir, bootimg_dir, kernel_dir,
140 native_sysroot):
141 """
142 Called before do_prepare_partition(), creates loader-specific config
143 """
144 hdddir = "%s/hdd/boot" % cr_workdir
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500145
146 install_cmd = "install -d %s/EFI/BOOT" % hdddir
147 exec_cmd(install_cmd)
148
149 try:
150 if source_params['loader'] == 'grub-efi':
151 cls.do_configure_grubefi(hdddir, creator, cr_workdir)
152 elif source_params['loader'] == 'gummiboot':
153 cls.do_configure_gummiboot(hdddir, creator, cr_workdir)
154 else:
155 msger.error("unrecognized bootimg-efi loader: %s" % source_params['loader'])
156 except KeyError:
157 msger.error("bootimg-efi requires a loader, none specified")
158
159
160 @classmethod
161 def do_prepare_partition(cls, part, source_params, creator, cr_workdir,
162 oe_builddir, bootimg_dir, kernel_dir,
163 rootfs_dir, native_sysroot):
164 """
165 Called to do the actual content population for a partition i.e. it
166 'prepares' the partition to be incorporated into the image.
167 In this case, prepare content for an EFI (grub) boot partition.
168 """
169 if not bootimg_dir:
170 bootimg_dir = get_bitbake_var("HDDDIR")
171 if not bootimg_dir:
172 msger.error("Couldn't find HDDDIR, exiting\n")
173 # just so the result notes display it
174 creator.set_bootimg_dir(bootimg_dir)
175
176 staging_kernel_dir = kernel_dir
177
178 hdddir = "%s/hdd/boot" % cr_workdir
179
180 install_cmd = "install -m 0644 %s/bzImage %s/bzImage" % \
181 (staging_kernel_dir, hdddir)
182 exec_cmd(install_cmd)
183
184 try:
185 if source_params['loader'] == 'grub-efi':
186 shutil.copyfile("%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir,
187 "%s/grub.cfg" % cr_workdir)
188 cp_cmd = "cp %s/EFI/BOOT/* %s/EFI/BOOT" % (bootimg_dir, hdddir)
189 exec_cmd(cp_cmd, True)
190 shutil.move("%s/grub.cfg" % cr_workdir,
191 "%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir)
192 elif source_params['loader'] == 'gummiboot':
193 cp_cmd = "cp %s/EFI/BOOT/* %s/EFI/BOOT" % (bootimg_dir, hdddir)
194 exec_cmd(cp_cmd, True)
195 else:
196 msger.error("unrecognized bootimg-efi loader: %s" % source_params['loader'])
197 except KeyError:
198 msger.error("bootimg-efi requires a loader, none specified")
199
200 du_cmd = "du -bks %s" % hdddir
201 out = exec_cmd(du_cmd)
202 blocks = int(out.split()[0])
203
204 extra_blocks = part.get_extra_block_count(blocks)
205
206 if extra_blocks < BOOTDD_EXTRA_SPACE:
207 extra_blocks = BOOTDD_EXTRA_SPACE
208
209 blocks += extra_blocks
210
211 msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
212 (extra_blocks, part.mountpoint, blocks))
213
214 # Ensure total sectors is an integral number of sectors per
215 # track or mcopy will complain. Sectors are 512 bytes, and we
216 # generate images with 32 sectors per track. This calculation is
217 # done in blocks, thus the mod by 16 instead of 32.
218 blocks += (16 - (blocks % 16))
219
220 # dosfs image, created by mkdosfs
221 bootimg = "%s/boot.img" % cr_workdir
222
223 dosfs_cmd = "mkdosfs -n efi -C %s %d" % (bootimg, blocks)
224 exec_native_cmd(dosfs_cmd, native_sysroot)
225
226 mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (bootimg, hdddir)
227 exec_native_cmd(mcopy_cmd, native_sysroot)
228
229 chmod_cmd = "chmod 644 %s" % bootimg
230 exec_cmd(chmod_cmd)
231
232 du_cmd = "du -Lbks %s" % bootimg
233 out = exec_cmd(du_cmd)
234 bootimg_size = out.split()[0]
235
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500236 part.size = bootimg_size
237 part.source_file = bootimg