def install_bootloader(self): """ Installs the uboot image to NAND. :exception RamLoaderException: On failure when loading to RAM. :exception NandInstallerError: On failure communicating with the uboot in NAND. """ comp = 'bootloader' comp_name = self._board.comp_name(comp) for part in self._partitions: if part.name == comp_name: self._l.info('Installing bootloader') self._l.debug("Loading uboot image to RAM") self._u.set_env('autostart', 'no') self._u.save_env() self._load_file_to_ram(part.image, self._ram_load_addr) offset = part.start_blk * self.nand_block_size img_size_blk = self._bytes_to_blks(os.path.getsize(part.image)) img_size_aligned = img_size_blk * self.nand_block_size self._l.debug("Erasing uboot NAND space") cmd = "%s %s %s" % (self._board.erase_cmd(comp), to_hex(offset), to_hex(img_size_aligned)) self._u.cmd(cmd, prompt_timeout=DEFAULT_NAND_TIMEOUT) self._l.debug("Writing uboot image from RAM to NAND") cmd = self._board.pre_write_cmd('bootloader') if cmd: self._u.cmd(cmd, prompt_timeout=DEFAULT_NAND_TIMEOUT) cmd = "%s %s %s %s" % (self._board.write_cmd(comp), to_hex(self._ram_load_addr), to_hex(offset), to_hex(img_size_aligned)) self._u.cmd(cmd, prompt_timeout=DEFAULT_NAND_TIMEOUT) cmd = self._board.post_write_cmd(comp) if cmd: self._u.cmd(cmd, prompt_timeout=DEFAULT_NAND_TIMEOUT) self._l.debug("Restarting to use the uboot in NAND") self._u.cmd('reset', prompt_timeout=None) found_reset_str = self._u.expect('U-Boot', timeout=10)[0] if not found_reset_str: raise NandInstallerError("Failed to detect the uboot in " "NAND restarting") time.sleep(2) # Give uboot time to initialize self._u.cmd('') # Emtpy command to stop autoboot ret = self._u.sync() if ret is False: raise NandInstallerError("Failed synchronizing with the " "uboot in NAND") self._u.set_env('autostart', 'yes') self._u.save_env() self._l.info('Bootloader installation complete')
def install_bootloader(self): """ Installs the uboot image to NAND. :exception RamLoaderException: On failure when loading to RAM. :exception NandInstallerError: On failure communicating with the uboot in NAND. """ comp = 'bootloader' comp_name = self._board.comp_name(comp) for part in self._partitions: if part.name == comp_name: self._l.info('Installing bootloader') self._l.debug("Loading uboot image to RAM") self._u.set_env('autostart', 'no') self._u.save_env() self._load_file_to_ram(part.image, self._ram_load_addr) offset = part.start_blk * self.nand_block_size img_size_blk = self._bytes_to_blks(os.path.getsize(part.image)) img_size_aligned = img_size_blk * self.nand_block_size self._l.debug("Erasing uboot NAND space") cmd = "%s %s %s" % (self._board.erase_cmd(comp), to_hex(offset), to_hex(img_size_aligned)) self._u.cmd(cmd, prompt_timeout=DEFAULT_NAND_TIMEOUT) self._l.debug("Writing uboot image from RAM to NAND") cmd = self._board.pre_write_cmd('bootloader') if cmd: self._u.cmd(cmd, prompt_timeout=DEFAULT_NAND_TIMEOUT) cmd = "%s %s %s %s" % ( self._board.write_cmd(comp), to_hex(self._ram_load_addr), to_hex(offset), to_hex(img_size_aligned)) self._u.cmd(cmd, prompt_timeout=DEFAULT_NAND_TIMEOUT) cmd = self._board.post_write_cmd(comp) if cmd: self._u.cmd(cmd, prompt_timeout=DEFAULT_NAND_TIMEOUT) self._l.debug("Restarting to use the uboot in NAND") self._u.cmd('reset', prompt_timeout=None) found_reset_str = self._u.expect('U-Boot', timeout=10)[0] if not found_reset_str: raise NandInstallerError("Failed to detect the uboot in " "NAND restarting") time.sleep(2) # Give uboot time to initialize self._u.cmd('') # Emtpy command to stop autoboot ret = self._u.sync() if ret is False: raise NandInstallerError("Failed synchronizing with the " "uboot in NAND") self._u.set_env('autostart', 'yes') self._u.save_env() self._l.info('Bootloader installation complete')
def load_uboot_to_ram(self, img_filename, load_addr): """ Loads an uboot image to RAM and executes it. This uboot will drive the installation. :param img_filename: Path to the uboot image file. :param load_addr: Load address in RAM where to load the uboot image. :exception RamLoaderException: On failure when loading to RAM. :exception NandInstallerError: On failure communicating with the uboot loaded to RAM. """ self._l.info('Loading uboot to RAM') self._check_icache() self._l.debug("Storing the current uboot's bootcmd") prev_bootcmd = self._u.get_env('bootcmd') self._u.set_env('bootcmd', '') self._u.save_env() self._load_file_to_ram(img_filename, load_addr) self._l.debug('Running the new uboot') self._u.cmd('icache off') self._u.cmd('go %s' % to_hex(load_addr), echo_timeout=None, prompt_timeout=None) time.sleep(2) # Give time to uboot to restart self._u.cmd('') # Empty command just to interrupt autoboot ret = self._u.sync() if ret is False: raise NandInstallerError('Failed to detect the new uboot starting') if prev_bootcmd: self._l.debug('Restoring the previous uboot bootcmd') self._u.set_env('bootcmd', prev_bootcmd) self._u.save_env()
def __set_ram_load_addr(self, ram_load_addr): if hexutils.is_valid_addr(ram_load_addr): self._ram_load_addr = hexutils.to_hex(str(ram_load_addr)) else: self._ram_load_addr = None raise NandInstallerError('Invalid RAM load address: %s' % ram_load_addr)
def get_env_load_file_to_ram(self, filename, load_addr): """ Set the tftp file to be transfer and returns the loadtftp uboot enviroment variable :param filename: File to load. :param load_addr: RAM address where to load the file. :exception RamLoaderException: Error loading to RAM. """ # Copy the file to the host's TFTP directory basename = os.path.basename(filename) tftp_filename = '%s/%s' % (self._dir, basename) if self._net_mode == TftpRamLoader.MODE_STATIC: ip_method = 'setenv ipaddr' elif self._net_mode == TftpRamLoader.MODE_DHCP: ip_method = 'setenv autoload no;dhcp' cmd = 'cp -f %s %s' % (filename, tftp_filename) ret, output = self._e.check_output(cmd) if ret != 0: raise RamLoaderException(output) size_b = os.path.getsize(tftp_filename) if size_b == 0: raise RamLoaderException("Size of file %s is 0" % filename) hex_load_addr = hexutils.to_hex(load_addr) cmd = '%s;setenv serverip %s; setenv loadaddr %s;tftp %s' % ( ip_method, self._host_ipaddr, hex_load_addr, basename) self._l.debug("Setting TFTP transfer from file '%s' to RAM address " "'%s'" % (tftp_filename, hex_load_addr)) return cmd
def load_file_to_ram(self, filename, load_addr): """ Loads a file to RAM via TFTP. :param filename: File to load. :param load_addr: RAM address where to load the file. :exception RamLoaderException: Error loading to RAM. """ # Copy the file to the host's TFTP directory basename = os.path.basename(filename) tftp_filename = '%s/%s' % (self._dir, basename) cmd = 'cp -f %s %s' % (filename, tftp_filename) ret, output = self._e.check_output(cmd) if ret != 0: raise RamLoaderException(output) # Transfer size_b = os.path.getsize(tftp_filename) if size_b == 0: raise RamLoaderException("Size of file %s is 0" % filename) hex_load_addr = hexutils.to_hex(load_addr) self._l.debug("Starting TFTP transfer from file '%s' to RAM address " "'%s'" % (tftp_filename, hex_load_addr)) cmd = 'tftp %s %s' % (to_hex(hex_load_addr), basename) try: self._u.cmd(cmd, prompt_timeout=self._transfer_timeout(size_b)) except UbootTimeoutException: self._u.cancel_cmd() raise RamLoaderException("TFTP transfer failed from '%s:%s'." % (self._host_ipaddr, self._port)) filesize = self._u.get_env('filesize') if filesize: env_size_b = int(filesize, base=16) else: env_size_b = 0 if size_b != env_size_b and not self._dryrun: raise RamLoaderException( "Something went wrong during the transfer, the size " "of file '%s' (%s) differs from the transferred bytes (%s)" % (tftp_filename, size_b, env_size_b))
def load_file_to_ram(self, filename, load_addr): """ Loads a file to RAM via TFTP. :param filename: File to load. :param load_addr: RAM address where to load the file. :exception RamLoaderException: Error loading to RAM. """ # Copy the file to the host's TFTP directory basename = os.path.basename(filename) tftp_filename = "%s/%s" % (self._dir, basename) cmd = "cp -f %s %s" % (filename, tftp_filename) ret, output = self._e.check_output(cmd) if ret != 0: raise RamLoaderException(output) # Transfer size_b = os.path.getsize(tftp_filename) if size_b == 0: raise RamLoaderException("Size of file %s is 0" % filename) hex_load_addr = hexutils.to_hex(load_addr) self._l.debug("Starting TFTP transfer from file '%s' to RAM address " "'%s'" % (tftp_filename, hex_load_addr)) cmd = "tftp %s %s" % (to_hex(hex_load_addr), basename) try: self._u.cmd(cmd, prompt_timeout=self._transfer_timeout(size_b)) except UbootTimeoutException: self._u.cancel_cmd() raise RamLoaderException("TFTP transfer failed from '%s:%s'." % (self._host_ipaddr, self._port)) filesize = self._u.get_env("filesize") if filesize: env_size_b = int(filesize, base=16) else: env_size_b = 0 if size_b != env_size_b and not self._dryrun: raise RamLoaderException( "Something went wrong during the transfer, the size " "of file '%s' (%s) differs from the transferred bytes (%s)" % (tftp_filename, size_b, env_size_b) )
def _install_img(self, filename, comp, start_blk, size_blks=0, timeout=DEFAULT_NAND_TIMEOUT, force=False): self._l.info('Installing %s' % comp) offset = start_blk * self.nand_block_size img_size_blks = self._bytes_to_blks(os.path.getsize(filename)) img_size_aligned = img_size_blks * self.nand_block_size part_size = img_size_aligned if size_blks: if img_size_blks > size_blks: self._l.warning("Using %s NAND blocks instead of %s for the " "%s partition" % (img_size_blks, size_blks, comp)) else: part_size = size_blks * self.nand_block_size self._l.debug('Verifying if %s installation is needed' % comp) img_env = { 'md5sum': self._md5sum(filename), 'offset': to_hex(offset), 'size': to_hex(img_size_aligned), 'partitionsize': to_hex(part_size) } if not force and not self._is_img_install_needed(comp, img_env): self._l.info("%s doesn't need to be installed" % comp.capitalize()) return self._l.debug("Loading %s image to RAM" % comp) self._u.set_env('autostart', 'no') self._load_file_to_ram(filename, self._ram_load_addr) self._u.set_env('autostart', 'yes') self._l.debug("Erasing %s NAND space" % comp) cmd = "%s %s %s" % \ (self._board.erase_cmd(comp), to_hex(offset), to_hex(part_size)) self._u.cmd(cmd, prompt_timeout=timeout) self._l.debug("Writing %s image from RAM to NAND" % comp) cmd = self._board.pre_write_cmd(comp) if cmd: self._u.cmd(cmd, prompt_timeout=timeout) cmd = "%s %s %s %s" % (self._board.write_cmd(comp), to_hex(self._ram_load_addr), to_hex(offset), to_hex(img_size_aligned)) self._u.cmd(cmd, prompt_timeout=timeout) cmd = self._board.post_write_cmd(comp) if cmd: self._u.cmd(cmd, prompt_timeout=timeout) self._l.debug("Saving %s partition info" % comp) self._save_img_env(comp, img_env) self._u.save_env() self._l.info('%s installation complete' % comp.capitalize())
def set_env(self, variable, value): """ Sets an uboot env variable. :exception UbootTimeoutException: When a timeout is reached. """ value = value.strip() if ' ' in value or ';' in value: self.cmd("setenv %s '%s'" % (variable, value)) else: if value.startswith('0x') and value.endswith('L'): self.cmd("setenv %s %s" % (variable, to_hex(value))) else: self.cmd("setenv %s %s" % (variable, value))
def load_file_to_ram_and_boot(self, filename, load_addr, boot_line, boot_timeout=0): """ Loads a file to RAM via TFTP. :param filename: File to load. :param load_addr: RAM address where to load the file. :param boot_line: Line to expect in the serial port to determine that boot has been reached. :param boot_timeout: Timeout (in seconds) to wait for :const:`boot_line`. :exception RamLoaderException: Error loading to RAM or booting. """ # Copy the file to the host's TFTP directory basename = os.path.basename(filename) tftp_filename = '%s/%s' % (self._dir, basename) cmd = 'cp %s %s' % (filename, tftp_filename) ret, output = self._e.check_output(cmd) if ret != 0: raise RamLoaderException(output) self._u.set_env('autostart', 'yes') # Transfer size_b = os.path.getsize(tftp_filename) if size_b == 0: raise RamLoaderException("Size of file %s is 0" % filename) hex_load_addr = hexutils.to_hex(load_addr) self._l.debug("Starting TFTP transfer from file '%s' to RAM address " "'%s'" % (tftp_filename, hex_load_addr)) cmd = 'tftp %s %s' % (hex_load_addr, basename) self._u.cmd(cmd, prompt_timeout=None) autobooting = self._u.expect("Automatic boot of image at addr", timeout=self._transfer_timeout(size_b))[0] if not autobooting: raise RamLoaderException("Didn't detect Autoboot from addr " "%s" % hex_load_addr) self._l.info("Booting from %s" % hex_load_addr) self._u.log_prefix = " Serial" booted = self._u.expect(boot_line, timeout=boot_timeout, log_serial_output=True)[0] if not booted: raise RamLoaderException("Didn't encountered boot line '%s' " "after %s seconds" % (boot_line, boot_timeout))
def _install_img(self, filename, comp, start_blk, size_blks=0, timeout=DEFAULT_NAND_TIMEOUT, force=False): self._l.info('Installing %s' % comp) offset = start_blk * self.nand_block_size img_size_blks = self._bytes_to_blks(os.path.getsize(filename)) img_size_aligned = img_size_blks * self.nand_block_size part_size = img_size_aligned if size_blks: if img_size_blks > size_blks: self._l.warning("Using %s NAND blocks instead of %s for the " "%s partition" % (img_size_blks, size_blks, comp)) else: part_size = size_blks * self.nand_block_size self._l.debug('Verifying if %s installation is needed' % comp) img_env = {'md5sum': self._md5sum(filename), 'offset': to_hex(offset), 'size': to_hex(img_size_aligned), 'partitionsize': to_hex(part_size)} if not force and not self._is_img_install_needed(comp, img_env): self._l.info("%s doesn't need to be installed" % comp.capitalize()) return self._l.debug("Loading %s image to RAM" % comp) self._u.set_env('autostart', 'no') self._load_file_to_ram(filename, self._ram_load_addr) self._u.set_env('autostart', 'yes') self._l.debug("Erasing %s NAND space" % comp) cmd = "%s %s %s" % \ (self._board.erase_cmd(comp), to_hex(offset), to_hex(part_size)) self._u.cmd(cmd, prompt_timeout=timeout) self._l.debug("Writing %s image from RAM to NAND" % comp) cmd = self._board.pre_write_cmd(comp) if cmd: self._u.cmd(cmd, prompt_timeout=timeout) cmd = "%s %s %s %s" % (self._board.write_cmd(comp), to_hex(self._ram_load_addr), to_hex(offset), to_hex(img_size_aligned)) self._u.cmd(cmd, prompt_timeout=timeout) cmd = self._board.post_write_cmd(comp) if cmd: self._u.cmd(cmd, prompt_timeout=timeout) self._l.debug("Saving %s partition info" % comp) self._save_img_env(comp, img_env) self._u.save_env() self._l.info('%s installation complete' % comp.capitalize())
def load_file_to_ram_and_boot(self, filename, load_addr, boot_line, boot_timeout=0): """ Loads a file to RAM via TFTP. :param filename: File to load. :param load_addr: RAM address where to load the file. :param boot_line: Line to expect in the serial port to determine that boot has been reached. :param boot_timeout: Timeout (in seconds) to wait for :const:`boot_line`. :exception RamLoaderException: Error loading to RAM or booting. """ # Copy the file to the host's TFTP directory basename = os.path.basename(filename) tftp_filename = "%s/%s" % (self._dir, basename) cmd = "cp %s %s" % (filename, tftp_filename) ret, output = self._e.check_output(cmd) if ret != 0: raise RamLoaderException(output) self._u.set_env("autostart", "yes") # Transfer size_b = os.path.getsize(tftp_filename) if size_b == 0: raise RamLoaderException("Size of file %s is 0" % filename) hex_load_addr = hexutils.to_hex(load_addr) self._l.debug("Starting TFTP transfer from file '%s' to RAM address " "'%s'" % (tftp_filename, hex_load_addr)) cmd = "tftp %s %s" % (hex_load_addr, basename) self._u.cmd(cmd, prompt_timeout=None) autobooting = self._u.expect("Automatic boot of image at addr", timeout=self._transfer_timeout(size_b))[0] if not autobooting: raise RamLoaderException("Didn't detect Autoboot from addr " "%s" % hex_load_addr) self._l.info("Booting from %s" % hex_load_addr) self._u.log_prefix = " Serial" booted = self._u.expect(boot_line, timeout=boot_timeout, log_serial_output=True)[0] if not booted: raise RamLoaderException( "Didn't encountered boot line '%s' " "after %s seconds" % (boot_line, boot_timeout) )
def get_env_load_file_to_ram(self, filename, load_addr): """ Set the tftp file to be transfer and returns the loadtftp uboot enviroment variable :param filename: File to load. :param load_addr: RAM address where to load the file. :exception RamLoaderException: Error loading to RAM. """ # Copy the file to the host's TFTP directory basename = os.path.basename(filename) tftp_filename = "%s/%s" % (self._dir, basename) if self._net_mode == TftpRamLoader.MODE_STATIC: ip_method = "setenv ipaddr" elif self._net_mode == TftpRamLoader.MODE_DHCP: ip_method = "setenv autoload no;dhcp" cmd = "cp -f %s %s" % (filename, tftp_filename) ret, output = self._e.check_output(cmd) if ret != 0: raise RamLoaderException(output) size_b = os.path.getsize(tftp_filename) if size_b == 0: raise RamLoaderException("Size of file %s is 0" % filename) hex_load_addr = hexutils.to_hex(load_addr) cmd = "%s;setenv serverip %s; setenv loadaddr %s;tftp %s" % ( ip_method, self._host_ipaddr, hex_load_addr, basename, ) self._l.debug("Setting TFTP transfer from file '%s' to RAM address " "'%s'" % (tftp_filename, hex_load_addr)) return cmd