def do_install_disk(cls, disk, disk_name, image_creator, workdir, oe_builddir, bootimg_dir, kernel_dir, native_sysroot): """ Assemble partitions to disk image Called after all partitions have been prepared and assembled into a disk image. In this case, we install the MBR. """ mbrfile = os.path.join(native_sysroot, "usr/share/syslinux/") if image_creator.ptable_format == 'msdos': mbrfile += "mbr.bin" elif image_creator.ptable_format == 'gpt': mbrfile += "gptmbr.bin" else: msger.error("Unsupported partition table: %s" % \ image_creator.ptable_format) if not os.path.exists(mbrfile): msger.error("Couldn't find %s. Has syslinux-native been baked?" % mbrfile) full_path = disk['disk'].device msger.debug("Installing MBR on disk %s as %s with size %s bytes" \ % (disk_name, full_path, disk['min_size'])) ret_code = runner.show( ['dd', 'if=%s' % mbrfile, 'of=%s' % full_path, 'conv=notrunc']) if ret_code != 0: raise ImageError("Unable to set MBR to %s" % full_path)
def do_install_disk(cls, disk, disk_name, cr, workdir, oe_builddir, bootimg_dir, kernel_dir, native_sysroot): """ Called after all partitions have been prepared and assembled into a disk image. In this case, we install the MBR. """ mbrfile = "%s/syslinux/" % bootimg_dir if cr.ptable_format == 'msdos': mbrfile += "mbr.bin" elif cr.ptable_format == 'gpt': mbrfile += "gptmbr.bin" else: msger.error("Unsupported partition table: %s" % cr.ptable_format) if not os.path.exists(mbrfile): msger.error("Couldn't find %s. If using the -e option, do you " "have the right MACHINE set in local.conf? If not, " "is the bootimg_dir path correct?" % mbrfile) full_path = cr._full_path(workdir, disk_name, "direct") msger.debug("Installing MBR on disk %s as %s with size %s bytes" \ % (disk_name, full_path, disk['min_size'])) rc = runner.show( ['dd', 'if=%s' % mbrfile, 'of=%s' % full_path, 'conv=notrunc']) if rc != 0: raise ImageError("Unable to set MBR to %s" % full_path)
def do_configure_partition(self, part, source_params, cr, cr_workdir, oe_builddir, bootimg_dir, kernel_dir, native_sysroot): """ Called before do_prepare_partition(), creates syslinux config """ hdddir = "%s/hdd/boot" % cr_workdir rm_cmd = "rm -rf " + cr_workdir exec_cmd(rm_cmd) install_cmd = "install -d %s" % hdddir exec_cmd(install_cmd) splash = os.path.join(cr_workdir, "/hdd/boot/splash.jpg") if os.path.exists(splash): splashline = "menu background splash.jpg" else: splashline = "" (rootdev, root_part_uuid) = cr._get_boot_config() options = cr.ks.handler.bootloader.appendLine syslinux_conf = "" syslinux_conf += "PROMPT 0\n" timeout = kickstart.get_timeout(cr.ks) if not timeout: timeout = 0 syslinux_conf += "TIMEOUT " + str(timeout) + "\n" syslinux_conf += "\n" syslinux_conf += "ALLOWOPTIONS 1\n" syslinux_conf += "SERIAL 0 115200\n" syslinux_conf += "\n" if splashline: syslinux_conf += "%s\n" % splashline syslinux_conf += "DEFAULT boot\n" syslinux_conf += "LABEL boot\n" kernel = "/vmlinuz" syslinux_conf += "KERNEL " + kernel + "\n" if cr._ptable_format == 'msdos': rootstr = rootdev else: raise ImageError("Unsupported partition table format found") syslinux_conf += "APPEND label=boot root=%s %s\n" % (rootstr, options) msger.debug("Writing syslinux config %s/hdd/boot/syslinux.cfg" \ % cr_workdir) cfg = open("%s/hdd/boot/syslinux.cfg" % cr_workdir, "w") cfg.write(syslinux_conf) cfg.close()
def do_configure_gummiboot(self, hdddir, cr, cr_workdir): """ Create loader-specific (gummiboot) config """ install_cmd = "install -d %s/loader" % hdddir exec_cmd(install_cmd) install_cmd = "install -d %s/loader/entries" % hdddir exec_cmd(install_cmd) (rootdev, root_part_uuid) = cr._get_boot_config() options = cr.ks.handler.bootloader.appendLine timeout = kickstart.get_timeout(cr.ks) if not timeout: timeout = 0 loader_conf = "" loader_conf += "default boot\n" loader_conf += "timeout %d\n" % timeout msger.debug("Writing gummiboot config %s/hdd/boot/loader/loader.conf" \ % cr_workdir) cfg = open("%s/hdd/boot/loader/loader.conf" % cr_workdir, "w") cfg.write(loader_conf) cfg.close() kernel = "/bzImage" if cr._ptable_format == 'msdos': rootstr = rootdev else: raise ImageError("Unsupported partition table format found") boot_conf = "" boot_conf += "title boot\n" boot_conf += "linux %s\n" % kernel boot_conf += "options LABEL=Boot root=%s %s\n" \ % (rootstr, options) msger.debug("Writing gummiboot config %s/hdd/boot/loader/entries/boot.conf" \ % cr_workdir) cfg = open("%s/hdd/boot/loader/entries/boot.conf" % cr_workdir, "w") cfg.write(boot_conf) cfg.close()
def do_configure_partition(cls, part, source_params, image_creator, image_creator_workdir, oe_builddir, bootimg_dir, kernel_dir, native_sysroot): """ Creates syslinux config in rootfs directory Called before do_prepare_partition() """ rootdev = image_creator._get_boot_config()[0] options = image_creator.ks.handler.bootloader.appendLine syslinux_conf = "" syslinux_conf += "PROMPT 0\n" timeout = kickstart.get_timeout(image_creator.ks) if not timeout: timeout = 0 syslinux_conf += "TIMEOUT " + str(timeout) + "\n" syslinux_conf += "ALLOWOPTIONS 1\n" # Derive SERIAL... line from from kernel boot parameters syslinux_conf += syslinux.serial_console_form_kargs(options) + "\n" syslinux_conf += "DEFAULT linux\n" syslinux_conf += "LABEL linux\n" syslinux_conf += " KERNEL /boot/bzImage\n" if image_creator._ptable_format == 'msdos': rootstr = rootdev else: raise ImageError("Unsupported partition table format found") syslinux_conf += " APPEND label=boot root=%s %s\n" % (rootstr, options) syslinux_cfg = os.path.join(image_creator.rootfs_dir['ROOTFS_DIR'], "boot", "syslinux.cfg") msger.debug("Writing syslinux config %s" % syslinux_cfg) with open(syslinux_cfg, "w") as cfg: cfg.write(syslinux_conf)
def do_configure_grubefi(self, hdddir, cr, cr_workdir): """ Create loader-specific (grub-efi) config """ splash = os.path.join(cr_workdir, "/EFI/boot/splash.jpg") if os.path.exists(splash): splashline = "menu background splash.jpg" else: splashline = "" (rootdev, root_part_uuid) = cr._get_boot_config() options = cr.ks.handler.bootloader.appendLine grubefi_conf = "" grubefi_conf += "serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1\n" grubefi_conf += "default=boot\n" timeout = kickstart.get_timeout(cr.ks) if not timeout: timeout = 0 grubefi_conf += "timeout=%s\n" % timeout grubefi_conf += "menuentry 'boot'{\n" kernel = "/bzImage" if cr._ptable_format == 'msdos': rootstr = rootdev else: raise ImageError("Unsupported partition table format found") grubefi_conf += "linux %s root=%s rootwait %s\n" \ % (kernel, rootstr, options) grubefi_conf += "}\n" msger.debug("Writing grubefi config %s/hdd/boot/EFI/BOOT/grub.cfg" \ % cr_workdir) cfg = open("%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir, "w") cfg.write(grubefi_conf) cfg.close()
def layout_partitions(self, ptable_format="msdos"): """ Layout the partitions, meaning calculate the position of every partition on the disk. The 'ptable_format' parameter defines the partition table format and may be "msdos". """ msger.debug("Assigning %s partitions to disks" % ptable_format) if self._partitions_layed_out: return self._partitions_layed_out = True # Go through partitions in the order they are added in .ks file for num in range(len(self.partitions)): part = self.partitions[num] if part['disk_name'] not in self.disks: raise ImageError("No disk %s for partition %s" \ % (part['disk_name'], part['mountpoint'])) if ptable_format == 'msdos' and part['part_type']: # The --part-type can also be implemented for MBR partitions, # in which case it would map to the 1-byte "partition type" # filed at offset 3 of the partition entry. raise ImageError("setting custom partition type is not " \ "implemented for msdos partitions") # Get the disk where the partition is located disk = self.disks[part['disk_name']] disk['numpart'] += 1 if not part['no_table']: disk['realpart'] += 1 disk['ptable_format'] = ptable_format if disk['numpart'] == 1: if ptable_format == "msdos": overhead = MBR_OVERHEAD elif ptable_format == "gpt": overhead = GPT_OVERHEAD # Skip one sector required for the partitioning scheme overhead disk['offset'] += overhead if disk['realpart'] > 3: # Reserve a sector for EBR for every logical partition # before alignment is performed. if ptable_format == "msdos": disk['offset'] += 1 if part['align']: # If not first partition and we do have alignment set we need # to align the partition. # FIXME: This leaves a empty spaces to the disk. To fill the # gaps we could enlargea the previous partition? # Calc how much the alignment is off. align_sectors = disk['offset'] % (part['align'] * 1024 // self.sector_size) if align_sectors: # If partition is not aligned as required, we need # to move forward to the next alignment point align_sectors = (part['align'] * 1024 // self.sector_size) - align_sectors msger.debug( "Realignment for %s%s with %s sectors, original" " offset %s, target alignment is %sK." % (part['disk_name'], disk['numpart'], align_sectors, disk['offset'], part['align'])) # increase the offset so we actually start the partition on right alignment disk['offset'] += align_sectors part['start'] = disk['offset'] disk['offset'] += part['size'] part['type'] = 'primary' if not part['no_table']: part['num'] = disk['realpart'] else: part['num'] = 0 if disk['ptable_format'] == "msdos": # only count the partitions that are in partition table if len([p for p in self.partitions if not p['no_table']]) > 4: if disk['realpart'] > 3: part['type'] = 'logical' part['num'] = disk['realpart'] + 1 disk['partitions'].append(num) msger.debug("Assigned %s to %s%d, sectors range %d-%d size %d " "sectors (%d bytes)." \ % (part['mountpoint'], part['disk_name'], part['num'], part['start'], disk['offset'] - 1, part['size'], part['size'] * self.sector_size)) # Once all the partitions have been layed out, we can calculate the # minumim disk sizes. for disk in self.disks.values(): disk['min_size'] = disk['offset'] if disk['ptable_format'] == "gpt": disk['min_size'] += GPT_OVERHEAD disk['min_size'] *= self.sector_size
def layout_partitions(self, ptable_format="msdos"): """ Layout the partitions, meaning calculate the position of every partition on the disk. The 'ptable_format' parameter defines the partition table format and may be "msdos". """ msger.debug("Assigning %s partitions to disks" % ptable_format) if ptable_format not in ('msdos'): raise ImageError("Unknown partition table format '%s', supported " \ "formats are: 'msdos'" % ptable_format) if self._partitions_layed_out: return self._partitions_layed_out = True # Go through partitions in the order they are added in .ks file for n in range(len(self.partitions)): p = self.partitions[n] if not self.disks.has_key(p['disk_name']): raise ImageError("No disk %s for partition %s" \ % (p['disk_name'], p['mountpoint'])) if p['part_type']: # The --part-type can also be implemented for MBR partitions, # in which case it would map to the 1-byte "partition type" # filed at offset 3 of the partition entry. raise ImageError("setting custom partition type is not " \ "implemented for msdos partitions") # Get the disk where the partition is located d = self.disks[p['disk_name']] d['numpart'] += 1 d['ptable_format'] = ptable_format if d['numpart'] == 1: if ptable_format == "msdos": overhead = MBR_OVERHEAD # Skip one sector required for the partitioning scheme overhead d['offset'] += overhead if p['align']: # If not first partition and we do have alignment set we need # to align the partition. # FIXME: This leaves a empty spaces to the disk. To fill the # gaps we could enlargea the previous partition? # Calc how much the alignment is off. align_sectors = d['offset'] % (p['align'] * 1024 / self.sector_size) if align_sectors: # If partition is not aligned as required, we need # to move forward to the next alignment point align_sectors = (p['align'] * 1024 / self.sector_size) - align_sectors msger.debug( "Realignment for %s%s with %s sectors, original" " offset %s, target alignment is %sK." % (p['disk_name'], d['numpart'], align_sectors, d['offset'], p['align'])) # increase the offset so we actually start the partition on right alignment d['offset'] += align_sectors p['start'] = d['offset'] d['offset'] += p['size'] p['type'] = 'primary' p['num'] = d['numpart'] if d['ptable_format'] == "msdos": if d['numpart'] > 2: # Every logical partition requires an additional sector for # the EBR, so steal the last sector from the end of each # partition starting from the 3rd one for the EBR. This # will make sure the logical partitions are aligned # correctly. p['size'] -= 1 if d['numpart'] > 3: p['type'] = 'logical' p['num'] = d['numpart'] + 1 d['partitions'].append(n) msger.debug("Assigned %s to %s%d, sectors range %d-%d size %d " "sectors (%d bytes)." \ % (p['mountpoint'], p['disk_name'], p['num'], p['start'], p['start'] + p['size'] - 1, p['size'], p['size'] * self.sector_size)) # Once all the partitions have been layed out, we can calculate the # minumim disk sizes. for disk_name, d in self.disks.items(): d['min_size'] = d['offset'] d['min_size'] *= self.sector_size
def layout_partitions(self): """ Layout the partitions, meaning calculate the position of every partition on the disk. The 'ptable_format' parameter defines the partition table format and may be "msdos". """ msger.debug("Assigning %s partitions to disks" % self.ptable_format) # Go through partitions in the order they are added in .ks file for num in range(len(self.partitions)): part = self.partitions[num] if self.ptable_format == 'msdos' and part.part_type: # The --part-type can also be implemented for MBR partitions, # in which case it would map to the 1-byte "partition type" # filed at offset 3 of the partition entry. raise ImageError("setting custom partition type is not " \ "implemented for msdos partitions") # Get the disk where the partition is located self.numpart += 1 if not part.no_table: self.realpart += 1 if self.numpart == 1: if self.ptable_format == "msdos": overhead = MBR_OVERHEAD elif self.ptable_format == "gpt": overhead = GPT_OVERHEAD # Skip one sector required for the partitioning scheme overhead self.offset += overhead if self.realpart > 3: # Reserve a sector for EBR for every logical partition # before alignment is performed. if self.ptable_format == "msdos": self.offset += 1 if part.align: # If not first partition and we do have alignment set we need # to align the partition. # FIXME: This leaves a empty spaces to the disk. To fill the # gaps we could enlargea the previous partition? # Calc how much the alignment is off. align_sectors = self.offset % (part.align * 1024 // self.sector_size) if align_sectors: # If partition is not aligned as required, we need # to move forward to the next alignment point align_sectors = (part.align * 1024 // self.sector_size) - align_sectors msger.debug( "Realignment for %s%s with %s sectors, original" " offset %s, target alignment is %sK." % (part.disk, self.numpart, align_sectors, self.offset, part.align)) # increase the offset so we actually start the partition on right alignment self.offset += align_sectors part.start = self.offset self.offset += part.size_sec part.type = 'primary' if not part.no_table: part.num = self.realpart else: part.num = 0 if self.ptable_format == "msdos": # only count the partitions that are in partition table if len([p for p in self.partitions if not p.no_table]) > 4: if self.realpart > 3: part.type = 'logical' part.num = self.realpart + 1 msger.debug("Assigned %s to %s%d, sectors range %d-%d size %d " "sectors (%d bytes)." \ % (part.mountpoint, part.disk, part.num, part.start, self.offset - 1, part.size_sec, part.size_sec * self.sector_size)) # Once all the partitions have been layed out, we can calculate the # minumim disk size self.min_size = self.offset if self.ptable_format == "gpt": self.min_size += GPT_OVERHEAD self.min_size *= self.sector_size