aos/tools/harness/machines/pandaboard.py
Daniel Schwyn 6d444bf552 Main handout
Signed-off-by: Daniel Schwyn <daniel.schwyn@inf.ethz.ch>
2022-03-03 14:57:51 +01:00

204 lines
7.8 KiB
Python

##########################################################################
# Copyright (c) 2014-2016 ETH Zurich.
# All rights reserved.
#
# This file is distributed under the terms in the attached LICENSE file.
# If you do not find this file, copies can be found by writing to:
# ETH Zurich D-INFK, Universitaetstr 6, CH-8092 Zurich. Attn: Systems Group.
##########################################################################
import debug, eth_machinedata
import subprocess, os, socket, sys, shutil, tempfile, pty
from machines import ARMMachineBase, MachineFactory, MachineOperations
from machines.eth import ETHBaseMachineOperations
# XXX: the rack-mount pandaboard machines are ETH-specific
PANDA_ROOT='/mnt/emmentaler1_nfs/pandaboot'
PANDA_BOOT_HOST='masterpanda.in.barrelfish.org'
PANDA_PORT=10000
TOOLS_PATH='/home/netos/tools/bin'
RACKBOOT=os.path.join(TOOLS_PATH, 'rackboot.sh')
RACKPOWER=os.path.join(TOOLS_PATH, 'rackpower')
class PandaboardMachine(ARMMachineBase):
'''Machine to run tests on locally attached pandaboard. Assumes your
pandaboard's serial port is attached to /dev/ttyUSB0'''
name = 'panda_local'
imagename = "armv7_omap44xx_image"
def __init__(self, options, **kwargs):
super(PandaboardMachine, self).__init__(options, PandaboardOperations(self), **kwargs)
self.menulst_template = "menu.lst.armv7_omap44xx"
def setup(self, builddir=None):
pass
def get_buildall_target(self):
return "PandaboardES"
class PandaboardOperations(MachineOperations):
def __init__(self, machine):
super(PandaboardOperations, self).__init__(machine)
self.picocom = None
self.tftp_dir = None
self.masterfd = None
def get_tftp_dir(self):
if self.tftp_dir is None:
self.tftp_dir = tempfile.mkdtemp(prefix="panda_")
return self.tftp_dir
def set_bootmodules(self, modules):
menulst_fullpath = os.path.join(self._machine.options.builds[0].build_dir,
"platforms", "arm", self._machine.menulst_template)
self._machine._write_menu_lst(modules.get_menu_data("/"), menulst_fullpath)
debug.verbose("building proper pandaboard image")
debug.checkcmd(["make", self._machine.imagename],
cwd=self._machine.options.builds[0].build_dir)
def __usbboot(self):
debug.verbose("Usbbooting pandaboard; press reset")
debug.verbose("build dir: %s" % self._machine.options.builds[0].build_dir)
debug.checkcmd(["make", "usbboot_panda"],
cwd=self._machine.options.builds[0].build_dir)
def lock(self):
pass
def unlock(self):
pass
def reboot(self):
self.__usbboot()
def shutdown(self):
'''shutdown: close picocom'''
# FIXME: sending C-A C-X to close picocom does not seem to work
#if self.masterfd is not None:
# debug.verbose("Sending C-A C-X to picocom")
# os.write(self.masterfd, "\x01\x24")
if self.picocom is not None:
debug.verbose("Killing picocom")
self.picocom.kill()
try:
os.unlink("/var/lock/LCK..ttyUSB0")
except OSError:
pass
self.picocom = None
self.masterfd = None
def get_output(self):
'''Use picocom to get output. This replicates part of
ETHMachine.lock()'''
(self.masterfd, slavefd) = pty.openpty()
self.picocom = subprocess.Popen(
["picocom", "-b", "115200", "/dev/ttyUSB0"],
close_fds=True, stdout=slavefd, stdin=slavefd)
os.close(slavefd)
self.console_out = os.fdopen(self.masterfd, 'rb', 0)
return self.console_out
class ETHRackPandaboardMachine(ARMMachineBase):
_machines = eth_machinedata.pandaboards
imagename = "armv7_omap44xx_image"
def __init__(self, options, **kwargs):
super(ETHRackPandaboardMachine, self).__init__(options, ETHRackPandaboardMachineOperations(self), **kwargs)
self.menulst_template = "menu.lst.armv7_omap44xx"
def setup(self, builddir=None):
pass
# pandaboard specifics
def get_platform(self):
return 'omap44xx'
def get_buildall_target(self):
return "PandaboardES"
class ETHRackPandaboardMachineOperations(ETHBaseMachineOperations):
def __init__(self, machine):
super(ETHRackPandaboardMachineOperations, self).__init__(machine)
self._tftp_dir = None
self.targe_name = None
def __chmod_ar(self, file):
'''make file/directory readable by all'''
import stat
extra = stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH
if os.path.isdir(file):
extra |= stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
os.chmod(file, os.stat(file).st_mode | extra)
def get_tftp_dir(self):
if self._tftp_dir is None:
self._tftp_dir = tempfile.mkdtemp(dir=PANDA_ROOT, prefix="%s_" % self._machine.getName())
self.__chmod_ar(self._tftp_dir)
return self._tftp_dir
def set_bootmodules(self, modules):
menulst_fullpath = os.path.join(self._machine.options.builds[0].build_dir,
"platforms", "arm", self._machine.menulst_template)
self._machine._write_menu_lst(modules.get_menu_data("/"), menulst_fullpath)
source_name = os.path.join(self._machine.options.builds[0].build_dir, self._machine.imagename)
self.target_name = os.path.join(self.get_tftp_dir(), self._machine.imagename)
debug.verbose("building proper pandaboard image")
debug.checkcmd(["make", self._machine.imagename],
cwd=self._machine.options.builds[0].build_dir)
debug.verbose("copying %s to %s" % (source_name, self.target_name))
shutil.copyfile(source_name, self.target_name)
self.__chmod_ar(self.target_name)
def __usbboot(self):
pandanum = self._machine.get_machine_name()[5:]
imagename = os.path.relpath(self.target_name, PANDA_ROOT)
# send "boot PANDANUM pandaboot/$tempdir/IMAGE_NAME" to
# masterpanda:10000
debug.verbose("sending boot command for pandaboard %s; pandaboard_image %s" % (pandanum, imagename))
masterpanda_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
masterpanda_sock.connect((PANDA_BOOT_HOST, PANDA_PORT))
masterpanda_sock.send('boot %s pandaboot/%s\n' %
(pandanum, imagename))
masterpanda_sock.shutdown(socket.SHUT_WR)
while True:
data = masterpanda_sock.recv(1024)
os.write(sys.stdout.fileno(), data)
if data == "":
break
def _get_console_status(self):
# for Pandaboards we cannot do console -i <machine> so we grab full -i
# output and find relevant line here
proc = subprocess.Popen(["console", "-i"], stdout=subprocess.PIPE)
output = proc.communicate()[0]
assert(proc.returncode == 0)
output = map(str.strip, output.split("\n"))
return filter(lambda l: l.startswith(self._machine.get_machine_name()), output)[0]
def __rackpower(self, arg):
try:
debug.checkcmd([RACKPOWER, arg, self._machine.get_machine_name()])
except subprocess.CalledProcessError:
debug.warning("rackpower %s %s failed" %
(arg, self._machine.get_machine_name()))
def reboot(self):
self.__usbboot()
def shutdown(self):
self.__rackpower('-d')
for pb in ETHRackPandaboardMachine._machines:
class TmpMachine(ETHRackPandaboardMachine):
name = pb
MachineFactory.addMachine(pb, TmpMachine, **ETHRackPandaboardMachine._machines[pb])
MachineFactory.addMachine("panda_local", PandaboardMachine,
bootarch='armv7',
platform='omap44xx',
ncores=2)