blob: 3d60e6f0ff030e736d798f439b9aa3f181e923ba [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# This program is free software; you can distribute it and/or modify
5# it under the terms of the GNU General Public License version 2 as
6# published by the Free Software Foundation.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for mo details.
12#
13# You should have received a copy of the GNU General Public License along
14# with this program; if not, write to the Free Software Foundation, Inc.,
15# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16#
17# AUTHOR
18# Adrian Freihofer <adrian.freihofer (at] neratec.com>
19#
20
21import os
Patrick Williamsc124f4f2015-09-15 14:41:29 -050022from wic import msger
23from wic.utils import syslinux
24from wic.utils import runner
25from wic.utils.oe import misc
26from wic.utils.errors import ImageError
27from wic.pluginbase import SourcePlugin
28
29
30# pylint: disable=no-init
31class RootfsPlugin(SourcePlugin):
32 """
33 Create root partition and install syslinux bootloader
34
35 This plugin creates a disk image containing a bootable root partition with
36 syslinux installed. The filesystem is ext2/3/4, no extra boot partition is
37 required.
38
39 Example kickstart file:
40 part / --source rootfs-pcbios-ext --ondisk sda --fstype=ext4 --label rootfs --align 1024
41 bootloader --source rootfs-pcbios-ext --timeout=0 --append="rootwait rootfstype=ext4"
42
43 The first line generates a root file system including a syslinux.cfg file
44 The "--source rootfs-pcbios-ext" in the second line triggers the installation
45 of ldlinux.sys into the image.
46 """
47
48 name = 'rootfs-pcbios-ext'
49
50 @staticmethod
51 def _get_rootfs_dir(rootfs_dir):
52 """
53 Find rootfs pseudo dir
54
55 If rootfs_dir is a directory consider it as rootfs directory.
56 Otherwise ask bitbake about the IMAGE_ROOTFS directory.
57 """
58 if os.path.isdir(rootfs_dir):
59 return rootfs_dir
60
61 image_rootfs_dir = misc.get_bitbake_var("IMAGE_ROOTFS", rootfs_dir)
62 if not os.path.isdir(image_rootfs_dir):
63 msg = "No valid artifact IMAGE_ROOTFS from image named"
64 msg += " %s has been found at %s, exiting.\n" % \
65 (rootfs_dir, image_rootfs_dir)
66 msger.error(msg)
67
68 return image_rootfs_dir
69
70 # pylint: disable=unused-argument
71 @classmethod
72 def do_configure_partition(cls, part, source_params, image_creator,
73 image_creator_workdir, oe_builddir, bootimg_dir,
74 kernel_dir, native_sysroot):
75 """
76 Creates syslinux config in rootfs directory
77
78 Called before do_prepare_partition()
79 """
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050080 bootloader = image_creator.ks.bootloader
Patrick Williamsc124f4f2015-09-15 14:41:29 -050081
82 syslinux_conf = ""
83 syslinux_conf += "PROMPT 0\n"
84
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050085 syslinux_conf += "TIMEOUT " + str(bootloader.timeout) + "\n"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050086 syslinux_conf += "ALLOWOPTIONS 1\n"
87
88 # Derive SERIAL... line from from kernel boot parameters
89 syslinux_conf += syslinux.serial_console_form_kargs(options) + "\n"
90
91 syslinux_conf += "DEFAULT linux\n"
92 syslinux_conf += "LABEL linux\n"
93 syslinux_conf += " KERNEL /boot/bzImage\n"
94
95 syslinux_conf += " APPEND label=boot root=%s %s\n" % \
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050096 (image_creator.rootdev, bootloader.append)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050097
98 syslinux_cfg = os.path.join(image_creator.rootfs_dir['ROOTFS_DIR'], "boot", "syslinux.cfg")
99 msger.debug("Writing syslinux config %s" % syslinux_cfg)
100 with open(syslinux_cfg, "w") as cfg:
101 cfg.write(syslinux_conf)
102
103 @classmethod
104 def do_prepare_partition(cls, part, source_params, image_creator,
105 image_creator_workdir, oe_builddir, bootimg_dir,
106 kernel_dir, krootfs_dir, native_sysroot):
107 """
108 Creates partition out of rootfs directory
109
110 Prepare content for a rootfs partition i.e. create a partition
111 and fill it from a /rootfs dir.
112 Install syslinux bootloader into root partition image file
113 """
114 def is_exe(exepath):
115 """Verify exepath is an executable file"""
116 return os.path.isfile(exepath) and os.access(exepath, os.X_OK)
117
118 # Make sure syslinux-nomtools is available in native sysroot or fail
119 native_syslinux_nomtools = os.path.join(native_sysroot, "usr/bin/syslinux-nomtools")
120 if not is_exe(native_syslinux_nomtools):
121 msger.info("building syslinux-native...")
122 misc.exec_cmd("bitbake syslinux-native")
123 if not is_exe(native_syslinux_nomtools):
124 msger.error("Couldn't find syslinux-nomtools (%s), exiting\n" %
125 native_syslinux_nomtools)
126
127 if part.rootfs is None:
128 if 'ROOTFS_DIR' not in krootfs_dir:
129 msger.error("Couldn't find --rootfs-dir, exiting")
130 rootfs_dir = krootfs_dir['ROOTFS_DIR']
131 else:
132 if part.rootfs in krootfs_dir:
133 rootfs_dir = krootfs_dir[part.rootfs]
134 elif part.rootfs:
135 rootfs_dir = part.rootfs
136 else:
137 msg = "Couldn't find --rootfs-dir=%s connection"
138 msg += " or it is not a valid path, exiting"
139 msger.error(msg % part.rootfs)
140
141 real_rootfs_dir = cls._get_rootfs_dir(rootfs_dir)
142
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500143 part.rootfs_dir = real_rootfs_dir
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500144 part.prepare_rootfs(image_creator_workdir, oe_builddir, real_rootfs_dir, native_sysroot)
145
146 # install syslinux into rootfs partition
147 syslinux_cmd = "syslinux-nomtools -d /boot -i %s" % part.source_file
148 misc.exec_native_cmd(syslinux_cmd, native_sysroot)
149
150 @classmethod
151 def do_install_disk(cls, disk, disk_name, image_creator, workdir, oe_builddir,
152 bootimg_dir, kernel_dir, native_sysroot):
153 """
154 Assemble partitions to disk image
155
156 Called after all partitions have been prepared and assembled into a
157 disk image. In this case, we install the MBR.
158 """
159 mbrfile = os.path.join(native_sysroot, "usr/share/syslinux/")
160 if image_creator.ptable_format == 'msdos':
161 mbrfile += "mbr.bin"
162 elif image_creator.ptable_format == 'gpt':
163 mbrfile += "gptmbr.bin"
164 else:
165 msger.error("Unsupported partition table: %s" % \
166 image_creator.ptable_format)
167
168 if not os.path.exists(mbrfile):
169 msger.error("Couldn't find %s. Has syslinux-native been baked?" % mbrfile)
170
171 full_path = disk['disk'].device
172 msger.debug("Installing MBR on disk %s as %s with size %s bytes" \
173 % (disk_name, full_path, disk['min_size']))
174
175 ret_code = runner.show(['dd', 'if=%s' % mbrfile, 'of=%s' % full_path, 'conv=notrunc'])
176 if ret_code != 0:
177 raise ImageError("Unable to set MBR to %s" % full_path)