summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2019-05-31 17:09:54 +1000
committerChris Johns <chrisj@rtems.org>2019-05-31 17:09:54 +1000
commit1b46f4625ff188f910100a6ba663ca8ed46721fb (patch)
tree2cf96bde3f4338f0c1710b3926809cd575d8ae00
parentac0f986efb78075c314fffd0f6d062ebd1061dd8 (diff)
misc/boot-image: Add Linux support.
-rw-r--r--misc/tools/boot.py121
1 files changed, 99 insertions, 22 deletions
diff --git a/misc/tools/boot.py b/misc/tools/boot.py
index 876113c..206dc8d 100644
--- a/misc/tools/boot.py
+++ b/misc/tools/boot.py
@@ -197,15 +197,16 @@ class image(object):
device = self.image_attach(output)
#
- # Partition the image.
+ # Partition the image. The device may change.
#
log.notice('Partition device: %s as %s' % (device,
self.settings.part_type))
- self.partition(device,
- self.settings.part_type,
- self.settings.fs_format,
- self.settings.fs_size,
- self.settings.fs_alignment)
+ device = self.partition(output,
+ device,
+ self.settings.part_type,
+ self.settings.fs_format,
+ self.settings.fs_size,
+ self.settings.fs_alignment)
part = self.device_partition(device, 1)
@@ -271,8 +272,8 @@ class image(object):
self.detach_images.remove(device)
self.host_image_detach(device)
- def partition(self, device, ptype, pformat, psize, palign):
- self.host_partition(device, ptype, pformat, psize, palign)
+ def partition(self, image_, device, ptype, pformat, psize, palign):
+ return self.host_partition(image_, device, ptype, pformat, psize, palign)
def format_partition(self, device, pformat):
self.host_format_partition(device, pformat)
@@ -313,7 +314,15 @@ class image(object):
log.notice('host executable not found: %s' % (exe))
ok = False
if not ok:
- raise error.general('missing commands; please fix.')
+ raise error.general('command(s) not found; please fix.')
+
+ def si_units(self, units):
+ siunits = {'k': 1024,
+ 'm': 1024 * 1024,
+ 'g': 1024 * 1024 * 1024 }
+ if units not in siunits:
+ raise error.general('invalid SI unit: %s' % (units))
+ return siunits[units]
def si_parse_size(self, size):
orig = size
@@ -382,7 +391,7 @@ class image(object):
def host_image_detach(self, device):
raise error.general('no platform support: host_image_detach')
- def host_partition(self, device, ptype, pformat, psize, palign):
+ def host_partition(self, image_, device, ptype, pformat, psize, palign):
raise error.general('no platform support: host_partition')
def host_format_partition(self, device, pformat):
@@ -415,7 +424,7 @@ class freebsd_image(image):
def host_image_detach(self, device):
self.command('sudo mdconfig -d -u %s' % (device))
- def host_partition(self, device, ptype, pformat, psize, palign):
+ def host_partition(self, image_, device, ptype, pformat, psize, palign):
types = { 'MBR': 'MBR' }
formats = { 'fat16': 'fat16',
'fat32': 'fat32' }
@@ -430,6 +439,7 @@ class freebsd_image(image):
palign,
device))
self.command('sudo gpart set -a active -i 1 %s' % (device))
+ return device
def host_format_partition(self, device, pformat):
formats = { 'fat16': ('newfs_msdos', '16'),
@@ -459,26 +469,87 @@ class linux_image(image):
def __init__(self, settings):
super(linux_image, self).__init__(settings)
+ def get_exes(self):
+ exes = super(linux_image, self).get_exes()
+ return exes + ['losetup',
+ 'fdisk',
+ 'mkfs.fat',
+ 'mount',
+ 'umount']
+
+ def host_image_create(self, path_, size, exists):
+ img_size, img_units = self.si_size_units(size)
+ self.command('dd if=/dev/zero of=%s bs=%s count=%d' % (path_,
+ self.si_units(img_units),
+ img_size))
def host_image_attach(self, path_):
- pass
+ return self.command('sudo losetup --partscan --find --show %s' % (path_))
def host_image_detach(self, device):
- pass
+ self.command('sudo losetup --detach %s' % (device))
- def host_partition(self, device, ptype, pformat, psize, palign):
- pass
+ def host_partition(self, image_, device, ptype, pformat, psize, palign):
+ types = { 'MBR': 'MBR' }
+ formats = { 'fat16': '6',
+ 'fat32': 'b' }
+ if ptype not in types:
+ err = 'unknown type of partitioning: %s' % (ptype)
+ raise error.general(err)
+ if pformat not in formats:
+ raise error.general('unknown format: %s' % (pformat))
+ #
+ # Datch the loop back device, we use fdisk on the image to avoid any
+ # kernel errors related to re-reading the updated partition data.
+ #
+ self.host_image_detach(device)
+ #
+ # This awkward exchange is needed to script fdisk, hmmm.
+ #
+ with tempfile.NamedTemporaryFile() as tmp:
+ s = os.linesep.join(['o', # create a new empty part table
+ 'n', # add a new partition
+ 'p', # primary
+ '1', # partition 1
+ '%d' % (self.si_size(palign) / 512),
+ '%d' % (self.si_size(psize) / 512),
+ 't', # change a partition type
+ '%s' % (formats[pformat]), # hex code
+ 'a', # toggle a bootable flag
+ 'p', # print
+ 'w', # write table to disk and exit
+ ''])
+ log.output('fdisk script:')
+ log.output(s)
+ tmp.write(s.encode())
+ tmp.seek(0)
+ self.command('cat %s | fdisk -t %s %s' % (tmp.name,
+ types[ptype],
+ image_))
+ return self.host_image_attach(image_)
def host_format_partition(self, device, pformat):
- pass
+ formats = { 'fat16': ('mkfs.fat', '16'),
+ 'fat32': ('mkfs.fat', '32') }
+ if pformat not in formats:
+ raise error.general('unknown format: %s' % (pformat))
+ self.command('sudo %s -F %s %s' % (formats[pformat][0],
+ formats[pformat][1],
+ device))
def host_device_partition(self, device, pindex):
- pass
+ return '%sp%d' % (device, pindex)
def host_mount(self, pformat, device, path_):
- pass
+ options = { 'fat16': '-o uid=%d' % (os.getuid()),
+ 'fat32': '-o uid=%d' % (os.getuid()) }
+ if pformat in options:
+ opts = options[pformat]
+ else:
+ opts = ''
+ self.command('sudo mount %s %s %s' % (opts, device, path_))
def host_unmount(self, path_):
- pass
+ self.command('sudo umount %s' % (path_))
class darwin_image(image):
def __init__(self, settings):
@@ -503,7 +574,7 @@ class darwin_image(image):
def host_image_detach(self, device):
self.command('sudo hdiutil detach %s' % (device))
- def host_partition(self, device, ptype, pformat, psize, palign):
+ def host_partition(self, image_, device, ptype, pformat, psize, palign):
types = { 'MBR': 'MBR' }
formats = { 'fat16': 'MS-DOS FAT16',
'fat32': 'MS-DOS FAT32' }
@@ -528,9 +599,15 @@ class darwin_image(image):
# This awkward exchange is needed to set the active bit.
#
with tempfile.NamedTemporaryFile() as tmp:
- tmp.write(os.linesep.join(['f 1', 'w', 'p', 'q', '']))
+ s = os.linesep.join(['f 1', # flag toggle on partition 1
+ 'w', # write
+ 'p', # print
+ 'q', # quit
+ ''])
+ tmp.write(s.encode())
tmp.seek(0)
self.command('cat %s | sudo fdisk -y -e %s' % (tmp.name, device))
+ return device
def host_format_partition(self, device, pformat):
log.output(' * No format stage; done when partitioning')
@@ -546,7 +623,7 @@ class darwin_image(image):
builders = {
'freebsd': freebsd_image,
- 'linux ' : linux_image,
+ 'linux' : linux_image,
'darwin' : darwin_image
}