~salgado/linaro-image-tools/bug-702645

« back to all changes in this revision

Viewing changes to linaro_media_create/boards.py

Move remaining board-specific code from populate_boot.py to boards.py

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
"""Configuration for boards supported by linaro-media-create.
2
2
 
3
 
To add support for a new board, you just need to create a subclass of
4
 
BoardConfig and set appropriate values for its variables.
 
3
To add support for a new board, you need to create a subclass of
 
4
BoardConfig, set appropriate values for its variables and add it to
 
5
board_configs at the bottom of this file.
5
6
"""
6
7
 
 
8
import atexit
 
9
import glob
 
10
import os
 
11
import tempfile
7
12
import uuid
8
13
 
 
14
from linaro_media_create import cmd_runner
 
15
 
9
16
ROOTFS_UUID = str(uuid.uuid4())
10
17
 
11
18
 
12
19
class BoardConfig(object):
13
20
    """The configuration used when building an image for a board."""
 
21
    # These attributes may not need to be redefined on some subclasses.
14
22
    uboot_flavor = None
15
23
    mmc_option = '0:1'
16
24
    mmc_part_offset = 0
17
 
    extra_serial_opts = None
18
 
    live_serial_opts = None
 
25
    fat_size = 32
 
26
    extra_serial_opts = ''
 
27
    live_serial_opts = ''
 
28
    extra_boot_args_options = None
 
29
 
 
30
    # These attributes must be defined on all subclasses.
19
31
    kernel_addr = None
20
32
    initrd_addr = None
21
33
    load_addr = None
22
34
    sub_arch = None
23
35
    boot_script = None
24
 
    extra_boot_args_options = None
25
 
    fat_size = 32
26
36
 
27
37
    @classmethod
28
 
    def get_boot_cmd(cls, is_live, is_lowmem, consoles):
29
 
        """Get the boot command for this board."""
 
38
    def _get_boot_cmd(cls, is_live, is_lowmem, consoles):
 
39
        """Get the boot command for this board.
 
40
 
 
41
        In general subclasses should not have to override this.
 
42
        """
30
43
        boot_args_options = 'rootwait ro'
31
 
        if cls.extra_boot_args_options:
32
 
            boot_args_options += " %s" % cls.extra_boot_args_options
 
44
        if cls.extra_boot_args_options is not None:
 
45
            boot_args_options += ' %s' % cls.extra_boot_args_options
33
46
        serial_opts = ''
34
47
        if consoles is not None:
35
48
            for console in consoles:
63
76
                "%(boot_snippet)s %(boot_args_options)s'\n"
64
77
            "boot" % replacements)
65
78
 
 
79
    @classmethod
 
80
    def make_boot_files(cls, uboot_parts_dir, is_live, is_lowmem, consoles,
 
81
                        root_dir, boot_dir, boot_script, boot_device_or_file):
 
82
        boot_cmd = cls._get_boot_cmd(is_live, is_lowmem, consoles)
 
83
        cls._make_boot_files(
 
84
            uboot_parts_dir, boot_cmd, root_dir, boot_dir, boot_script,
 
85
            boot_device_or_file)
 
86
 
 
87
    @classmethod
 
88
    def _make_boot_files(cls, uboot_parts_dir, boot_cmd, root_dir, boot_dir,
 
89
                         boot_script, boot_device_or_file):
 
90
        """Make the necessary boot files for this board.
 
91
 
 
92
        This is usually board-specific so ought to be defined in every
 
93
        subclass.
 
94
        """
 
95
        raise NotImplementedError()
 
96
 
66
97
 
67
98
class BeagleConfig(BoardConfig):
68
99
    uboot_flavor = 'omap3_beagle'
77
108
        'earlyprintk fixrtc nocompcache vram=12M omapfb.debug=y '
78
109
        'omapfb.mode=dvi:1280x720MR-16@60')
79
110
 
 
111
    @classmethod
 
112
    def _make_boot_files(cls, uboot_parts_dir, boot_cmd, chroot_dir,
 
113
                         boot_dir, boot_script, boot_device_or_file):
 
114
        mlo_file = os.path.join(
 
115
            chroot_dir, 'usr', 'lib', 'x-loader-omap', 'MLO')
 
116
        install_omap_boot_loader(mlo_file, boot_dir)
 
