33
33
from linaro_media_create import cmd_runner
34
from linaro_media_create.partitions import SECTOR_SIZE
37
# * geometry is currently always 255 heads and 63 sectors due to limitations of
38
# older OMAP3 boot ROMs
39
# * apparently some OMAP3 ROMs don't tolerate vfat length of an odd number of
40
# sectors (only sizes rounded to 1 KiB seem to boot)
41
# * we want partitions aligned on 4 MiB as to get the best performance and
43
# * image_size is passed on the command-line and should preferably be a power
44
# of 2; it should be used as a "don't go over this size" information for a
45
# real device, and a "give me a file exactly this big" requirement for an
46
# image file. Having exactly a power of 2 helps with QEMU; there seem to be
47
# some truncating issues otherwise. XXX to be researched
50
PART_ALIGN_S = 4 * 1024 * 1024 / SECTOR_SIZE
52
def align_up(value, align):
53
"""Round value to the next multiple of align."""
54
return (value + align - 1) / align * align
56
# optional bootloader partition; at least 1 MiB; in theory, an i.MX5 bootloader
57
# partition could hold RedBoot, FIS table, RedBoot config, kernel, and initrd,
58
# but we typically use U-Boot which is about 167 KiB as of 2011/02/11 and
59
# currently doesn't even store its environment there, so this should be enough
60
LOADER_MIN_SIZE_S = align_up(1 * 1024 * 1024, SECTOR_SIZE) / SECTOR_SIZE
61
# boot partition; at least 50 MiB; XXX this shouldn't be hardcoded
62
BOOT_MIN_SIZE_S = align_up(50 * 1024 * 1024, SECTOR_SIZE) / SECTOR_SIZE
63
# root partition; at least 50 MiB; XXX this shouldn't be hardcoded
64
ROOT_MIN_SIZE_S = align_up(50 * 1024 * 1024, SECTOR_SIZE) / SECTOR_SIZE
67
def align_partition(min_start, min_length, start_alignment, end_alignment):
68
"""Compute partition start and end offsets based on specified constraints.
70
:param min_start: Minimal start offset of partition
71
:param min_lengh: Minimal length of partition
72
:param start_alignment: Alignment of this partition
73
:param end_alignment: Alignment of the data following this partition
74
:return: start offset, end offset (inclusive), length
76
start = align_up(min_start, start_alignment)
77
# end offset is inclusive, so substact one
78
end = align_up(start + min_length, end_alignment) - 1
79
# and add one to length
80
length = end - start + 1
81
return start, end, length
36
84
class BoardConfig(object):
37
85
"""The configuration used when building an image for a board."""
38
86
# These attributes may not need to be redefined on some subclasses.
39
87
uboot_flavor = None
88
# whether to copy u-boot to the boot partition
89
uboot_in_boot_part = False
41
91
mmc_part_offset = 0
56
def get_sfdisk_cmd(cls):
57
"""Return the sfdisk command to partition the media."""
106
def get_sfdisk_cmd(cls, should_align_boot_part=False):
107
"""Return the sfdisk command to partition the media.
109
:param should_align_boot_part: Whether to align the boot partition too.
111
This default implementation returns a boot vfat partition of type FAT16
112
or FAT32, followed by a root partition.
58
114
if cls.fat_size == 32:
59
115
partition_type = '0x0C'
61
117
partition_type = '0x0E'
63
# This will create a partition of the given type, containing 9
64
# cylinders (74027520 bytes, ~70 MiB), followed by a Linux-type
65
# partition containing the rest of the free space.
66
return ',9,%s,*\n,,,-' % partition_type
119
# align on sector 63 for compatibility with broken versions of x-loader
120
# unless align_boot_part is set
122
if should_align_boot_part:
123
boot_align = PART_ALIGN_S
125
# can only start on sector 1 (sector 0 is MBR / partition table)
126
boot_start, boot_end, boot_len = align_partition(
127
1, BOOT_MIN_SIZE_S, boot_align, PART_ALIGN_S)
128
# apparently OMAP3 ROMs require the vfat length to be an even number
129
# of sectors (multiple of 1 KiB); decrease the length if it's odd,
130
# there should still be enough room
131
boot_len = boot_len - boot_len % 2
132
boot_end = boot_start + boot_len - 1
133
# we ignore _root_end / _root_len and return a sfdisk command to
134
# instruct the use of all remaining space; XXX if we had some root size
135
# config, we could do something more sensible
136
root_start, _root_end, _root_len = align_partition(
137
boot_end + 1, ROOT_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S)
139
return '%s,%s,%s,*\n%s,,,-' % (
140
boot_start, boot_len, partition_type, root_start)
69
143
def _get_boot_cmd(cls, is_live, is_lowmem, consoles, rootfs_uuid):
287
364
mmc_option = '0:2'
290
def get_sfdisk_cmd(cls):
291
# Create a one cylinder partition for fixed-offset bootloader data at
292
# the beginning of the image (size is one cylinder, so 8224768 bytes
293
# with the first sector for MBR).
294
sfdisk_cmd = super(Mx51evkConfig, cls).get_sfdisk_cmd()
295
return ',1,0xDA\n%s' % sfdisk_cmd
367
def get_sfdisk_cmd(cls, should_align_boot_part=None):
368
"""Return the sfdisk command to partition the media.
370
:param should_align_boot_part: Ignored.
372
This i.MX5 implementation returns a non-FS data bootloader partition,
373
followed by a FAT32 boot partition, followed by a root partition.
375
# boot ROM expects bootloader at 0x400 which is sector 2 with the usual
376
# SECTOR_SIZE of 512; we could theoretically leave sector 1 unused, but
377
# older bootloaders like RedBoot might store the environment from 0x0
378
# onwards, so it's safer to just start at the first sector, sector 1
379
# (sector 0 is MBR / partition table)
380
loader_start, loader_end, loader_len = align_partition(
381
1, LOADER_MIN_SIZE_S, 1, PART_ALIGN_S)
383
boot_start, boot_end, boot_len = align_partition(
384
loader_end + 1, BOOT_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S)
385
# we ignore _root_end / _root_len and return a sfdisk command to
386
# instruct the use of all remaining space; XXX if we had some root size
387
# config, we could do something more sensible
388
root_start, _root_end, _root_len = align_partition(
389
boot_end + 1, ROOT_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S)
391
return '%s,%s,0xDA\n%s,%s,0x0C,*\n%s,,,-' % (
392
loader_start, loader_len, boot_start, boot_len, root_start)
298
395
def _make_boot_files(cls, uboot_parts_dir, boot_cmd, chroot_dir,
299
396
boot_dir, boot_script, boot_device_or_file):
300
397
uboot_file = os.path.join(
301
chroot_dir, 'usr', 'lib', 'u-boot', 'mx51evk', 'u-boot.imx')
302
install_mx51evk_boot_loader(uboot_file, boot_device_or_file)
398
chroot_dir, 'usr', 'lib', 'u-boot', cls.uboot_flavor, 'u-boot.imx')
399
install_mx5_boot_loader(uboot_file, boot_device_or_file)
304
401
cls.load_addr, uboot_parts_dir, cls.kernel_suffix, boot_dir)
305
402
make_uInitrd(uboot_parts_dir, cls.kernel_suffix, boot_dir)
306
403
make_boot_script(boot_cmd, boot_script)
406
class EfikamxConfig(Mx5Config):
407
uboot_flavor = 'efikamx'
410
class Mx51evkConfig(Mx5Config):
411
uboot_flavor = 'mx51evk'
309
414
class Mx53LoCoConfig(BoardConfig):
310
415
uboot_flavor = 'mx53_loco'
311
416
serial_tty = 'ttymxc0'