blob: fa63c6abda8d5b3e0d6171891e1d55364919beb8 [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
30from wic import kickstart, msger
31from wic.pluginbase import SourcePlugin
32from wic.utils.oe.misc import exec_cmd, exec_native_cmd, get_bitbake_var, \
33 BOOTDD_EXTRA_SPACE
34
35class BootimgEFIPlugin(SourcePlugin):
36 """
37 Create EFI boot partition.
38 This plugin supports GRUB 2 and gummiboot bootloaders.
39 """
40
41 name = 'bootimg-efi'
42
43 @classmethod
44 def do_configure_grubefi(cls, hdddir, creator, cr_workdir):
45 """
46 Create loader-specific (grub-efi) config
47 """
48 options = creator.ks.handler.bootloader.appendLine
49
50 grubefi_conf = ""
51 grubefi_conf += "serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1\n"
52 grubefi_conf += "default=boot\n"
53 timeout = kickstart.get_timeout(creator.ks)
54 if not timeout:
55 timeout = 0
56 grubefi_conf += "timeout=%s\n" % timeout
57 grubefi_conf += "menuentry 'boot'{\n"
58
59 kernel = "/bzImage"
60
61 grubefi_conf += "linux %s root=%s rootwait %s\n" \
62 % (kernel, creator.rootdev, options)
63 grubefi_conf += "}\n"
64
65 msger.debug("Writing grubefi config %s/hdd/boot/EFI/BOOT/grub.cfg" \
66 % cr_workdir)
67 cfg = open("%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir, "w")
68 cfg.write(grubefi_conf)
69 cfg.close()
70
71 @classmethod
72 def do_configure_gummiboot(cls, hdddir, creator, cr_workdir):
73 """
74 Create loader-specific (gummiboot) config
75 """
76 install_cmd = "install -d %s/loader" % hdddir
77 exec_cmd(install_cmd)
78
79 install_cmd = "install -d %s/loader/entries" % hdddir
80 exec_cmd(install_cmd)
81
82 options = creator.ks.handler.bootloader.appendLine
83
84 timeout = kickstart.get_timeout(creator.ks)
85 if not timeout:
86 timeout = 0
87
88 loader_conf = ""
89 loader_conf += "default boot\n"
90 loader_conf += "timeout %d\n" % timeout
91
92 msger.debug("Writing gummiboot config %s/hdd/boot/loader/loader.conf" \
93 % cr_workdir)
94 cfg = open("%s/hdd/boot/loader/loader.conf" % cr_workdir, "w")
95 cfg.write(loader_conf)
96 cfg.close()
97
98 kernel = "/bzImage"
99
100 boot_conf = ""
101 boot_conf += "title boot\n"
102 boot_conf += "linux %s\n" % kernel
103 boot_conf += "options LABEL=Boot root=%s %s\n" % (creator.rootdev, options)
104
105 msger.debug("Writing gummiboot config %s/hdd/boot/loader/entries/boot.conf" \
106 % cr_workdir)
107 cfg = open("%s/hdd/boot/loader/entries/boot.conf" % cr_workdir, "w")
108 cfg.write(boot_conf)
109 cfg.close()
110
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 """
117 Called before do_prepare_partition(), creates loader-specific config
118 """
119 hdddir = "%s/hdd/boot" % cr_workdir
120 rm_cmd = "rm -rf %s" % cr_workdir
121 exec_cmd(rm_cmd)
122
123 install_cmd = "install -d %s/EFI/BOOT" % hdddir
124 exec_cmd(install_cmd)
125
126 try:
127 if source_params['loader'] == 'grub-efi':
128 cls.do_configure_grubefi(hdddir, creator, cr_workdir)
129 elif source_params['loader'] == 'gummiboot':
130 cls.do_configure_gummiboot(hdddir, creator, cr_workdir)
131 else:
132 msger.error("unrecognized bootimg-efi loader: %s" % source_params['loader'])
133 except KeyError:
134 msger.error("bootimg-efi requires a loader, none specified")
135
136
137 @classmethod
138 def do_prepare_partition(cls, part, source_params, creator, cr_workdir,
139 oe_builddir, bootimg_dir, kernel_dir,
140 rootfs_dir, native_sysroot):
141 """
142 Called to do the actual content population for a partition i.e. it
143 'prepares' the partition to be incorporated into the image.
144 In this case, prepare content for an EFI (grub) boot partition.
145 """
146 if not bootimg_dir:
147 bootimg_dir = get_bitbake_var("HDDDIR")
148 if not bootimg_dir:
149 msger.error("Couldn't find HDDDIR, exiting\n")
150 # just so the result notes display it
151 creator.set_bootimg_dir(bootimg_dir)
152
153 staging_kernel_dir = kernel_dir
154
155 hdddir = "%s/hdd/boot" % cr_workdir
156
157 install_cmd = "install -m 0644 %s/bzImage %s/bzImage" % \
158 (staging_kernel_dir, hdddir)
159 exec_cmd(install_cmd)
160
161 try:
162 if source_params['loader'] == 'grub-efi':
163 shutil.copyfile("%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir,
164 "%s/grub.cfg" % cr_workdir)
165 cp_cmd = "cp %s/EFI/BOOT/* %s/EFI/BOOT" % (bootimg_dir, hdddir)
166 exec_cmd(cp_cmd, True)
167 shutil.move("%s/grub.cfg" % cr_workdir,
168 "%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir)
169 elif source_params['loader'] == 'gummiboot':
170 cp_cmd = "cp %s/EFI/BOOT/* %s/EFI/BOOT" % (bootimg_dir, hdddir)
171 exec_cmd(cp_cmd, True)
172 else:
173 msger.error("unrecognized bootimg-efi loader: %s" % source_params['loader'])
174 except KeyError:
175 msger.error("bootimg-efi requires a loader, none specified")
176
177 du_cmd = "du -bks %s" % hdddir
178 out = exec_cmd(du_cmd)
179 blocks = int(out.split()[0])
180
181 extra_blocks = part.get_extra_block_count(blocks)
182
183 if extra_blocks < BOOTDD_EXTRA_SPACE:
184 extra_blocks = BOOTDD_EXTRA_SPACE
185
186 blocks += extra_blocks
187
188 msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
189 (extra_blocks, part.mountpoint, blocks))
190
191 # Ensure total sectors is an integral number of sectors per
192 # track or mcopy will complain. Sectors are 512 bytes, and we
193 # generate images with 32 sectors per track. This calculation is
194 # done in blocks, thus the mod by 16 instead of 32.
195 blocks += (16 - (blocks % 16))
196
197 # dosfs image, created by mkdosfs
198 bootimg = "%s/boot.img" % cr_workdir
199
200 dosfs_cmd = "mkdosfs -n efi -C %s %d" % (bootimg, blocks)
201 exec_native_cmd(dosfs_cmd, native_sysroot)
202
203 mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (bootimg, hdddir)
204 exec_native_cmd(mcopy_cmd, native_sysroot)
205
206 chmod_cmd = "chmod 644 %s" % bootimg
207 exec_cmd(chmod_cmd)
208
209 du_cmd = "du -Lbks %s" % bootimg
210 out = exec_cmd(du_cmd)
211 bootimg_size = out.split()[0]
212
213 part.set_size(bootimg_size)
214 part.set_source_file(bootimg)