117
        make_uImage(cls.load_addr, uboot_parts_dir, cls.sub_arch, boot_dir)
 
118
        make_uInitrd(uboot_parts_dir, cls.sub_arch, boot_dir)
 
119
        make_boot_script(boot_cmd, boot_script)
 
120
        make_boot_ini(boot_script, boot_dir)
 
121
 
80
122
 
81
123
class PandaConfig(BoardConfig):
82
124
    uboot_flavor = 'omap4_panda'
91
133
        'earlyprintk fixrtc nocompcache vram = 32M omapfb.debug = y '
92
134
        'omapfb.vram = 0:8M mem = 463M ip = none')
93
135
 
 
136
    @classmethod
 
137
    def _make_boot_files(cls, uboot_parts_dir, boot_cmd, chroot_dir,
 
138
                         boot_dir, boot_script, boot_device_or_file):
 
139
        mlo_file = os.path.join(
 
140
            chroot_dir, 'usr', 'lib', 'x-loader-omap4', 'MLO')
 
141
        install_omap_boot_loader(mlo_file, boot_dir)
 
142
        make_uImage(cls.load_addr, uboot_parts_dir, cls.sub_arch, boot_dir)
 
143
        make_uInitrd(uboot_parts_dir, cls.sub_arch, boot_dir)
 
144
        make_boot_script(boot_cmd, boot_script)
 
145
        make_boot_ini(boot_script, boot_dir)
 
146
 
94
147
 
95
148
class IgepConfig(BeagleConfig):
96
149
    uboot_flavor = None
97
150
 
 
151
    @classmethod
 
152
    def _make_boot_files(cls, uboot_parts_dir, boot_cmd, chroot_dir,
 
153
                         boot_dir, boot_script, boot_device_or_file):
 
154
        make_uImage(cls.load_addr, uboot_parts_dir, cls.sub_arch, boot_dir)
 
155
        make_uInitrd(uboot_parts_dir, cls.sub_arch, boot_dir)
 
156
        make_boot_script(boot_cmd, boot_script)
 
157
        make_boot_ini(boot_script, boot_dir)
 
158
 
98
159
 
99
160
class Ux500Config(BoardConfig):
100
161
    extra_serial_opts = 'console = tty0 console = ttyAMA2,115200n8'
111
172
        'hwmem = 48M@302M mem = 152M@360M')
112
173
    mmc_option = '1:1'
113
174
 
 
175
    @classmethod
 
176
    def _make_boot_files(cls, uboot_parts_dir, boot_cmd, chroot_dir,
 
177
                         boot_dir, boot_script, boot_device_or_file):
 
178
        make_uImage(cls.load_addr, uboot_parts_dir, cls.sub_arch, boot_dir)
 
179
        make_uInitrd(uboot_parts_dir, cls.sub_arch, boot_dir)
 
180
        make_boot_script(boot_cmd, boot_script)
 
181
 
114
182
 
115
183
class Mx51evkConfig(BoardConfig):
116
184
    extra_serial_opts = 'console = tty0 console = ttymxc0,115200n8'
123
191
    mmc_part_offset = 1
124
192
    mmc_option = '0:2'
125
193
 
 
194
    @classmethod
 
195
    def _make_boot_files(cls, uboot_parts_dir, boot_cmd, chroot_dir,
 
196
                         boot_dir, boot_script, boot_device_or_file):
 
197
        uboot_file = os.path.join(
 
198
            chroot_dir, 'usr', 'lib', 'u-boot', 'mx51evk', 'u-boot.imx')
 
199
        install_mx51evk_boot_loader(uboot_file, boot_device_or_file)
 
200
        make_uImage(cls.load_addr, uboot_parts_dir, cls.sub_arch, boot_dir)
 
201
        make_uInitrd(uboot_parts_dir, cls.sub_arch, boot_dir)
 
202
        make_boot_script(boot_cmd, boot_script)
 
203
 
126
204
 
127
205
class VexpressConfig(BoardConfig):
128
206
    uboot_flavor = 'ca9x4_ct_vxp'
137
215
    # only allows for FAT16
138
216
    fat_size = 16
139
217
 
 
218
    @classmethod
 
219
    def _make_boot_files(cls, uboot_parts_dir, boot_cmd, chroot_dir,
 
220
                         boot_dir, boot_script):
 
