diff options
author | Chris Johns <chrisj@rtems.org> | 2019-05-31 17:09:54 +1000 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2019-05-31 17:09:54 +1000 |
commit | 1b46f4625ff188f910100a6ba663ca8ed46721fb (patch) | |
tree | 2cf96bde3f4338f0c1710b3926809cd575d8ae00 | |
parent | ac0f986efb78075c314fffd0f6d062ebd1061dd8 (diff) |
misc/boot-image: Add Linux support.
-rw-r--r-- | misc/tools/boot.py | 121 |
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 } |