221
        make_uImage(cls.load_addr, uboot_parts_dir, cls.sub_arch, boot_dir)
 
222
        make_uInitrd(uboot_parts_dir, cls.sub_arch, boot_dir)
 
223
 
140
224
 
141
225
board_configs = {
142
226
    'beagle': BeagleConfig,
146
230
    'ux500': Ux500Config,
147
231
    'mx51evk': Mx51evkConfig,
148
232
    }
 
233
 
 
234
 
 
235
def _run_mkimage(img_type, load_addr, entry_point, name, img_data, img,
 
236
                 stdout=None, as_root=True):
 
237
    cmd = ['mkimage',
 
238
           '-A', 'arm',
 
239
           '-O', 'linux',
 
240
           '-T', img_type,
 
241
           '-C', 'none',
 
242
           '-a', load_addr,
 
243
           '-e', load_addr,
 
244
           '-n', name,
 
245
           '-d', img_data,
 
246
           img]
 
247
    proc = cmd_runner.run(cmd, as_root=as_root, stdout=stdout)
 
248
    proc.wait()
 
249
    return proc.returncode
 
250
 
 
251
 
 
252
def _get_file_matching(regex):
 
253
    """Return a file whose path matches the given regex.
 
254
 
 
255
    If zero or more than one files match, raise a ValueError.
 
256
    """
 
257
    files = glob.glob(regex)
 
258
    if len(files) == 1:
 
259
        return files[0]
 
260
    elif len(files) == 0:
 
261
        raise ValueError(
 
262
            "No files found matching '%s'; can't continue" % regex)
 
263
    else:
 
264
        # TODO: Could ask the user to chosse which file to use instead of
 
265
        # raising an exception.
 
266
        raise ValueError("Too many files matching '%s' found." % regex)
 
267
 
 
268
 
 
269
def make_uImage(load_addr, uboot_parts_dir, sub_arch, boot_disk):
 
270
    img_data = _get_file_matching(
 
271
        '%s/vmlinuz-*-%s' % (uboot_parts_dir, sub_arch))
 
272
    img = '%s/uImage' % boot_disk
 
273
    return _run_mkimage(
 
274
        'kernel', load_addr, load_addr, 'Linux', img_data, img)
 
275
 
 
276
 
 
277
def make_uInitrd(uboot_parts_dir, sub_arch, boot_disk):
 
278
    img_data = _get_file_matching(
 
279
        '%s/initrd.img-*-%s' % (uboot_parts_dir, sub_arch))
 
280
    img = '%s/uInitrd' % boot_disk
 
281
    return _run_mkimage('ramdisk', '0', '0', 'initramfs', img_data, img)
 
282
 
 
283
 
 
284
def make_boot_script(boot_script_data, boot_script):
 
285
    # Need to save the boot script data into a file that will be passed to
 
286
    # mkimage.
 
287
    _, tmpfile = tempfile.mkstemp()
 
288
    atexit.register(os.unlink, tmpfile)
 
289
    with open(tmpfile, 'w') as fd:
 
290
        fd.write(boot_script_data)
 
291
    return _run_mkimage(
 
292
        'script', '0', '0', 'boot script', tmpfile, boot_script)
 
293
 
 
294
 
 
295
def install_mx51evk_boot_loader(imx_file, boot_device_or_file):
 
296
    proc = cmd_runner.run([
 
297
        "dd",
 
298
        "if=%s" % imx_file,
 
299
        "of=%s" % boot_device_or_file,
 
300
        "bs=1024",
 
301
        "seek=1",
 
302
        "conv=notrunc"], as_root=True)
 
303
    proc.wait()
 
304
 
 
305
 
 
306
def install_omap_boot_loader(mlo_file, boot_disk):
 
307
    cmd_runner.run(["cp", "-v", mlo_file, boot_disk], as_root=True).wait()
 
308
    # XXX: Is this really needed?
 
309
    cmd_runner.run(["sync"]).wait()
 
310
 
 
311
 
 
312
def make_boot_ini(boot_script, boot_disk):
 
313
    proc = cmd_runner.run(
 
314
        ["cp", "-v", boot_script, "%s/boot.ini" % boot_disk], as_root=True)
 
315
    proc.wait()