Squashed 'yocto-poky/' content from commit ea562de

git-subtree-dir: yocto-poky
git-subtree-split: ea562de57590c966cd5a75fda8defecd397e6436
diff --git a/scripts/README b/scripts/README
new file mode 100644
index 0000000..1b8d127
--- /dev/null
+++ b/scripts/README
@@ -0,0 +1 @@
+This directory contains Various useful scripts for working with OE builds
diff --git a/scripts/bitbake-prserv-tool b/scripts/bitbake-prserv-tool
new file mode 100755
index 0000000..28c2416
--- /dev/null
+++ b/scripts/bitbake-prserv-tool
@@ -0,0 +1,103 @@
+#!/usr/bin/env bash
+
+help ()
+{
+    base=`basename $0`
+    echo -e "Usage: $base command"
+    echo "Avaliable commands:"
+    echo -e "\texport <file.conf>: export and lock down the AUTOPR values from the PR service into a file for release."
+    echo -e "\timport <file.conf>: import the AUTOPR values from the exported file into the PR service."
+}
+
+clean_cache()
+{
+    s=`bitbake -e | grep ^CACHE= | cut -f2 -d\"`
+    if [ "x${s}" != "x" ]; then
+        rm -rf ${s}
+    fi
+}
+
+do_export ()
+{
+    file=$1
+    [ "x${file}" == "x" ] && help && exit 1
+    rm -f ${file}
+
+    clean_cache
+    bitbake -R conf/prexport.conf -p
+    s=`bitbake -R conf/prexport.conf -e | grep ^PRSERV_DUMPFILE= | cut -f2 -d\"`
+    if [ "x${s}" != "x" ];
+    then
+       [ -e $s ] && mv -f $s $file && echo "Exporting to file $file succeeded!"
+       return 0
+    fi
+    echo "Exporting to file $file failed!"
+    return 1
+}
+
+do_import ()
+{
+    file=$1
+    [ "x${file}" == "x" ] && help && exit 1
+
+    clean_cache
+    bitbake -R conf/primport.conf -R $file -p
+    ret=$?
+    [ $ret -eq 0 ] && echo "Importing from file $file succeeded!" || echo "Importing from file $file failed!"
+    return $ret
+}
+
+do_migrate_localcount ()
+{
+    df=`bitbake -R conf/migrate_localcount.conf -e | \
+                grep ^LOCALCOUNT_DUMPFILE= | cut -f2 -d\"`
+    if [ "x${df}" == "x" ];
+    then
+        echo "LOCALCOUNT_DUMPFILE is not defined!"
+        return 1
+    fi
+
+    rm -rf $df
+    clean_cache
+    echo "Exporting LOCALCOUNT to AUTOINCs..."
+    bitbake -R conf/migrate_localcount.conf -p
+    [ ! $? -eq 0 ] && echo "Exporting to file $df failed!" && exit 1
+
+    if [ -e $df ];
+    then
+        echo "Exporting to file $df succeeded!"
+    else
+        echo "Exporting to file $df failed!"
+        exit 1
+    fi
+    
+    echo "Importing generated AUTOINC entries..."
+    [ -e $df ] && do_import $df
+
+    if [ ! $? -eq 0 ]
+    then
+        echo "Migration from LOCALCOUNT to AUTOINCs failed!"
+        return 1
+    fi
+
+    echo "Migration from LOCALCOUNT to AUTOINCs succeeded!"
+    return 0
+}
+
+[ $# -eq 0 ] && help  && exit 1
+
+case $1 in
+export)
+    do_export $2
+    ;;
+import)
+    do_import $2
+    ;;
+migrate_localcount)
+    do_migrate_localcount
+    ;;
+*)
+    help
+    exit 1
+    ;;
+esac
diff --git a/scripts/bitbake-whatchanged b/scripts/bitbake-whatchanged
new file mode 100755
index 0000000..55cfe4b
--- /dev/null
+++ b/scripts/bitbake-whatchanged
@@ -0,0 +1,339 @@
+#!/usr/bin/env python
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+
+# Copyright (c) 2013 Wind River Systems, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+from __future__ import print_function
+import os
+import sys
+import getopt
+import shutil
+import re
+import warnings
+import subprocess
+from optparse import OptionParser
+
+scripts_path = os.path.abspath(os.path.dirname(os.path.abspath(sys.argv[0])))
+lib_path = scripts_path + '/lib'
+sys.path = sys.path + [lib_path]
+
+import scriptpath
+
+# Figure out where is the bitbake/lib/bb since we need bb.siggen and bb.process
+bitbakepath = scriptpath.add_bitbake_lib_path()
+if not bitbakepath:
+    sys.stderr.write("Unable to find bitbake by searching parent directory of this script or PATH\n")
+    sys.exit(1)
+
+import bb.siggen
+import bb.process
+
+# Match the stamp's filename
+# group(1): PE_PV (may no PE)
+# group(2): PR
+# group(3): TASK
+# group(4): HASH
+stamp_re = re.compile("(?P<pv>.*)-(?P<pr>r\d+)\.(?P<task>do_\w+)\.(?P<hash>[^\.]*)")
+sigdata_re = re.compile(".*\.sigdata\..*")
+
+def gen_dict(stamps):
+    """
+    Generate the dict from the stamps dir.
+    The output dict format is:
+    {fake_f: {pn: PN, pv: PV, pr: PR, task: TASK, path: PATH}}
+    Where:
+    fake_f: pv + task + hash
+    path: the path to the stamp file
+    """
+    # The member of the sub dict (A "path" will be appended below)
+    sub_mem = ("pv", "pr", "task")
+    d = {}
+    for dirpath, _, files in os.walk(stamps):
+        for f in files:
+            # The "bitbake -S" would generate ".sigdata", but no "_setscene".
+            fake_f = re.sub('_setscene.', '.', f)
+            fake_f = re.sub('.sigdata', '', fake_f)
+            subdict = {}
+            tmp = stamp_re.match(fake_f)
+            if tmp:
+                for i in sub_mem:
+                    subdict[i] = tmp.group(i)
+                if len(subdict) != 0:
+                    pn = os.path.basename(dirpath)
+                    subdict['pn'] = pn
+                    # The path will be used by os.stat() and bb.siggen
+                    subdict['path'] = dirpath + "/" + f
+                    fake_f = tmp.group('pv') + tmp.group('task') + tmp.group('hash')
+                    d[fake_f] = subdict
+    return d
+
+# Re-construct the dict
+def recon_dict(dict_in):
+    """
+    The output dict format is:
+    {pn_task: {pv: PV, pr: PR, path: PATH}}
+    """
+    dict_out = {}
+    for k in dict_in.keys():
+        subdict = {}
+        # The key
+        pn_task = "%s_%s" % (dict_in.get(k).get('pn'), dict_in.get(k).get('task'))
+        # If more than one stamps are found, use the latest one.
+        if pn_task in dict_out:
+            full_path_pre = dict_out.get(pn_task).get('path')
+            full_path_cur = dict_in.get(k).get('path')
+            if os.stat(full_path_pre).st_mtime > os.stat(full_path_cur).st_mtime:
+                continue
+        subdict['pv'] = dict_in.get(k).get('pv')
+        subdict['pr'] = dict_in.get(k).get('pr')
+        subdict['path'] = dict_in.get(k).get('path')
+        dict_out[pn_task] = subdict
+
+    return dict_out
+
+def split_pntask(s):
+    """
+    Split the pn_task in to (pn, task) and return it
+    """
+    tmp = re.match("(.*)_(do_.*)", s)
+    return (tmp.group(1), tmp.group(2))
+
+
+def print_added(d_new = None, d_old = None):
+    """
+    Print the newly added tasks
+    """
+    added = {}
+    for k in d_new.keys():
+        if k not in d_old:
+            # Add the new one to added dict, and remove it from
+            # d_new, so the remaining ones are the changed ones
+            added[k] = d_new.get(k)
+            del(d_new[k])
+
+    if not added:
+        return 0
+
+    # Format the output, the dict format is:
+    # {pn: task1, task2 ...}
+    added_format = {}
+    counter = 0
+    for k in added.keys():
+        pn, task = split_pntask(k)
+        if pn in added_format:
+            # Append the value
+            added_format[pn] = "%s %s" % (added_format.get(pn), task)
+        else:
+            added_format[pn] = task
+        counter += 1
+    print("=== Newly added tasks: (%s tasks)" % counter)
+    for k in added_format.keys():
+        print("  %s: %s" % (k, added_format.get(k)))
+
+    return counter
+
+def print_vrchanged(d_new = None, d_old = None, vr = None):
+    """
+    Print the pv or pr changed tasks.
+    The arg "vr" is "pv" or "pr"
+    """
+    pvchanged = {}
+    counter = 0
+    for k in d_new.keys():
+        if d_new.get(k).get(vr) != d_old.get(k).get(vr):
+            counter += 1
+            pn, task = split_pntask(k)
+            if pn not in pvchanged:
+                # Format the output, we only print pn (no task) since
+                # all the tasks would be changed when pn or pr changed,
+                # the dict format is:
+                # {pn: pv/pr_old -> pv/pr_new}
+                pvchanged[pn] = "%s -> %s" % (d_old.get(k).get(vr), d_new.get(k).get(vr))
+            del(d_new[k])
+
+    if not pvchanged:
+        return 0
+
+    print("\n=== %s changed: (%s tasks)" % (vr.upper(), counter))
+    for k in pvchanged.keys():
+        print("  %s: %s" % (k, pvchanged.get(k)))
+
+    return counter
+
+def print_depchanged(d_new = None, d_old = None, verbose = False):
+    """
+    Print the dependency changes
+    """
+    depchanged = {}
+    counter = 0
+    for k in d_new.keys():
+        counter += 1
+        pn, task = split_pntask(k)
+        if (verbose):
+            full_path_old = d_old.get(k).get("path")
+            full_path_new = d_new.get(k).get("path")
+            # No counter since it is not ready here
+            if sigdata_re.match(full_path_old) and sigdata_re.match(full_path_new):
+                output = bb.siggen.compare_sigfiles(full_path_old, full_path_new)
+                if output:
+                    print("\n=== The verbose changes of %s.do_%s:" % (pn, task))
+                    print('\n'.join(output))
+        else:
+            # Format the output, the format is:
+            # {pn: task1, task2, ...}
+            if pn in depchanged:
+                depchanged[pn] = "%s %s" % (depchanged.get(pn), task)
+            else:
+                depchanged[pn] = task
+
+    if len(depchanged) > 0:
+        print("\n=== Dependencies changed: (%s tasks)" % counter)
+        for k in depchanged.keys():
+            print("  %s: %s" % (k, depchanged[k]))
+
+    return counter
+
+
+def main():
+    """
+    Print what will be done between the current and last builds:
+    1) Run "STAMPS_DIR=<path> bitbake -S recipe" to re-generate the stamps
+    2) Figure out what are newly added and changed, can't figure out
+       what are removed since we can't know the previous stamps
+       clearly, for example, if there are several builds, we can't know
+       which stamps the last build has used exactly.
+    3) Use bb.siggen.compare_sigfiles to diff the old and new stamps
+    """
+
+    parser = OptionParser(
+        version = "1.0",
+        usage = """%prog [options] [package ...]
+print what will be done between the current and last builds, for example:
+
+    $ bitbake core-image-sato
+    # Edit the recipes
+    $ bitbake-whatchanged core-image-sato
+
+The changes will be printed"
+
+Note:
+    The amount of tasks is not accurate when the task is "do_build" since
+    it usually depends on other tasks.
+    The "nostamp" task is not included.
+"""
+)
+    parser.add_option("-v", "--verbose", help = "print the verbose changes",
+               action = "store_true", dest = "verbose")
+
+    options, args = parser.parse_args(sys.argv)
+
+    verbose = options.verbose
+
+    if len(args) != 2:
+        parser.error("Incorrect number of arguments")
+    else:
+        recipe = args[1]
+
+    # Get the STAMPS_DIR
+    print("Figuring out the STAMPS_DIR ...")
+    cmdline = "bitbake -e | sed -ne 's/^STAMPS_DIR=\"\(.*\)\"/\\1/p'"
+    try:
+        stampsdir, err = bb.process.run(cmdline)
+    except:
+        raise
+    if not stampsdir:
+        print("ERROR: No STAMPS_DIR found for '%s'" % recipe, file=sys.stderr)
+        return 2
+    stampsdir = stampsdir.rstrip("\n")
+    if not os.path.isdir(stampsdir):
+        print("ERROR: stamps directory \"%s\" not found!" % stampsdir, file=sys.stderr)
+        return 2
+
+    # The new stamps dir
+    new_stampsdir = stampsdir + ".bbs"
+    if os.path.exists(new_stampsdir):
+        print("ERROR: %s already exists!" % new_stampsdir, file=sys.stderr)
+        return 2
+
+    try:
+        # Generate the new stamps dir
+        print("Generating the new stamps ... (need several minutes)")
+        cmdline = "STAMPS_DIR=%s bitbake -S none %s" % (new_stampsdir, recipe)
+        # FIXME
+        # The "bitbake -S" may fail, not fatal error, the stamps will still
+        # be generated, this might be a bug of "bitbake -S".
+        try:
+            bb.process.run(cmdline)
+        except Exception as exc:
+            print(exc)
+
+        # The dict for the new and old stamps.
+        old_dict = gen_dict(stampsdir)
+        new_dict = gen_dict(new_stampsdir)
+
+        # Remove the same one from both stamps.
+        cnt_unchanged = 0
+        for k in new_dict.keys():
+            if k in old_dict:
+                cnt_unchanged += 1
+                del(new_dict[k])
+                del(old_dict[k])
+
+        # Re-construct the dict to easily find out what is added or changed.
+        # The dict format is:
+        # {pn_task: {pv: PV, pr: PR, path: PATH}}
+        new_recon = recon_dict(new_dict)
+        old_recon = recon_dict(old_dict)
+
+        del new_dict
+        del old_dict
+
+        # Figure out what are changed, the new_recon would be changed
+        # by the print_xxx function.
+        # Newly added
+        cnt_added = print_added(new_recon, old_recon)
+
+        # PV (including PE) and PR changed
+        # Let the bb.siggen handle them if verbose
+        cnt_rv = {}
+        if not verbose:
+            for i in ('pv', 'pr'):
+               cnt_rv[i] = print_vrchanged(new_recon, old_recon, i)
+
+        # Dependencies changed (use bitbake-diffsigs)
+        cnt_dep = print_depchanged(new_recon, old_recon, verbose)
+
+        total_changed = cnt_added + (cnt_rv.get('pv') or 0) + (cnt_rv.get('pr') or 0) + cnt_dep
+
+        print("\n=== Summary: (%s changed, %s unchanged)" % (total_changed, cnt_unchanged))
+        if verbose:
+            print("Newly added: %s\nDependencies changed: %s\n" % \
+                (cnt_added, cnt_dep))
+        else:
+            print("Newly added: %s\nPV changed: %s\nPR changed: %s\nDependencies changed: %s\n" % \
+                (cnt_added, cnt_rv.get('pv') or 0, cnt_rv.get('pr') or 0, cnt_dep))
+    except:
+        print("ERROR occurred!")
+        raise
+    finally:
+        # Remove the newly generated stamps dir
+        if os.path.exists(new_stampsdir):
+            print("Removing the newly generated stamps dir ...")
+            shutil.rmtree(new_stampsdir)
+
+if __name__ == "__main__":
+    sys.exit(main())
diff --git a/scripts/buildhistory-collect-srcrevs b/scripts/buildhistory-collect-srcrevs
new file mode 100755
index 0000000..58a2708
--- /dev/null
+++ b/scripts/buildhistory-collect-srcrevs
@@ -0,0 +1,109 @@
+#!/usr/bin/env python
+#
+# Collects the recorded SRCREV values from buildhistory and reports on them
+#
+# Copyright 2013 Intel Corporation
+# Authored-by:  Paul Eggleton <paul.eggleton@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import os, sys
+import optparse
+import logging
+
+def logger_create():
+    logger = logging.getLogger("buildhistory")
+    loggerhandler = logging.StreamHandler()
+    loggerhandler.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))
+    logger.addHandler(loggerhandler)
+    logger.setLevel(logging.INFO)
+    return logger
+
+logger = logger_create()
+
+def main():
+    parser = optparse.OptionParser(
+        description = "Collects the recorded SRCREV values from buildhistory and reports on them.",
+        usage = """
+    %prog [options]""")
+
+    parser.add_option("-a", "--report-all",
+            help = "Report all SRCREV values, not just ones where AUTOREV has been used",
+            action="store_true", dest="reportall")
+    parser.add_option("-f", "--forcevariable",
+            help = "Use forcevariable override for all output lines",
+            action="store_true", dest="forcevariable")
+    parser.add_option("-p", "--buildhistory-dir",
+            help = "Specify path to buildhistory directory (defaults to buildhistory/ under cwd)",
+            action="store", dest="buildhistory_dir", default='buildhistory/')
+
+    options, args = parser.parse_args(sys.argv)
+
+    if len(args) > 1:
+        sys.stderr.write('Invalid argument(s) specified: %s\n\n' % ' '.join(args[1:]))
+        parser.print_help()
+        sys.exit(1)
+
+    if not os.path.exists(options.buildhistory_dir):
+        sys.stderr.write('Buildhistory directory "%s" does not exist\n\n' % options.buildhistory_dir)
+        parser.print_help()
+        sys.exit(1)
+
+    if options.forcevariable:
+        forcevariable = '_forcevariable'
+    else:
+        forcevariable = ''
+
+    lastdir = ''
+    for root, dirs, files in os.walk(options.buildhistory_dir):
+        if '.git' in dirs:
+            dirs.remove('.git')
+        for fn in files:
+            if fn == 'latest_srcrev':
+                curdir = os.path.basename(os.path.dirname(root))
+                if lastdir != curdir:
+                    print('# %s' % curdir)
+                    lastdir = curdir
+                fullpath = os.path.join(root, fn)
+                pn = os.path.basename(root)
+                srcrev = None
+                orig_srcrev = None
+                orig_srcrevs = {}
+                srcrevs = {}
+                with open(fullpath) as f:
+                    for line in f:
+                        if '=' in line:
+                            splitval = line.split('=')
+                            value = splitval[1].strip('" \t\n\r')
+                        if line.startswith('# SRCREV = '):
+                            orig_srcrev = value
+                        elif line.startswith('# SRCREV_'):
+                            splitval = line.split('=')
+                            name = splitval[0].split('_')[1].strip()
+                            orig_srcrevs[name] = value
+                        elif line.startswith('SRCREV ='):
+                            srcrev = value
+                        elif line.startswith('SRCREV_'):
+                            name = splitval[0].split('_')[1].strip()
+                            srcrevs[name] = value
+                if srcrev and (options.reportall or srcrev != orig_srcrev):
+                    print('SRCREV_pn-%s%s = "%s"' % (pn, forcevariable, srcrev))
+                for name, value in srcrevs.items():
+                    orig = orig_srcrevs.get(name, orig_srcrev)
+                    if options.reportall or value != orig:
+                        print('SRCREV_%s_pn-%s%s = "%s"' % (name, pn, forcevariable, value))
+
+
+if __name__ == "__main__":
+    main()
diff --git a/scripts/buildhistory-diff b/scripts/buildhistory-diff
new file mode 100755
index 0000000..dfebcdd
--- /dev/null
+++ b/scripts/buildhistory-diff
@@ -0,0 +1,100 @@
+#!/usr/bin/env python
+
+# Report significant differences in the buildhistory repository since a specific revision
+#
+# Copyright (C) 2013 Intel Corporation
+# Author: Paul Eggleton <paul.eggleton@linux.intel.com>
+
+import sys
+import os
+import optparse
+from distutils.version import LooseVersion
+
+# Ensure PythonGit is installed (buildhistory_analysis needs it)
+try:
+    import git
+except ImportError:
+    print("Please install GitPython (python-git) 0.3.1 or later in order to use this script")
+    sys.exit(1)
+
+def main():
+    parser = optparse.OptionParser(
+        description = "Reports significant differences in the buildhistory repository.",
+        usage = """
+    %prog [options] [from-revision [to-revision]]
+(if not specified, from-revision defaults to build-minus-1, and to-revision defaults to HEAD)""")
+
+    parser.add_option("-p", "--buildhistory-dir",
+            help = "Specify path to buildhistory directory (defaults to buildhistory/ under cwd)",
+            action="store", dest="buildhistory_dir", default='buildhistory/')
+    parser.add_option("-v", "--report-version",
+            help = "Report changes in PKGE/PKGV/PKGR even when the values are still the default (PE/PV/PR)",
+            action="store_true", dest="report_ver", default=False)
+    parser.add_option("-a", "--report-all",
+            help = "Report all changes, not just the default significant ones",
+            action="store_true", dest="report_all", default=False)
+
+    options, args = parser.parse_args(sys.argv)
+
+    if len(args) > 3:
+        sys.stderr.write('Invalid argument(s) specified: %s\n\n' % ' '.join(args[3:]))
+        parser.print_help()
+        sys.exit(1)
+
+    if LooseVersion(git.__version__) < '0.3.1':
+        sys.stderr.write("Version of GitPython is too old, please install GitPython (python-git) 0.3.1 or later in order to use this script\n")
+        sys.exit(1)
+
+    if not os.path.exists(options.buildhistory_dir):
+        sys.stderr.write('Buildhistory directory "%s" does not exist\n\n' % options.buildhistory_dir)
+        parser.print_help()
+        sys.exit(1)
+
+    scripts_path = os.path.abspath(os.path.dirname(os.path.abspath(sys.argv[0])))
+    lib_path = scripts_path + '/lib'
+    sys.path = sys.path + [lib_path]
+
+    import scriptpath
+
+    # Set path to OE lib dir so we can import the buildhistory_analysis module
+    scriptpath.add_oe_lib_path()
+    # Set path to bitbake lib dir so the buildhistory_analysis module can load bb.utils
+    bitbakepath = scriptpath.add_bitbake_lib_path()
+    if not bitbakepath:
+        sys.stderr.write("Unable to find bitbake by searching parent directory of this script or PATH\n")
+        sys.exit(1)
+
+    import oe.buildhistory_analysis
+
+    fromrev = 'build-minus-1'
+    torev = 'HEAD'
+    if len(args) > 1:
+        if len(args) == 2 and '..' in args[1]:
+            revs = args[1].split('..')
+            fromrev = revs[0]
+            if revs[1]:
+                torev = revs[1]
+        else:
+            fromrev = args[1]
+    if len(args) > 2:
+        torev = args[2]
+
+    import gitdb
+    try:
+        changes = oe.buildhistory_analysis.process_changes(options.buildhistory_dir, fromrev, torev, options.report_all, options.report_ver)
+    except gitdb.exc.BadObject as e:
+        if len(args) == 1:
+            sys.stderr.write("Unable to find previous build revision in buildhistory repository\n\n")
+            parser.print_help()
+        else:
+            sys.stderr.write('Specified git revision "%s" is not valid\n' % e.args[0])
+        sys.exit(1)
+
+    for chg in changes:
+        print('%s' % chg)
+
+    sys.exit(0)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/scripts/cleanup-workdir b/scripts/cleanup-workdir
new file mode 100755
index 0000000..a7f5a3a
--- /dev/null
+++ b/scripts/cleanup-workdir
@@ -0,0 +1,198 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2012 Wind River Systems, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import os
+import sys
+import optparse
+import re
+import subprocess
+import shutil
+
+pkg_cur_dirs = {}
+obsolete_dirs = []
+parser = None
+
+def err_quit(msg):
+    print msg
+    parser.print_usage()
+    sys.exit(1)
+
+def parse_version(verstr):
+    elems = verstr.split(':')
+    epoch = elems[0]
+    if len(epoch) == 0:
+        return elems[1]
+    else:
+        return epoch + '_' + elems[1]
+
+def run_command(cmd):
+    pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
+    output = pipe.communicate()[0]
+    if pipe.returncode != 0:
+        print "Execute command '%s' failed." % cmd
+        sys.exit(1)
+    return output
+
+def get_cur_arch_dirs(workdir, arch_dirs):
+    pattern = workdir + '/(.*?)/'
+
+    cmd = "bitbake -e | grep ^SDK_ARCH="
+    output = run_command(cmd)
+    sdk_arch = output.split('"')[1]
+
+    # select thest 5 packages to get the dirs of current arch
+    pkgs = ['hicolor-icon-theme', 'base-files', 'acl-native', 'binutils-crosssdk-' + sdk_arch, 'nativesdk-autoconf']
+
+    for pkg in pkgs:
+        cmd = "bitbake -e " + pkg + " | grep ^IMAGE_ROOTFS="
+        output = run_command(cmd)
+        output = output.split('"')[1]
+        m = re.match(pattern, output)
+        arch_dirs.append(m.group(1))
+
+def main():
+    global parser
+    parser = optparse.OptionParser(
+        usage = """%prog
+
+%prog removes the obsolete packages' build directories in WORKDIR.
+This script must be ran under BUILDDIR after source file \"oe-init-build-env\".
+
+Any file or directory under WORKDIR which is not created by Yocto
+will be deleted. Be CAUTIOUS.""")
+
+    options, args = parser.parse_args(sys.argv)
+
+    builddir = run_command('echo $BUILDDIR').strip()
+    if len(builddir) == 0:
+        err_quit("Please source file \"oe-init-build-env\" first.\n")
+
+    if os.getcwd() != builddir:
+        err_quit("Please run %s under: %s\n" % (os.path.basename(args[0]), builddir))
+
+    print 'Updating bitbake caches...'
+    cmd = "bitbake -s"
+    output = run_command(cmd)
+
+    output = output.split('\n')
+    index = 0
+    while len(output[index]) > 0:
+        index += 1
+    alllines = output[index+1:]
+
+    for line in alllines:
+        # empty again means end of the versions output
+        if len(line) == 0:
+            break
+        line = line.strip()
+        line = re.sub('\s+', ' ', line)
+        elems = line.split(' ')
+        if len(elems) == 2:
+            version = parse_version(elems[1])
+        else:
+            version = parse_version(elems[2])
+        pkg_cur_dirs[elems[0]] = version
+
+    cmd = "bitbake -e"
+    output = run_command(cmd)
+
+    tmpdir = None
+    image_rootfs = None
+    output = output.split('\n')
+    for line in output:
+        if tmpdir and image_rootfs:
+            break
+
+        if not tmpdir:
+            m = re.match('TMPDIR="(.*)"', line)
+            if m:
+                tmpdir = m.group(1)
+
+        if not image_rootfs:
+            m = re.match('IMAGE_ROOTFS="(.*)"', line)
+            if m:
+                image_rootfs = m.group(1)
+
+    # won't fail just in case
+    if not tmpdir or not image_rootfs:
+        print "Can't get TMPDIR or IMAGE_ROOTFS."
+        return 1
+
+    pattern = tmpdir + '/(.*?)/(.*?)/'
+    m = re.match(pattern, image_rootfs)
+    if not m:
+        print "Can't get WORKDIR."
+        return 1
+
+    workdir = os.path.join(tmpdir, m.group(1))
+
+    # we only deal the dirs of current arch, total numbers of dirs are 6
+    cur_arch_dirs = [m.group(2)]
+    get_cur_arch_dirs(workdir, cur_arch_dirs)
+
+    for workroot, dirs, files in os.walk(workdir):
+        # For the files, they should NOT exist in WORKDIR. Remove them.
+        for f in files:
+            obsolete_dirs.append(os.path.join(workroot, f))
+
+        for d in dirs:
+            if d not in cur_arch_dirs:
+                continue
+
+            for pkgroot, pkgdirs, filenames in os.walk(os.path.join(workroot, d)):
+                for f in filenames:
+                    obsolete_dirs.append(os.path.join(pkgroot, f))
+
+                for pkgdir in sorted(pkgdirs):
+                    if pkgdir not in pkg_cur_dirs:
+                        obsolete_dirs.append(os.path.join(pkgroot, pkgdir))
+                    else:
+                        for verroot, verdirs, verfiles in os.walk(os.path.join(pkgroot, pkgdir)):
+                            for f in verfiles:
+                                obsolete_dirs.append(os.path.join(pkgroot, f))
+                            for v in sorted(verdirs):
+                               if v not in pkg_cur_dirs[pkgdir]:
+                                   obsolete_dirs.append(os.path.join(pkgroot, pkgdir, v))
+                            break
+
+                # just process the top dir of every package under tmp/work/*/,
+                # then jump out of the above os.walk()
+                break
+
+        # it is convenient to use os.walk() to get dirs and files at same time
+        # both of them have been dealed in the loop, so jump out
+        break
+
+    for d in obsolete_dirs:
+        print "Deleting %s" % d
+        shutil.rmtree(d, True)
+
+    if len(obsolete_dirs):
+        print '\nTotal %d items.' % len(obsolete_dirs)
+    else:
+        print '\nNo obsolete directory found under %s.' % workdir
+
+    return 0
+
+if __name__ == '__main__':
+    try:
+        ret = main()
+    except Exception:
+        ret = 2
+        import traceback
+        traceback.print_exc(3)
+    sys.exit(ret)
diff --git a/scripts/combo-layer b/scripts/combo-layer
new file mode 100755
index 0000000..7435a17
--- /dev/null
+++ b/scripts/combo-layer
@@ -0,0 +1,949 @@
+#!/usr/bin/env python
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# Copyright 2011 Intel Corporation
+# Authored-by:  Yu Ke <ke.yu@intel.com>
+#               Paul Eggleton <paul.eggleton@intel.com>
+#               Richard Purdie <richard.purdie@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import fnmatch
+import os, sys
+import optparse
+import logging
+import subprocess
+import tempfile
+import ConfigParser
+import re
+from collections import OrderedDict
+from string import Template
+
+__version__ = "0.2.1"
+
+def logger_create():
+    logger = logging.getLogger("")
+    loggerhandler = logging.StreamHandler()
+    loggerhandler.setFormatter(logging.Formatter("[%(asctime)s] %(message)s","%H:%M:%S"))
+    logger.addHandler(loggerhandler)
+    logger.setLevel(logging.INFO)
+    return logger
+
+logger = logger_create()
+
+def get_current_branch(repodir=None):
+    try:
+        if not os.path.exists(os.path.join(repodir if repodir else '', ".git")):
+            # Repo not created yet (i.e. during init) so just assume master
+            return "master"
+        branchname = runcmd("git symbolic-ref HEAD 2>/dev/null", repodir).strip()
+        if branchname.startswith("refs/heads/"):
+            branchname = branchname[11:]
+        return branchname
+    except subprocess.CalledProcessError:
+        return ""
+
+class Configuration(object):
+    """
+    Manages the configuration
+
+    For an example config file, see combo-layer.conf.example
+
+    """
+    def __init__(self, options):
+        for key, val in options.__dict__.items():
+            setattr(self, key, val)
+
+        def readsection(parser, section, repo):
+            for (name, value) in parser.items(section):
+                if value.startswith("@"):
+                    self.repos[repo][name] = eval(value.strip("@"))
+                else:
+                    # Apply special type transformations for some properties.
+                    # Type matches the RawConfigParser.get*() methods.
+                    types = {'signoff': 'boolean'}
+                    if name in types:
+                        value = getattr(parser, 'get' + types[name])(section, name)
+                    self.repos[repo][name] = value
+
+        def readglobalsection(parser, section):
+            for (name, value) in parser.items(section):
+                if name == "commit_msg":
+                    self.commit_msg_template = value
+
+        logger.debug("Loading config file %s" % self.conffile)
+        self.parser = ConfigParser.ConfigParser()
+        with open(self.conffile) as f:
+            self.parser.readfp(f)
+
+        # initialize default values
+        self.commit_msg_template = "Automatic commit to update last_revision"
+
+        self.repos = {}
+        for repo in self.parser.sections():
+            if repo == "combo-layer-settings":
+                # special handling for global settings
+                readglobalsection(self.parser, repo)
+            else:
+                self.repos[repo] = {}
+                readsection(self.parser, repo, repo)
+
+        # Load local configuration, if available
+        self.localconffile = None
+        self.localparser = None
+        self.combobranch = None
+        if self.conffile.endswith('.conf'):
+            lcfile = self.conffile.replace('.conf', '-local.conf')
+            if os.path.exists(lcfile):
+                # Read combo layer branch
+                self.combobranch = get_current_branch()
+                logger.debug("Combo layer branch is %s" % self.combobranch)
+
+                self.localconffile = lcfile
+                logger.debug("Loading local config file %s" % self.localconffile)
+                self.localparser = ConfigParser.ConfigParser()
+                with open(self.localconffile) as f:
+                    self.localparser.readfp(f)
+
+                for section in self.localparser.sections():
+                    if '|' in section:
+                        sectionvals = section.split('|')
+                        repo = sectionvals[0]
+                        if sectionvals[1] != self.combobranch:
+                            continue
+                    else:
+                        repo = section
+                    if repo in self.repos:
+                        readsection(self.localparser, section, repo)
+
+    def update(self, repo, option, value, initmode=False):
+        # If the main config has the option already, that is what we
+        # are expected to modify.
+        if self.localparser and not self.parser.has_option(repo, option):
+            parser = self.localparser
+            section = "%s|%s" % (repo, self.combobranch)
+            conffile = self.localconffile
+            if initmode and not parser.has_section(section):
+                parser.add_section(section)
+        else:
+            parser = self.parser
+            section = repo
+            conffile = self.conffile
+        parser.set(section, option, value)
+        with open(conffile, "w") as f:
+            parser.write(f)
+        self.repos[repo][option] = value
+
+    def sanity_check(self, initmode=False):
+        required_options=["src_uri", "local_repo_dir", "dest_dir", "last_revision"]
+        if initmode:
+            required_options.remove("last_revision")
+        msg = ""
+        missing_options = []
+        for name in self.repos:
+            for option in required_options:
+                if option not in self.repos[name]:
+                    msg = "%s\nOption %s is not defined for component %s" %(msg, option, name)
+                    missing_options.append(option)
+            # Sanitize dest_dir so that we do not have to deal with edge cases
+            # (unset, empty string, double slashes) in the rest of the code.
+            # It not being set will still be flagged as error because it is
+            # listed as required option above; that could be changed now.
+            dest_dir = os.path.normpath(self.repos[name].get("dest_dir", "."))
+            self.repos[name]["dest_dir"] = "." if not dest_dir else dest_dir
+        if msg != "":
+            logger.error("configuration file %s has the following error: %s" % (self.conffile,msg))
+            if self.localconffile and 'last_revision' in missing_options:
+                logger.error("local configuration file %s may be missing configuration for combo branch %s" % (self.localconffile, self.combobranch))
+            sys.exit(1)
+
+        # filterdiff is required by action_splitpatch, so check its availability
+        if subprocess.call("which filterdiff > /dev/null 2>&1", shell=True) != 0:
+            logger.error("ERROR: patchutils package is missing, please install it (e.g. # apt-get install patchutils)")
+            sys.exit(1)
+
+def runcmd(cmd,destdir=None,printerr=True,out=None):
+    """
+        execute command, raise CalledProcessError if fail
+        return output if succeed
+    """
+    logger.debug("run cmd '%s' in %s" % (cmd, os.getcwd() if destdir is None else destdir))
+    if not out:
+        out = os.tmpfile()
+        err = out
+    else:
+        err = os.tmpfile()
+    try:
+        subprocess.check_call(cmd, stdout=out, stderr=err, cwd=destdir, shell=isinstance(cmd, str))
+    except subprocess.CalledProcessError,e:
+        err.seek(0)
+        if printerr:
+            logger.error("%s" % err.read())
+        raise e
+
+    err.seek(0)
+    output = err.read()
+    logger.debug("output: %s" % output )
+    return output
+
+def action_init(conf, args):
+    """
+        Clone component repositories
+        Check git is initialised; if not, copy initial data from component repos
+    """
+    for name in conf.repos:
+        ldir = conf.repos[name]['local_repo_dir']
+        if not os.path.exists(ldir):
+            logger.info("cloning %s to %s" %(conf.repos[name]['src_uri'], ldir))
+            subprocess.check_call("git clone %s %s" % (conf.repos[name]['src_uri'], ldir), shell=True)
+    if not os.path.exists(".git"):
+        runcmd("git init")
+        if conf.history:
+            # Need a common ref for all trees.
+            runcmd('git commit -m "initial empty commit" --allow-empty')
+            startrev = runcmd('git rev-parse master').strip()
+
+        for name in conf.repos:
+            repo = conf.repos[name]
+            ldir = repo['local_repo_dir']
+            branch = repo.get('branch', "master")
+            lastrev = repo.get('last_revision', None)
+            if lastrev and lastrev != "HEAD":
+                initialrev = lastrev
+                if branch:
+                    if not check_rev_branch(name, ldir, lastrev, branch):
+                        sys.exit(1)
+                logger.info("Copying data from %s at specified revision %s..." % (name, lastrev))
+            else:
+                lastrev = None
+                initialrev = branch
+                logger.info("Copying data from %s..." % name)
+            # Sanity check initialrev and turn it into hash (required for copying history,
+            # because resolving a name ref only works in the component repo).
+            rev = runcmd('git rev-parse %s' % initialrev, ldir).strip()
+            if rev != initialrev:
+                try:
+                    refs = runcmd('git show-ref -s %s' % initialrev, ldir).split('\n')
+                    if len(set(refs)) > 1:
+                        # Happens for example when configured to track
+                        # "master" and there is a refs/heads/master. The
+                        # traditional behavior from "git archive" (preserved
+                        # here) it to choose the first one. This might not be
+                        # intended, so at least warn about it.
+                        logger.warn("%s: initial revision '%s' not unique, picking result of rev-parse = %s" %
+                                    (name, initialrev, refs[0]))
+                        initialrev = rev
+                except:
+                    # show-ref fails for hashes. Skip the sanity warning in that case.
+                    pass
+                initialrev = rev
+            dest_dir = repo['dest_dir']
+            if dest_dir != ".":
+                extract_dir = os.path.join(os.getcwd(), dest_dir)
+                if not os.path.exists(extract_dir):
+                    os.makedirs(extract_dir)
+            else:
+                extract_dir = os.getcwd()
+            file_filter = repo.get('file_filter', "")
+            exclude_patterns = repo.get('file_exclude', '').split()
+            def copy_selected_files(initialrev, extract_dir, file_filter, exclude_patterns, ldir,
+                                    subdir=""):
+                # When working inside a filtered branch which had the
+                # files already moved, we need to prepend the
+                # subdirectory to all filters, otherwise they would
+                # not match.
+                if subdir == '.':
+                    subdir = ''
+                elif subdir:
+                    subdir = os.path.normpath(subdir)
+                    file_filter = ' '.join([subdir + '/' + x for x in file_filter.split()])
+                    exclude_patterns = [subdir + '/' + x for x in exclude_patterns]
+                # To handle both cases, we cd into the target
+                # directory and optionally tell tar to strip the path
+                # prefix when the files were already moved.
+                subdir_components = len(subdir.split(os.path.sep)) if subdir else 0
+                strip=('--strip-components=%d' % subdir_components) if subdir else ''
+                # TODO: file_filter wild cards do not work (and haven't worked before either), because
+                # a) GNU tar requires a --wildcards parameter before turning on wild card matching.
+                # b) The semantic is not as intendend (src/*.c also matches src/foo/bar.c,
+                #    in contrast to the other use of file_filter as parameter of "git archive"
+                #    where it only matches .c files directly in src).
+                files = runcmd("git archive %s %s | tar -x -v %s -C %s %s" %
+                               (initialrev, subdir,
+                                strip, extract_dir, file_filter),
+                               ldir)
+                if exclude_patterns:
+                    # Implement file removal by letting tar create the
+                    # file and then deleting it in the file system
+                    # again. Uses the list of files created by tar (easier
+                    # than walking the tree).
+                    for file in files.split('\n'):
+                        for pattern in exclude_patterns:
+                            if fnmatch.fnmatch(file, pattern):
+                                os.unlink(os.path.join(*([extract_dir] + ['..'] * subdir_components + [file])))
+                                break
+
+            if not conf.history:
+                copy_selected_files(initialrev, extract_dir, file_filter, exclude_patterns, ldir)
+            else:
+                # First fetch remote history into local repository.
+                # We need a ref for that, so ensure that there is one.
+                refname = "combo-layer-init-%s" % name
+                runcmd("git branch -f %s %s" % (refname, initialrev), ldir)
+                runcmd("git fetch %s %s" % (ldir, refname))
+                runcmd("git branch -D %s" % refname, ldir)
+                # Make that the head revision.
+                runcmd("git checkout -b %s %s" % (name, initialrev))
+                # Optional: cut the history by replacing the given
+                # start point(s) with commits providing the same
+                # content (aka tree), but with commit information that
+                # makes it clear that this is an artifically created
+                # commit and nothing the original authors had anything
+                # to do with.
+                since_rev = repo.get('since_revision', '')
+                if since_rev:
+                    committer = runcmd('git var GIT_AUTHOR_IDENT').strip()
+                    # Same time stamp, no name.
+                    author = re.sub('.* (\d+ [+-]\d+)', r'unknown <unknown> \1', committer)
+                    logger.info('author %s' % author)
+                    for rev in since_rev.split():
+                        # Resolve in component repo...
+                        rev = runcmd('git log --oneline --no-abbrev-commit -n1 %s' % rev, ldir).split()[0]
+                        # ... and then get the tree in current
+                        # one. The commit should be in both repos with
+                        # the same tree, but better check here.
+                        tree = runcmd('git show -s --pretty=format:%%T %s' % rev).strip()
+                        with tempfile.NamedTemporaryFile() as editor:
+                            editor.write('''cat >$1 <<EOF
+tree %s
+author %s
+committer %s
+
+%s: squashed import of component
+
+This commit copies the entire set of files as found in
+%s %s
+
+For more information about previous commits, see the
+upstream repository.
+
+Commit created by combo-layer.
+EOF
+''' % (tree, author, committer, name, name, since_rev))
+                            editor.flush()
+                            os.environ['GIT_EDITOR'] = 'sh %s' % editor.name
+                            runcmd('git replace --edit %s' % rev)
+
+                # Optional: rewrite history to change commit messages or to move files.
+                if 'hook' in repo or dest_dir != ".":
+                    filter_branch = ['git', 'filter-branch', '--force']
+                    with tempfile.NamedTemporaryFile() as hookwrapper:
+                        if 'hook' in repo:
+                            # Create a shell script wrapper around the original hook that
+                            # can be used by git filter-branch. Hook may or may not have
+                            # an absolute path.
+                            hook = repo['hook']
+                            hook = os.path.join(os.path.dirname(conf.conffile), '..', hook)
+                            # The wrappers turns the commit message
+                            # from stdin into a fake patch header.
+                            # This is good enough for changing Subject
+                            # and commit msg body with normal
+                            # combo-layer hooks.
+                            hookwrapper.write('''set -e
+tmpname=$(mktemp)
+trap "rm $tmpname" EXIT
+echo -n 'Subject: [PATCH] ' >>$tmpname
+cat >>$tmpname
+if ! [ $(tail -c 1 $tmpname | od -A n -t x1) == '0a' ]; then
+    echo >>$tmpname
+fi
+echo '---' >>$tmpname
+%s $tmpname $GIT_COMMIT %s
+tail -c +18 $tmpname | head -c -4
+''' % (hook, name))
+                            hookwrapper.flush()
+                            filter_branch.extend(['--msg-filter', 'bash %s' % hookwrapper.name])
+                        if dest_dir != ".":
+                            parent = os.path.dirname(dest_dir)
+                            if not parent:
+                                parent = '.'
+                            # May run outside of the current directory, so do not assume that .git exists.
+                            filter_branch.extend(['--tree-filter', 'mkdir -p .git/tmptree && mv $(ls -1 -a | grep -v -e ^.git$ -e ^.$ -e ^..$) .git/tmptree && mkdir -p %s && mv .git/tmptree %s' % (parent, dest_dir)])
+                        filter_branch.append('HEAD')
+                        runcmd(filter_branch)
+                        runcmd('git update-ref -d refs/original/refs/heads/%s' % name)
+                repo['rewritten_revision'] = runcmd('git rev-parse HEAD').strip()
+                repo['stripped_revision'] = repo['rewritten_revision']
+                # Optional filter files: remove everything and re-populate using the normal filtering code.
+                # Override any potential .gitignore.
+                if file_filter or exclude_patterns:
+                    runcmd('git rm -rf .')
+                    if not os.path.exists(extract_dir):
+                        os.makedirs(extract_dir)
+                    copy_selected_files('HEAD', extract_dir, file_filter, exclude_patterns, '.',
+                                        subdir=dest_dir)
+                    runcmd('git add --all --force .')
+                    if runcmd('git status --porcelain'):
+                        # Something to commit.
+                        runcmd(['git', 'commit', '-m',
+                                '''%s: select file subset
+
+Files from the component repository were chosen based on
+the following filters:
+file_filter = %s
+file_exclude = %s''' % (name, file_filter or '<empty>', repo.get('file_exclude', '<empty>'))])
+                        repo['stripped_revision'] = runcmd('git rev-parse HEAD').strip()
+
+            if not lastrev:
+                lastrev = runcmd('git rev-parse %s' % initialrev, ldir).strip()
+                conf.update(name, "last_revision", lastrev, initmode=True)
+
+        if not conf.history:
+            runcmd("git add .")
+        else:
+            # Create Octopus merge commit according to http://stackoverflow.com/questions/10874149/git-octopus-merge-with-unrelated-repositoies
+            runcmd('git checkout master')
+            merge = ['git', 'merge', '--no-commit']
+            for name in conf.repos:
+                repo = conf.repos[name]
+                # Use branch created earlier.
+                merge.append(name)
+                # Root all commits which have no parent in the common
+                # ancestor in the new repository.
+                for start in runcmd('git log --pretty=format:%%H --max-parents=0 %s' % name).split('\n'):
+                    runcmd('git replace --graft %s %s' % (start, startrev))
+            try:
+                runcmd(merge)
+            except Exception, error:
+                logger.info('''Merging component repository history failed, perhaps because of merge conflicts.
+It may be possible to commit anyway after resolving these conflicts.
+
+%s''' % error)
+            # Create MERGE_HEAD and MERGE_MSG. "git merge" itself
+            # does not create MERGE_HEAD in case of a (harmless) failure,
+            # and we want certain auto-generated information in the
+            # commit message for future reference and/or automation.
+            with open('.git/MERGE_HEAD', 'w') as head:
+                with open('.git/MERGE_MSG', 'w') as msg:
+                    msg.write('repo: initial import of components\n\n')
+                    # head.write('%s\n' % startrev)
+                    for name in conf.repos:
+                        repo = conf.repos[name]
+                        # <upstream ref> <rewritten ref> <rewritten + files removed>
+                        msg.write('combo-layer-%s: %s %s %s\n' % (name,
+                                                                  repo['last_revision'],
+                                                                  repo['rewritten_revision'],
+                                                                  repo['stripped_revision']))
+                        rev = runcmd('git rev-parse %s' % name).strip()
+                        head.write('%s\n' % rev)
+
+        if conf.localconffile:
+            localadded = True
+            try:
+                runcmd("git rm --cached %s" % conf.localconffile, printerr=False)
+            except subprocess.CalledProcessError:
+                localadded = False
+            if localadded:
+                localrelpath = os.path.relpath(conf.localconffile)
+                runcmd("grep -q %s .gitignore || echo %s >> .gitignore" % (localrelpath, localrelpath))
+                runcmd("git add .gitignore")
+                logger.info("Added local configuration file %s to .gitignore", localrelpath)
+        logger.info("Initial combo layer repository data has been created; please make any changes if desired and then use 'git commit' to make the initial commit.")
+    else:
+        logger.info("Repository already initialised, nothing to do.")
+
+
+def check_repo_clean(repodir):
+    """
+        check if the repo is clean
+        exit if repo is dirty
+    """
+    output=runcmd("git status --porcelain", repodir)
+    r = re.compile('\?\? patch-.*/')
+    dirtyout = [item for item in output.splitlines() if not r.match(item)]
+    if dirtyout:
+        logger.error("git repo %s is dirty, please fix it first", repodir)
+        sys.exit(1)
+
+def check_patch(patchfile):
+    f = open(patchfile)
+    ln = f.readline()
+    of = None
+    in_patch = False
+    beyond_msg = False
+    pre_buf = ''
+    while ln:
+        if not beyond_msg:
+            if ln == '---\n':
+                if not of:
+                    break
+                in_patch = False
+                beyond_msg = True
+            elif ln.startswith('--- '):
+                # We have a diff in the commit message
+                in_patch = True
+                if not of:
+                    print('WARNING: %s contains a diff in its commit message, indenting to avoid failure during apply' % patchfile)
+                    of = open(patchfile + '.tmp', 'w')
+                    of.write(pre_buf)
+                    pre_buf = ''
+            elif in_patch and not ln[0] in '+-@ \n\r':
+                in_patch = False
+        if of:
+            if in_patch:
+                of.write(' ' + ln)
+            else:
+                of.write(ln)
+        else:
+            pre_buf += ln
+        ln = f.readline()
+    f.close()
+    if of:
+        of.close()
+        os.rename(patchfile + '.tmp', patchfile)
+
+def drop_to_shell(workdir=None):
+    if not sys.stdin.isatty():
+        print "Not a TTY so can't drop to shell for resolution, exiting."
+        return False
+
+    shell = os.environ.get('SHELL', 'bash')
+    print('Dropping to shell "%s"\n' \
+          'When you are finished, run the following to continue:\n' \
+          '       exit    -- continue to apply the patches\n' \
+          '       exit 1  -- abort\n' % shell);
+    ret = subprocess.call([shell], cwd=workdir)
+    if ret != 0:
+        print "Aborting"
+        return False
+    else:
+        return True
+
+def check_rev_branch(component, repodir, rev, branch):
+    try:
+        actualbranch = runcmd("git branch --contains %s" % rev, repodir, printerr=False)
+    except subprocess.CalledProcessError as e:
+        if e.returncode == 129:
+            actualbranch = ""
+        else:
+            raise
+
+    if not actualbranch:
+        logger.error("%s: specified revision %s is invalid!" % (component, rev))
+        return False
+
+    branches = []
+    branchlist = actualbranch.split("\n")
+    for b in branchlist:
+        branches.append(b.strip().split(' ')[-1])
+
+    if branch not in branches:
+        logger.error("%s: specified revision %s is not on specified branch %s!" % (component, rev, branch))
+        return False
+    return True
+
+def get_repos(conf, repo_names):
+    repos = []
+    for name in repo_names:
+        if name.startswith('-'):
+            break
+        else:
+            repos.append(name)
+    for repo in repos:
+        if not repo in conf.repos:
+            logger.error("Specified component '%s' not found in configuration" % repo)
+            sys.exit(1)
+
+    if not repos:
+        repos = conf.repos
+
+    return repos
+
+def action_pull(conf, args):
+    """
+        update the component repos only
+    """
+    repos = get_repos(conf, args[1:])
+
+    # make sure all repos are clean
+    for name in repos:
+        check_repo_clean(conf.repos[name]['local_repo_dir'])
+
+    for name in repos:
+        repo = conf.repos[name]
+        ldir = repo['local_repo_dir']
+        branch = repo.get('branch', "master")
+        logger.info("update branch %s of component repo %s in %s ..." % (branch, name, ldir))
+        if not conf.hard_reset:
+            # Try to pull only the configured branch. Beware that this may fail
+            # when the branch is currently unknown (for example, after reconfiguring
+            # combo-layer). In that case we need to fetch everything and try the check out
+            # and pull again.
+            try:
+                runcmd("git checkout %s" % branch, ldir, printerr=False)
+            except subprocess.CalledProcessError:
+                output=runcmd("git fetch", ldir)
+                logger.info(output)
+                runcmd("git checkout %s" % branch, ldir)
+                runcmd("git pull --ff-only", ldir)
+            else:
+                output=runcmd("git pull --ff-only", ldir)
+                logger.info(output)
+        else:
+            output=runcmd("git fetch", ldir)
+            logger.info(output)
+            runcmd("git checkout %s" % branch, ldir)
+            runcmd("git reset --hard FETCH_HEAD", ldir)
+
+def action_update(conf, args):
+    """
+        update the component repos
+        generate the patch list
+        apply the generated patches
+    """
+    components = [arg.split(':')[0] for arg in args[1:]]
+    revisions = {}
+    for arg in args[1:]:
+        if ':' in arg:
+            a = arg.split(':', 1)
+            revisions[a[0]] = a[1]
+    repos = get_repos(conf, components)
+
+    # make sure combo repo is clean
+    check_repo_clean(os.getcwd())
+
+    import uuid
+    patch_dir = "patch-%s" % uuid.uuid4()
+    if not os.path.exists(patch_dir):
+        os.mkdir(patch_dir)
+
+    # Step 1: update the component repos
+    if conf.nopull:
+        logger.info("Skipping pull (-n)")
+    else:
+        action_pull(conf, ['arg0'] + components)
+
+    for name in repos:
+        revision = revisions.get(name, None)
+        repo = conf.repos[name]
+        ldir = repo['local_repo_dir']
+        dest_dir = repo['dest_dir']
+        branch = repo.get('branch', "master")
+        repo_patch_dir = os.path.join(os.getcwd(), patch_dir, name)
+
+        # Step 2: generate the patch list and store to patch dir
+        logger.info("Generating patches from %s..." % name)
+        top_revision = revision or branch
+        if not check_rev_branch(name, ldir, top_revision, branch):
+            sys.exit(1)
+        if dest_dir != ".":
+            prefix = "--src-prefix=a/%s/ --dst-prefix=b/%s/" % (dest_dir, dest_dir)
+        else:
+            prefix = ""
+        if repo['last_revision'] == "":
+            logger.info("Warning: last_revision of component %s is not set, starting from the first commit" % name)
+            patch_cmd_range = "--root %s" % top_revision
+            rev_cmd_range = top_revision
+        else:
+            if not check_rev_branch(name, ldir, repo['last_revision'], branch):
+                sys.exit(1)
+            patch_cmd_range = "%s..%s" % (repo['last_revision'], top_revision)
+            rev_cmd_range = patch_cmd_range
+
+        file_filter = repo.get('file_filter',"")
+
+        patch_cmd = "git format-patch -N %s --output-directory %s %s -- %s" % \
+            (prefix,repo_patch_dir, patch_cmd_range, file_filter)
+        output = runcmd(patch_cmd, ldir)
+        logger.debug("generated patch set:\n%s" % output)
+        patchlist = output.splitlines()
+
+        rev_cmd = "git rev-list --no-merges %s -- %s" % (rev_cmd_range, file_filter)
+        revlist = runcmd(rev_cmd, ldir).splitlines()
+
+        # Step 3: Call repo specific hook to adjust patch
+        if 'hook' in repo:
+            # hook parameter is: ./hook patchpath revision reponame
+            count=len(revlist)-1
+            for patch in patchlist:
+                runcmd("%s %s %s %s" % (repo['hook'], patch, revlist[count], name))
+                count=count-1
+
+        # Step 3a: Filter out unwanted files and patches.
+        exclude = repo.get('file_exclude', '')
+        if exclude:
+            filter = ['filterdiff', '-p1']
+            for path in exclude.split():
+                filter.append('-x')
+                filter.append('%s/%s' % (dest_dir, path) if dest_dir != '.' else path)
+            for patch in patchlist[:]:
+                filtered = patch + '.tmp'
+                with open(filtered, 'w') as f:
+                    runcmd(filter + [patch], out=f)
+                # Now check for empty patches.
+                if runcmd(['filterdiff', '--list', filtered]):
+                    # Possibly modified.
+                    os.unlink(patch)
+                    os.rename(filtered, patch)
+                else:
+                    # Empty, ignore it. Must also remove from revlist.
+                    with open(patch, 'r') as f:
+                        fromline = f.readline()
+                    if not fromline:
+                        # Patch must have been empty to start with. No need
+                        # to remove it.
+                        continue
+                    m = re.match(r'''^From ([0-9a-fA-F]+) .*\n''', fromline)
+                    rev = m.group(1)
+                    logger.debug('skipping empty patch %s = %s' % (patch, rev))
+                    os.unlink(patch)
+                    os.unlink(filtered)
+                    patchlist.remove(patch)
+                    revlist.remove(rev)
+
+        # Step 4: write patch list and revision list to file, for user to edit later
+        patchlist_file = os.path.join(os.getcwd(), patch_dir, "patchlist-%s" % name)
+        repo['patchlist'] = patchlist_file
+        f = open(patchlist_file, 'w')
+        count=len(revlist)-1
+        for patch in patchlist:
+            f.write("%s %s\n" % (patch, revlist[count]))
+            check_patch(os.path.join(patch_dir, patch))
+            count=count-1
+        f.close()
+
+    # Step 5: invoke bash for user to edit patch and patch list
+    if conf.interactive:
+        print('You may now edit the patch and patch list in %s\n' \
+              'For example, you can remove unwanted patch entries from patchlist-*, so that they will be not applied later' % patch_dir);
+        if not drop_to_shell(patch_dir):
+            sys.exit(1)
+
+    # Step 6: apply the generated and revised patch
+    apply_patchlist(conf, repos)
+    runcmd("rm -rf %s" % patch_dir)
+
+    # Step 7: commit the updated config file if it's being tracked
+    relpath = os.path.relpath(conf.conffile)
+    try:
+        output = runcmd("git status --porcelain %s" % relpath, printerr=False)
+    except:
+        # Outside the repository
+        output = None
+    if output:
+        logger.info("Committing updated configuration file")
+        if output.lstrip().startswith("M"):
+
+            # create the "components" string
+            component_str = "all components"
+            if len(components) > 0:
+                # otherwise tell which components were actually changed
+                component_str = ", ".join(components)
+
+            # expand the template with known values
+            template = Template(conf.commit_msg_template)
+            raw_msg = template.substitute(components = component_str)
+
+            # sanitize the string before using it in command line
+            msg = raw_msg.replace('"', '\\"')
+
+            runcmd('git commit -m "%s" %s' % (msg, relpath))
+
+def apply_patchlist(conf, repos):
+    """
+        apply the generated patch list to combo repo
+    """
+    for name in repos:
+        repo = conf.repos[name]
+        lastrev = repo["last_revision"]
+        prevrev = lastrev
+
+        # Get non-blank lines from patch list file
+        patchlist = []
+        if os.path.exists(repo['patchlist']) or not conf.interactive:
+            # Note: we want this to fail here if the file doesn't exist and we're not in
+            # interactive mode since the file should exist in this case
+            with open(repo['patchlist']) as f:
+                for line in f:
+                    line = line.rstrip()
+                    if line:
+                        patchlist.append(line)
+
+        ldir = conf.repos[name]['local_repo_dir']
+        branch = conf.repos[name].get('branch', "master")
+        branchrev = runcmd("git rev-parse %s" % branch, ldir).strip()
+
+        if patchlist:
+            logger.info("Applying patches from %s..." % name)
+            linecount = len(patchlist)
+            i = 1
+            for line in patchlist:
+                patchfile = line.split()[0]
+                lastrev = line.split()[1]
+                patchdisp = os.path.relpath(patchfile)
+                if os.path.getsize(patchfile) == 0:
+                    logger.info("(skipping %d/%d %s - no changes)" % (i, linecount, patchdisp))
+                else:
+                    cmd = "git am --keep-cr %s-p1 %s" % ('-s ' if repo.get('signoff', True) else '', patchfile)
+                    logger.info("Applying %d/%d: %s" % (i, linecount, patchdisp))
+                    try:
+                        runcmd(cmd)
+                    except subprocess.CalledProcessError:
+                        logger.info('Running "git am --abort" to cleanup repo')
+                        runcmd("git am --abort")
+                        logger.error('"%s" failed' % cmd)
+                        logger.info("Please manually apply patch %s" % patchdisp)
+                        logger.info("Note: if you exit and continue applying without manually applying the patch, it will be skipped")
+                        if not drop_to_shell():
+                            if prevrev != repo['last_revision']:
+                                conf.update(name, "last_revision", prevrev)
+                            sys.exit(1)
+                prevrev = lastrev
+                i += 1
+            # Once all patches are applied, we should update
+            # last_revision to the branch head instead of the last
+            # applied patch. The two are not necessarily the same when
+            # the last commit is a merge commit or when the patches at
+            # the branch head were intentionally excluded.
+            #
+            # If we do not do that for a merge commit, the next
+            # combo-layer run will only exclude patches reachable from
+            # one of the merged branches and try to re-apply patches
+            # from other branches even though they were already
+            # copied.
+            #
+            # If patches were intentionally excluded, the next run will
+            # present them again instead of skipping over them. This
+            # may or may not be intended, so the code here is conservative
+            # and only addresses the "head is merge commit" case.
+            if lastrev != branchrev and \
+               len(runcmd("git show --pretty=format:%%P --no-patch %s" % branch, ldir).split()) > 1:
+                lastrev = branchrev
+        else:
+            logger.info("No patches to apply from %s" % name)
+            lastrev = branchrev
+
+        if lastrev != repo['last_revision']:
+            conf.update(name, "last_revision", lastrev)
+
+def action_splitpatch(conf, args):
+    """
+        generate the commit patch and
+        split the patch per repo
+    """
+    logger.debug("action_splitpatch")
+    if len(args) > 1:
+        commit = args[1]
+    else:
+        commit = "HEAD"
+    patchdir = "splitpatch-%s" % commit
+    if not os.path.exists(patchdir):
+        os.mkdir(patchdir)
+
+    # filerange_root is for the repo whose dest_dir is root "."
+    # and it should be specified by excluding all other repo dest dir
+    # like "-x repo1 -x repo2 -x repo3 ..."
+    filerange_root = ""
+    for name in conf.repos:
+        dest_dir = conf.repos[name]['dest_dir']
+        if dest_dir != ".":
+            filerange_root = '%s -x "%s/*"' % (filerange_root, dest_dir)
+
+    for name in conf.repos:
+        dest_dir = conf.repos[name]['dest_dir']
+        patch_filename = "%s/%s.patch" % (patchdir, name)
+        if dest_dir == ".":
+            cmd = "git format-patch -n1 --stdout %s^..%s | filterdiff -p1 %s > %s" % (commit, commit, filerange_root, patch_filename)
+        else:
+            cmd = "git format-patch --no-prefix -n1 --stdout %s^..%s -- %s > %s" % (commit, commit, dest_dir, patch_filename)
+        runcmd(cmd)
+        # Detect empty patches (including those produced by filterdiff above
+        # that contain only preamble text)
+        if os.path.getsize(patch_filename) == 0 or runcmd("filterdiff %s" % patch_filename) == "":
+            os.remove(patch_filename)
+            logger.info("(skipping %s - no changes)", name)
+        else:
+            logger.info(patch_filename)
+
+def action_error(conf, args):
+    logger.info("invalid action %s" % args[0])
+
+actions = {
+    "init": action_init,
+    "update": action_update,
+    "pull": action_pull,
+    "splitpatch": action_splitpatch,
+}
+
+def main():
+    parser = optparse.OptionParser(
+        version = "Combo Layer Repo Tool version %s" % __version__,
+        usage = """%prog [options] action
+
+Create and update a combination layer repository from multiple component repositories.
+
+Action:
+  init                 initialise the combo layer repo
+  update [components]  get patches from component repos and apply them to the combo repo
+  pull [components]    just pull component repos only
+  splitpatch [commit]  generate commit patch and split per component, default commit is HEAD""")
+
+    parser.add_option("-c", "--conf", help = "specify the config file (conf/combo-layer.conf is the default).",
+               action = "store", dest = "conffile", default = "conf/combo-layer.conf")
+
+    parser.add_option("-i", "--interactive", help = "interactive mode, user can edit the patch list and patches",
+               action = "store_true", dest = "interactive", default = False)
+
+    parser.add_option("-D", "--debug", help = "output debug information",
+               action = "store_true", dest = "debug", default = False)
+
+    parser.add_option("-n", "--no-pull", help = "skip pulling component repos during update",
+               action = "store_true", dest = "nopull", default = False)
+
+    parser.add_option("--hard-reset",
+               help = "instead of pull do fetch and hard-reset in component repos",
+               action = "store_true", dest = "hard_reset", default = False)
+
+    parser.add_option("-H", "--history", help = "import full history of components during init",
+                      action = "store_true", default = False)
+
+    options, args = parser.parse_args(sys.argv)
+
+    # Dispatch to action handler
+    if len(args) == 1:
+        logger.error("No action specified, exiting")
+        parser.print_help()
+    elif args[1] not in actions:
+        logger.error("Unsupported action %s, exiting\n" % (args[1]))
+        parser.print_help()
+    elif not os.path.exists(options.conffile):
+        logger.error("No valid config file, exiting\n")
+        parser.print_help()
+    else:
+        if options.debug:
+            logger.setLevel(logging.DEBUG)
+        confdata = Configuration(options)
+        initmode = (args[1] == 'init')
+        confdata.sanity_check(initmode)
+        actions.get(args[1], action_error)(confdata, args[1:])
+
+if __name__ == "__main__":
+    try:
+        ret = main()
+    except Exception:
+        ret = 1
+        import traceback
+        traceback.print_exc(5)
+    sys.exit(ret)
diff --git a/scripts/combo-layer-hook-default.sh b/scripts/combo-layer-hook-default.sh
new file mode 100755
index 0000000..1e3a3b9
--- /dev/null
+++ b/scripts/combo-layer-hook-default.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+# Hook to add source component/revision info to commit message
+# Parameter:
+#   $1 patch-file
+#   $2 revision
+#   $3 reponame
+
+patchfile=$1
+rev=$2
+reponame=$3
+
+sed -i -e "0,/^Subject:/s#^Subject: \[PATCH\] \($reponame: \)*\(.*\)#Subject: \[PATCH\] $reponame: \2#" $patchfile
+if grep -q '^Signed-off-by:' $patchfile; then
+    # Insert before Signed-off-by.
+    sed -i -e "0,/^Signed-off-by:/s#\(^Signed-off-by:.*\)#\(From $reponame rev: $rev\)\n\n\1#" $patchfile
+else
+    # Insert before final --- separator, with extra blank lines removed.
+    perl -e "\$_ = join('', <>); s/^(.*\S[ \t]*)(\n|\n\s*\n)---\n/\$1\n\nFrom $reponame rev: $rev\n---\n/s; print;" $patchfile >$patchfile.tmp
+    mv $patchfile.tmp $patchfile
+fi
diff --git a/scripts/combo-layer.conf.example b/scripts/combo-layer.conf.example
new file mode 100644
index 0000000..90e2b58
--- /dev/null
+++ b/scripts/combo-layer.conf.example
@@ -0,0 +1,93 @@
+# combo-layer example configuration file
+
+# Default values for all sections.
+[DEFAULT]
+
+# Add 'Signed-off-by' to all commits that get imported automatically.
+signoff = True
+
+# component name
+[bitbake]
+
+# Override signedoff default above (not very useful, but possible).
+signoff = False
+
+# mandatory options
+# git upstream uri
+src_uri = git://git.openembedded.org/bitbake
+
+# the directory to clone the component repo
+local_repo_dir = /home/kyu3/src/test/bitbake
+
+# the relative dir within the combo repo to put the component files
+# use "." if the files should be in the root dir
+dest_dir = bitbake
+
+# the last update revision.
+# "init" will set this to the latest revision automatically, however if it
+# is empty when "update" is run, the tool will start from the first commit.
+# Note that this value will get updated by "update" if the component repo's
+# latest revision changed and the operation completes successfully.
+last_revision =
+
+# optional options:
+
+# branch: specify the branch in the component repo to pull from
+# (master if not specified)
+
+# file_filter: only include the specified file(s)
+# file_filter = [path] [path] ...
+# example:
+#   file_filter = src/  : only include the subdir src
+#   file_filter = src/*.c : only include the src *.c file
+#   file_filter = src/main.c src/Makefile.am : only include these two files
+
+# file_exclude: filter out these file(s)
+# file_exclude = [path] [path] ...
+#
+# Each entry must match a file name. In contrast do file_filter, matching
+# a directory has no effect. To achieve that, use append a * wildcard
+# at the end.
+#
+# Wildcards are applied to the complete path and also match slashes.
+#
+# example:
+#   file_exclude = src/foobar/*  : exclude everything under src/foobar
+#   file_exclude = src/main.c : filter out main.c after including it with file_filter = src/*.c
+#   file_exclude = *~ : exclude backup files
+
+# hook: if provided, the tool will call the hook to process the generated
+#     patch from upstream, and then apply the modified patch to the combo
+#     repo.
+# the hook script is called as follows: ./hook patchpath revision reponame
+# example:
+#     hook = combo-layer-hook-default.sh
+
+# since_revision:
+#   since_revision = release-1-2
+#   since_revision = 12345 abcdf
+#
+# If provided, truncate imported history during "combo-layer --history
+# init" at the specified revision(s).  More than one can be specified
+# to cut off multiple component branches.
+#
+# The specified commits themselves do not get imported. Instead, an
+# artificial commit with "unknown" author is created with a content
+# that matches the original commit.
+
+[oe-core]
+src_uri = git://git.openembedded.org/openembedded-core
+local_repo_dir = /home/kyu3/src/test/oecore
+dest_dir = .
+last_revision =
+since_revision = some-tag-or-commit-on-master-branch
+
+# It is also possible to embed python code in the config values. Similar
+# to bitbake it considers every value starting with @ to be a python
+# script.
+# e.g. local_repo_dir could easily be configured using an environment
+# variable:
+#
+# [bitbake]
+# local_repo_dir = @os.getenv("LOCAL_REPO_DIR") + "/bitbake"
+#
diff --git a/scripts/contrib/bb-perf/bb-matrix-plot.sh b/scripts/contrib/bb-perf/bb-matrix-plot.sh
new file mode 100755
index 0000000..136a255
--- /dev/null
+++ b/scripts/contrib/bb-perf/bb-matrix-plot.sh
@@ -0,0 +1,137 @@
+#!/bin/bash
+#
+# Copyright (c) 2011, Intel Corporation.
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# DESCRIPTION
+# This script operates on the .dat file generated by bb-matrix.sh. It tolerates
+# the header by skipping the first line, but error messages and bad data records
+# need to be removed first. It will generate three views of the plot, and leave
+# an interactive view open for further analysis.
+#
+# AUTHORS
+# Darren Hart <dvhart@linux.intel.com>
+#
+
+# Setup the defaults
+DATFILE="bb-matrix.dat"
+XLABEL="BB_NUMBER_THREADS"
+YLABEL="PARALLEL_MAKE"
+FIELD=3
+DEF_TITLE="Elapsed Time (seconds)"
+PM3D_FRAGMENT="unset surface; set pm3d at s hidden3d 100"
+SIZE="640,480"
+
+function usage {
+CMD=$(basename $0)
+cat <<EOM
+Usage: $CMD [-d datfile] [-f field] [-h] [-t title] [-w]
+  -d datfile    The data file generated by bb-matrix.sh (default: $DATFILE)
+  -f field      The field index to plot as the Z axis from the data file
+                (default: $FIELD, "$DEF_TITLE")
+  -h            Display this help message
+  -s W,H        PNG and window size in pixels (default: $SIZE)
+  -t title      The title to display, should describe the field (-f) and units
+                (default: "$DEF_TITLE")
+  -w            Render the plot as wireframe with a 2D colormap projected on the
+                XY plane rather than as the texture for the surface
+EOM
+}
+
+# Parse and validate arguments
+while getopts "d:f:hs:t:w" OPT; do
+	case $OPT in
+	d)
+		DATFILE="$OPTARG"
+		;;
+	f)
+		FIELD="$OPTARG"
+		;;
+	h)
+		usage
+		exit 0
+		;;
+	s)
+		SIZE="$OPTARG"
+		;;
+	t)
+		TITLE="$OPTARG"
+		;;
+	w)
+		PM3D_FRAGMENT="set pm3d at b"
+		W="-w"
+		;;
+	*)
+		usage
+		exit 1
+		;;
+	esac
+done
+
+# Ensure the data file exists
+if [ ! -f "$DATFILE" ]; then
+	echo "ERROR: $DATFILE does not exist"
+	usage
+	exit 1
+fi
+PLOT_BASENAME=${DATFILE%.*}-f$FIELD$W
+
+# Set a sane title
+# TODO: parse the header and define titles for each format parameter for TIME(1)
+if [ -z "$TITLE" ]; then
+	if [ ! "$FIELD" == "3" ]; then
+		TITLE="Field $FIELD"
+	else
+		TITLE="$DEF_TITLE"
+	fi
+fi
+
+# Determine the dgrid3d mesh dimensions size
+MIN=$(tail -n +2 "$DATFILE" | cut -d ' ' -f 1 | sed 's/^0*//' | sort -n | uniq | head -n1)
+MAX=$(tail -n +2 "$DATFILE" | cut -d ' ' -f 1 | sed 's/^0*//' | sort -n | uniq | tail -n1)
+BB_CNT=$[${MAX} - $MIN + 1]
+MIN=$(tail -n +2 "$DATFILE" | cut -d ' ' -f 2 | sed 's/^0*//' | sort -n | uniq | head -n1)
+MAX=$(tail -n +2 "$DATFILE" | cut -d ' ' -f 2 | sed 's/^0*//' | sort -n | uniq | tail -n1)
+PM_CNT=$[${MAX} - $MIN + 1]
+
+
+(cat <<EOF
+set title "$TITLE"
+set xlabel "$XLABEL"
+set ylabel "$YLABEL"
+set style line 100 lt 5 lw 1.5
+$PM3D_FRAGMENT
+set dgrid3d $PM_CNT,$BB_CNT splines
+set ticslevel 0.2
+
+set term png size $SIZE
+set output "$PLOT_BASENAME.png"
+splot "$DATFILE" every ::1 using 1:2:$FIELD with lines ls 100
+
+set view 90,0
+set output "$PLOT_BASENAME-bb.png"
+replot
+
+set view 90,90
+set output "$PLOT_BASENAME-pm.png"
+replot
+
+set view 60,30
+set term wxt size $SIZE
+replot
+EOF
+) | gnuplot --persist
diff --git a/scripts/contrib/bb-perf/bb-matrix.sh b/scripts/contrib/bb-perf/bb-matrix.sh
new file mode 100755
index 0000000..1064565
--- /dev/null
+++ b/scripts/contrib/bb-perf/bb-matrix.sh
@@ -0,0 +1,79 @@
+#!/bin/bash
+#
+# Copyright (c) 2011, Intel Corporation.
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# DESCRIPTION
+# This script runs BB_CMD (typically building core-image-sato) for all
+# combincations of BB_RANGE and PM_RANGE values. It saves off all the console
+# logs, the buildstats directories, and creates a bb-pm-runtime.dat file which
+# can be used to postprocess the results with a plotting tool, spreadsheet, etc.
+# Before running this script, it is recommended that you pre-download all the
+# necessary sources by performing the BB_CMD once manually. It is also a good
+# idea to disable cron to avoid runtime variations caused by things like the
+# locate process. Be sure to sanitize the dat file prior to post-processing as
+# it may contain error messages or bad runs that should be removed.
+#
+# AUTHORS
+# Darren Hart <dvhart@linux.intel.com>
+#
+
+# The following ranges are appropriate for a 4 core system with 8 logical units
+# Use leading 0s to ensure all digits are the same string length, this results
+# in nice log file names and columnar dat files.
+BB_RANGE="04 05 06 07 08 09 10 11 12 13 14 15 16"
+PM_RANGE="04 05 06 07 08 09 10 11 12 13 14 15 16"
+
+DATADIR="bb-matrix-$$"
+BB_CMD="bitbake core-image-minimal"
+RUNTIME_LOG="$DATADIR/bb-matrix.dat"
+
+# See TIME(1) for a description of the time format parameters
+# The following all report 0: W K r s t w
+TIME_STR="%e %S %U %P %c %w %R %F %M %x"
+
+# Prepare the DATADIR
+mkdir $DATADIR
+if [ $? -ne 0 ]; then
+	echo "Failed to create $DATADIR."
+	exit 1
+fi
+
+# Add a simple header
+echo "BB PM $TIME_STR" > $RUNTIME_LOG
+for BB in $BB_RANGE; do
+	for PM in $PM_RANGE; do
+		RUNDIR="$DATADIR/$BB-$PM-build"
+		mkdir $RUNDIR
+		BB_LOG=$RUNDIR/$BB-$PM-bitbake.log
+		date
+		echo "BB=$BB PM=$PM Logging to $BB_LOG"
+
+		echo -n "  Preparing the work directory... "
+		rm -rf pseudodone tmp sstate-cache tmp-eglibc &> /dev/null
+		echo "done"
+
+		# Export the variables under test and run the bitbake command
+		# Strip any leading zeroes before passing to bitbake
+		export BB_NUMBER_THREADS=$(echo $BB | sed 's/^0*//')
+		export PARALLEL_MAKE="-j $(echo $PM | sed 's/^0*//')"
+		/usr/bin/time -f "$BB $PM $TIME_STR" -a -o $RUNTIME_LOG $BB_CMD &> $BB_LOG
+
+		echo "  $(tail -n1 $RUNTIME_LOG)"
+		cp -a tmp/buildstats $RUNDIR/$BB-$PM-buildstats
+	done
+done
diff --git a/scripts/contrib/bb-perf/buildstats.sh b/scripts/contrib/bb-perf/buildstats.sh
new file mode 100755
index 0000000..96158a9
--- /dev/null
+++ b/scripts/contrib/bb-perf/buildstats.sh
@@ -0,0 +1,90 @@
+#!/bin/bash
+#
+# Copyright (c) 2011, Intel Corporation.
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# DESCRIPTION
+# Given a 'buildstats' path (created by bitbake when setting
+# USER_CLASSES ?= "buildstats" on local.conf) and task names, outputs
+# '<task> <recipe> <elapsed time>' for all recipes. Elapsed times are in
+# seconds, and task should be given without the 'do_' prefix.
+#
+# Some useful pipelines
+#
+# 1. Tasks with largest elapsed times
+# $ buildstats.sh -b <buildstats> | sort -k3 -n -r | head
+#
+# 2. Min, max, sum per task (in needs GNU datamash)
+# $ buildstats.sh -b <buildstats> | datamash -t' ' -g1 min 3 max 3 sum 3 | sort -k4 -n -r
+#
+# AUTHORS
+# Leonardo Sandoval <leonardo.sandoval.gonzalez@linux.intel.com>
+#
+BS_DIR="tmp/buildstats"
+TASKS="compile:configure:fetch:install:patch:populate_lic:populate_sysroot:unpack"
+
+function usage {
+CMD=$(basename $0)
+cat <<EOM
+Usage: $CMD [-b buildstats_dir] [-t do_task]
+  -b buildstats The path where the folder resides
+                (default: "$BS_DIR")
+  -t tasks      The tasks to be computed
+                (default: "$TASKS")
+  -h            Display this help message
+EOM
+}
+
+# Parse and validate arguments
+while getopts "b:t:h" OPT; do
+	case $OPT in
+	b)
+		BS_DIR="$OPTARG"
+		;;
+	t)
+		TASKS="$OPTARG"
+		;;
+	h)
+		usage
+		exit 0
+		;;
+	*)
+		usage
+		exit 1
+		;;
+	esac
+done
+
+# Ensure the buildstats folder exists
+if [ ! -d "$BS_DIR" ]; then
+	echo "ERROR: $BS_DIR does not exist"
+	usage
+	exit 1
+fi
+
+RECIPE_FIELD=1
+TIME_FIELD=4
+
+tasks=(${TASKS//:/ })
+for task in "${tasks[@]}"; do
+    task="do_${task}"
+    for file in $(find ${BS_DIR} -type f -name ${task}); do
+        recipe=$(sed -n -e "/$task/p" ${file} | cut -d ':' -f${RECIPE_FIELD})
+        time=$(sed -n -e "/$task/p" ${file} | cut -d ':' -f${TIME_FIELD} | cut -d ' ' -f2)
+        echo "${task} ${recipe} ${time}"
+    done
+done
diff --git a/scripts/contrib/bbvars.py b/scripts/contrib/bbvars.py
new file mode 100755
index 0000000..0896d64
--- /dev/null
+++ b/scripts/contrib/bbvars.py
@@ -0,0 +1,186 @@
+#!/usr/bin/env python
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Copyright (C) Darren Hart <dvhart@linux.intel.com>, 2010
+
+
+import sys
+import getopt
+import os
+import os.path
+import re
+
+def usage():
+    print 'Usage: %s -d FILENAME [-d FILENAME]* -m METADIR [-m MATADIR]*' % os.path.basename(sys.argv[0])
+    print '  -d FILENAME         documentation file to search'
+    print '  -h, --help          display this help and exit'
+    print '  -m METADIR          meta directory to search for recipes'
+    print '  -t FILENAME         documentation config file (for doc tags)'
+    print '  -T                  Only display variables with doc tags (requires -t)'
+
+def recipe_bbvars(recipe):
+    ''' Return a unique set of every bbvar encountered in the recipe '''
+    prog = re.compile("[A-Z_]+")
+    vset = set()
+    try:
+        r = open(recipe)
+    except IOError as (errno, strerror):
+        print 'WARNING: Failed to open recipe ', recipe
+        print strerror
+
+    for line in r:
+        # Strip any comments from the line
+        line = line.rsplit('#')[0]
+        vset = vset.union(set(prog.findall(line)))
+    r.close()
+
+    bbvars = {}
+    for v in vset:
+        bbvars[v] = 1
+
+    return bbvars
+
+def collect_bbvars(metadir):
+    ''' Walk the metadir and collect the bbvars from each recipe found '''
+    bbvars = {}
+    for root,dirs,files in os.walk(metadir):
+        for name in files:
+            if name.find(".bb") >= 0:
+                for key in recipe_bbvars(os.path.join(root,name)).iterkeys():
+                    if bbvars.has_key(key):
+                        bbvars[key] = bbvars[key] + 1
+                    else:
+                        bbvars[key] = 1
+    return bbvars
+
+def bbvar_is_documented(var, docfiles):
+    prog = re.compile(".*($|[^A-Z_])%s([^A-Z_]|$)" % (var))
+    for doc in docfiles:
+        try:
+            f = open(doc)
+        except IOError as (errno, strerror):
+            print 'WARNING: Failed to open doc ', doc
+            print strerror
+        for line in f:
+            if prog.match(line):
+                return True
+        f.close()
+    return False
+
+def bbvar_doctag(var, docconf):
+    prog = re.compile('^%s\[doc\] *= *"(.*)"' % (var))
+    if docconf == "":
+        return "?"
+
+    try:
+        f = open(docconf)
+    except IOError as (errno, strerror):
+        return strerror
+
+    for line in f:
+        m = prog.search(line)
+        if m:
+            return m.group(1)
+
+    f.close()
+    return ""
+
+def main():
+    docfiles = []
+    metadirs = []
+    bbvars = {}
+    undocumented = []
+    docconf = ""
+    onlydoctags = False
+
+    # Collect and validate input
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "d:hm:t:T", ["help"])
+    except getopt.GetoptError, err:
+        print '%s' % str(err)
+        usage()
+        sys.exit(2)
+
+    for o, a in opts:
+        if o in ('-h', '--help'):
+            usage()
+            sys.exit(0)
+        elif o == '-d':
+            if os.path.isfile(a):
+                docfiles.append(a)
+            else:
+                print 'ERROR: documentation file %s is not a regular file' % (a)
+                sys.exit(3)
+        elif o == '-m':
+            if os.path.isdir(a):
+                metadirs.append(a)
+            else:
+                print 'ERROR: meta directory %s is not a directory' % (a)
+                sys.exit(4)
+        elif o == "-t":
+            if os.path.isfile(a):
+                docconf = a
+        elif o == "-T":
+            onlydoctags = True
+        else:
+            assert False, "unhandled option"
+
+    if len(docfiles) == 0:
+        print 'ERROR: no docfile specified'
+        usage()
+        sys.exit(5)
+
+    if len(metadirs) == 0:
+        print 'ERROR: no metadir specified'
+        usage()
+        sys.exit(6)
+
+    if onlydoctags and docconf == "":
+        print 'ERROR: no docconf specified'
+        usage()
+        sys.exit(7)
+
+    # Collect all the variable names from the recipes in the metadirs
+    for m in metadirs:
+        for key,cnt in collect_bbvars(m).iteritems():
+            if bbvars.has_key(key):
+                bbvars[key] = bbvars[key] + cnt
+            else:
+                bbvars[key] = cnt
+
+    # Check each var for documentation
+    varlen = 0
+    for v in bbvars.iterkeys():
+        if len(v) > varlen:
+            varlen = len(v)
+        if not bbvar_is_documented(v, docfiles):
+            undocumented.append(v)
+    undocumented.sort()
+    varlen = varlen + 1
+
+    # Report all undocumented variables
+    print 'Found %d undocumented bb variables (out of %d):' % (len(undocumented), len(bbvars))
+    header = '%s%s%s' % (str("VARIABLE").ljust(varlen), str("COUNT").ljust(6), str("DOCTAG").ljust(7))
+    print header
+    print str("").ljust(len(header), '=')
+    for v in undocumented:
+        doctag = bbvar_doctag(v, docconf)
+        if not onlydoctags or not doctag == "":
+            print '%s%s%s' % (v.ljust(varlen), str(bbvars[v]).ljust(6), doctag)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/scripts/contrib/build-perf-test.sh b/scripts/contrib/build-perf-test.sh
new file mode 100755
index 0000000..cdd7885
--- /dev/null
+++ b/scripts/contrib/build-perf-test.sh
@@ -0,0 +1,369 @@
+#!/bin/bash
+#
+# This script runs a series of tests  (with and without sstate) and reports build time (and tmp/ size)
+# 
+# Build performance test script
+#
+# Copyright 2013 Intel Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+#
+# AUTHORS:
+# Stefan Stanacar <stefanx.stanacar@intel.com>
+
+
+ME=$(basename $0)
+
+#
+# usage and setup
+#
+
+usage () {
+cat << EOT
+Usage: $ME [-h]
+       $ME [-c <commit>] [-v] [-m <val>] [-j <val>] [-t <val>] [-i <image-name>] [-d <path>]
+Options:
+        -h
+                Display this help and exit.
+        -c <commit>
+                git checkout <commit> before anything else
+        -v
+                Show bitbake output, don't redirect it to a log.
+        -m <machine>
+                Value for MACHINE. Default is qemux86.
+        -j <val>
+                Value for PARALLEL_MAKE. Default is 8. 
+        -t <val>
+                Value for BB_NUMBER_THREADS. Default is 8.
+        -i <image-name>
+                Instead of timing against core-image-sato, use <image-name>
+        -d <path>
+                Use <path> as DL_DIR
+        -p <githash>
+                Cherry pick githash onto the commit
+                
+Note: current working directory must be inside a poky git clone.
+ 
+EOT
+}
+
+
+if clonedir=$(git rev-parse --show-toplevel); then
+        cd $clonedir
+else
+        echo "The current working dir doesn't seem to be a poky git clone. Please cd there before running $ME"
+        exit 1
+fi
+
+IMAGE="core-image-sato"
+verbose=0
+dldir=
+commit=
+pmake=
+cherrypicks=
+while getopts "hvc:m:j:t:i:d:p:" opt; do
+        case $opt in
+                h)      usage
+                        exit 0
+                        ;;
+                v)      verbose=1
+                        ;;
+                c)      commit=$OPTARG
+                        ;;
+                m)      export MACHINE=$OPTARG
+                        ;;
+                j)      pmake=$OPTARG
+                        ;;
+                t)      export BB_NUMBER_THREADS=$OPTARG
+                        ;;
+                i)      IMAGE=$OPTARG
+                        ;;
+                d)      dldir=$OPTARG
+                        ;;
+                p)      cherrypicks="$cherrypicks $OPTARG"
+                        ;;
+                *)      usage
+                        exit 1
+                        ;;                      
+        esac
+done
+
+
+#drop cached credentials and test for sudo access without a password
+sudo -k -n ls > /dev/null 2>&1
+reqpass=$?
+if [ $reqpass -ne 0 ]; then
+    echo "The script requires sudo access to drop caches between builds (echo 3 > /proc/sys/vm/drop_caches)"
+    read -s -p "Please enter your sudo password: " pass
+    echo
+fi
+
+if [ -n "$commit" ]; then
+            echo "git checkout -f $commit"
+            git pull > /dev/null 2>&1
+            git checkout -f $commit || exit 1
+            git pull > /dev/null 2>&1
+fi
+
+if [ -n "$cherrypicks" ]; then
+    for c in $cherrypicks; do
+        git cherry-pick $c
+    done
+fi
+
+rev=$(git rev-parse --short HEAD)  || exit 1
+OUTDIR="$clonedir/build-perf-test/results-$rev-`date "+%Y%m%d%H%M%S"`"
+BUILDDIR="$OUTDIR/build"
+resultsfile="$OUTDIR/results.log"
+bboutput="$OUTDIR/bitbake.log"
+myoutput="$OUTDIR/output.log"
+globalres="$clonedir/build-perf-test/globalres.log"
+
+mkdir -p $OUTDIR || exit 1
+                                
+log () {
+    local msg="$1"
+    echo "`date`: $msg" | tee -a $myoutput
+}
+
+
+#
+# Config stuff
+#
+
+branch=`git branch 2>&1 | grep "^* " | tr -d "* "`
+gitcommit=$(git rev-parse HEAD)  || exit 1
+log "Running on $branch:$gitcommit"
+
+source ./oe-init-build-env $OUTDIR/build >/dev/null || exit 1
+cd $OUTDIR/build
+
+[ -n "$MACHINE" ] || export MACHINE="qemux86"
+[ -n "$BB_NUMBER_THREADS" ] || export BB_NUMBER_THREADS="8"
+
+if [ -n "$pmake" ]; then
+        export PARALLEL_MAKE="-j $pmake"
+else
+        export PARALLEL_MAKE="-j 8"
+fi
+
+if [ -n "$dldir" ]; then
+    echo "DL_DIR = \"$dldir\"" >> conf/local.conf
+else
+    echo "DL_DIR = \"$clonedir/build-perf-test/downloads\"" >> conf/local.conf
+fi
+
+# Sometimes I've noticed big differences in timings for the same commit, on the same machine
+# Disabling the network sanity check helps a bit (because of my crappy network connection and/or proxy)
+echo "CONNECTIVITY_CHECK_URIS =\"\"" >> conf/local.conf
+
+
+#
+# Functions
+#
+
+declare -a TIMES
+time_count=0
+declare -a SIZES
+size_count=0
+
+bbtime () {
+    local arg="$@"
+    log "   Timing: bitbake ${arg}"
+
+    if [ $verbose -eq 0 ]; then 
+        /usr/bin/time -v -o $resultsfile bitbake ${arg} >> $bboutput
+    else
+        /usr/bin/time -v -o $resultsfile bitbake ${arg}
+    fi
+    ret=$?
+    if [ $ret -eq 0 ]; then
+        t=`grep wall $resultsfile | sed 's/.*m:ss): //'`
+        log "   TIME: $t"
+        TIMES[(( time_count++ ))]="$t"
+    else
+        log "ERROR: exit status was non-zero, will report time as 0."
+        TIMES[(( time_count++ ))]="0"
+    fi
+    
+    #time by default overwrites the output file and we  want to keep the results
+    #it has an append option but I don't want to clobber the results in the same file
+    i=`ls $OUTDIR/results.log* |wc -l`
+    mv $resultsfile "${resultsfile}.${i}"
+    log "More stats can be found in ${resultsfile}.${i}"    
+}
+
+#we don't time bitbake here
+bbnotime () {
+    local arg="$@"
+    log "   Running: bitbake ${arg}"
+    if [ $verbose -eq 0 ]; then
+        bitbake ${arg} >> $bboutput
+    else
+        bitbake ${arg}
+    fi
+    ret=$?
+    if [ $ret -eq 0 ]; then
+        log "   Finished bitbake ${arg}"
+    else
+        log "ERROR: exit status was non-zero. Exit.."
+        exit $ret
+    fi
+
+}
+
+do_rmtmp() {
+    log "   Removing tmp"
+    rm -rf bitbake.lock pseudodone conf/sanity_info cache tmp
+}
+do_rmsstate () {
+    log "   Removing sstate-cache"
+    rm -rf sstate-cache
+}
+do_sync () {
+    log "   Syncing and dropping caches"
+    sync; sync
+    if [ $reqpass -eq 0 ]; then
+        sudo sh -c "echo 3 > /proc/sys/vm/drop_caches"
+    else
+        echo "$pass" | sudo -S sh -c "echo 3 > /proc/sys/vm/drop_caches"
+        echo
+    fi
+    sleep 3
+}
+
+write_results() {
+    echo -n "`uname -n`,$branch:$gitcommit,`git describe`," >> $globalres
+    for i in "${TIMES[@]}"; do
+        echo -n "$i," >> $globalres
+    done
+    for i in "${SIZES[@]}"; do
+        echo -n "$i," >> $globalres
+    done
+    echo >> $globalres
+    sed -i '$ s/,$//' $globalres
+}
+
+####
+
+#
+# Test 1
+# Measure: Wall clock of "bitbake core-image-sato" and size of tmp/dir (w/o rm_work and w/ rm_work)
+# Pre: Downloaded sources, no sstate
+# Steps:
+#     Part1:
+#        - fetchall 
+#        - clean build dir
+#        - time bitbake core-image-sato
+#        - collect data
+#     Part2:
+#        - bitbake virtual/kernel -c cleansstate
+#        - time bitbake virtual/kernel
+#     Part3:
+#        - add INHERIT to local.conf
+#        - clean build dir
+#        - build
+#        - report size, remove INHERIT
+
+test1_p1 () {
+    log "Running Test 1, part 1/3: Measure wall clock of bitbake $IMAGE and size of tmp/ dir"
+    bbnotime $IMAGE -c fetchall
+    do_rmtmp
+    do_rmsstate
+    do_sync
+    bbtime $IMAGE
+    s=`du -s tmp | sed 's/tmp//' | sed 's/[ \t]*$//'`
+    SIZES[(( size_count++ ))]="$s"
+    log "SIZE of tmp dir is: $s"
+    log "Buildstats are saved in $OUTDIR/buildstats-test1"
+    mv tmp/buildstats $OUTDIR/buildstats-test1
+}
+
+
+test1_p2 () {
+    log "Running Test 1, part 2/3: bitbake virtual/kernel -c cleansstate and time bitbake virtual/kernel"
+    bbnotime virtual/kernel -c cleansstate
+    do_sync
+    bbtime virtual/kernel
+}
+
+test1_p3 () {
+    log "Running Test 1, part 3/3: Build $IMAGE w/o sstate and report size of tmp/dir with rm_work enabled"
+    echo "INHERIT += \"rm_work\"" >> conf/local.conf
+    do_rmtmp
+    do_rmsstate
+    do_sync
+    bbtime $IMAGE
+    sed -i 's/INHERIT += \"rm_work\"//' conf/local.conf
+    s=`du -s tmp | sed 's/tmp//' | sed 's/[ \t]*$//'`
+    SIZES[(( size_count++ ))]="$s"
+    log "SIZE of tmp dir is: $s"
+    log "Buildstats are saved in $OUTDIR/buildstats-test13"
+    mv tmp/buildstats $OUTDIR/buildstats-test13
+}
+
+
+#
+# Test 2
+# Measure: Wall clock of "bitbake core-image-sato" and size of tmp/dir
+# Pre: populated sstate cache
+
+test2 () {
+    # Assuming test 1 has run
+    log "Running Test 2: Measure wall clock of bitbake $IMAGE -c rootfs with sstate"
+    do_rmtmp
+    do_sync
+    bbtime $IMAGE -c rootfs
+}
+
+
+# Test 3
+# parsing time metrics
+#
+#  Start with
+#   i) "rm -rf tmp/cache; time bitbake -p"
+#  ii) "rm -rf tmp/cache/default-glibc/; time bitbake -p"
+# iii) "time bitbake -p"
+
+
+test3 () {
+    log "Running Test 3: Parsing time metrics (bitbake -p)"
+    log "   Removing tmp/cache && cache"
+    rm -rf tmp/cache cache
+    bbtime -p
+    log "   Removing tmp/cache/default-glibc/"
+    rm -rf tmp/cache/default-glibc/
+    bbtime -p
+    bbtime -p
+}
+
+
+
+# RUN!
+
+test1_p1
+test1_p2
+test1_p3
+test2
+test3
+
+# if we got til here write to global results
+write_results
+
+log "All done, cleaning up..."
+
+do_rmtmp
+do_rmsstate
diff --git a/scripts/contrib/ddimage b/scripts/contrib/ddimage
new file mode 100755
index 0000000..a503f11
--- /dev/null
+++ b/scripts/contrib/ddimage
@@ -0,0 +1,104 @@
+#!/bin/sh
+
+# Default to avoiding the first two disks on typical Linux and Mac OS installs
+# Better safe than sorry :-)
+BLACKLIST_DEVICES="/dev/sda /dev/sdb /dev/disk1 /dev/disk2"
+
+# 1MB blocksize
+BLOCKSIZE=1048576
+
+usage() {
+	echo "Usage: $(basename $0) IMAGE DEVICE"
+}
+
+image_details() {
+	IMG=$1
+	echo "Image details"
+	echo "============="
+	echo "    image: $(basename $IMG)"
+	# stat format is different on Mac OS and Linux
+	if [ "$(uname)" = "Darwin" ]; then
+		echo "     size: $(stat -L -f '%z bytes' $IMG)"
+		echo " modified: $(stat -L -f '%Sm' $IMG)"
+	else
+		echo "     size: $(stat -L -c '%s bytes' $IMG)"
+		echo " modified: $(stat -L -c '%y' $IMG)"
+	fi
+	echo "     type: $(file -L -b $IMG)"
+	echo ""
+}
+
+device_details() {
+	DEV=$1
+	BLOCK_SIZE=512
+
+	echo "Device details"
+	echo "=============="
+
+	# Collect disk info using diskutil on Mac OS
+	if [ "$(uname)" = "Darwin" ]; then
+		diskutil info $DEVICE | egrep "(Device Node|Media Name|Total Size)"
+		return
+	fi
+
+	# Default / Linux information collection
+	echo "  device: $DEVICE"
+	if [ -f "/sys/class/block/$DEV/device/vendor" ]; then
+		echo "  vendor: $(cat /sys/class/block/$DEV/device/vendor)"
+	else
+		echo "  vendor: UNKOWN"
+	fi
+	if [ -f "/sys/class/block/$DEV/device/model" ]; then
+		echo "   model: $(cat /sys/class/block/$DEV/device/model)"
+	else
+		echo "   model: UNKNOWN"
+	fi
+	if [ -f "/sys/class/block/$DEV/size" ]; then
+		echo "    size: $(($(cat /sys/class/block/$DEV/size) * $BLOCK_SIZE)) bytes"
+	else
+		echo "    size: UNKNOWN"
+	fi
+	echo ""
+}
+
+if [ $# -ne 2 ]; then
+	usage
+	exit 1
+fi
+
+IMAGE=$1
+DEVICE=$2
+
+if [ ! -e "$IMAGE" ]; then
+	echo "ERROR: Image $IMAGE does not exist"
+	usage
+	exit 1
+fi
+
+
+for i in ${BLACKLIST_DEVICES}; do
+	if [ "$i" = "$DEVICE" ]; then
+		echo "ERROR: Device $DEVICE is blacklisted"
+		exit 1
+	fi
+done
+
+if [ ! -w "$DEVICE" ]; then
+	echo "ERROR: Device $DEVICE does not exist or is not writable"
+	usage
+	exit 1
+fi
+
+image_details $IMAGE
+device_details $(basename $DEVICE)
+
+printf "Write $IMAGE to $DEVICE [y/N]? "
+read RESPONSE
+if [ "$RESPONSE" != "y" ]; then
+	echo "Write aborted"
+	exit 0
+fi
+
+echo "Writing image..."
+dd if="$IMAGE" of="$DEVICE" bs="$BLOCKSIZE"
+sync
diff --git a/scripts/contrib/dialog-power-control b/scripts/contrib/dialog-power-control
new file mode 100755
index 0000000..7550ea5
--- /dev/null
+++ b/scripts/contrib/dialog-power-control
@@ -0,0 +1,53 @@
+#!/bin/sh
+#
+# Simple script to show a manual power prompt for when you want to use
+# automated hardware testing with testimage.bbclass but you don't have a
+# web-enabled power strip or similar to do the power on/off/cycle.
+#
+# You can enable it by enabling testimage (see the Yocto Project
+# Development manual "Performing Automated Runtime Testing" section)
+# and setting the following in your local.conf:
+#
+# TEST_POWERCONTROL_CMD = "${COREBASE}/scripts/contrib/dialog-power-control"
+#
+
+PROMPT=""
+while true; do
+    case $1 in
+        on)
+            PROMPT="Please turn device power on";;
+        off)
+            PROMPT="Please turn device power off";;
+        cycle)
+            PROMPT="Please click Done, then turn the device power off then on";;
+        "")
+            break;;
+    esac
+    shift
+done
+
+if [ "$PROMPT" = "" ] ; then
+    echo "ERROR: no power action specified on command line"
+    exit 2
+fi
+
+if [ "`which kdialog 2>/dev/null`" != "" ] ; then
+    DIALOGUTIL="kdialog"
+elif [ "`which zenity 2>/dev/null`" != "" ] ; then
+    DIALOGUTIL="zenity"
+else
+    echo "ERROR: couldn't find program to display a message, install kdialog or zenity"
+    exit 3
+fi
+
+if [ "$DIALOGUTIL" = "kdialog" ] ; then
+    kdialog --yesno "$PROMPT" --title "TestImage Power Control" --yes-label "Done" --no-label "Cancel test"
+elif [ "$DIALOGUTIL" = "zenity" ] ; then
+    zenity --question --text="$PROMPT" --title="TestImage Power Control" --ok-label="Done" --cancel-label="Cancel test"
+fi
+
+if [ "$?" != "0" ] ; then
+    echo "User cancelled test at power prompt"
+    exit 1
+fi
+
diff --git a/scripts/contrib/documentation-audit.sh b/scripts/contrib/documentation-audit.sh
new file mode 100755
index 0000000..2144aac
--- /dev/null
+++ b/scripts/contrib/documentation-audit.sh
@@ -0,0 +1,94 @@
+#!/bin/bash
+#
+# Perform an audit of which packages provide documentation and which
+# are missing -doc packages.
+#
+# Setup requirements: be sure to be building for MACHINE=qemux86. Run
+# this script after source'ing the build environment script, so you're
+# running it from build/ directory.
+#
+# Maintainer: Scott Garman <scott.a.garman@intel.com>
+
+REPORT_DOC_SIMPLE="documentation_exists.txt"
+REPORT_DOC_DETAIL="documentation_exists_detail.txt"
+REPORT_MISSING_SIMPLE="documentation_missing.txt"
+REPORT_MISSING_DETAIL="documentation_missing_detail.txt"
+REPORT_BUILD_ERRORS="build_errors.txt"
+
+rm -rf $REPORT_DOC_SIMPLE $REPORT_DOC_DETAIL $REPORT_MISSING_SIMPLE $REPORT_MISSING_DETAIL
+
+BITBAKE=`which bitbake`
+if [ -z "$BITBAKE" ]; then
+	echo "Error: bitbake command not found."
+	echo "Did you forget to source the build environment script?"
+	exit 1
+fi
+
+echo "REMINDER: you need to build for MACHINE=qemux86 or you won't get useful results"
+echo "REMINDER: you need to set LICENSE_FLAGS_WHITELIST appropriately in local.conf or "
+echo " you'll get false positives.  For example, LICENSE_FLAGS_WHITELIST = \"Commercial\""
+
+for pkg in `bitbake -s | awk '{ print \$1 }'`; do
+	if [[ "$pkg" == "Loading" || "$pkg" == "Loaded" ||
+	  "$pkg" == "Recipe"  ||
+          "$pkg" == "Parsing" || "$pkg" == "Package" ||
+          "$pkg" == "NOTE:"   || "$pkg" == "WARNING:" ||
+          "$pkg" == "done."   || "$pkg" == "===========" ]]
+	then
+		# Skip initial bitbake output
+		continue
+	fi
+	if [[ "$pkg" =~ -native$ || "$pkg" =~ -nativesdk$ ||
+          "$pkg" =~ -cross-canadian ]]; then
+		# Skip native/nativesdk/cross-canadian recipes
+		continue
+	fi
+	if [[ "$pkg" =~ ^meta- || "$pkg" =~ ^packagegroup- || "$pkg" =~ -image ]]; then
+		# Skip meta, task and image recipes
+		continue
+	fi
+	if [[ "$pkg" =~ ^glibc- || "$pkg" =~ ^libiconv$ ||
+          "$pkg" =~ -toolchain$ || "$pkg" =~ ^package-index$ ||
+          "$pkg" =~ ^linux- || "$pkg" =~ ^adt-installer$ ||
+          "$pkg" =~ ^eds-tools$ || "$pkg" =~ ^external-python-tarball$ ||
+          "$pkg" =~ ^qt4-embedded$ || "$pkg" =~ ^qt-mobility ]]; then
+		# Skip glibc, libiconv, -toolchain, and other recipes known
+		# to cause build conflicts or trigger false positives.
+		continue
+	fi	
+
+	echo "Building package $pkg..."
+	bitbake $pkg > /dev/null
+	if [ $? -ne 0 ]; then
+		echo "There was an error building package $pkg" >> "$REPORT_MISSING_DETAIL"
+		echo "$pkg" >> $REPORT_BUILD_ERRORS
+
+		# Do not skip the remaining tests, as sometimes the
+		# exit status is 1 due to QA errors, and we can still
+		# perform the -doc checks.
+	fi
+
+	echo "$pkg built successfully, checking for a documentation package..."
+	WORKDIR=`bitbake -e $pkg | grep ^WORKDIR | awk -F '=' '{ print \$2 }' | awk -F '"' '{ print \$2 }'`
+	FIND_DOC_PKG=`find $WORKDIR/packages-split/*-doc -maxdepth 0 -type d`
+	if [ -z "$FIND_DOC_PKG" ]; then
+		# No -doc package was generated:
+		echo "No -doc package: $pkg" >> "$REPORT_MISSING_DETAIL"
+		echo "$pkg" >> $REPORT_MISSING_SIMPLE
+		continue
+	fi
+
+	FIND_DOC_FILES=`find $FIND_DOC_PKG -type f`
+	if [ -z "$FIND_DOC_FILES" ]; then
+		# No files shipped with the -doc package:
+		echo "No files shipped with the -doc package: $pkg" >> "$REPORT_MISSING_DETAIL"
+		echo "$pkg" >> $REPORT_MISSING_SIMPLE
+		continue
+	fi
+
+	echo "Documentation shipped with $pkg:" >> "$REPORT_DOC_DETAIL"
+	echo "$FIND_DOC_FILES" >> "$REPORT_DOC_DETAIL"
+	echo ""	>> "$REPORT_DOC_DETAIL"
+
+	echo "$pkg" >> "$REPORT_DOC_SIMPLE"
+done
diff --git a/scripts/contrib/graph-tool b/scripts/contrib/graph-tool
new file mode 100755
index 0000000..6dc7d33
--- /dev/null
+++ b/scripts/contrib/graph-tool
@@ -0,0 +1,92 @@
+#!/usr/bin/env python
+
+# Simple graph query utility
+# useful for getting answers from .dot files produced by bitbake -g
+#
+# Written by: Paul Eggleton <paul.eggleton@linux.intel.com>
+#
+# Copyright 2013 Intel Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+import sys
+
+def get_path_networkx(dotfile, fromnode, tonode):
+    try:
+        import networkx
+    except ImportError:
+        print('ERROR: Please install the networkx python module')
+        sys.exit(1)
+
+    graph = networkx.DiGraph(networkx.read_dot(dotfile))
+
+    def node_missing(node):
+        import difflib
+        close_matches = difflib.get_close_matches(node, graph.nodes(), cutoff=0.7)
+        if close_matches:
+            print('ERROR: no node "%s" in graph. Close matches:\n  %s' % (node, '\n  '.join(close_matches)))
+        sys.exit(1)
+
+    if not fromnode in graph:
+        node_missing(fromnode)
+    if not tonode in graph:
+        node_missing(tonode)
+    return networkx.all_simple_paths(graph, source=fromnode, target=tonode)
+
+
+def find_paths(args, usage):
+    if len(args) < 3:
+        usage()
+        sys.exit(1)
+
+    fromnode = args[1]
+    tonode = args[2]
+    paths = list(get_path_networkx(args[0], fromnode, tonode))
+    if paths:
+        for path in paths:
+            print ' -> '.join(path)
+    else:
+        print("ERROR: no path from %s to %s in graph" % (fromnode, tonode))
+        sys.exit(1)
+
+def main():
+    import optparse
+    parser = optparse.OptionParser(
+        usage = '''%prog [options] <command> <arguments>
+
+Available commands:
+    find-paths <dotfile> <from> <to>
+        Find all of the paths between two nodes in a dot graph''')
+
+    #parser.add_option("-d", "--debug",
+    #        help = "Report all SRCREV values, not just ones where AUTOREV has been used",
+    #        action="store_true", dest="debug", default=False)
+
+    options, args = parser.parse_args(sys.argv)
+    args = args[1:]
+
+    if len(args) < 1:
+        parser.print_help()
+        sys.exit(1)
+
+    if args[0] == "find-paths":
+        find_paths(args[1:], parser.print_help)
+    else:
+        parser.print_help()
+        sys.exit(1)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/scripts/contrib/list-packageconfig-flags.py b/scripts/contrib/list-packageconfig-flags.py
new file mode 100755
index 0000000..2f3b8b0
--- /dev/null
+++ b/scripts/contrib/list-packageconfig-flags.py
@@ -0,0 +1,179 @@
+#!/usr/bin/env python
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation.
+#
+# Copyright (C) 2013 Wind River Systems, Inc.
+# Copyright (C) 2014 Intel Corporation
+#
+# - list available recipes which have PACKAGECONFIG flags
+# - list available PACKAGECONFIG flags and all affected recipes
+# - list all recipes and PACKAGECONFIG information
+
+import sys
+import optparse
+import os
+
+
+scripts_path = os.path.abspath(os.path.dirname(os.path.abspath(sys.argv[0])))
+lib_path = os.path.abspath(scripts_path + '/../lib')
+sys.path = sys.path + [lib_path]
+
+import scriptpath
+
+# For importing the following modules
+bitbakepath = scriptpath.add_bitbake_lib_path()
+if not bitbakepath:
+    sys.stderr.write("Unable to find bitbake by searching parent directory of this script or PATH\n")
+    sys.exit(1)
+
+import bb.cache
+import bb.cooker
+import bb.providers
+import bb.tinfoil
+
+def get_fnlist(bbhandler, pkg_pn, preferred):
+    ''' Get all recipe file names '''
+    if preferred:
+        (latest_versions, preferred_versions) = bb.providers.findProviders(bbhandler.config_data, bbhandler.cooker.recipecache, pkg_pn)
+
+    fn_list = []
+    for pn in sorted(pkg_pn):
+        if preferred:
+            fn_list.append(preferred_versions[pn][1])
+        else:
+            fn_list.extend(pkg_pn[pn])
+
+    return fn_list
+
+def get_recipesdata(bbhandler, preferred):
+    ''' Get data of all available recipes which have PACKAGECONFIG flags '''
+    pkg_pn = bbhandler.cooker.recipecache.pkg_pn
+
+    data_dict = {}
+    for fn in get_fnlist(bbhandler, pkg_pn, preferred):
+        data = bb.cache.Cache.loadDataFull(fn, bbhandler.cooker.collection.get_file_appends(fn), bbhandler.config_data)
+        flags = data.getVarFlags("PACKAGECONFIG")
+        flags.pop('doc', None)
+        if flags:
+            data_dict[fn] = data
+
+    return data_dict
+
+def collect_pkgs(data_dict):
+    ''' Collect available pkgs in which have PACKAGECONFIG flags '''
+    # pkg_dict = {'pkg1': ['flag1', 'flag2',...]}
+    pkg_dict = {}
+    for fn in data_dict:
+        pkgconfigflags = data_dict[fn].getVarFlags("PACKAGECONFIG")
+        pkgconfigflags.pop('doc', None)
+        pkgname = data_dict[fn].getVar("P", True)
+        pkg_dict[pkgname] = sorted(pkgconfigflags.keys())
+
+    return pkg_dict
+
+def collect_flags(pkg_dict):
+    ''' Collect available PACKAGECONFIG flags and all affected pkgs '''
+    # flag_dict = {'flag': ['pkg1', 'pkg2',...]}
+    flag_dict = {}
+    for pkgname, flaglist in pkg_dict.iteritems():
+        for flag in flaglist:
+            if flag in flag_dict:
+                flag_dict[flag].append(pkgname)
+            else:
+                flag_dict[flag] = [pkgname]
+
+    return flag_dict
+
+def display_pkgs(pkg_dict):
+    ''' Display available pkgs which have PACKAGECONFIG flags '''
+    pkgname_len = len("RECIPE NAME") + 1
+    for pkgname in pkg_dict:
+        if pkgname_len < len(pkgname):
+            pkgname_len = len(pkgname)
+    pkgname_len += 1
+
+    header = '%-*s%s' % (pkgname_len, str("RECIPE NAME"), str("PACKAGECONFIG FLAGS"))
+    print header
+    print str("").ljust(len(header), '=')
+    for pkgname in sorted(pkg_dict):
+        print('%-*s%s' % (pkgname_len, pkgname, ' '.join(pkg_dict[pkgname])))
+
+
+def display_flags(flag_dict):
+    ''' Display available PACKAGECONFIG flags and all affected pkgs '''
+    flag_len = len("PACKAGECONFIG FLAG") + 5
+
+    header = '%-*s%s' % (flag_len, str("PACKAGECONFIG FLAG"), str("RECIPE NAMES"))
+    print header
+    print str("").ljust(len(header), '=')
+
+    for flag in sorted(flag_dict):
+        print('%-*s%s' % (flag_len, flag, '  '.join(sorted(flag_dict[flag]))))
+
+def display_all(data_dict):
+    ''' Display all pkgs and PACKAGECONFIG information '''
+    print str("").ljust(50, '=')
+    for fn in data_dict:
+        print('%s' % data_dict[fn].getVar("P", True))
+        print fn
+        packageconfig = data_dict[fn].getVar("PACKAGECONFIG", True) or ''
+        if packageconfig.strip() == '':
+            packageconfig = 'None'
+        print('PACKAGECONFIG %s' % packageconfig)
+
+        for flag,flag_val in data_dict[fn].getVarFlags("PACKAGECONFIG").iteritems():
+            if flag == "doc":
+                continue
+            print('PACKAGECONFIG[%s] %s' % (flag, flag_val))
+        print ''
+
+def main():
+    pkg_dict = {}
+    flag_dict = {}
+
+    # Collect and validate input
+    parser = optparse.OptionParser(
+        description = "Lists recipes and PACKAGECONFIG flags. Without -a or -f, recipes and their available PACKAGECONFIG flags are listed.",
+        usage = """
+    %prog [options]""")
+
+    parser.add_option("-f", "--flags",
+            help = "list available PACKAGECONFIG flags and affected recipes",
+            action="store_const", dest="listtype", const="flags", default="recipes")
+    parser.add_option("-a", "--all",
+            help = "list all recipes and PACKAGECONFIG information",
+            action="store_const", dest="listtype", const="all")
+    parser.add_option("-p", "--preferred-only",
+            help = "where multiple recipe versions are available, list only the preferred version",
+            action="store_true", dest="preferred", default=False)
+
+    options, args = parser.parse_args(sys.argv)
+
+    bbhandler = bb.tinfoil.Tinfoil()
+    bbhandler.prepare()
+    print("Gathering recipe data...")
+    data_dict = get_recipesdata(bbhandler, options.preferred)
+
+    if options.listtype == 'flags':
+        pkg_dict = collect_pkgs(data_dict)
+        flag_dict = collect_flags(pkg_dict)
+        display_flags(flag_dict)
+    elif options.listtype == 'recipes':
+        pkg_dict = collect_pkgs(data_dict)
+        display_pkgs(pkg_dict)
+    elif options.listtype == 'all':
+        display_all(data_dict)
+
+if __name__ == "__main__":
+    main()
diff --git a/scripts/contrib/mkefidisk.sh b/scripts/contrib/mkefidisk.sh
new file mode 100755
index 0000000..55f72b0
--- /dev/null
+++ b/scripts/contrib/mkefidisk.sh
@@ -0,0 +1,403 @@
+#!/bin/sh
+#
+# Copyright (c) 2012, Intel Corporation.
+# All rights reserved.
+#
+# This program is free software;  you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY;  without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+# the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program;  if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+LANG=C
+
+# Set to 1 to enable additional output
+DEBUG=0
+OUT="/dev/null"
+
+#
+# Defaults
+#
+# 20 Mb for the boot partition
+BOOT_SIZE=20
+# 5% for swap
+SWAP_RATIO=5
+
+# Cleanup after die()
+cleanup() {
+	debug "Syncing and unmounting devices"
+	# Unmount anything we mounted
+	unmount $ROOTFS_MNT || error "Failed to unmount $ROOTFS_MNT"
+	unmount $BOOTFS_MNT || error "Failed to unmount $BOOTFS_MNT"
+	unmount $HDDIMG_ROOTFS_MNT || error "Failed to unmount $HDDIMG_ROOTFS_MNT"
+	unmount $HDDIMG_MNT || error "Failed to unmount $HDDIMG_MNT"
+
+	# Remove the TMPDIR
+	debug "Removing temporary files"
+	if [ -d "$TMPDIR" ]; then
+		rm -rf $TMPDIR || error "Failed to remove $TMPDIR"
+	fi
+}
+
+trap 'die "Signal Received, Aborting..."' HUP INT TERM
+
+# Logging routines
+WARNINGS=0
+ERRORS=0
+CLEAR="$(tput sgr0)"
+INFO="$(tput bold)"
+RED="$(tput setaf 1)$(tput bold)"
+GREEN="$(tput setaf 2)$(tput bold)"
+YELLOW="$(tput setaf 3)$(tput bold)"
+info() {
+	echo "${INFO}$1${CLEAR}"
+}
+error() {
+	ERRORS=$((ERRORS+1))
+	echo "${RED}$1${CLEAR}"
+}
+warn() {
+	WARNINGS=$((WARNINGS+1))
+	echo "${YELLOW}$1${CLEAR}"
+}
+success() {
+	echo "${GREEN}$1${CLEAR}"
+}
+die() {
+	error "$1"
+	cleanup
+	exit 1
+}
+debug() {
+	if [ $DEBUG -eq 1 ]; then
+		echo "$1"
+	fi
+}
+
+usage() {
+	echo "Usage: $(basename $0) [-v] DEVICE HDDIMG TARGET_DEVICE"
+	echo "       -v: Verbose debug"
+	echo "       DEVICE: The device to write the image to, e.g. /dev/sdh"
+	echo "       HDDIMG: The hddimg file to generate the efi disk from"
+	echo "       TARGET_DEVICE: The device the target will boot from, e.g.  /dev/mmcblk0"
+}
+
+image_details() {
+	IMG=$1
+	info "Image details"
+	echo "    image: $(stat --printf '%N\n' $IMG)"
+	echo "     size: $(stat -L --printf '%s bytes\n' $IMG)"
+	echo " modified: $(stat -L --printf '%y\n' $IMG)"
+	echo "     type: $(file -L -b $IMG)"
+	echo ""
+}
+
+device_details() {
+	DEV=$1
+	BLOCK_SIZE=512
+
+	info "Device details"
+	echo "  device: $DEVICE"
+	if [ -f "/sys/class/block/$DEV/device/vendor" ]; then
+		echo "  vendor: $(cat /sys/class/block/$DEV/device/vendor)"
+	else
+		echo "  vendor: UNKOWN"
+	fi
+	if [ -f "/sys/class/block/$DEV/device/model" ]; then
+		echo "   model: $(cat /sys/class/block/$DEV/device/model)"
+	else
+		echo "   model: UNKNOWN"
+	fi
+	if [ -f "/sys/class/block/$DEV/size" ]; then
+		echo "    size: $(($(cat /sys/class/block/$DEV/size) * $BLOCK_SIZE)) bytes"
+	else
+		echo "    size: UNKNOWN"
+	fi
+	echo ""
+}
+
+unmount_device() {
+	grep -q $DEVICE /proc/mounts
+	if [ $? -eq 0 ]; then
+		warn "$DEVICE listed in /proc/mounts, attempting to unmount"
+		umount $DEVICE* 2>/dev/null
+		return $?
+	fi
+	return 0
+}
+
+unmount() {
+	if [ "$1" = "" ] ; then
+		return 0
+	fi
+	grep -q $1 /proc/mounts
+	if [ $? -eq 0 ]; then
+		debug "Unmounting $1"
+		umount $1
+		return $?
+	fi
+	return 0
+}
+
+#
+# Parse and validate arguments
+#
+if [ $# -lt 3 ] || [ $# -gt 4 ]; then
+	usage
+	exit 1
+fi
+
+if [ "$1" = "-v" ]; then
+	DEBUG=1
+	OUT="1"
+	shift
+fi
+
+DEVICE=$1
+HDDIMG=$2
+TARGET_DEVICE=$3
+
+LINK=$(readlink $DEVICE)
+if [ $? -eq 0 ]; then
+	DEVICE="$LINK"
+fi
+
+if [ ! -w "$DEVICE" ]; then
+	usage
+	if [ ! -e "${DEVICE}" ] ; then
+		die "Device $DEVICE cannot be found"
+	else
+		die "Device $DEVICE is not writable (need to run under sudo?)"
+	fi
+fi
+
+if [ ! -e "$HDDIMG" ]; then
+	usage
+	die "HDDIMG $HDDIMG does not exist"
+fi
+
+#
+# Ensure the hddimg is not mounted
+#
+unmount "$HDDIMG" || die "Failed to unmount $HDDIMG"
+
+#
+# Check if any $DEVICE partitions are mounted
+#
+unmount_device || die "Failed to unmount $DEVICE"
+
+#
+# Confirm device with user
+#
+image_details $HDDIMG
+device_details $(basename $DEVICE)
+echo -n "${INFO}Prepare EFI image on $DEVICE [y/N]?${CLEAR} "
+read RESPONSE
+if [ "$RESPONSE" != "y" ]; then
+	echo "Image creation aborted"
+	exit 0
+fi
+
+
+#
+# Prepare the temporary working space
+#
+TMPDIR=$(mktemp -d mkefidisk-XXX) || die "Failed to create temporary mounting directory."
+HDDIMG_MNT=$TMPDIR/hddimg
+HDDIMG_ROOTFS_MNT=$TMPDIR/hddimg_rootfs
+ROOTFS_MNT=$TMPDIR/rootfs
+BOOTFS_MNT=$TMPDIR/bootfs
+mkdir $HDDIMG_MNT || die "Failed to create $HDDIMG_MNT"
+mkdir $HDDIMG_ROOTFS_MNT || die "Failed to create $HDDIMG_ROOTFS_MNT"
+mkdir $ROOTFS_MNT || die "Failed to create $ROOTFS_MNT"
+mkdir $BOOTFS_MNT || die "Failed to create $BOOTFS_MNT"
+
+
+#
+# Partition $DEVICE
+#
+DEVICE_SIZE=$(parted -s $DEVICE unit mb print | grep ^Disk | cut -d" " -f 3 | sed -e "s/MB//")
+# If the device size is not reported there may not be a valid label
+if [ "$DEVICE_SIZE" = "" ] ; then
+	parted -s $DEVICE mklabel msdos || die "Failed to create MSDOS partition table"
+	DEVICE_SIZE=$(parted -s $DEVICE unit mb print | grep ^Disk | cut -d" " -f 3 | sed -e "s/MB//")
+fi
+SWAP_SIZE=$((DEVICE_SIZE*SWAP_RATIO/100))
+ROOTFS_SIZE=$((DEVICE_SIZE-BOOT_SIZE-SWAP_SIZE))
+ROOTFS_START=$((BOOT_SIZE))
+ROOTFS_END=$((ROOTFS_START+ROOTFS_SIZE))
+SWAP_START=$((ROOTFS_END))
+
+# MMC devices use a partition prefix character 'p'
+PART_PREFIX=""
+if [ ! "${DEVICE#/dev/mmcblk}" = "${DEVICE}" ] || [ ! "${DEVICE#/dev/loop}" = "${DEVICE}" ]; then
+	PART_PREFIX="p"
+fi
+BOOTFS=$DEVICE${PART_PREFIX}1
+ROOTFS=$DEVICE${PART_PREFIX}2
+SWAP=$DEVICE${PART_PREFIX}3
+
+TARGET_PART_PREFIX=""
+if [ ! "${TARGET_DEVICE#/dev/mmcblk}" = "${TARGET_DEVICE}" ]; then
+	TARGET_PART_PREFIX="p"
+fi
+TARGET_ROOTFS=$TARGET_DEVICE${TARGET_PART_PREFIX}2
+TARGET_SWAP=$TARGET_DEVICE${TARGET_PART_PREFIX}3
+
+echo ""
+info "Boot partition size:   $BOOT_SIZE MB ($BOOTFS)"
+info "ROOTFS partition size: $ROOTFS_SIZE MB ($ROOTFS)"
+info "Swap partition size:   $SWAP_SIZE MB ($SWAP)"
+echo ""
+
+# Use MSDOS by default as GPT cannot be reliably distributed in disk image form
+# as it requires the backup table to be on the last block of the device, which
+# of course varies from device to device.
+
+info "Partitioning installation media ($DEVICE)"
+
+debug "Deleting partition table on $DEVICE"
+dd if=/dev/zero of=$DEVICE bs=512 count=2 >$OUT 2>&1 || die "Failed to zero beginning of $DEVICE"
+
+debug "Creating new partition table (MSDOS) on $DEVICE"
+parted -s $DEVICE mklabel msdos >$OUT 2>&1 || die "Failed to create MSDOS partition table"
+
+debug "Creating boot partition on $BOOTFS"
+parted -s $DEVICE mkpart primary 0% $BOOT_SIZE >$OUT 2>&1 || die "Failed to create BOOT partition"
+
+debug "Enabling boot flag on $BOOTFS"
+parted -s $DEVICE set 1 boot on >$OUT 2>&1 || die "Failed to enable boot flag"
+
+debug "Creating ROOTFS partition on $ROOTFS"
+parted -s $DEVICE mkpart primary $ROOTFS_START $ROOTFS_END >$OUT 2>&1 || die "Failed to create ROOTFS partition"
+
+debug "Creating swap partition on $SWAP"
+parted -s $DEVICE mkpart primary $SWAP_START 100% >$OUT 2>&1 || die "Failed to create SWAP partition"
+
+if [ $DEBUG -eq 1 ]; then
+	parted -s $DEVICE print
+fi
+
+
+#
+# Check if any $DEVICE partitions are mounted after partitioning
+#
+unmount_device || die "Failed to unmount $DEVICE partitions"
+
+
+#
+# Format $DEVICE partitions
+#
+info "Formatting partitions"
+debug "Formatting $BOOTFS as vfat"
+if [ ! "${DEVICE#/dev/loop}" = "${DEVICE}" ]; then
+	mkfs.vfat -I $BOOTFS -n "EFI" >$OUT 2>&1 || die "Failed to format $BOOTFS"
+else
+	mkfs.vfat $BOOTFS -n "EFI" >$OUT 2>&1 || die "Failed to format $BOOTFS"
+fi
+
+debug "Formatting $ROOTFS as ext3"
+mkfs.ext3 -F $ROOTFS -L "ROOT" >$OUT 2>&1 || die "Failed to format $ROOTFS"
+
+debug "Formatting swap partition ($SWAP)"
+mkswap $SWAP >$OUT 2>&1 || die "Failed to prepare swap"
+
+
+#
+# Installing to $DEVICE
+#
+debug "Mounting images and device in preparation for installation"
+mount -o loop $HDDIMG $HDDIMG_MNT >$OUT 2>&1 || error "Failed to mount $HDDIMG"
+mount -o loop $HDDIMG_MNT/rootfs.img $HDDIMG_ROOTFS_MNT >$OUT 2>&1 || error "Failed to mount rootfs.img"
+mount $ROOTFS $ROOTFS_MNT >$OUT 2>&1 || error "Failed to mount $ROOTFS on $ROOTFS_MNT"
+mount $BOOTFS $BOOTFS_MNT >$OUT 2>&1 || error "Failed to mount $BOOTFS on $BOOTFS_MNT"
+
+info "Preparing boot partition"
+EFIDIR="$BOOTFS_MNT/EFI/BOOT"
+cp $HDDIMG_MNT/vmlinuz $BOOTFS_MNT >$OUT 2>&1 || error "Failed to copy vmlinuz"
+# Copy the efi loader and configs (booti*.efi and grub.cfg if it exists)
+cp -r $HDDIMG_MNT/EFI $BOOTFS_MNT >$OUT 2>&1 || error "Failed to copy EFI dir"
+# Silently ignore a missing gummiboot loader dir (we might just be a GRUB image)
+cp -r $HDDIMG_MNT/loader $BOOTFS_MNT >$OUT 2>&1
+
+# Update the boot loaders configurations for an installed image
+# Remove any existing root= kernel parameters and:
+# o Add a root= parameter with the target rootfs
+# o Specify ro so fsck can be run during boot
+# o Specify rootwait in case the target media is an asyncronous block device
+#   such as MMC or USB disks
+# o Specify "quiet" to minimize boot time when using slow serial consoles
+
+# Look for a GRUB installation
+GRUB_CFG="$EFIDIR/grub.cfg"
+if [ -e "$GRUB_CFG" ]; then
+	info "Configuring GRUB"
+	# Delete the install entry
+	sed -i "/menuentry 'install'/,/^}/d" $GRUB_CFG
+	# Delete the initrd lines
+	sed -i "/initrd /d" $GRUB_CFG
+	# Delete any LABEL= strings
+	sed -i "s/ LABEL=[^ ]*/ /" $GRUB_CFG
+
+	sed -i "s@ root=[^ ]*@ @" $GRUB_CFG
+	sed -i "s@vmlinuz @vmlinuz root=$TARGET_ROOTFS ro rootwait quiet @" $GRUB_CFG
+fi
+
+# Look for a gummiboot installation
+GUMMI_ENTRIES="$BOOTFS_MNT/loader/entries"
+GUMMI_CFG="$GUMMI_ENTRIES/boot.conf"
+if [ -d "$GUMMI_ENTRIES" ]; then
+	info "Configuring Gummiboot"
+	# remove the install target if it exists
+	rm $GUMMI_ENTRIES/install.conf >$OUT 2>&1
+
+	if [ ! -e "$GUMMI_CFG" ]; then
+		echo "ERROR: $GUMMI_CFG not found"
+	fi
+
+	sed -i "/initrd /d" $GUMMI_CFG
+	sed -i "s@ root=[^ ]*@ @" $GUMMI_CFG
+	sed -i "s@options *LABEL=boot @options LABEL=Boot root=$TARGET_ROOTFS ro rootwait quiet @" $GUMMI_CFG
+fi
+
+# Ensure we have at least one EFI bootloader configured
+if [ ! -e $GRUB_CFG ] && [ ! -e $GUMMI_CFG ]; then
+	die "No EFI bootloader configuration found"
+fi
+
+
+info "Copying ROOTFS files (this may take a while)"
+cp -a $HDDIMG_ROOTFS_MNT/* $ROOTFS_MNT >$OUT 2>&1 || die "Root FS copy failed"
+
+echo "$TARGET_SWAP     swap             swap       defaults              0 0" >> $ROOTFS_MNT/etc/fstab
+
+# We dont want udev to mount our root device while we're booting...
+if [ -d $ROOTFS_MNT/etc/udev/ ] ; then
+	echo "$TARGET_DEVICE" >> $ROOTFS_MNT/etc/udev/mount.blacklist
+fi
+
+
+# Call cleanup to unmount devices and images and remove the TMPDIR
+cleanup
+
+echo ""
+if [ $WARNINGS -ne 0 ] && [ $ERRORS -eq 0 ]; then
+	echo "${YELLOW}Installation completed with warnings${CLEAR}"
+	echo "${YELLOW}Warnings: $WARNINGS${CLEAR}"
+elif [ $ERRORS -ne 0 ]; then
+	echo "${RED}Installation encountered errors${CLEAR}"
+	echo "${RED}Errors: $ERRORS${CLEAR}"
+	echo "${YELLOW}Warnings: $WARNINGS${CLEAR}"
+else
+	success "Installation completed successfully"
+fi
+echo ""
diff --git a/scripts/contrib/python/generate-manifest-2.7.py b/scripts/contrib/python/generate-manifest-2.7.py
new file mode 100755
index 0000000..936522e
--- /dev/null
+++ b/scripts/contrib/python/generate-manifest-2.7.py
@@ -0,0 +1,398 @@
+#!/usr/bin/env python
+
+# generate Python Manifest for the OpenEmbedded build system
+# (C) 2002-2010 Michael 'Mickey' Lauer <mlauer@vanille-media.de>
+# (C) 2007 Jeremy Laine
+# licensed under MIT, see COPYING.MIT
+#
+# June 22, 2011 -- Mark Hatle <mark.hatle@windriver.com>
+#  * Updated to no longer generate special -dbg package, instead use the
+#    single system -dbg
+#  * Update version with ".1" to indicate this change
+
+import os
+import sys
+import time
+
+VERSION = "2.7.2"
+
+__author__ = "Michael 'Mickey' Lauer <mlauer@vanille-media.de>"
+__version__ = "20110222.2"
+
+class MakefileMaker:
+
+    def __init__( self, outfile ):
+        """initialize"""
+        self.packages = {}
+        self.targetPrefix = "${libdir}/python%s/" % VERSION[:3]
+        self.output = outfile
+        self.out( """
+# WARNING: This file is AUTO GENERATED: Manual edits will be lost next time I regenerate the file.
+# Generator: '%s' Version %s (C) 2002-2010 Michael 'Mickey' Lauer <mlauer@vanille-media.de>
+# Visit the Python for Embedded Systems Site => http://www.Vanille.de/projects/python.spy
+""" % ( sys.argv[0], __version__ ) )
+
+    #
+    # helper functions
+    #
+
+    def out( self, data ):
+        """print a line to the output file"""
+        self.output.write( "%s\n" % data )
+
+    def setPrefix( self, targetPrefix ):
+        """set a file prefix for addPackage files"""
+        self.targetPrefix = targetPrefix
+
+    def doProlog( self ):
+        self.out( """ """ )
+        self.out( "" )
+
+    def addPackage( self, name, description, dependencies, filenames ):
+        """add a package to the Makefile"""
+        if type( filenames ) == type( "" ):
+            filenames = filenames.split()
+        fullFilenames = []
+        for filename in filenames:
+            if filename[0] != "$":
+                fullFilenames.append( "%s%s" % ( self.targetPrefix, filename ) )
+            else:
+                fullFilenames.append( filename )
+        self.packages[name] = description, dependencies, fullFilenames
+
+    def doBody( self ):
+        """generate body of Makefile"""
+
+        global VERSION
+
+        #
+        # generate provides line
+        #
+
+        provideLine = 'PROVIDES+="'
+        for name in sorted(self.packages):
+            provideLine += "%s " % name
+        provideLine += '"'
+
+        self.out( provideLine )
+        self.out( "" )
+
+        #
+        # generate package line
+        #
+
+        packageLine = 'PACKAGES="${PN}-dbg '
+        for name in sorted(self.packages):
+            if name.startswith("${PN}-distutils"):
+                if name == "${PN}-distutils":
+                    packageLine += "%s-staticdev %s " % (name, name)
+            elif name != '${PN}-dbg':
+                packageLine += "%s " % name
+        packageLine += '${PN}-modules"'
+
+        self.out( packageLine )
+        self.out( "" )
+
+        #
+        # generate package variables
+        #
+
+        for name, data in sorted(self.packages.iteritems()):
+            desc, deps, files = data
+
+            #
+            # write out the description, revision and dependencies
+            #
+            self.out( 'SUMMARY_%s="%s"' % ( name, desc ) )
+            self.out( 'RDEPENDS_%s="%s"' % ( name, deps ) )
+
+            line = 'FILES_%s="' % name
+
+            #
+            # check which directories to make in the temporary directory
+            #
+
+            dirset = {} # if python had a set-datatype this would be sufficient. for now, we're using a dict instead.
+            for target in files:
+                dirset[os.path.dirname( target )] = True
+
+            #
+            # generate which files to copy for the target (-dfR because whole directories are also allowed)
+            #
+
+            for target in files:
+                line += "%s " % target
+
+            line += '"'
+            self.out( line )
+            self.out( "" )
+
+        self.out( 'SUMMARY_${PN}-modules="All Python modules"' )
+        line = 'RDEPENDS_${PN}-modules="'
+
+        for name, data in sorted(self.packages.iteritems()):
+            if name not in ['${PN}-dev', '${PN}-distutils-staticdev']:
+                line += "%s " % name
+
+        self.out( "%s \"" % line )
+        self.out( 'ALLOW_EMPTY_${PN}-modules = "1"' )
+
+    def doEpilog( self ):
+        self.out( """""" )
+        self.out( "" )
+
+    def make( self ):
+        self.doProlog()
+        self.doBody()
+        self.doEpilog()
+
+if __name__ == "__main__":
+
+    if len( sys.argv ) > 1:
+        try:
+            os.unlink(sys.argv[1])
+        except Exception:
+            sys.exc_clear()
+        outfile = file( sys.argv[1], "w" )
+    else:
+        outfile = sys.stdout
+
+    m = MakefileMaker( outfile )
+
+    # Add packages here. Only specify dlopen-style library dependencies here, no ldd-style dependencies!
+    # Parameters: revision, name, description, dependencies, filenames
+    #
+
+    m.addPackage( "${PN}-core", "Python interpreter and core modules", "${PN}-lang ${PN}-re",
+    "__future__.* _abcoll.* abc.* copy.* copy_reg.* ConfigParser.* " +
+    "genericpath.* getopt.* linecache.* new.* " +
+    "os.* posixpath.* struct.* " +
+    "warnings.* site.* stat.* " +
+    "UserDict.* UserList.* UserString.* " +
+    "lib-dynload/binascii.so lib-dynload/_struct.so lib-dynload/time.so " +
+    "lib-dynload/xreadlines.so types.* platform.* ${bindir}/python* "  +
+    "_weakrefset.* sysconfig.* _sysconfigdata.* config/Makefile " +
+    "${includedir}/python${PYTHON_MAJMIN}/pyconfig*.h " +
+    "${libdir}/python${PYTHON_MAJMIN}/sitecustomize.py ")
+
+    m.addPackage( "${PN}-dev", "Python development package", "${PN}-core",
+    "${includedir} " +
+    "${libdir}/lib*${SOLIBSDEV} " +
+    "${libdir}/*.la " +
+    "${libdir}/*.a " +
+    "${libdir}/*.o " +
+    "${libdir}/pkgconfig " +
+    "${base_libdir}/*.a " +
+    "${base_libdir}/*.o " +
+    "${datadir}/aclocal " +
+    "${datadir}/pkgconfig " )
+
+    m.addPackage( "${PN}-2to3", "Python automated Python 2 to 3 code translator", "${PN}-core",
+    "${bindir}/2to3 lib2to3" ) # package
+
+    m.addPackage( "${PN}-idle", "Python Integrated Development Environment", "${PN}-core ${PN}-tkinter",
+    "${bindir}/idle idlelib" ) # package
+
+    m.addPackage( "${PN}-pydoc", "Python interactive help support", "${PN}-core ${PN}-lang ${PN}-stringold ${PN}-re",
+    "${bindir}/pydoc pydoc.* pydoc_data" )
+
+    m.addPackage( "${PN}-smtpd", "Python Simple Mail Transport Daemon", "${PN}-core ${PN}-netserver ${PN}-email ${PN}-mime",
+    "${bindir}/smtpd.* smtpd.*" )
+
+    m.addPackage( "${PN}-audio", "Python Audio Handling", "${PN}-core",
+    "wave.* chunk.* sndhdr.* lib-dynload/ossaudiodev.so lib-dynload/audioop.so audiodev.* sunaudio.* sunau.* toaiff.*" )
+
+    m.addPackage( "${PN}-bsddb", "Python bindings for the Berkeley Database", "${PN}-core",
+    "bsddb lib-dynload/_bsddb.so" ) # package
+
+    m.addPackage( "${PN}-codecs", "Python codecs, encodings & i18n support", "${PN}-core ${PN}-lang",
+    "codecs.* encodings gettext.* locale.* lib-dynload/_locale.so lib-dynload/_codecs* lib-dynload/_multibytecodec.so lib-dynload/unicodedata.so stringprep.* xdrlib.*" )
+
+    m.addPackage( "${PN}-compile", "Python bytecode compilation support", "${PN}-core",
+    "py_compile.* compileall.*" )
+
+    m.addPackage( "${PN}-compiler", "Python compiler support", "${PN}-core",
+    "compiler" ) # package
+
+    m.addPackage( "${PN}-compression", "Python high-level compression support", "${PN}-core ${PN}-zlib",
+    "gzip.* zipfile.* tarfile.* lib-dynload/bz2.so" )
+
+    m.addPackage( "${PN}-crypt", "Python basic cryptographic and hashing support", "${PN}-core",
+    "hashlib.* md5.* sha.* lib-dynload/crypt.so lib-dynload/_hashlib.so lib-dynload/_sha256.so lib-dynload/_sha512.so" )
+
+    m.addPackage( "${PN}-textutils", "Python option parsing, text wrapping and CSV support", "${PN}-core ${PN}-io ${PN}-re ${PN}-stringold",
+    "lib-dynload/_csv.so csv.* optparse.* textwrap.*" )
+
+    m.addPackage( "${PN}-curses", "Python curses support", "${PN}-core",
+    "curses lib-dynload/_curses.so lib-dynload/_curses_panel.so" ) # directory + low level module
+
+    m.addPackage( "${PN}-ctypes", "Python C types support", "${PN}-core",
+    "ctypes lib-dynload/_ctypes.so lib-dynload/_ctypes_test.so" ) # directory + low level module
+
+    m.addPackage( "${PN}-datetime", "Python calendar and time support", "${PN}-core ${PN}-codecs",
+    "_strptime.* calendar.* lib-dynload/datetime.so" )
+
+    m.addPackage( "${PN}-db", "Python file-based database support", "${PN}-core",
+    "anydbm.* dumbdbm.* whichdb.* " )
+
+    m.addPackage( "${PN}-debugger", "Python debugger", "${PN}-core ${PN}-io ${PN}-lang ${PN}-re ${PN}-stringold ${PN}-shell ${PN}-pprint",
+    "bdb.* pdb.*" )
+
+    m.addPackage( "${PN}-difflib", "Python helpers for computing deltas between objects", "${PN}-lang ${PN}-re",
+    "difflib.*" )
+
+    m.addPackage( "${PN}-distutils-staticdev", "Python distribution utilities (static libraries)", "${PN}-distutils",
+    "config/lib*.a" ) # package
+
+    m.addPackage( "${PN}-distutils", "Python Distribution Utilities", "${PN}-core",
+    "config distutils" ) # package
+
+    m.addPackage( "${PN}-doctest", "Python framework for running examples in docstrings", "${PN}-core ${PN}-lang ${PN}-io ${PN}-re ${PN}-unittest ${PN}-debugger ${PN}-difflib",
+    "doctest.*" )
+
+    # FIXME consider adding to some higher level package
+    m.addPackage( "${PN}-elementtree", "Python elementree", "${PN}-core",
+    "lib-dynload/_elementtree.so" )
+
+    m.addPackage( "${PN}-email", "Python email support", "${PN}-core ${PN}-io ${PN}-re ${PN}-mime ${PN}-audio ${PN}-image ${PN}-netclient",
+    "imaplib.* email" ) # package
+
+    m.addPackage( "${PN}-fcntl", "Python's fcntl interface", "${PN}-core",
+    "lib-dynload/fcntl.so" )
+
+    m.addPackage( "${PN}-hotshot", "Python hotshot performance profiler", "${PN}-core",
+    "hotshot lib-dynload/_hotshot.so" )
+
+    m.addPackage( "${PN}-html", "Python HTML processing support", "${PN}-core",
+    "formatter.* htmlentitydefs.* htmllib.* markupbase.* sgmllib.* HTMLParser.* " )
+
+    m.addPackage( "${PN}-importlib", "Python import implementation library", "${PN}-core",
+    "importlib" )
+
+    m.addPackage( "${PN}-gdbm", "Python GNU database support", "${PN}-core",
+    "lib-dynload/gdbm.so" )
+
+    m.addPackage( "${PN}-image", "Python graphical image handling", "${PN}-core",
+    "colorsys.* imghdr.* lib-dynload/imageop.so lib-dynload/rgbimg.so" )
+
+    m.addPackage( "${PN}-io", "Python low-level I/O", "${PN}-core ${PN}-math ${PN}-textutils ${PN}-netclient ${PN}-contextlib",
+    "lib-dynload/_socket.so lib-dynload/_io.so lib-dynload/_ssl.so lib-dynload/select.so lib-dynload/termios.so lib-dynload/cStringIO.so " +
+    "pipes.* socket.* ssl.* tempfile.* StringIO.* io.* _pyio.*" )
+
+    m.addPackage( "${PN}-json", "Python JSON support", "${PN}-core ${PN}-math ${PN}-re ${PN}-codecs",
+    "json lib-dynload/_json.so" ) # package
+
+    m.addPackage( "${PN}-lang", "Python low-level language support", "${PN}-core",
+    "lib-dynload/_bisect.so lib-dynload/_collections.so lib-dynload/_heapq.so lib-dynload/_weakref.so lib-dynload/_functools.so " +
+    "lib-dynload/array.so lib-dynload/itertools.so lib-dynload/operator.so lib-dynload/parser.so " +
+    "atexit.* bisect.* code.* codeop.* collections.* dis.* functools.* heapq.* inspect.* keyword.* opcode.* symbol.* repr.* token.* " +
+    "tokenize.* traceback.* weakref.*" )
+
+    m.addPackage( "${PN}-logging", "Python logging support", "${PN}-core ${PN}-io ${PN}-lang ${PN}-pickle ${PN}-stringold",
+    "logging" ) # package
+
+    m.addPackage( "${PN}-mailbox", "Python mailbox format support", "${PN}-core ${PN}-mime",
+    "mailbox.*" )
+
+    m.addPackage( "${PN}-math", "Python math support", "${PN}-core ${PN}-crypt",
+    "lib-dynload/cmath.so lib-dynload/math.so lib-dynload/_random.so random.* sets.*" )
+
+    m.addPackage( "${PN}-mime", "Python MIME handling APIs", "${PN}-core ${PN}-io",
+    "mimetools.* uu.* quopri.* rfc822.* MimeWriter.*" )
+
+    m.addPackage( "${PN}-mmap", "Python memory-mapped file support", "${PN}-core ${PN}-io",
+    "lib-dynload/mmap.so " )
+
+    m.addPackage( "${PN}-multiprocessing", "Python multiprocessing support", "${PN}-core ${PN}-io ${PN}-lang ${PN}-pickle ${PN}-threading ${PN}-ctypes ${PN}-mmap",
+    "lib-dynload/_multiprocessing.so multiprocessing" ) # package
+
+    m.addPackage( "${PN}-netclient", "Python Internet Protocol clients", "${PN}-core ${PN}-crypt ${PN}-datetime ${PN}-io ${PN}-lang ${PN}-logging ${PN}-mime",
+    "*Cookie*.* " +
+    "base64.* cookielib.* ftplib.* gopherlib.* hmac.* httplib.* mimetypes.* nntplib.* poplib.* smtplib.* telnetlib.* urllib.* urllib2.* urlparse.* uuid.* rfc822.* mimetools.*" )
+
+    m.addPackage( "${PN}-netserver", "Python Internet Protocol servers", "${PN}-core ${PN}-netclient ${PN}-shell ${PN}-threading",
+    "cgi.* *HTTPServer.* SocketServer.*" )
+
+    m.addPackage( "${PN}-numbers", "Python number APIs", "${PN}-core ${PN}-lang ${PN}-re",
+    "decimal.* fractions.* numbers.*" )
+
+    m.addPackage( "${PN}-pickle", "Python serialisation/persistence support", "${PN}-core ${PN}-codecs ${PN}-io ${PN}-re",
+    "pickle.* shelve.* lib-dynload/cPickle.so pickletools.*" )
+
+    m.addPackage( "${PN}-pkgutil", "Python package extension utility support", "${PN}-core",
+    "pkgutil.*")
+
+    m.addPackage( "${PN}-pprint", "Python pretty-print support", "${PN}-core ${PN}-io",
+    "pprint.*" )
+
+    m.addPackage( "${PN}-profile", "Python basic performance profiling support", "${PN}-core ${PN}-textutils",
+    "profile.* pstats.* cProfile.* lib-dynload/_lsprof.so" )
+
+    m.addPackage( "${PN}-re", "Python Regular Expression APIs", "${PN}-core",
+    "re.* sre.* sre_compile.* sre_constants* sre_parse.*" ) # _sre is builtin
+
+    m.addPackage( "${PN}-readline", "Python readline support", "${PN}-core",
+    "lib-dynload/readline.so rlcompleter.*" )
+
+    m.addPackage( "${PN}-resource", "Python resource control interface", "${PN}-core",
+    "lib-dynload/resource.so" )
+
+    m.addPackage( "${PN}-shell", "Python shell-like functionality", "${PN}-core ${PN}-re",
+    "cmd.* commands.* dircache.* fnmatch.* glob.* popen2.* shlex.* shutil.*" )
+
+    m.addPackage( "${PN}-robotparser", "Python robots.txt parser", "${PN}-core ${PN}-netclient",
+    "robotparser.*")
+
+    m.addPackage( "${PN}-subprocess", "Python subprocess support", "${PN}-core ${PN}-io ${PN}-re ${PN}-fcntl ${PN}-pickle",
+    "subprocess.*" )
+
+    m.addPackage( "${PN}-sqlite3", "Python Sqlite3 database support", "${PN}-core ${PN}-datetime ${PN}-lang ${PN}-crypt ${PN}-io ${PN}-threading ${PN}-zlib",
+    "lib-dynload/_sqlite3.so sqlite3/dbapi2.* sqlite3/__init__.* sqlite3/dump.*" )
+
+    m.addPackage( "${PN}-sqlite3-tests", "Python Sqlite3 database support tests", "${PN}-core ${PN}-sqlite3",
+    "sqlite3/test" )
+
+    m.addPackage( "${PN}-stringold", "Python string APIs [deprecated]", "${PN}-core ${PN}-re",
+    "lib-dynload/strop.so string.* stringold.*" )
+
+    m.addPackage( "${PN}-syslog", "Python syslog interface", "${PN}-core",
+    "lib-dynload/syslog.so" )
+
+    m.addPackage( "${PN}-terminal", "Python terminal controlling support", "${PN}-core ${PN}-io",
+    "pty.* tty.*" )
+
+    m.addPackage( "${PN}-tests", "Python tests", "${PN}-core",
+    "test" ) # package
+
+    m.addPackage( "${PN}-threading", "Python threading & synchronization support", "${PN}-core ${PN}-lang",
+    "_threading_local.* dummy_thread.* dummy_threading.* mutex.* threading.* Queue.*" )
+
+    m.addPackage( "${PN}-tkinter", "Python Tcl/Tk bindings", "${PN}-core",
+    "lib-dynload/_tkinter.so lib-tk" ) # package
+
+    m.addPackage( "${PN}-unittest", "Python unit testing framework", "${PN}-core ${PN}-stringold ${PN}-lang ${PN}-io ${PN}-difflib ${PN}-pprint ${PN}-shell",
+    "unittest/" )
+
+    m.addPackage( "${PN}-unixadmin", "Python Unix administration support", "${PN}-core",
+    "lib-dynload/nis.so lib-dynload/grp.so lib-dynload/pwd.so getpass.*" )
+
+    m.addPackage( "${PN}-xml", "Python basic XML support", "${PN}-core ${PN}-elementtree ${PN}-re",
+    "lib-dynload/pyexpat.so xml xmllib.*" ) # package
+
+    m.addPackage( "${PN}-xmlrpc", "Python XML-RPC support", "${PN}-core ${PN}-xml ${PN}-netserver ${PN}-lang",
+    "xmlrpclib.* SimpleXMLRPCServer.* DocXMLRPCServer.*" )
+
+    m.addPackage( "${PN}-zlib", "Python zlib compression support", "${PN}-core",
+    "lib-dynload/zlib.so" )
+
+    m.addPackage( "${PN}-mailbox", "Python mailbox format support", "${PN}-core ${PN}-mime",
+    "mailbox.*" )
+
+    m.addPackage( "${PN}-argparse", "Python command line argument parser", "${PN}-core ${PN}-codecs ${PN}-textutils",
+    "argparse.*" )
+
+    m.addPackage( "${PN}-contextlib", "Python utilities for with-statement" +
+    "contexts.", "${PN}-core",
+    "${libdir}/python${PYTHON_MAJMIN}/contextlib.*" )
+
+    m.make()
diff --git a/scripts/contrib/python/generate-manifest-3.4.py b/scripts/contrib/python/generate-manifest-3.4.py
new file mode 100755
index 0000000..06eecdc
--- /dev/null
+++ b/scripts/contrib/python/generate-manifest-3.4.py
@@ -0,0 +1,388 @@
+#!/usr/bin/env python
+
+# generate Python Manifest for the OpenEmbedded build system
+# (C) 2002-2010 Michael 'Mickey' Lauer <mlauer@vanille-media.de>
+# (C) 2007 Jeremy Laine
+# licensed under MIT, see COPYING.MIT
+#
+# June 22, 2011 -- Mark Hatle <mark.hatle@windriver.com>
+#  * Updated to no longer generate special -dbg package, instead use the
+#    single system -dbg
+#  * Update version with ".1" to indicate this change
+#
+# 2014 Khem Raj <raj.khem@gmail.com>
+# Added python3 support
+#
+import os
+import sys
+import time
+
+VERSION = "3.4.2"
+
+__author__ = "Michael 'Mickey' Lauer <mlauer@vanille-media.de>"
+__version__ = "20140131"
+
+class MakefileMaker:
+
+    def __init__( self, outfile ):
+        """initialize"""
+        self.packages = {}
+        self.targetPrefix = "${libdir}/python%s/" % VERSION[:3]
+        self.output = outfile
+        self.out( """
+# WARNING: This file is AUTO GENERATED: Manual edits will be lost next time I regenerate the file.
+# Generator: '%s' Version %s (C) 2002-2010 Michael 'Mickey' Lauer <mlauer@vanille-media.de>
+# Visit the Python for Embedded Systems Site => http://www.Vanille.de/projects/python.spy
+""" % ( sys.argv[0], __version__ ) )
+
+    #
+    # helper functions
+    #
+
+    def out( self, data ):
+        """print a line to the output file"""
+        self.output.write( "%s\n" % data )
+
+    def setPrefix( self, targetPrefix ):
+        """set a file prefix for addPackage files"""
+        self.targetPrefix = targetPrefix
+
+    def doProlog( self ):
+        self.out( """ """ )
+        self.out( "" )
+
+    def addPackage( self, name, description, dependencies, filenames ):
+        """add a package to the Makefile"""
+        if type( filenames ) == type( "" ):
+            filenames = filenames.split()
+        fullFilenames = []
+        for filename in filenames:
+            if filename[0] != "$":
+                fullFilenames.append( "%s%s" % ( self.targetPrefix, filename ) )
+            else:
+                fullFilenames.append( filename )
+        self.packages[name] = description, dependencies, fullFilenames
+
+    def doBody( self ):
+        """generate body of Makefile"""
+
+        global VERSION
+
+        #
+        # generate provides line
+        #
+
+        provideLine = 'PROVIDES+="'
+        for name in sorted(self.packages):
+            provideLine += "%s " % name
+        provideLine += '"'
+
+        self.out( provideLine )
+        self.out( "" )
+
+        #
+        # generate package line
+        #
+
+        packageLine = 'PACKAGES="${PN}-dbg '
+        for name in sorted(self.packages):
+            if name.startswith("${PN}-distutils"):
+                if name == "${PN}-distutils":
+                    packageLine += "%s-staticdev %s " % (name, name)
+            elif name != '${PN}-dbg':
+                packageLine += "%s " % name
+        packageLine += '${PN}-modules"'
+
+        self.out( packageLine )
+        self.out( "" )
+
+        #
+        # generate package variables
+        #
+
+        for name, data in sorted(self.packages.iteritems()):
+            desc, deps, files = data
+
+            #
+            # write out the description, revision and dependencies
+            #
+            self.out( 'SUMMARY_%s="%s"' % ( name, desc ) )
+            self.out( 'RDEPENDS_%s="%s"' % ( name, deps ) )
+
+            line = 'FILES_%s="' % name
+
+            #
+            # check which directories to make in the temporary directory
+            #
+
+            dirset = {} # if python had a set-datatype this would be sufficient. for now, we're using a dict instead.
+            for target in files:
+                dirset[os.path.dirname( target )] = True
+
+            #
+            # generate which files to copy for the target (-dfR because whole directories are also allowed)
+            #
+
+            for target in files:
+                line += "%s " % target
+
+            line += '"'
+            self.out( line )
+            self.out( "" )
+
+        self.out( 'SUMMARY_${PN}-modules="All Python modules"' )
+        line = 'RDEPENDS_${PN}-modules="'
+
+        for name, data in sorted(self.packages.iteritems()):
+            if name not in ['${PN}-dev', '${PN}-distutils-staticdev']:
+                line += "%s " % name
+
+        self.out( "%s \"" % line )
+        self.out( 'ALLOW_EMPTY_${PN}-modules = "1"' )
+
+    def doEpilog( self ):
+        self.out( """""" )
+        self.out( "" )
+
+    def make( self ):
+        self.doProlog()
+        self.doBody()
+        self.doEpilog()
+
+if __name__ == "__main__":
+
+    if len( sys.argv ) > 1:
+        try:
+            os.unlink(sys.argv[1])
+        except Exception:
+            sys.exc_clear()
+        outfile = file( sys.argv[1], "w" )
+    else:
+        outfile = sys.stdout
+
+    m = MakefileMaker( outfile )
+
+    # Add packages here. Only specify dlopen-style library dependencies here, no ldd-style dependencies!
+    # Parameters: revision, name, description, dependencies, filenames
+    #
+
+    m.addPackage( "${PN}-core", "Python interpreter and core modules", "${PN}-lang ${PN}-re ${PN}-reprlib ${PN}-codecs ${PN}-io ${PN}-math",
+    "__future__.* _abcoll.* abc.* copy.* copyreg.* ConfigParser.* " +
+    "genericpath.* getopt.* linecache.* new.* " +
+    "os.* posixpath.* struct.* " +
+    "warnings.* site.* stat.* " +
+    "UserDict.* UserList.* UserString.* " +
+    "lib-dynload/binascii.*.so lib-dynload/_struct.*.so lib-dynload/time.*.so " +
+    "lib-dynload/xreadlines.*.so types.* platform.* ${bindir}/python* "  + 
+    "_weakrefset.* sysconfig.* _sysconfigdata.* config/Makefile " +
+    "${includedir}/python${PYTHON_BINABI}/pyconfig*.h " +
+    "${libdir}/python${PYTHON_MAJMIN}/collections " +
+    "${libdir}/python${PYTHON_MAJMIN}/_collections_abc.* " +
+    "${libdir}/python${PYTHON_MAJMIN}/_sitebuiltins.* " +
+    "${libdir}/python${PYTHON_MAJMIN}/sitecustomize.py ")
+
+    m.addPackage( "${PN}-dev", "Python development package", "${PN}-core",
+    "${includedir} " +
+    "${libdir}/lib*${SOLIBSDEV} " +
+    "${libdir}/*.la " +
+    "${libdir}/*.a " +
+    "${libdir}/*.o " +
+    "${libdir}/pkgconfig " +
+    "${base_libdir}/*.a " +
+    "${base_libdir}/*.o " +
+    "${datadir}/aclocal " +
+    "${datadir}/pkgconfig " )
+
+    m.addPackage( "${PN}-2to3", "Python automated Python 2 to 3 code translator", "${PN}-core",
+    "lib2to3" ) # package
+
+    m.addPackage( "${PN}-idle", "Python Integrated Development Environment", "${PN}-core ${PN}-tkinter",
+    "${bindir}/idle idlelib" ) # package
+
+    m.addPackage( "${PN}-pydoc", "Python interactive help support", "${PN}-core ${PN}-lang ${PN}-stringold ${PN}-re",
+    "${bindir}/pydoc pydoc.* pydoc_data" )
+
+    m.addPackage( "${PN}-smtpd", "Python Simple Mail Transport Daemon", "${PN}-core ${PN}-netserver ${PN}-email ${PN}-mime",
+    "${bindir}/smtpd.* smtpd.*" )
+
+    m.addPackage( "${PN}-audio", "Python Audio Handling", "${PN}-core",
+    "wave.* chunk.* sndhdr.* lib-dynload/ossaudiodev.*.so lib-dynload/audioop.*.so audiodev.* sunaudio.* sunau.* toaiff.*" )
+
+    m.addPackage( "${PN}-asyncio", "Python Asynchronous I/O, event loop, coroutines and tasks", "${PN}-core",
+    "asyncio" )
+
+    m.addPackage( "${PN}-codecs", "Python codecs, encodings & i18n support", "${PN}-core ${PN}-lang",
+    "codecs.* encodings gettext.* locale.* lib-dynload/_locale.*.so lib-dynload/_codecs* lib-dynload/_multibytecodec.*.so lib-dynload/unicodedata.*.so stringprep.* xdrlib.*" )
+
+    m.addPackage( "${PN}-compile", "Python bytecode compilation support", "${PN}-core",
+    "py_compile.* compileall.*" )
+
+    m.addPackage( "${PN}-compression", "Python high-level compression support", "${PN}-core ${PN}-codecs",
+    "gzip.* zipfile.* tarfile.* lib-dynload/bz2.*.so" )
+
+    m.addPackage( "${PN}-crypt", "Python basic cryptographic and hashing support", "${PN}-core",
+    "hashlib.* md5.* sha.* lib-dynload/crypt.*.so lib-dynload/_hashlib.*.so lib-dynload/_sha256.*.so lib-dynload/_sha512.*.so" )
+
+    m.addPackage( "${PN}-textutils", "Python option parsing, text wrapping and CSV support", "${PN}-core ${PN}-io ${PN}-re ${PN}-stringold",
+    "lib-dynload/_csv.*.so csv.* optparse.* textwrap.*" )
+
+    m.addPackage( "${PN}-curses", "Python curses support", "${PN}-core",
+    "curses lib-dynload/_curses.*.so lib-dynload/_curses_panel.*.so" ) # directory + low level module
+
+    m.addPackage( "${PN}-ctypes", "Python C types support", "${PN}-core",
+    "ctypes lib-dynload/_ctypes.*.so lib-dynload/_ctypes_test.*.so" ) # directory + low level module
+
+    m.addPackage( "${PN}-datetime", "Python calendar and time support", "${PN}-core ${PN}-codecs",
+    "_strptime.* calendar.* lib-dynload/datetime.*.so" )
+
+    m.addPackage( "${PN}-db", "Python file-based database support", "${PN}-core",
+    "anydbm.* dumbdbm.* whichdb.* dbm lib-dynload/_dbm.*.so" )
+
+    m.addPackage( "${PN}-debugger", "Python debugger", "${PN}-core ${PN}-io ${PN}-lang ${PN}-re ${PN}-stringold ${PN}-shell ${PN}-pprint",
+    "bdb.* pdb.*" )
+
+    m.addPackage( "${PN}-difflib", "Python helpers for computing deltas between objects", "${PN}-lang ${PN}-re",
+    "difflib.*" )
+
+    m.addPackage( "${PN}-distutils-staticdev", "Python distribution utilities (static libraries)", "${PN}-distutils",
+    "config/lib*.a" ) # package
+
+    m.addPackage( "${PN}-distutils", "Python Distribution Utilities", "${PN}-core",
+    "config distutils" ) # package
+
+    m.addPackage( "${PN}-doctest", "Python framework for running examples in docstrings", "${PN}-core ${PN}-lang ${PN}-io ${PN}-re ${PN}-unittest ${PN}-debugger ${PN}-difflib",
+    "doctest.*" )
+
+    # FIXME consider adding to some higher level package
+    m.addPackage( "${PN}-elementtree", "Python elementree", "${PN}-core",
+    "lib-dynload/_elementtree.*.so" )
+
+    m.addPackage( "${PN}-email", "Python email support", "${PN}-core ${PN}-io ${PN}-re ${PN}-mime ${PN}-audio ${PN}-image ${PN}-netclient",
+    "imaplib.* email" ) # package
+
+    m.addPackage( "${PN}-fcntl", "Python's fcntl interface", "${PN}-core",
+    "lib-dynload/fcntl.*.so" )
+
+    m.addPackage( "${PN}-html", "Python HTML processing support", "${PN}-core",
+    "formatter.* htmlentitydefs.* htmllib.* markupbase.* sgmllib.* HTMLParser.* " )
+
+    m.addPackage( "${PN}-importlib", "Python import implementation library", "${PN}-core",
+    "importlib" )
+
+    m.addPackage( "${PN}-gdbm", "Python GNU database support", "${PN}-core",
+    "lib-dynload/_gdbm.*.so" )
+
+    m.addPackage( "${PN}-image", "Python graphical image handling", "${PN}-core",
+    "colorsys.* imghdr.* lib-dynload/imageop.*.so lib-dynload/rgbimg.*.so" )
+
+    m.addPackage( "${PN}-io", "Python low-level I/O", "${PN}-core ${PN}-math",
+    "lib-dynload/_socket.*.so lib-dynload/_io.*.so lib-dynload/_ssl.*.so lib-dynload/select.*.so lib-dynload/termios.*.so lib-dynload/cStringIO.*.so " +
+    "pipes.* socket.* ssl.* tempfile.* StringIO.* io.* _pyio.*" )
+
+    m.addPackage( "${PN}-json", "Python JSON support", "${PN}-core ${PN}-math ${PN}-re",
+    "json lib-dynload/_json.*.so" ) # package
+
+    m.addPackage( "${PN}-lang", "Python low-level language support", "${PN}-core",
+    "lib-dynload/_bisect.*.so lib-dynload/_collections.*.so lib-dynload/_heapq.*.so lib-dynload/_weakref.*.so lib-dynload/_functools.*.so " +
+    "lib-dynload/array.*.so lib-dynload/itertools.*.so lib-dynload/operator.*.so lib-dynload/parser.*.so " +
+    "atexit.* bisect.* code.* codeop.* collections.* _collections_abc.* dis.* functools.* heapq.* inspect.* keyword.* opcode.* symbol.* repr.* token.* " +
+    "tokenize.* traceback.* weakref.*" )
+
+    m.addPackage( "${PN}-logging", "Python logging support", "${PN}-core ${PN}-io ${PN}-lang ${PN}-pickle ${PN}-stringold",
+    "logging" ) # package
+
+    m.addPackage( "${PN}-mailbox", "Python mailbox format support", "${PN}-core ${PN}-mime",
+    "mailbox.*" )
+
+    m.addPackage( "${PN}-math", "Python math support", "${PN}-core",
+    "lib-dynload/cmath.*.so lib-dynload/math.*.so lib-dynload/_random.*.so random.* sets.*" )
+
+    m.addPackage( "${PN}-mime", "Python MIME handling APIs", "${PN}-core ${PN}-io",
+    "mimetools.* uu.* quopri.* rfc822.* MimeWriter.*" )
+
+    m.addPackage( "${PN}-mmap", "Python memory-mapped file support", "${PN}-core ${PN}-io",
+    "lib-dynload/mmap.*.so " )
+
+    m.addPackage( "${PN}-multiprocessing", "Python multiprocessing support", "${PN}-core ${PN}-io ${PN}-lang ${PN}-pickle ${PN}-threading ${PN}-ctypes ${PN}-mmap",
+    "lib-dynload/_multiprocessing.*.so multiprocessing" ) # package
+
+    m.addPackage( "${PN}-netclient", "Python Internet Protocol clients", "${PN}-core ${PN}-crypt ${PN}-datetime ${PN}-io ${PN}-lang ${PN}-logging ${PN}-mime",
+    "*Cookie*.* " +
+    "base64.* cookielib.* ftplib.* gopherlib.* hmac.* httplib.* mimetypes.* nntplib.* poplib.* smtplib.* telnetlib.* urllib  uuid.* rfc822.* mimetools.*" )
+
+    m.addPackage( "${PN}-netserver", "Python Internet Protocol servers", "${PN}-core ${PN}-netclient ${PN}-shell ${PN}-threading",
+    "cgi.* *HTTPServer.* SocketServer.*" )
+
+    m.addPackage( "${PN}-numbers", "Python number APIs", "${PN}-core ${PN}-lang ${PN}-re",
+    "decimal.* fractions.* numbers.*" )
+
+    m.addPackage( "${PN}-pickle", "Python serialisation/persistence support", "${PN}-core ${PN}-codecs ${PN}-io ${PN}-re",
+    "pickle.* shelve.* lib-dynload/cPickle.*.so pickletools.*" )
+
+    m.addPackage( "${PN}-pkgutil", "Python package extension utility support", "${PN}-core",
+    "pkgutil.*")
+
+    m.addPackage( "${PN}-pprint", "Python pretty-print support", "${PN}-core ${PN}-io",
+    "pprint.*" )
+
+    m.addPackage( "${PN}-profile", "Python basic performance profiling support", "${PN}-core ${PN}-textutils",
+    "profile.* pstats.* cProfile.* lib-dynload/_lsprof.*.so" )
+
+    m.addPackage( "${PN}-re", "Python Regular Expression APIs", "${PN}-core",
+    "re.* sre.* sre_compile.* sre_constants* sre_parse.*" ) # _sre is builtin
+
+    m.addPackage( "${PN}-readline", "Python readline support", "${PN}-core",
+    "lib-dynload/readline.*.so rlcompleter.*" )
+
+    m.addPackage( "${PN}-reprlib", "Python alternate repr() implementation", "${PN}-core",
+    "reprlib.py" )
+
+    m.addPackage( "${PN}-resource", "Python resource control interface", "${PN}-core",
+    "lib-dynload/resource.*.so" )
+
+    m.addPackage( "${PN}-shell", "Python shell-like functionality", "${PN}-core ${PN}-re",
+    "cmd.* commands.* dircache.* fnmatch.* glob.* popen2.* shlex.* shutil.*" )
+
+    m.addPackage( "${PN}-subprocess", "Python subprocess support", "${PN}-core ${PN}-io ${PN}-re ${PN}-fcntl ${PN}-pickle",
+    "subprocess.*" )
+
+    m.addPackage( "${PN}-sqlite3", "Python Sqlite3 database support", "${PN}-core ${PN}-datetime ${PN}-lang ${PN}-crypt ${PN}-io ${PN}-threading",
+    "lib-dynload/_sqlite3.*.so sqlite3/dbapi2.* sqlite3/__init__.* sqlite3/dump.*" )
+
+    m.addPackage( "${PN}-sqlite3-tests", "Python Sqlite3 database support tests", "${PN}-core ${PN}-sqlite3",
+    "sqlite3/test" )
+
+    m.addPackage( "${PN}-stringold", "Python string APIs [deprecated]", "${PN}-core ${PN}-re",
+    "lib-dynload/strop.*.so string.* stringold.*" )
+
+    m.addPackage( "${PN}-syslog", "Python syslog interface", "${PN}-core",
+    "lib-dynload/syslog.*.so" )
+
+    m.addPackage( "${PN}-terminal", "Python terminal controlling support", "${PN}-core ${PN}-io",
+    "pty.* tty.*" )
+
+    m.addPackage( "${PN}-tests", "Python tests", "${PN}-core",
+    "test" ) # package
+
+    m.addPackage( "${PN}-threading", "Python threading & synchronization support", "${PN}-core ${PN}-lang",
+    "_threading_local.* dummy_thread.* dummy_threading.* mutex.* threading.* Queue.*" )
+
+    m.addPackage( "${PN}-tkinter", "Python Tcl/Tk bindings", "${PN}-core",
+    "lib-dynload/_tkinter.*.so lib-tk tkinter" ) # package
+
+    m.addPackage( "${PN}-unittest", "Python unit testing framework", "${PN}-core ${PN}-stringold ${PN}-lang ${PN}-io ${PN}-difflib ${PN}-pprint ${PN}-shell",
+    "unittest/" )
+
+    m.addPackage( "${PN}-unixadmin", "Python Unix administration support", "${PN}-core",
+    "lib-dynload/nis.*.so lib-dynload/grp.*.so lib-dynload/pwd.*.so getpass.*" )
+
+    m.addPackage( "${PN}-xml", "Python basic XML support", "${PN}-core ${PN}-elementtree ${PN}-re",
+    "lib-dynload/pyexpat.*.so xml xmllib.*" ) # package
+
+    m.addPackage( "${PN}-xmlrpc", "Python XML-RPC support", "${PN}-core ${PN}-xml ${PN}-netserver ${PN}-lang",
+    "xmlrpclib.* SimpleXMLRPCServer.* DocXMLRPCServer.* xmlrpc" )
+
+    m.addPackage( "${PN}-mailbox", "Python mailbox format support", "${PN}-core ${PN}-mime",
+    "mailbox.*" )
+
+    m.make()
diff --git a/scripts/contrib/serdevtry b/scripts/contrib/serdevtry
new file mode 100755
index 0000000..74bd7b7
--- /dev/null
+++ b/scripts/contrib/serdevtry
@@ -0,0 +1,60 @@
+#!/bin/sh
+
+# Copyright (C) 2014 Intel Corporation
+#
+# Released under the MIT license (see COPYING.MIT)
+
+if [ "$1" = "" -o "$1" = "--help" ] ; then
+    echo "Usage: $0 <serial terminal command>"
+    echo
+    echo "Simple script to handle maintaining a terminal for serial devices that"
+    echo "disappear when a device is powered down or reset, such as the USB"
+    echo "serial console on the original BeagleBone (white version)."
+    echo
+    echo "e.g. $0 picocom -b 115200 /dev/ttyUSB0"
+    echo
+    exit
+fi
+
+args="$@"
+DEVICE=""
+while [ "$1" != "" ]; do
+    case "$1" in
+        /dev/*)
+            DEVICE=$1
+            break;;
+    esac
+    shift
+done
+
+if [ "$DEVICE" != "" ] ; then
+    while true; do
+        if [ ! -e $DEVICE ] ; then
+            echo "serdevtry: waiting for $DEVICE to exist..."
+            while [ ! -e $DEVICE ]; do
+                sleep 0.1
+            done
+        fi
+        if [ ! -w $DEVICE ] ; then
+            # Sometimes (presumably because of a race with udev) we get to
+            # the device before its permissions have been set up
+            RETRYNUM=0
+            while [ ! -w $DEVICE ]; do
+                if [ "$RETRYNUM" = "2" ] ; then
+                    echo "Device $DEVICE exists but is not writable!"
+                    exit 1
+                fi
+                RETRYNUM=$((RETRYNUM+1))
+                sleep 0.1
+            done
+        fi
+        $args
+        if [ -e $DEVICE ] ; then
+            break
+        fi
+    done
+else
+    echo "Unable to determine device node from command: $args"
+    exit 1
+fi
+
diff --git a/scripts/contrib/test_build_time.sh b/scripts/contrib/test_build_time.sh
new file mode 100755
index 0000000..9e5725a
--- /dev/null
+++ b/scripts/contrib/test_build_time.sh
@@ -0,0 +1,237 @@
+#!/bin/bash
+
+# Build performance regression test script
+#
+# Copyright 2011 Intel Corporation
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+#
+# DESCRIPTION
+# This script is intended to be used in conjunction with "git bisect run"
+# in order to find regressions in build time, however it can also be used
+# independently. It cleans out the build output directories, runs a
+# specified worker script (an example is test_build_time_worker.sh) under
+# TIME(1), logs the results to TEST_LOGDIR (default /tmp) and returns a
+# value telling "git bisect run" whether the build time is good (under
+# the specified threshold) or bad (over it). There is also a tolerance
+# option but it is not particularly useful as it only subtracts the
+# tolerance from the given threshold and uses it as the actual threshold.
+#
+# It is also capable of taking a file listing git revision hashes to be
+# test-applied to the repository in order to get past build failures that
+# would otherwise cause certain revisions to have to be skipped; if a
+# revision does not apply cleanly then the script assumes it does not
+# need to be applied and ignores it.
+#
+# Please see the help output (syntax below) for some important setup
+# instructions.
+#
+# AUTHORS
+# Paul Eggleton <paul.eggleton@linux.intel.com>
+
+
+syntax() {
+    echo "syntax: $0 <script> <time> <tolerance> [patchrevlist]"
+    echo ""
+    echo "  script       - worker script file (if in current dir, prefix with ./)"
+    echo "  time         - time threshold (in seconds, suffix m for minutes)"
+    echo "  tolerance    - tolerance (in seconds, suffix m for minutes or % for"
+    echo "                 percentage, can be 0)"
+    echo "  patchrevlist - optional file listing revisions to apply as patches on top"
+    echo ""
+    echo "You must set TEST_BUILDDIR to point to a previously created build directory,"
+    echo "however please note that this script will wipe out the TMPDIR defined in"
+    echo "TEST_BUILDDIR/conf/local.conf as part of its initial setup (as well as your"
+    echo "~/.ccache)"
+    echo ""
+    echo "To get rid of the sudo prompt, please add the following line to /etc/sudoers"
+    echo "(use 'visudo' to edit this; also it is assumed that the user you are running"
+    echo "as is a member of the 'wheel' group):"
+    echo ""
+    echo "%wheel ALL=(ALL) NOPASSWD: /sbin/sysctl -w vm.drop_caches=[1-3]"
+    echo ""
+    echo "Note: it is recommended that you disable crond and any other process that"
+    echo "may cause significant CPU or I/O usage during build performance tests."
+}
+
+# Note - we exit with 250 here because that will tell git bisect run that
+# something bad happened and stop
+if [ "$1" = "" ] ; then
+   syntax
+   exit 250
+fi
+
+if [ "$2" = "" ] ; then
+   syntax
+   exit 250
+fi
+
+if [ "$3" = "" ] ; then
+   syntax
+   exit 250
+fi
+
+if ! [[ "$2" =~ ^[0-9][0-9m.]*$ ]] ; then
+   echo "'$2' is not a valid number for threshold"
+   exit 250
+fi
+
+if ! [[ "$3" =~ ^[0-9][0-9m.%]*$ ]] ; then
+   echo "'$3' is not a valid number for tolerance"
+   exit 250
+fi
+
+if [ "$TEST_BUILDDIR" = "" ] ; then
+   echo "Please set TEST_BUILDDIR to a previously created build directory"
+   exit 250
+fi
+
+if [ ! -d "$TEST_BUILDDIR" ] ; then
+   echo "TEST_BUILDDIR $TEST_BUILDDIR not found"
+   exit 250
+fi
+
+git diff --quiet
+if [ $? != 0 ] ; then
+    echo "Working tree is dirty, cannot proceed"
+    exit 251
+fi
+
+if [ "$BB_ENV_EXTRAWHITE" != "" ] ; then
+   echo "WARNING: you are running after sourcing the build environment script, this is not recommended"
+fi
+
+runscript=$1
+timethreshold=$2
+tolerance=$3
+
+if [ "$4" != "" ] ; then
+    patchrevlist=`cat $4`
+else
+    patchrevlist=""
+fi
+
+if [[ timethreshold == *m* ]] ; then
+    timethreshold=`echo $timethreshold | sed s/m/*60/ | bc`
+fi
+
+if [[ $tolerance == *m* ]] ; then
+    tolerance=`echo $tolerance | sed s/m/*60/ | bc`
+elif [[ $tolerance == *%* ]] ; then
+    tolerance=`echo $tolerance | sed s/%//`
+    tolerance=`echo "scale = 2; (($tolerance * $timethreshold) / 100)" | bc`
+fi
+
+tmpdir=`grep "^TMPDIR" $TEST_BUILDDIR/conf/local.conf | sed -e 's/TMPDIR[ \t]*=[ \t\?]*"//' -e 's/"//'`
+if [ "x$tmpdir" = "x" ]; then
+    echo "Unable to determine TMPDIR from $TEST_BUILDDIR/conf/local.conf, bailing out"
+    exit 250
+fi
+sstatedir=`grep "^SSTATE_DIR" $TEST_BUILDDIR/conf/local.conf | sed -e 's/SSTATE_DIR[ \t\?]*=[ \t]*"//' -e 's/"//'`
+if [ "x$sstatedir" = "x" ]; then
+    echo "Unable to determine SSTATE_DIR from $TEST_BUILDDIR/conf/local.conf, bailing out"
+    exit 250
+fi
+
+if [ `expr length $tmpdir` -lt 4 ] ; then
+    echo "TMPDIR $tmpdir is less than 4 characters, bailing out"
+    exit 250
+fi
+
+if [ `expr length $sstatedir` -lt 4 ] ; then
+    echo "SSTATE_DIR $sstatedir is less than 4 characters, bailing out"
+    exit 250
+fi
+
+echo -n "About to wipe out TMPDIR $tmpdir, press Ctrl+C to break out...  "
+for i in 9 8 7 6 5 4 3 2 1
+do
+    echo -ne "\x08$i"
+    sleep 1
+done
+echo
+
+pushd . > /dev/null
+
+rm -f pseudodone
+echo "Removing TMPDIR $tmpdir..."
+rm -rf $tmpdir
+echo "Removing TMPDIR $tmpdir-*libc..."
+rm -rf $tmpdir-*libc
+echo "Removing SSTATE_DIR $sstatedir..."
+rm -rf $sstatedir
+echo "Removing ~/.ccache..."
+rm -rf ~/.ccache
+
+echo "Syncing..."
+sync
+sync
+echo "Dropping VM cache..."
+#echo 3 > /proc/sys/vm/drop_caches
+sudo /sbin/sysctl -w vm.drop_caches=3 > /dev/null
+
+if [ "$TEST_LOGDIR" = "" ] ; then
+    logdir="/tmp"
+else
+    logdir="$TEST_LOGDIR"
+fi
+rev=`git rev-parse HEAD`
+logfile="$logdir/timelog_$rev.log"
+echo -n > $logfile
+
+gitroot=`git rev-parse --show-toplevel`
+cd $gitroot
+for patchrev in $patchrevlist ; do
+    echo "Applying $patchrev"
+    patchfile=`mktemp`
+    git show $patchrev > $patchfile
+    git apply --check $patchfile &> /dev/null
+    if [ $? != 0 ] ; then
+        echo " ... patch does not apply without errors, ignoring"
+    else
+        echo "Applied $patchrev" >> $logfile
+        git apply $patchfile &> /dev/null
+    fi
+    rm $patchfile
+done
+
+sync
+echo "Quiescing for 5s..."
+sleep 5
+
+echo "Running $runscript at $rev..."
+timeoutfile=`mktemp`
+/usr/bin/time -o $timeoutfile -f "%e\nreal\t%E\nuser\t%Us\nsys\t%Ss\nmaxm\t%Mk" $runscript 2>&1 | tee -a $logfile
+exitstatus=$PIPESTATUS
+
+git reset --hard HEAD > /dev/null
+popd > /dev/null
+
+timeresult=`head -n1 $timeoutfile`
+cat $timeoutfile | tee -a $logfile
+rm $timeoutfile
+
+if [ $exitstatus != 0 ] ; then
+    # Build failed, exit with 125 to tell git bisect run to skip this rev
+    echo "*** Build failed (exit code $exitstatus), skipping..." | tee -a $logfile
+    exit 125
+fi
+
+ret=`echo "scale = 2; $timeresult > $timethreshold - $tolerance" | bc`
+echo "Returning $ret" | tee -a $logfile
+exit $ret
+
diff --git a/scripts/contrib/test_build_time_worker.sh b/scripts/contrib/test_build_time_worker.sh
new file mode 100755
index 0000000..8e20a9e
--- /dev/null
+++ b/scripts/contrib/test_build_time_worker.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+# This is an example script to be used in conjunction with test_build_time.sh
+
+if [ "$TEST_BUILDDIR" = "" ] ; then
+    echo "TEST_BUILDDIR is not set"
+    exit 1
+fi
+
+buildsubdir=`basename $TEST_BUILDDIR`
+if [ ! -d $buildsubdir ] ; then
+    echo "Unable to find build subdir $buildsubdir in current directory"
+    exit 1
+fi
+
+if [ -f oe-init-build-env ] ; then
+    . ./oe-init-build-env $buildsubdir
+elif [ -f poky-init-build-env ] ; then
+    . ./poky-init-build-env $buildsubdir
+else
+    echo "Unable to find build environment setup script"
+    exit 1
+fi
+
+if [ -f ../meta/recipes-sato/images/core-image-sato.bb ] ; then
+    target="core-image-sato"
+else
+    target="poky-image-sato"
+fi
+
+echo "Build started at `date "+%Y-%m-%d %H:%M:%S"`"
+echo "bitbake $target"
+bitbake $target
+ret=$?
+echo "Build finished at `date "+%Y-%m-%d %H:%M:%S"`"
+exit $ret
+
diff --git a/scripts/contrib/verify-homepage.py b/scripts/contrib/verify-homepage.py
new file mode 100755
index 0000000..86cc82b
--- /dev/null
+++ b/scripts/contrib/verify-homepage.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+
+# This script is used for verify HOMEPAGE.
+# The result is influenced by network environment, since the timeout of connect url is 5 seconds as default.
+
+import sys
+import os
+import subprocess
+import urllib2
+
+def search_bitbakepath():
+    bitbakepath = ""
+
+    # Search path to bitbake lib dir in order to load bb modules
+    if os.path.exists(os.path.join(os.path.dirname(sys.argv[0]), '../../bitbake/lib/bb')):
+        bitbakepath = os.path.join(os.path.dirname(sys.argv[0]), '../../bitbake/lib')
+        bitbakepath = os.path.abspath(bitbakepath)
+    else:
+        # Look for bitbake/bin dir in PATH
+        for pth in os.environ['PATH'].split(':'):
+            if os.path.exists(os.path.join(pth, '../lib/bb')):
+                bitbakepath = os.path.abspath(os.path.join(pth, '../lib'))
+                break
+        if not bitbakepath:
+            sys.stderr.write("Unable to find bitbake by searching parent directory of this script or PATH\n")
+            sys.exit(1)
+    return bitbakepath
+
+# For importing the following modules
+sys.path.insert(0, search_bitbakepath())
+import bb.tinfoil
+
+def wgetHomepage(pn, homepage):
+    result = subprocess.call('wget ' + '-q -T 5 -t 1 --spider ' + homepage, shell = True)
+    if result:
+        bb.warn("Failed to verify HOMEPAGE (%s) of %s" % (homepage, pn))
+        return 1
+    else:
+        return 0
+
+def verifyHomepage(bbhandler):
+    pkg_pn = bbhandler.cooker.recipecache.pkg_pn
+    pnlist = sorted(pkg_pn)
+    count = 0
+    for pn in pnlist:
+        fn = pkg_pn[pn].pop()
+        data = bb.cache.Cache.loadDataFull(fn, bbhandler.cooker.collection.get_file_appends(fn), bbhandler.config_data)
+        homepage = data.getVar("HOMEPAGE")
+        if homepage:
+            try:
+                urllib2.urlopen(homepage, timeout=5)
+            except Exception:
+                count = count + wgetHomepage(pn, homepage)
+    return count
+
+if __name__=='__main__':
+    failcount = 0
+    bbhandler = bb.tinfoil.Tinfoil()
+    bbhandler.prepare()
+    print "Start to verify HOMEPAGE:"
+    failcount = verifyHomepage(bbhandler)
+    print "finish to verify HOMEPAGE."
+    print "Summary: %s failed" % failcount
diff --git a/scripts/cp-noerror b/scripts/cp-noerror
new file mode 100755
index 0000000..28eb90d
--- /dev/null
+++ b/scripts/cp-noerror
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+#
+# Allow copying of $1 to $2 but if files in $1 disappear during the copy operation,
+# don't error.
+# Also don't error if $1 disappears.
+#
+
+import sys
+import os
+import shutil
+
+def copytree(src, dst, symlinks=False, ignore=None):
+    """Based on shutil.copytree"""
+    names = os.listdir(src)
+    try:
+        os.makedirs(dst)
+    except OSError: 
+        # Already exists
+        pass
+    errors = []
+    for name in names:
+        srcname = os.path.join(src, name)
+        dstname = os.path.join(dst, name)
+        try:
+            d = dstname
+            if os.path.isdir(dstname):
+                d = os.path.join(dstname, os.path.basename(srcname))
+            if os.path.exists(d):
+                continue
+            try:
+                os.link(srcname, dstname)
+            except OSError:
+                shutil.copy2(srcname, dstname)
+        # catch the Error from the recursive copytree so that we can
+        # continue with other files
+        except shutil.Error, err:
+            errors.extend(err.args[0])
+        except EnvironmentError, why:
+            errors.append((srcname, dstname, str(why)))
+    try:
+        shutil.copystat(src, dst)
+    except OSError, why:
+        errors.extend((src, dst, str(why)))
+    if errors:
+        raise shutil.Error, errors
+
+try:
+    copytree(sys.argv[1], sys.argv[2])
+except shutil.Error:
+   pass
+except OSError:
+   pass
diff --git a/scripts/create-pull-request b/scripts/create-pull-request
new file mode 100755
index 0000000..19ba588
--- /dev/null
+++ b/scripts/create-pull-request
@@ -0,0 +1,258 @@
+#!/bin/sh
+#
+# Copyright (c) 2010-2013,  Intel Corporation.
+# All Rights Reserved
+# 
+# This program is free software;  you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY;  without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+# the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program;  if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+#
+# This script is intended to be used to prepare a series of patches
+# and a cover letter in an appropriate and consistent format for
+# submission to Open Embedded and The Yocto Project, as well as to
+# related projects and layers.
+#
+
+ODIR=pull-$$
+RELATIVE_TO="master"
+COMMIT_ID="HEAD"
+PREFIX="PATCH"
+RFC=0
+
+usage() {
+CMD=$(basename $0)
+cat <<EOM
+Usage: $CMD [-h] [-o output_dir] [-m msg_body_file] [-s subject] [-r relative_to] [-i commit_id] [-d relative_dir] -u remote [-b branch]
+  -b branch           Branch name in the specified remote (default: current branch)
+  -c                  Create an RFC (Request for Comment) patch series
+  -h                  Display this help message
+  -i commit_id        Ending commit (default: HEAD)
+  -m msg_body_file    The file containing a blurb to be inserted into the summary email
+  -o output_dir       Specify the output directory for the messages (default: pull-PID)
+  -p prefix           Use [prefix N/M] instead of [PATCH N/M] as the subject prefix
+  -r relative_to      Starting commit (default: master)
+  -s subject          The subject to be inserted into the summary email
+  -u remote           The git remote where the branch is located
+  -d relative_dir     Generate patches relative to directory
+
+ Examples:
+   $CMD -u contrib -b nitin/basic
+   $CMD -u contrib -r distro/master -i nitin/distro -b nitin/distro
+   $CMD -u contrib -r master -i misc -b nitin/misc -o pull-misc
+   $CMD -u contrib -p "RFC PATCH" -b nitin/experimental
+   $CMD -u contrib -i misc -b nitin/misc -d ./bitbake
+EOM
+}
+
+# Parse and validate arguments
+while getopts "b:cd:hi:m:o:p:r:s:u:" OPT; do
+	case $OPT in
+	b)
+		BRANCH="$OPTARG"
+		;;
+	c)
+		RFC=1
+		;;
+	d)
+		RELDIR="$OPTARG"
+		;;
+	h)
+		usage
+		exit 0
+		;;
+	i)
+		COMMIT_ID="$OPTARG"
+		;;
+	m)
+		BODY="$OPTARG"
+		if [ ! -e "$BODY" ]; then
+			echo "ERROR: Body file does not exist"
+			exit 1
+		fi
+		;;
+	o)
+		ODIR="$OPTARG"
+		;;
+	p)
+		PREFIX="$OPTARG"
+		;;
+	r)
+		RELATIVE_TO="$OPTARG"
+		;;
+	s)
+		SUBJECT="$OPTARG"
+		;;
+	u)
+		REMOTE="$OPTARG"
+		REMOTE_URL=$(git config remote.$REMOTE.url)
+		if [ $? -ne 0 ]; then
+			echo "ERROR: git config failed to find a url for '$REMOTE'"
+			echo
+			echo "To add a remote url for $REMOTE, use:"
+			echo "  git config remote.$REMOTE.url <url>"
+			exit 1
+		fi
+
+		# Rewrite private URLs to public URLs
+		# Determine the repository name for use in the WEB_URL later
+		case "$REMOTE_URL" in
+		*@*)
+			USER_RE="[A-Za-z0-9_.@][A-Za-z0-9_.@-]*\$\?"
+			PROTO_RE="[a-z][a-z+]*://"
+			GIT_RE="\(^\($PROTO_RE\)\?$USER_RE@\)\([^:/]*\)[:/]\(.*\)"
+			REMOTE_URL=${REMOTE_URL%.git}
+			REMOTE_REPO=$(echo $REMOTE_URL | sed "s#$GIT_RE#\4#")
+			REMOTE_URL=$(echo $REMOTE_URL | sed "s#$GIT_RE#git://\3/\4#")
+			;;
+		*)
+			echo "WARNING: Unrecognized remote URL: $REMOTE_URL"
+			echo "         The pull and browse URLs will likely be incorrect"
+			;;
+		esac
+		;;
+	esac
+done
+
+if [ -z "$BRANCH" ]; then
+	BRANCH=$(git branch | grep -e "^\* " | cut -d' ' -f2)
+	echo "NOTE: Assuming remote branch '$BRANCH', use -b to override."
+fi
+
+if [ -z "$REMOTE_URL" ]; then
+	echo "ERROR: Missing parameter -u, no git remote!"
+	usage
+	exit 1
+fi
+
+if [ $RFC -eq 1 ]; then
+	PREFIX="RFC $PREFIX"
+fi
+
+
+# Set WEB_URL from known remotes
+WEB_URL=""
+case "$REMOTE_URL" in
+	*git.yoctoproject.org*)
+		WEB_URL="http://git.yoctoproject.org/cgit.cgi/$REMOTE_REPO/log/?h=$BRANCH"
+		;;
+	*git.pokylinux.org*)
+		WEB_URL="http://git.pokylinux.org/cgit.cgi/$REMOTE_REPO/log/?h=$BRANCH"
+		;;
+	*git.openembedded.org*)
+		WEB_URL="http://cgit.openembedded.org/cgit.cgi/$REMOTE_REPO/log/?h=$BRANCH"
+		;;
+	*github.com*)
+		WEB_URL="https://github.com/$REMOTE_REPO/tree/$BRANCH"
+		;;
+esac
+
+# Perform a sanity test on the web URL. Issue a warning if it is not
+# accessible, but do not abort as users may want to run offline.
+if [ -n "$WEB_URL" ]; then
+	wget --no-check-certificate -q $WEB_URL -O /dev/null
+	if [ $? -ne 0 ]; then
+		echo "WARNING: Branch '$BRANCH' was not found on the contrib git tree."
+		echo "         Please check your remote and branch parameter before sending."
+		echo ""
+	fi
+fi
+
+if [ -e $ODIR ]; then
+	echo "ERROR: output directory $ODIR exists."
+	exit 1
+fi
+mkdir $ODIR
+
+if [ -n "$RELDIR" ]; then
+	ODIR=$(realpath $ODIR)
+	pdir=$(pwd)
+	cd $RELDIR
+	extraopts="--relative"
+fi
+
+# Generate the patches and cover letter
+git format-patch $extraopts -M40 --subject-prefix="$PREFIX" -n -o $ODIR --thread=shallow --cover-letter $RELATIVE_TO..$COMMIT_ID > /dev/null
+
+[ -n "$RELDIR" ] && cd $pdir
+
+# Customize the cover letter
+CL="$ODIR/0000-cover-letter.patch"
+PM="$ODIR/pull-msg"
+GIT_VERSION=$(`git --version` | tr -d '[:alpha:][:space:].' | sed 's/\(...\).*/\1/')
+NEWER_GIT_VERSION=210
+if [ $GIT_VERSION -lt $NEWER_GIT_VERSION ]; then
+	git request-pull $RELATIVE_TO $REMOTE_URL $COMMIT_ID >> "$PM"
+else
+	git request-pull $RELATIVE_TO $REMOTE_URL :$BRANCH >> "$PM"
+fi
+if [ $? -ne 0 ]; then
+	echo "ERROR: git request-pull reported an error"
+	exit 1
+fi
+
+# The cover letter already has a diffstat, remove it from the pull-msg
+# before inserting it.
+sed -n "0,\#$REMOTE_URL# p" "$PM" | sed -i "/BLURB HERE/ r /dev/stdin" "$CL"
+rm "$PM"
+
+# If this is an RFC, make that clear in the cover letter
+if [ $RFC -eq 1 ]; then
+(cat <<EOM
+Please review the following changes for suitability for inclusion. If you have
+any objections or suggestions for improvement, please respond to the patches. If
+you agree with the changes, please provide your Acked-by.
+
+EOM
+) | sed -i "/BLURB HERE/ r /dev/stdin" "$CL"
+fi
+
+# Insert the WEB_URL if there is one
+if [ -n "$WEB_URL" ]; then
+	echo "  $WEB_URL" | sed -i "\#$REMOTE_URL# r /dev/stdin" "$CL"
+fi
+
+
+# If the user specified a message body, insert it into the cover letter and
+# remove the BLURB token.
+if [ -n "$BODY" ]; then
+	sed -i "/BLURB HERE/ r $BODY" "$CL"
+	sed -i "/BLURB HERE/ d" "$CL"
+fi
+
+# If the user specified a subject, replace the SUBJECT token with it.
+if [ -n "$SUBJECT" ]; then
+	sed -i -e "s/\*\*\* SUBJECT HERE \*\*\*/$SUBJECT/" "$CL"
+fi
+
+
+# Generate report for user
+cat <<EOM
+The following patches have been prepared:
+$(for PATCH in $(ls $ODIR/*); do echo "    $PATCH"; done)
+
+Review their content, especially the summary mail:
+    $CL
+
+When you are satisfied, you can send them with:
+    send-pull-request -a -p $ODIR
+EOM
+
+# Check the patches for trailing white space
+egrep -q -e "^\+.*\s+$" $ODIR/*
+if [ $? -ne 1 ]; then
+	echo
+	echo "WARNING: Trailing white space detected at these locations"
+	egrep -nH --color -e "^\+.*\s+$" $ODIR/*
+fi
diff --git a/scripts/crosstap b/scripts/crosstap
new file mode 100755
index 0000000..58317cf
--- /dev/null
+++ b/scripts/crosstap
@@ -0,0 +1,148 @@
+#!/bin/bash
+#
+# Run a systemtap script on remote target
+#
+# Examples (run on build host, target is 192.168.1.xxx):
+#   $ source oe-init-build-env"
+#   $ cd ~/my/systemtap/scripts"
+#
+#   $ crosstap root@192.168.1.xxx myscript.stp"
+#   $ crosstap root@192.168.1.xxx myscript-with-args.stp 99 ninetynine"
+#
+# Copyright (c) 2012, Intel Corporation.
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+function usage() {
+    echo "Usage: $0 <user@hostname> <sytemtap-script> [additional systemtap-script args]"
+}
+
+function setup_usage() {
+    echo ""
+    echo "'crosstap' requires a local sdk build of the target system"
+    echo "(or a build that includes 'tools-profile') in order to build"
+    echo "kernel modules that can probe the target system."
+    echo ""
+    echo "Practically speaking, that means you need to do the following:"
+    echo "  - If you're running a pre-built image, download the release"
+    echo "    and/or BSP tarballs used to build the image."
+    echo "  - If you're working from git sources, just clone the metadata"
+    echo "    and BSP layers needed to build the image you'll be booting."
+    echo "  - Make sure you're properly set up to build a new image (see"
+    echo "    the BSP README and/or the widely available basic documentation"
+    echo "    that discusses how to build images)."
+    echo "  - Build an -sdk version of the image e.g.:"
+    echo "      $ bitbake core-image-sato-sdk"
+    echo "  OR"
+    echo "  - Build a non-sdk image but include the profiling tools:"
+    echo "      [ edit local.conf and add 'tools-profile' to the end of"
+    echo "        the EXTRA_IMAGE_FEATURES variable ]"
+    echo "      $ bitbake core-image-sato"
+    echo ""
+    echo "  [ NOTE that 'crosstap' needs to be able to ssh into the target"
+    echo "    system, which isn't enabled by default in -minimal images. ]"
+    echo ""
+    echo "Once you've build the image on the host system, you're ready to"
+    echo "boot it (or the equivalent pre-built image) and use 'crosstap'"
+    echo "to probe it (you need to source the environment as usual first):"
+    echo ""
+    echo "    $ source oe-init-build-env"
+    echo "    $ cd ~/my/systemtap/scripts"
+    echo "    $ crosstap root@192.168.1.xxx myscript.stp"
+    echo ""
+}
+
+function systemtap_target_arch() {
+    SYSTEMTAP_TARGET_ARCH=$1
+    case $SYSTEMTAP_TARGET_ARCH in
+        i?86)
+            SYSTEMTAP_TARGET_ARCH="i386"
+            ;;
+        x86?64*)
+            SYSTEMTAP_TARGET_ARCH="x86_64"
+            ;;
+        arm*)
+            SYSTEMTAP_TARGET_ARCH="arm"
+            ;;
+        powerpc*)
+            SYSTEMTAP_TARGET_ARCH="powerpc"
+            ;;
+        *)
+            ;;
+    esac
+}
+
+if [ $# -lt 2 ]; then
+	usage
+	exit 1
+fi
+
+if [ -z "$BUILDDIR" ]; then
+    echo "Error: Unable to find the BUILDDIR environment variable."
+    echo "Did you forget to source your build system environment setup script?"
+    exit 1
+fi
+
+pushd $PWD
+cd $BUILDDIR
+BITBAKE_VARS=`bitbake -e virtual/kernel`
+popd
+
+STAGING_BINDIR_TOOLCHAIN=$(echo "$BITBAKE_VARS" | grep ^STAGING_BINDIR_TOOLCHAIN \
+  | cut -d '=' -f2 | cut -d '"' -f2)
+STAGING_BINDIR_TOOLPREFIX=$(echo "$BITBAKE_VARS" | grep ^TARGET_PREFIX \
+  | cut -d '=' -f2 | cut -d '"' -f2)
+SYSTEMTAP_HOST_INSTALLDIR=$(echo "$BITBAKE_VARS" | grep ^STAGING_DIR_NATIVE \
+  | cut -d '=' -f2 | cut -d '"' -f2)
+TARGET_ARCH=$(echo "$BITBAKE_VARS" | grep ^TRANSLATED_TARGET_ARCH \
+  | cut -d '=' -f2 | cut -d '"' -f2)
+TARGET_KERNEL_BUILDDIR=$(echo "$BITBAKE_VARS" | grep ^B= \
+  | cut -d '=' -f2 | cut -d '"' -f2)
+
+systemtap_target_arch "$TARGET_ARCH"
+
+if [ ! -d $TARGET_KERNEL_BUILDDIR ] ||
+   [ ! -f $TARGET_KERNEL_BUILDDIR/vmlinux ]; then
+    echo -e "\nError: No target kernel build found."
+    echo -e "Did you forget to create a local build of your image?"
+    setup_usage
+    exit 1
+fi
+
+if [ ! -f $SYSTEMTAP_HOST_INSTALLDIR/usr/bin/stap ]; then
+    echo -e "\nError: Native (host) systemtap not found."
+    echo -e "Did you accidentally build a local non-sdk image? (or forget to"
+    echo -e "add 'tools-profile' to EXTRA_IMAGE_FEATURES in your local.conf)?"
+    setup_usage
+    exit 1
+fi
+
+target_user_hostname="$1"
+full_script_name="$2"
+script_name=$(basename "$2")
+script_base=${script_name%.*}
+shift 2
+
+${SYSTEMTAP_HOST_INSTALLDIR}/usr/bin/stap \
+  -a ${SYSTEMTAP_TARGET_ARCH} \
+  -B CROSS_COMPILE="${STAGING_BINDIR_TOOLCHAIN}/${STAGING_BINDIR_TOOLPREFIX}" \
+  -r ${TARGET_KERNEL_BUILDDIR} \
+  -I ${SYSTEMTAP_HOST_INSTALLDIR}/usr/share/systemtap/tapset \
+  -R ${SYSTEMTAP_HOST_INSTALLDIR}/usr/share/systemtap/runtime \
+  --remote=$target_user_hostname \
+  -m $script_base \
+   $full_script_name "$@"
+
+exit 0
diff --git a/scripts/devtool b/scripts/devtool
new file mode 100755
index 0000000..87df951
--- /dev/null
+++ b/scripts/devtool
@@ -0,0 +1,295 @@
+#!/usr/bin/env python
+
+# OpenEmbedded Development tool
+#
+# Copyright (C) 2014-2015 Intel Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import sys
+import os
+import argparse
+import glob
+import re
+import ConfigParser
+import subprocess
+import logging
+
+basepath = ''
+workspace = {}
+config = None
+context = None
+
+
+scripts_path = os.path.dirname(os.path.realpath(__file__))
+lib_path = scripts_path + '/lib'
+sys.path = sys.path + [lib_path]
+from devtool import DevtoolError, setup_tinfoil
+import scriptutils
+logger = scriptutils.logger_create('devtool')
+
+plugins = []
+
+
+class ConfigHandler(object):
+    config_file = ''
+    config_obj = None
+    init_path = ''
+    workspace_path = ''
+
+    def __init__(self, filename):
+        self.config_file = filename
+        self.config_obj = ConfigParser.SafeConfigParser()
+
+    def get(self, section, option, default=None):
+        try:
+            ret = self.config_obj.get(section, option)
+        except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
+            if default != None:
+                ret = default
+            else:
+                raise
+        return ret
+
+    def read(self):
+        if os.path.exists(self.config_file):
+            self.config_obj.read(self.config_file)
+
+            if self.config_obj.has_option('General', 'init_path'):
+                pth = self.get('General', 'init_path')
+                self.init_path = os.path.join(basepath, pth)
+                if not os.path.exists(self.init_path):
+                    logger.error('init_path %s specified in config file cannot be found' % pth)
+                    return False
+        else:
+            self.config_obj.add_section('General')
+
+        self.workspace_path = self.get('General', 'workspace_path', os.path.join(basepath, 'workspace'))
+        return True
+
+
+    def write(self):
+        logger.debug('writing to config file %s' % self.config_file)
+        self.config_obj.set('General', 'workspace_path', self.workspace_path)
+        with open(self.config_file, 'w') as f:
+            self.config_obj.write(f)
+
+class Context:
+    def __init__(self, **kwargs):
+        self.__dict__.update(kwargs)
+
+
+def read_workspace():
+    global workspace
+    workspace = {}
+    if not os.path.exists(os.path.join(config.workspace_path, 'conf', 'layer.conf')):
+        if context.fixed_setup:
+            logger.error("workspace layer not set up")
+            sys.exit(1)
+        else:
+            logger.info('Creating workspace layer in %s' % config.workspace_path)
+            _create_workspace(config.workspace_path, config, basepath)
+    if not context.fixed_setup:
+        _enable_workspace_layer(config.workspace_path, config, basepath)
+
+    logger.debug('Reading workspace in %s' % config.workspace_path)
+    externalsrc_re = re.compile(r'^EXTERNALSRC(_pn-([^ =]+))? *= *"([^"]*)"$')
+    for fn in glob.glob(os.path.join(config.workspace_path, 'appends', '*.bbappend')):
+        with open(fn, 'r') as f:
+            for line in f:
+                res = externalsrc_re.match(line.rstrip())
+                if res:
+                    pn = res.group(2) or os.path.splitext(os.path.basename(fn))[0].split('_')[0]
+                    workspace[pn] = {'srctree': res.group(3),
+                                     'bbappend': fn}
+
+def create_workspace(args, config, basepath, workspace):
+    if args.layerpath:
+        workspacedir = os.path.abspath(args.layerpath)
+    else:
+        workspacedir = os.path.abspath(os.path.join(basepath, 'workspace'))
+    _create_workspace(workspacedir, config, basepath)
+    if not args.create_only:
+        _enable_workspace_layer(workspacedir, config, basepath)
+
+def _create_workspace(workspacedir, config, basepath):
+    import bb
+
+    confdir = os.path.join(workspacedir, 'conf')
+    if os.path.exists(os.path.join(confdir, 'layer.conf')):
+        logger.info('Specified workspace already set up, leaving as-is')
+    else:
+        # Add a config file
+        bb.utils.mkdirhier(confdir)
+        with open(os.path.join(confdir, 'layer.conf'), 'w') as f:
+            f.write('# ### workspace layer auto-generated by devtool ###\n')
+            f.write('BBPATH =. "$' + '{LAYERDIR}:"\n')
+            f.write('BBFILES += "$' + '{LAYERDIR}/recipes/*/*.bb \\\n')
+            f.write('            $' + '{LAYERDIR}/appends/*.bbappend"\n')
+            f.write('BBFILE_COLLECTIONS += "workspacelayer"\n')
+            f.write('BBFILE_PATTERN_workspacelayer = "^$' + '{LAYERDIR}/"\n')
+            f.write('BBFILE_PATTERN_IGNORE_EMPTY_workspacelayer = "1"\n')
+            f.write('BBFILE_PRIORITY_workspacelayer = "99"\n')
+        # Add a README file
+        with open(os.path.join(workspacedir, 'README'), 'w') as f:
+            f.write('This layer was created by the OpenEmbedded devtool utility in order to\n')
+            f.write('contain recipes and bbappends. In most instances you should use the\n')
+            f.write('devtool utility to manage files within it rather than modifying files\n')
+            f.write('directly (although recipes added with "devtool add" will often need\n')
+            f.write('direct modification.)\n')
+            f.write('\nIf you no longer need to use devtool you can remove the path to this\n')
+            f.write('workspace layer from your conf/bblayers.conf file (and then delete the\n')
+            f.write('layer, if you wish).\n')
+
+def _enable_workspace_layer(workspacedir, config, basepath):
+    """Ensure the workspace layer is in bblayers.conf"""
+    import bb
+    bblayers_conf = os.path.join(basepath, 'conf', 'bblayers.conf')
+    if not os.path.exists(bblayers_conf):
+        logger.error('Unable to find bblayers.conf')
+        return
+    _, added = bb.utils.edit_bblayers_conf(bblayers_conf, workspacedir, config.workspace_path)
+    if added:
+        logger.info('Enabling workspace layer in bblayers.conf')
+    if config.workspace_path != workspacedir:
+        # Update our config to point to the new location
+        config.workspace_path = workspacedir
+        config.write()
+
+
+def main():
+    global basepath
+    global config
+    global context
+
+    context = Context(fixed_setup=False)
+
+    # Default basepath
+    basepath = os.path.dirname(os.path.abspath(__file__))
+    pth = basepath
+    while pth != '' and pth != os.sep:
+        if os.path.exists(os.path.join(pth, '.devtoolbase')):
+            context.fixed_setup = True
+            basepath = pth
+            break
+        pth = os.path.dirname(pth)
+
+    parser = argparse.ArgumentParser(description="OpenEmbedded development tool",
+                                     add_help=False,
+                                     epilog="Use %(prog)s <subcommand> --help to get help on a specific command")
+    parser.add_argument('--basepath', help='Base directory of SDK / build directory')
+    parser.add_argument('--bbpath', help='Explicitly specify the BBPATH, rather than getting it from the metadata')
+    parser.add_argument('-d', '--debug', help='Enable debug output', action='store_true')
+    parser.add_argument('-q', '--quiet', help='Print only errors', action='store_true')
+    parser.add_argument('--color', choices=['auto', 'always', 'never'], default='auto', help='Colorize output (where %(metavar)s is %(choices)s)', metavar='COLOR')
+
+    global_args, unparsed_args = parser.parse_known_args()
+
+    # Help is added here rather than via add_help=True, as we don't want it to
+    # be handled by parse_known_args()
+    parser.add_argument('-h', '--help', action='help', default=argparse.SUPPRESS,
+                        help='show this help message and exit')
+
+    if global_args.debug:
+        logger.setLevel(logging.DEBUG)
+    elif global_args.quiet:
+        logger.setLevel(logging.ERROR)
+
+    if global_args.basepath:
+        # Override
+        basepath = global_args.basepath
+    elif not context.fixed_setup:
+        basepath = os.environ.get('BUILDDIR')
+        if not basepath:
+            logger.error("This script can only be run after initialising the build environment (e.g. by using oe-init-build-env)")
+            sys.exit(1)
+
+    logger.debug('Using basepath %s' % basepath)
+
+    config = ConfigHandler(os.path.join(basepath, 'conf', 'devtool.conf'))
+    if not config.read():
+        return -1
+
+    # We need to be in this directory or we won't be able to initialise tinfoil
+    os.chdir(basepath)
+
+    bitbake_subdir = config.get('General', 'bitbake_subdir', '')
+    if bitbake_subdir:
+        # Normally set for use within the SDK
+        logger.debug('Using bitbake subdir %s' % bitbake_subdir)
+        sys.path.insert(0, os.path.join(basepath, bitbake_subdir, 'lib'))
+        core_meta_subdir = config.get('General', 'core_meta_subdir')
+        sys.path.insert(0, os.path.join(basepath, core_meta_subdir, 'lib'))
+    else:
+        # Standard location
+        import scriptpath
+        bitbakepath = scriptpath.add_bitbake_lib_path()
+        if not bitbakepath:
+            logger.error("Unable to find bitbake by searching parent directory of this script or PATH")
+            sys.exit(1)
+        logger.debug('Using standard bitbake path %s' % bitbakepath)
+        scriptpath.add_oe_lib_path()
+
+    scriptutils.logger_setup_color(logger, global_args.color)
+
+    if global_args.bbpath is None:
+        tinfoil = setup_tinfoil(config_only=True)
+        global_args.bbpath = tinfoil.config_data.getVar('BBPATH', True)
+    else:
+        tinfoil = None
+
+    for path in [scripts_path] + global_args.bbpath.split(':'):
+        pluginpath = os.path.join(path, 'lib', 'devtool')
+        scriptutils.load_plugins(logger, plugins, pluginpath)
+
+    if tinfoil:
+        tinfoil.shutdown()
+
+    subparsers = parser.add_subparsers(dest="subparser_name", title='subcommands', metavar='<subcommand>')
+
+    if not context.fixed_setup:
+        parser_create_workspace = subparsers.add_parser('create-workspace',
+                                                        help='Set up a workspace',
+                                                        description='Sets up a new workspace. NOTE: other devtool subcommands will create a workspace automatically as needed, so you only need to use %(prog)s if you want to specify where the workspace should be located.')
+        parser_create_workspace.add_argument('layerpath', nargs='?', help='Path in which the workspace layer should be created')
+        parser_create_workspace.add_argument('--create-only', action="store_true", help='Only create the workspace layer, do not alter configuration')
+        parser_create_workspace.set_defaults(func=create_workspace)
+
+    for plugin in plugins:
+        if hasattr(plugin, 'register_commands'):
+            plugin.register_commands(subparsers, context)
+
+    args = parser.parse_args(unparsed_args, namespace=global_args)
+
+    if args.subparser_name != 'create-workspace':
+        read_workspace()
+
+    try:
+        ret = args.func(args, config, basepath, workspace)
+    except DevtoolError as err:
+        if str(err):
+            logger.error(str(err))
+        ret = 1
+
+    return ret
+
+
+if __name__ == "__main__":
+    try:
+        ret = main()
+    except Exception:
+        ret = 1
+        import traceback
+        traceback.print_exc(5)
+    sys.exit(ret)
diff --git a/scripts/gen-lockedsig-cache b/scripts/gen-lockedsig-cache
new file mode 100755
index 0000000..c93b2c0
--- /dev/null
+++ b/scripts/gen-lockedsig-cache
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+#
+# gen-lockedsig-cache <locked-sigs.inc> <input-cachedir> <output-cachedir>
+#
+
+import os
+import sys
+import glob
+import shutil
+import errno
+
+def mkdir(d):
+    try:
+        os.makedirs(d)
+    except OSError as e:
+        if e.errno != errno.EEXIST:
+            raise e
+
+if len(sys.argv) < 3:
+    print("Incorrect number of arguments specified")
+    sys.exit(1)
+
+sigs = []
+with open(sys.argv[1]) as f:
+    for l in f.readlines():
+        if ":" in l:
+            sigs.append(l.split(":")[2].split()[0])
+
+files = set()
+for s in sigs:
+    p = sys.argv[2] + "/" + s[:2] + "/*" + s + "*"
+    files |= set(glob.glob(p))
+    p = sys.argv[2] + "/*/" + s[:2] + "/*" + s + "*"
+    files |= set(glob.glob(p))
+
+for f in files:
+    dst = f.replace(sys.argv[2], sys.argv[3])
+    destdir = os.path.dirname(dst)
+    mkdir(destdir)
+
+    if os.path.exists(dst):
+        os.remove(dst)
+    if (os.stat(f).st_dev == os.stat(destdir).st_dev):
+        os.link(f, dst)
+    else:
+        shutil.copyfile(f, dst)
diff --git a/scripts/gen-site-config b/scripts/gen-site-config
new file mode 100755
index 0000000..7da7a0b
--- /dev/null
+++ b/scripts/gen-site-config
@@ -0,0 +1,53 @@
+#! /bin/sh
+#  Copyright (c) 2005-2008 Wind River Systems, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+cat << EOF
+AC_PREREQ(2.57)
+AC_INIT([site_wide],[1.0.0])
+
+EOF
+
+# Disable as endian is set in the default config
+#echo AC_C_BIGENDIAN
+#echo
+
+if [ -e $1/types ] ; then
+  while read type ; do
+    echo "AC_CHECK_SIZEOF([$type])"
+  done < $1/types
+
+  echo
+fi
+
+if [ -e $1/funcs ]; then
+  while read func ; do
+    echo "AC_CHECK_FUNCS([$func])"
+  done < $1/funcs
+
+  echo
+fi
+
+if [ -e $1/headers ]; then
+  while read header ; do
+    echo "AC_CHECK_HEADERS([$header])"
+  done < $1/headers
+
+  echo
+fi
+
+cat << EOF
+AC_OUTPUT
+EOF
diff --git a/scripts/hob b/scripts/hob
new file mode 100755
index 0000000..8d33ab1
--- /dev/null
+++ b/scripts/hob
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+export BB_ENV_EXTRAWHITE="DISABLE_SANITY_CHECKS $BB_ENV_EXTRAWHITE"
+DISABLE_SANITY_CHECKS=1 bitbake -u hob $@
+
+ret=$?
+exit $ret
diff --git a/scripts/lib/bsp/__init__.py b/scripts/lib/bsp/__init__.py
new file mode 100644
index 0000000..8bbb6e1
--- /dev/null
+++ b/scripts/lib/bsp/__init__.py
@@ -0,0 +1,22 @@
+#
+# Yocto BSP tools library
+#
+# Copyright (c) 2012, Intel Corporation.
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# AUTHORS
+# Tom Zanussi <tom.zanussi (at] intel.com>
+#
diff --git a/scripts/lib/bsp/engine.py b/scripts/lib/bsp/engine.py
new file mode 100644
index 0000000..7d6be23
--- /dev/null
+++ b/scripts/lib/bsp/engine.py
@@ -0,0 +1,1947 @@
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# Copyright (c) 2012, Intel Corporation.
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# DESCRIPTION
+# This module implements the templating engine used by 'yocto-bsp' to
+# create BSPs.  The BSP templates are simply the set of files expected
+# to appear in a generated BSP, marked up with a small set of tags
+# used to customize the output.  The engine parses through the
+# templates and generates a Python program containing all the logic
+# and input elements needed to display and retrieve BSP-specific
+# information from the user.  The resulting program uses those results
+# to generate the final BSP files.
+#
+# AUTHORS
+# Tom Zanussi <tom.zanussi (at] intel.com>
+#
+
+import os
+import sys
+from abc import ABCMeta, abstractmethod
+from tags import *
+import shlex
+import json
+import subprocess
+import shutil
+
+class Line():
+    """
+    Generic (abstract) container representing a line that will appear
+    in the BSP-generating program.
+    """
+    __metaclass__ = ABCMeta
+
+    def __init__(self, line):
+        self.line = line
+        self.generated_line = ""
+        self.prio = sys.maxint
+        self.discard = False
+
+    @abstractmethod
+    def gen(self, context = None):
+        """
+        Generate the final executable line that will appear in the
+        BSP-generation program.
+        """
+        pass
+
+    def escape(self, line):
+        """
+        Escape single and double quotes and backslashes until I find
+        something better (re.escape() escapes way too much).
+        """
+        return line.replace("\\", "\\\\").replace("\"", "\\\"").replace("'", "\\'")
+
+    def parse_error(self, msg, lineno, line):
+         raise SyntaxError("%s: %s" % (msg, line))
+
+
+class NormalLine(Line):
+    """
+    Container for normal (non-tag) lines.
+    """
+    def __init__(self, line):
+        Line.__init__(self, line)
+        self.is_filename = False
+        self.is_dirname = False
+        self.out_filebase = None
+
+    def gen(self, context = None):
+        if self.is_filename:
+            line = "current_file = \"" + os.path.join(self.out_filebase, self.escape(self.line)) + "\"; of = open(current_file, \"w\")"
+        elif self.is_dirname:
+            dirname = os.path.join(self.out_filebase, self.escape(self.line))
+            line = "if not os.path.exists(\"" + dirname + "\"): os.mkdir(\"" + dirname + "\")"
+        else:
+            line = "of.write(\"" + self.escape(self.line) + "\\n\")"
+        return line
+
+
+class CodeLine(Line):
+    """
+    Container for Python code tag lines.
+    """
+    def __init__(self, line):
+        Line.__init__(self, line)
+
+    def gen(self, context = None):
+        return self.line
+
+
+class Assignment:
+    """
+    Representation of everything we know about {{=name }} tags.
+    Instances of these are used by Assignment lines.
+    """
+    def __init__(self, start, end, name):
+        self.start = start
+        self.end = end
+        self.name = name
+
+
+class AssignmentLine(NormalLine):
+    """
+    Container for normal lines containing assignment tags.  Assignment
+    tags must be in ascending order of 'start' value.
+    """
+    def __init__(self, line):
+        NormalLine.__init__(self, line)
+        self.assignments = []
+
+    def add_assignment(self, start, end, name):
+        self.assignments.append(Assignment(start, end, name))
+
+    def gen(self, context = None):
+        line = self.escape(self.line)
+
+        for assignment in self.assignments:
+            replacement = "\" + " + assignment.name + " + \""
+            idx = line.find(ASSIGN_TAG)
+            line = line[:idx] + replacement + line[idx + assignment.end - assignment.start:]
+        if self.is_filename:
+            return "current_file = \"" + os.path.join(self.out_filebase, line) + "\"; of = open(current_file, \"w\")"
+        elif self.is_dirname:
+            dirname = os.path.join(self.out_filebase, line)
+            return "if not os.path.exists(\"" + dirname + "\"): os.mkdir(\"" + dirname + "\")"
+        else:
+            return "of.write(\"" + line + "\\n\")"
+
+
+class InputLine(Line):
+    """
+    Base class for Input lines.
+    """
+    def __init__(self, props, tag, lineno):
+        Line.__init__(self, tag)
+        self.props = props
+        self.lineno = lineno
+
+        try:
+            self.prio = int(props["prio"])
+        except KeyError:
+            self.prio = sys.maxint
+
+    def gen(self, context = None):
+        try:
+            depends_on = self.props["depends-on"]
+            try:
+                depends_on_val = self.props["depends-on-val"]
+            except KeyError:
+                self.parse_error("No 'depends-on-val' for 'depends-on' property",
+                                 self.lineno, self.line)
+        except KeyError:
+            pass
+
+
+class EditBoxInputLine(InputLine):
+    """
+    Base class for 'editbox' Input lines.
+
+    props:
+        name: example - "Load address"
+        msg: example - "Please enter the load address"
+    result:
+        Sets the value of the variable specified by 'name' to
+        whatever the user typed.
+    """
+    def __init__(self, props, tag, lineno):
+        InputLine.__init__(self, props, tag, lineno)
+
+    def gen(self, context = None):
+        InputLine.gen(self, context)
+        name = self.props["name"]
+        if not name:
+            self.parse_error("No input 'name' property found",
+                             self.lineno, self.line)
+        msg = self.props["msg"]
+        if not msg:
+            self.parse_error("No input 'msg' property found",
+                             self.lineno, self.line)
+
+        try:
+            default_choice = self.props["default"]
+        except KeyError:
+            default_choice = ""
+
+        msg += " [default: " + default_choice + "]"
+
+        line = name + " = default(raw_input(\"" + msg + " \"), " + name + ")"
+
+        return line
+
+
+class GitRepoEditBoxInputLine(EditBoxInputLine):
+    """
+    Base class for 'editbox' Input lines for user input of remote git
+    repos.  This class verifies the existence and connectivity of the
+    specified git repo.
+
+    props:
+        name: example - "Load address"
+        msg: example - "Please enter the load address"
+    result:
+        Sets the value of the variable specified by 'name' to
+        whatever the user typed.
+    """
+    def __init__(self, props, tag, lineno):
+        EditBoxInputLine.__init__(self, props, tag, lineno)
+
+    def gen(self, context = None):
+        EditBoxInputLine.gen(self, context)
+        name = self.props["name"]
+        if not name:
+            self.parse_error("No input 'name' property found",
+                             self.lineno, self.line)
+        msg = self.props["msg"]
+        if not msg:
+            self.parse_error("No input 'msg' property found",
+                             self.lineno, self.line)
+
+        try:
+            default_choice = self.props["default"]
+        except KeyError:
+            default_choice = ""
+
+        msg += " [default: " + default_choice + "]"
+
+        line = name + " = get_verified_git_repo(\"" + msg + "\"," + name + ")"
+
+        return line
+
+
+class FileEditBoxInputLine(EditBoxInputLine):
+    """
+    Base class for 'editbox' Input lines for user input of existing
+    files.  This class verifies the existence of the specified file.
+
+    props:
+        name: example - "Load address"
+        msg: example - "Please enter the load address"
+    result:
+        Sets the value of the variable specified by 'name' to
+        whatever the user typed.
+    """
+    def __init__(self, props, tag, lineno):
+        EditBoxInputLine.__init__(self, props, tag, lineno)
+
+    def gen(self, context = None):
+        EditBoxInputLine.gen(self, context)
+        name = self.props["name"]
+        if not name:
+            self.parse_error("No input 'name' property found",
+                             self.lineno, self.line)
+        msg = self.props["msg"]
+        if not msg:
+            self.parse_error("No input 'msg' property found",
+                             self.lineno, self.line)
+
+        try:
+            default_choice = self.props["default"]
+        except KeyError:
+            default_choice = ""
+
+        msg += " [default: " + default_choice + "]"
+
+        line = name + " = get_verified_file(\"" + msg + "\"," + name + ", True)"
+
+        return line
+
+
+class BooleanInputLine(InputLine):
+    """
+    Base class for boolean Input lines.
+    props:
+        name: example - "keyboard"
+        msg:  example - "Got keyboard?"
+    result:
+        Sets the value of the variable specified by 'name' to "yes" or "no"
+        example - keyboard = "yes"
+    """
+    def __init__(self, props, tag, lineno):
+        InputLine.__init__(self, props, tag, lineno)
+
+    def gen(self, context = None):
+        InputLine.gen(self, context)
+        name = self.props["name"]
+        if not name:
+            self.parse_error("No input 'name' property found",
+                             self.lineno, self.line)
+        msg = self.props["msg"]
+        if not msg:
+            self.parse_error("No input 'msg' property found",
+                             self.lineno, self.line)
+
+        try:
+            default_choice = self.props["default"]
+        except KeyError:
+            default_choice = ""
+
+        msg += " [default: " + default_choice + "]"
+
+        line = name + " = boolean(raw_input(\"" + msg + " \"), " + name + ")"
+
+        return line
+
+
+class ListInputLine(InputLine):
+    """
+    Base class for List-based Input lines. e.g. Choicelist, Checklist.
+    """
+    __metaclass__ = ABCMeta
+
+    def __init__(self, props, tag, lineno):
+        InputLine.__init__(self, props, tag, lineno)
+        self.choices = []
+
+    def gen_choicepair_list(self):
+        """Generate a list of 2-item val:desc lists from self.choices."""
+        if not self.choices:
+            return None
+
+        choicepair_list = list()
+
+        for choice in self.choices:
+            choicepair = []
+            choicepair.append(choice.val)
+            choicepair.append(choice.desc)
+            choicepair_list.append(choicepair)
+
+        return choicepair_list
+
+    def gen_degenerate_choicepair_list(self, choices):
+        """Generate a list of 2-item val:desc with val=desc from passed-in choices."""
+        choicepair_list = list()
+
+        for choice in choices:
+            choicepair = []
+            choicepair.append(choice)
+            choicepair.append(choice)
+            choicepair_list.append(choicepair)
+
+        return choicepair_list
+
+    def exec_listgen_fn(self, context = None):
+        """
+        Execute the list-generating function contained as a string in
+        the "gen" property.
+        """
+        retval = None
+        try:
+            fname = self.props["gen"]
+            modsplit = fname.split('.')
+            mod_fn = modsplit.pop()
+            mod = '.'.join(modsplit)
+
+            __import__(mod)
+            # python 2.7 has a better way to do this using importlib.import_module
+            m = sys.modules[mod]
+
+            fn = getattr(m, mod_fn)
+            if not fn:
+                self.parse_error("couldn't load function specified for 'gen' property ",
+                                 self.lineno, self.line)
+            retval = fn(context)
+            if not retval:
+                self.parse_error("function specified for 'gen' property returned nothing ",
+                                 self.lineno, self.line)
+        except KeyError:
+            pass
+
+        return retval
+
+    def gen_choices_str(self, choicepairs):
+        """
+        Generate a numbered list of choices from a list of choicepairs
+        for display to the user.
+        """
+        choices_str = ""
+
+        for i, choicepair in enumerate(choicepairs):
+            choices_str += "\t" + str(i + 1) + ") " + choicepair[1] + "\n"
+
+        return choices_str
+
+    def gen_choices_val_str(self, choicepairs):
+        """
+        Generate an array of choice values corresponding to the
+        numbered list generated by gen_choices_str().
+        """
+        choices_val_list = "["
+
+        for i, choicepair in enumerate(choicepairs):
+            choices_val_list += "\"" + choicepair[0] + "\","
+        choices_val_list += "]"
+
+        return choices_val_list
+
+    def gen_choices_val_list(self, choicepairs):
+        """
+        Generate an array of choice values corresponding to the
+        numbered list generated by gen_choices_str().
+        """
+        choices_val_list = []
+
+        for i, choicepair in enumerate(choicepairs):
+            choices_val_list.append(choicepair[0])
+
+        return choices_val_list
+
+    def gen_choices_list(self, context = None, checklist = False):
+        """
+        Generate an array of choice values corresponding to the
+        numbered list generated by gen_choices_str().
+        """
+        choices = self.exec_listgen_fn(context)
+        if choices:
+            if len(choices) == 0:
+                self.parse_error("No entries available for input list",
+                                 self.lineno, self.line)
+            choicepairs = self.gen_degenerate_choicepair_list(choices)
+        else:
+            if len(self.choices) == 0:
+                self.parse_error("No entries available for input list",
+                                 self.lineno, self.line)
+            choicepairs = self.gen_choicepair_list()
+            
+        return choicepairs
+
+    def gen_choices(self, context = None, checklist = False):
+        """
+        Generate an array of choice values corresponding to the
+        numbered list generated by gen_choices_str(), display it to
+        the user, and process the result.
+        """
+        msg = self.props["msg"]
+        if not msg:
+            self.parse_error("No input 'msg' property found",
+                             self.lineno, self.line)
+
+        try:
+            default_choice = self.props["default"]
+        except KeyError:
+            default_choice = ""
+
+        msg += " [default: " + default_choice + "]"
+
+        choicepairs = self.gen_choices_list(context, checklist)
+
+        choices_str = self.gen_choices_str(choicepairs)
+        choices_val_list = self.gen_choices_val_list(choicepairs)
+        if checklist:
+            choiceval = default(find_choicevals(raw_input(msg + "\n" + choices_str), choices_val_list), default_choice)
+        else:
+            choiceval = default(find_choiceval(raw_input(msg + "\n" + choices_str), choices_val_list), default_choice)
+
+        return choiceval
+
+
+def find_choiceval(choice_str, choice_list):
+    """
+    Take number as string and return val string from choice_list,
+    empty string if oob.  choice_list is a simple python list.
+    """
+    choice_val = ""
+
+    try:
+        choice_idx = int(choice_str)
+        if choice_idx <= len(choice_list):
+            choice_idx -= 1
+            choice_val = choice_list[choice_idx]
+    except ValueError:
+        pass
+
+    return choice_val
+
+
+def find_choicevals(choice_str, choice_list):
+    """
+    Take numbers as space-separated string and return vals list from
+    choice_list, empty list if oob.  choice_list is a simple python
+    list.
+    """
+    choice_vals = []
+
+    choices = choice_str.split()
+    for choice in choices:
+        choice_vals.append(find_choiceval(choice, choice_list))
+
+    return choice_vals
+
+
+def default(input_str, name):
+    """
+    Return default if no input_str, otherwise stripped input_str.
+    """
+    if not input_str:
+        return name
+
+    return input_str.strip()
+
+
+def verify_git_repo(giturl):
+    """
+    Verify that the giturl passed in can be connected to.  This can be
+    used as a check for the existence of the given repo and/or basic
+    git remote connectivity.
+
+    Returns True if the connection was successful, fals otherwise
+    """
+    if not giturl:
+        return False
+
+    gitcmd = "git ls-remote %s > /dev/null 2>&1" % (giturl)
+    rc = subprocess.call(gitcmd, shell=True)
+    if rc == 0:
+        return True
+
+    return False
+
+
+def get_verified_git_repo(input_str, name):
+    """
+    Return git repo if verified, otherwise loop forever asking user
+    for filename.
+    """
+    msg = input_str.strip() + " "
+
+    giturl = default(raw_input(msg), name)
+
+    while True:
+        if verify_git_repo(giturl):
+            return giturl
+        giturl = default(raw_input(msg), name)
+
+
+def get_verified_file(input_str, name, filename_can_be_null):
+    """
+    Return filename if the file exists, otherwise loop forever asking
+    user for filename.
+    """
+    msg = input_str.strip() + " "
+
+    filename = default(raw_input(msg), name)
+
+    while True:
+        if not filename and filename_can_be_null:
+            return filename
+        if os.path.isfile(filename):
+            return filename
+        filename = default(raw_input(msg), name)
+
+
+def replace_file(replace_this, with_this):
+    """
+    Replace the given file with the contents of filename, retaining
+    the original filename.
+    """
+    try:
+        replace_this.close()
+        shutil.copy(with_this, replace_this.name)
+    except IOError:
+        pass
+
+
+def boolean(input_str, name):
+    """
+    Return lowercase version of first char in string, or value in name.
+    """
+    if not input_str:
+        return name
+
+    str = input_str.lower().strip()
+    if str and str[0] == "y" or str[0] == "n":
+        return str[0]
+    else:
+        return name
+
+
+def strip_base(input_str):
+    """
+    strip '/base' off the end of input_str, so we can use 'base' in
+    the branch names we present to the user.
+    """
+    if input_str and input_str.endswith("/base"):
+        return input_str[:-len("/base")]
+    return input_str.strip()
+
+
+deferred_choices = {}
+
+def gen_choices_defer(input_line, context, checklist = False):
+    """
+    Save the context hashed the name of the input item, which will be
+    passed to the gen function later.
+    """
+    name = input_line.props["name"]
+
+    try:
+        nameappend = input_line.props["nameappend"]
+    except KeyError:
+        nameappend = ""
+
+    try:
+        branches_base = input_line.props["branches_base"]
+    except KeyError:
+        branches_base = ""
+
+    filename = input_line.props["filename"]
+
+    closetag_start = filename.find(CLOSE_TAG)
+
+    if closetag_start != -1:
+        filename = filename[closetag_start + len(CLOSE_TAG):]
+
+    filename = filename.strip()
+    filename = os.path.splitext(filename)[0]
+
+    captured_context = capture_context(context)
+    context["filename"] = filename
+    captured_context["filename"] = filename
+    context["nameappend"] = nameappend
+    captured_context["nameappend"] = nameappend
+    context["branches_base"] = branches_base
+    captured_context["branches_base"] = branches_base
+
+    deferred_choice = (input_line, captured_context, checklist)
+    key = name + "_" + filename + "_" + nameappend
+    deferred_choices[key] = deferred_choice
+
+
+def invoke_deferred_choices(name):
+    """
+    Invoke the choice generation function using the context hashed by
+    'name'.
+    """
+    deferred_choice = deferred_choices[name]
+    input_line = deferred_choice[0]
+    context = deferred_choice[1]
+    checklist = deferred_choice[2]
+
+    context["name"] = name
+
+    choices = input_line.gen_choices(context, checklist)
+
+    return choices
+
+
+class ChoicelistInputLine(ListInputLine):
+    """
+    Base class for choicelist Input lines.
+    props:
+        name: example - "xserver_choice"
+        msg:  example - "Please select an xserver for this machine"
+    result:
+        Sets the value of the variable specified by 'name' to whichever Choice was chosen
+        example - xserver_choice = "xserver_vesa"
+    """
+    def __init__(self, props, tag, lineno):
+        ListInputLine.__init__(self, props, tag, lineno)
+
+    def gen(self, context = None):
+        InputLine.gen(self, context)
+
+        gen_choices_defer(self, context)
+        name = self.props["name"]
+        nameappend = context["nameappend"]
+        filename = context["filename"]
+
+        try:
+            default_choice = self.props["default"]
+        except KeyError:
+            default_choice = ""
+
+        line = name + " = default(invoke_deferred_choices(\"" + name + "_" + filename + "_" + nameappend + "\"), \"" + default_choice + "\")"
+
+        return line
+
+
+class ListValInputLine(InputLine):
+    """
+    Abstract base class for choice and checkbox Input lines.
+    """
+    def __init__(self, props, tag, lineno):
+        InputLine.__init__(self, props, tag, lineno)
+
+        try:
+            self.val = self.props["val"]
+        except KeyError:
+            self.parse_error("No input 'val' property found", self.lineno, self.line)
+
+        try:
+            self.desc = self.props["msg"]
+        except KeyError:
+            self.parse_error("No input 'msg' property found", self.lineno, self.line)
+
+
+class ChoiceInputLine(ListValInputLine):
+    """
+    Base class for choicelist item Input lines.
+    """
+    def __init__(self, props, tag, lineno):
+        ListValInputLine.__init__(self, props, tag, lineno)
+
+    def gen(self, context = None):
+        return None
+
+
+class ChecklistInputLine(ListInputLine):
+    """
+    Base class for checklist Input lines.
+    """
+    def __init__(self, props, tag, lineno):
+        ListInputLine.__init__(self, props, tag, lineno)
+
+    def gen(self, context = None):
+        InputLine.gen(self, context)
+
+        gen_choices_defer(self, context, True)
+        name = self.props["name"]
+        nameappend = context["nameappend"]
+        filename = context["filename"]
+
+        try:
+            default_choice = self.props["default"]
+        except KeyError:
+            default_choice = ""
+
+        line = name + " = default(invoke_deferred_choices(\"" + name + "_" + filename + "_" + nameappend + "\"), \"" + default_choice + "\")"
+
+        return line
+
+
+class CheckInputLine(ListValInputLine):
+    """
+    Base class for checklist item Input lines.
+    """
+    def __init__(self, props, tag, lineno):
+        ListValInputLine.__init__(self, props, tag, lineno)
+
+    def gen(self, context = None):
+        return None
+
+
+dirname_substitutions = {}
+
+class SubstrateBase(object):
+    """
+    Base class for both expanded and unexpanded file and dir container
+    objects.
+    """
+    def __init__(self, filename, filebase, out_filebase):
+        self.filename = filename
+        self.filebase = filebase
+        self.translated_filename = filename
+        self.out_filebase = out_filebase
+        self.raw_lines = []
+        self.expanded_lines = []
+        self.prev_choicelist = None
+
+    def parse_error(self, msg, lineno, line):
+         raise SyntaxError("%s: [%s: %d]: %s" % (msg, self.filename, lineno, line))
+
+    def expand_input_tag(self, tag, lineno):
+        """
+        Input tags consist of the word 'input' at the beginning,
+        followed by name:value property pairs which are converted into
+        a dictionary.
+        """
+        propstr = tag[len(INPUT_TAG):]
+
+        props = dict(prop.split(":", 1) for prop in shlex.split(propstr))
+        props["filename"] = self.filename
+
+        input_type = props[INPUT_TYPE_PROPERTY]
+        if not props[INPUT_TYPE_PROPERTY]:
+            self.parse_error("No input 'type' property found", lineno, tag)
+
+        if input_type == "boolean":
+            return BooleanInputLine(props, tag, lineno)
+        if input_type == "edit":
+            return EditBoxInputLine(props, tag, lineno)
+        if input_type == "edit-git-repo":
+            return GitRepoEditBoxInputLine(props, tag, lineno)
+        if input_type == "edit-file":
+            return FileEditBoxInputLine(props, tag, lineno)
+        elif input_type == "choicelist":
+            self.prev_choicelist = ChoicelistInputLine(props, tag, lineno)
+            return self.prev_choicelist
+        elif input_type == "choice":
+            if not self.prev_choicelist:
+                self.parse_error("Found 'choice' input tag but no previous choicelist",
+                                 lineno, tag)
+            choice = ChoiceInputLine(props, tag, lineno)
+            self.prev_choicelist.choices.append(choice)
+            return choice
+        elif input_type == "checklist":
+            return ChecklistInputLine(props, tag, lineno)
+        elif input_type == "check":
+            return CheckInputLine(props, tag, lineno)
+
+    def expand_assignment_tag(self, start, line, lineno):
+        """
+        Expand all tags in a line.
+        """
+        expanded_line = AssignmentLine(line.rstrip())
+
+        while start != -1:
+            end = line.find(CLOSE_TAG, start)
+            if end == -1:
+                self.parse_error("No close tag found for assignment tag", lineno, line)
+            else:
+                name = line[start + len(ASSIGN_TAG):end].strip()
+                expanded_line.add_assignment(start, end + len(CLOSE_TAG), name)
+                start = line.find(ASSIGN_TAG, end)
+
+        return expanded_line
+
+    def expand_tag(self, line, lineno):
+        """
+        Returns a processed tag line, or None if there was no tag
+
+        The rules for tags are very simple:
+            - No nested tags
+            - Tags start with {{ and end with }}
+            - An assign tag, {{=, can appear anywhere and will
+              be replaced with what the assignment evaluates to
+            - Any other tag occupies the whole line it is on
+                - if there's anything else on the tag line, it's an error
+                - if it starts with 'input', it's an input tag and
+                  will only be used for prompting and setting variables
+                - anything else is straight Python
+                - tags are in effect only until the next blank line or tag or 'pass' tag
+                - we don't have indentation in tags, but we need some way to end a block
+                  forcefully without blank lines or other tags - that's the 'pass' tag
+                - todo: implement pass tag
+                - directories and filenames can have tags as well, but only assignment
+                  and 'if' code lines
+                - directories and filenames are the only case where normal tags can
+                  coexist with normal text on the same 'line'
+        """
+        start = line.find(ASSIGN_TAG)
+        if start != -1:
+            return self.expand_assignment_tag(start, line, lineno)
+
+        start = line.find(OPEN_TAG)
+        if start == -1:
+            return None
+
+        end = line.find(CLOSE_TAG, 0)
+        if end == -1:
+             self.parse_error("No close tag found for open tag", lineno, line)
+
+        tag = line[start + len(OPEN_TAG):end].strip()
+
+        if not tag.lstrip().startswith(INPUT_TAG):
+            return CodeLine(tag)
+
+        return self.expand_input_tag(tag, lineno)
+
+    def append_translated_filename(self, filename):
+        """
+        Simply append filename to translated_filename
+        """
+        self.translated_filename = os.path.join(self.translated_filename, filename)
+
+    def get_substituted_file_or_dir_name(self, first_line, tag):
+        """
+        If file or dir names contain name substitutions, return the name
+        to substitute.  Note that this is just the file or dirname and
+        doesn't include the path.
+        """
+        filename = first_line.find(tag)
+        if filename != -1:
+            filename += len(tag)
+        substituted_filename = first_line[filename:].strip()
+        this = substituted_filename.find(" this")
+        if this != -1:
+            head, tail = os.path.split(self.filename)
+            substituted_filename = substituted_filename[:this + 1] + tail
+            if tag == DIRNAME_TAG: # get rid of .noinstall in dirname
+                substituted_filename = substituted_filename.split('.')[0]
+
+        return substituted_filename
+
+    def get_substituted_filename(self, first_line):
+        """
+        If a filename contains a name substitution, return the name to
+        substitute.  Note that this is just the filename and doesn't
+        include the path.
+        """
+        return self.get_substituted_file_or_dir_name(first_line, FILENAME_TAG)
+
+    def get_substituted_dirname(self, first_line):
+        """
+        If a dirname contains a name substitution, return the name to
+        substitute.  Note that this is just the dirname and doesn't
+        include the path.
+        """
+        return self.get_substituted_file_or_dir_name(first_line, DIRNAME_TAG)
+
+    def substitute_filename(self, first_line):
+        """
+        Find the filename in first_line and append it to translated_filename.
+        """
+        substituted_filename = self.get_substituted_filename(first_line)
+        self.append_translated_filename(substituted_filename);
+
+    def substitute_dirname(self, first_line):
+        """
+        Find the dirname in first_line and append it to translated_filename.
+        """
+        substituted_dirname = self.get_substituted_dirname(first_line)
+        self.append_translated_filename(substituted_dirname);
+
+    def is_filename_substitution(self, line):
+        """
+        Do we have a filename subustition?
+        """
+        if line.find(FILENAME_TAG) != -1:
+            return True
+        return False
+
+    def is_dirname_substitution(self, line):
+        """
+        Do we have a dirname subustition?
+        """
+        if line.find(DIRNAME_TAG) != -1:
+            return True
+        return False
+
+    def translate_dirname(self, first_line):
+        """
+        Just save the first_line mapped by filename.  The later pass
+        through the directories will look for a dirname.noinstall
+        match and grab the substitution line.
+        """
+        dirname_substitutions[self.filename] = first_line
+
+    def translate_dirnames_in_path(self, path):
+        """
+        Translate dirnames below this file or dir, not including tail.
+        dirname_substititions is keyed on actual untranslated filenames.
+        translated_path contains the subsititutions for each element.
+        """
+        remainder = path[len(self.filebase)+1:]
+        translated_path = untranslated_path = self.filebase
+
+        untranslated_dirs = remainder.split(os.sep)
+
+        for dir in untranslated_dirs:
+            key = os.path.join(untranslated_path, dir + '.noinstall')
+            try:
+                first_line = dirname_substitutions[key]
+            except KeyError:
+                translated_path = os.path.join(translated_path, dir)
+                untranslated_path = os.path.join(untranslated_path, dir)
+                continue
+            substituted_dir = self.get_substituted_dirname(first_line)
+            translated_path = os.path.join(translated_path, substituted_dir)
+            untranslated_path = os.path.join(untranslated_path, dir)
+
+        return translated_path
+
+    def translate_file_or_dir_name(self):
+        """
+        Originally we were allowed to use open/close/assign tags and python
+        code in the filename, which fit in nicely with the way we
+        processed the templates and generated code.  Now that we can't
+        do that, we make those tags proper file contents and have this
+        pass substitute the nice but non-functional names with those
+        'strange' ones, and then proceed as usual.
+
+        So, if files or matching dir<.noinstall> files contain
+        filename substitutions, this function translates them into the
+        corresponding 'strange' names, which future passes will expand
+        as they always have.  The resulting pathname is kept in the
+        file or directory's translated_filename.  Another way to think
+        about it is that self.filename is the input filename, and
+        translated_filename is the output filename before expansion.
+        """
+        # remove leaf file or dirname
+        head, tail = os.path.split(self.filename)
+        translated_path = self.translate_dirnames_in_path(head)
+        self.translated_filename = translated_path
+
+        # This is a dirname - does it have a matching .noinstall with
+        # a substitution?  If so, apply the dirname subsititution.
+        if not os.path.isfile(self.filename):
+            key = self.filename + ".noinstall"
+            try:
+                first_line = dirname_substitutions[key]
+            except KeyError:
+                self.append_translated_filename(tail)
+                return
+            self.substitute_dirname(first_line)
+            return
+
+        f = open(self.filename)
+        first_line = f.readline()
+        f.close()
+
+        # This is a normal filename not needing translation, just use
+        # it as-is.
+        if not first_line or not first_line.startswith("#"):
+            self.append_translated_filename(tail)
+            return
+
+        # If we have a filename substitution (first line in the file
+        # is a FILENAME_TAG line) do the substitution now.  If we have
+        # a dirname substitution (DIRNAME_TAG in dirname.noinstall
+        # meta-file), hash it so we can apply it when we see the
+        # matching dirname later.  Otherwise we have a regular
+        # filename, just use it as-is.
+        if self.is_filename_substitution(first_line):
+            self.substitute_filename(first_line)
+        elif self.is_dirname_substitution(first_line):
+            self.translate_dirname(first_line)
+        else:
+            self.append_translated_filename(tail)
+
+    def expand_file_or_dir_name(self):
+        """
+        Expand file or dir names into codeline.  Dirnames and
+        filenames can only have assignments or if statements.  First
+        translate if statements into CodeLine + (dirname or filename
+        creation).
+        """
+        lineno = 0
+
+        line = self.translated_filename[len(self.filebase):]
+        if line.startswith("/"):
+            line = line[1:]
+        opentag_start = -1
+
+        start = line.find(OPEN_TAG)
+        while start != -1:
+            if not line[start:].startswith(ASSIGN_TAG):
+                opentag_start = start
+                break
+            start += len(ASSIGN_TAG)
+            start = line.find(OPEN_TAG, start)
+
+        if opentag_start != -1:
+            end = line.find(CLOSE_TAG, opentag_start)
+            if end == -1:
+                self.parse_error("No close tag found for open tag", lineno, line)
+            # we have a {{ tag i.e. code
+            tag = line[opentag_start + len(OPEN_TAG):end].strip()
+            if not tag.lstrip().startswith(IF_TAG):
+                self.parse_error("Only 'if' tags are allowed in file or directory names",
+                                 lineno, line)
+            self.expanded_lines.append(CodeLine(tag))
+
+            # everything after }} is the actual filename (possibly with assignments)
+            # everything before is the pathname
+            line = line[:opentag_start] + line[end + len(CLOSE_TAG):].strip()
+
+        assign_start = line.find(ASSIGN_TAG)
+        if assign_start != -1:
+            assignment_tag = self.expand_assignment_tag(assign_start, line, lineno)
+            if isinstance(self, SubstrateFile):
+                assignment_tag.is_filename = True
+                assignment_tag.out_filebase = self.out_filebase
+            elif isinstance(self, SubstrateDir):
+                assignment_tag.is_dirname = True
+                assignment_tag.out_filebase = self.out_filebase
+            self.expanded_lines.append(assignment_tag)
+            return
+
+        normal_line = NormalLine(line)
+        if isinstance(self, SubstrateFile):
+            normal_line.is_filename = True
+            normal_line.out_filebase = self.out_filebase
+        elif isinstance(self, SubstrateDir):
+            normal_line.is_dirname = True
+            normal_line.out_filebase = self.out_filebase
+        self.expanded_lines.append(normal_line)
+
+    def expand(self):
+        """
+        Expand the file or dir name first, eventually this ends up
+        creating the file or dir.
+        """
+        self.translate_file_or_dir_name()
+        self.expand_file_or_dir_name()
+
+
+class SubstrateFile(SubstrateBase):
+    """
+    Container for both expanded and unexpanded substrate files.
+    """
+    def __init__(self, filename, filebase, out_filebase):
+        SubstrateBase.__init__(self, filename, filebase, out_filebase)
+
+    def read(self):
+        if self.raw_lines:
+            return
+        f = open(self.filename)
+        self.raw_lines = f.readlines()
+
+    def expand(self):
+        """Expand the contents of all template tags in the file."""
+        SubstrateBase.expand(self)
+        self.read()
+
+        for lineno, line in enumerate(self.raw_lines):
+            # only first line can be a filename substitition
+            if lineno == 0 and line.startswith("#") and FILENAME_TAG in line:
+                continue # skip it - we've already expanded it
+            expanded_line = self.expand_tag(line, lineno + 1) # humans not 0-based
+            if not expanded_line:
+                expanded_line = NormalLine(line.rstrip())
+            self.expanded_lines.append(expanded_line)
+
+    def gen(self, context = None):
+        """Generate the code that generates the BSP."""
+        base_indent = 0
+
+        indent = new_indent = base_indent
+
+        for line in self.expanded_lines:
+            genline = line.gen(context)
+            if not genline:
+                continue
+            if isinstance(line, InputLine):
+                line.generated_line = genline
+                continue
+            if genline.startswith(OPEN_START):
+                if indent == 1:
+                    base_indent = 1
+            if indent:
+                if genline == BLANKLINE_STR or (not genline.startswith(NORMAL_START)
+                                                and not genline.startswith(OPEN_START)):
+                    indent = new_indent = base_indent
+            if genline.endswith(":"):
+                new_indent = base_indent + 1
+            line.generated_line = (indent * INDENT_STR) + genline
+            indent = new_indent
+
+
+class SubstrateDir(SubstrateBase):
+    """
+    Container for both expanded and unexpanded substrate dirs.
+    """
+    def __init__(self, filename, filebase, out_filebase):
+        SubstrateBase.__init__(self, filename, filebase, out_filebase)
+
+    def expand(self):
+        SubstrateBase.expand(self)
+
+    def gen(self, context = None):
+        """Generate the code that generates the BSP."""
+        indent = new_indent = 0
+        for line in self.expanded_lines:
+            genline = line.gen(context)
+            if not genline:
+                continue
+            if genline.endswith(":"):
+                new_indent = 1
+            else:
+                new_indent = 0
+            line.generated_line = (indent * INDENT_STR) + genline
+            indent = new_indent
+
+
+def expand_target(target, all_files, out_filebase):
+    """
+    Expand the contents of all template tags in the target.  This
+    means removing tags and categorizing or creating lines so that
+    future passes can process and present input lines and generate the
+    corresponding lines of the Python program that will be exec'ed to
+    actually produce the final BSP.  'all_files' includes directories.
+    """
+    for root, dirs, files in os.walk(target):
+        for file in files:
+            if file.endswith("~") or file.endswith("#"):
+                continue
+            f = os.path.join(root, file)
+            sfile = SubstrateFile(f, target, out_filebase)
+            sfile.expand()
+            all_files.append(sfile)
+
+        for dir in dirs:
+            d = os.path.join(root, dir)
+            sdir = SubstrateDir(d, target, out_filebase)
+            sdir.expand()
+            all_files.append(sdir)
+
+
+def gen_program_machine_lines(machine, program_lines):
+    """
+    Use the input values we got from the command line.
+    """
+    line = "machine = \"" + machine + "\""
+    program_lines.append(line)
+
+    line = "layer_name = \"" + machine + "\""
+    program_lines.append(line)
+
+
+def sort_inputlines(input_lines):
+    """Sort input lines according to priority (position)."""
+    input_lines.sort(key = lambda l: l.prio)
+
+
+def find_parent_dependency(lines, depends_on):
+    for i, line in lines:
+        if isinstance(line, CodeLine):
+            continue
+        if line.props["name"] == depends_on:
+            return i
+
+    return -1
+
+
+def process_inputline_dependencies(input_lines, all_inputlines):
+    """If any input lines depend on others, put the others first."""
+    for line in input_lines:
+        if isinstance(line, InputLineGroup):
+            group_inputlines = []
+            process_inputline_dependencies(line.group, group_inputlines)
+            line.group = group_inputlines
+            all_inputlines.append(line)
+            continue
+
+        if isinstance(line, CodeLine) or isinstance(line, NormalLine):
+            all_inputlines.append(line)
+            continue
+
+        try:
+            depends_on = line.props["depends-on"]
+            depends_codeline = "if " + line.props["depends-on"] + " == \"" + line.props["depends-on-val"] + "\":"
+            all_inputlines.append(CodeLine(depends_codeline))
+            all_inputlines.append(line)
+        except KeyError:
+            all_inputlines.append(line)
+
+
+def conditional_filename(filename):
+    """
+    Check if the filename itself contains a conditional statement.  If
+    so, return a codeline for it.
+    """
+    opentag_start = filename.find(OPEN_TAG)
+
+    if opentag_start != -1:
+        if filename[opentag_start:].startswith(ASSIGN_TAG):
+            return None
+        end = filename.find(CLOSE_TAG, opentag_start)
+        if end == -1:
+            print "No close tag found for open tag in filename %s" % filename
+            sys.exit(1)
+
+        # we have a {{ tag i.e. code
+        tag = filename[opentag_start + len(OPEN_TAG):end].strip()
+        if not tag.lstrip().startswith(IF_TAG):
+            print "Only 'if' tags are allowed in file or directory names, filename: %s" % filename
+            sys.exit(1)
+
+        return CodeLine(tag)
+
+    return None
+
+
+class InputLineGroup(InputLine):
+    """
+    InputLine that does nothing but group other input lines
+    corresponding to all the input lines in a SubstrateFile so they
+    can be generated as a group.  prio is the only property used.
+    """
+    def __init__(self, codeline):
+        InputLine.__init__(self, {}, "", 0)
+        self.group = []
+        self.prio = sys.maxint
+        self.group.append(codeline)
+
+    def append(self, line):
+        self.group.append(line)
+        if line.prio < self.prio:
+            self.prio = line.prio
+
+    def len(self):
+        return len(self.group)
+
+
+def gather_inputlines(files):
+    """
+    Gather all the InputLines - we want to generate them first.
+    """
+    all_inputlines = []
+    input_lines = []
+
+    for file in files:
+        if isinstance(file, SubstrateFile):
+            group = None
+            basename = os.path.basename(file.translated_filename)
+
+            codeline = conditional_filename(basename)
+            if codeline:
+                group = InputLineGroup(codeline)
+
+            have_condition = False
+            condition_to_write = None
+            for line in file.expanded_lines:
+                if isinstance(line, CodeLine):
+                    have_condition = True
+                    condition_to_write = line
+                    continue
+                if isinstance(line, InputLine):
+                    if group:
+                        if condition_to_write:
+                            condition_to_write.prio = line.prio
+                            condition_to_write.discard = True
+                            group.append(condition_to_write)
+                            condition_to_write = None
+                        group.append(line)
+                    else:
+                        if condition_to_write:
+                            condition_to_write.prio = line.prio
+                            condition_to_write.discard = True
+                            input_lines.append(condition_to_write)
+                            condition_to_write = None
+                        input_lines.append(line)
+                else:
+                    if condition_to_write:
+                        condition_to_write = None
+                    if have_condition:
+                        if not line.line.strip():
+                            line.discard = True
+                            input_lines.append(line)
+                    have_condition = False
+
+            if group and group.len() > 1:
+                input_lines.append(group)
+
+    sort_inputlines(input_lines)
+    process_inputline_dependencies(input_lines, all_inputlines)
+
+    return all_inputlines
+
+
+def run_program_lines(linelist, codedump):
+    """
+    For a single file, print all the python code into a buf and execute it.
+    """
+    buf = "\n".join(linelist)
+
+    if codedump:
+        of = open("bspgen.out", "w")
+        of.write(buf)
+        of.close()
+    exec buf
+
+
+def gen_target(files, context = None):
+    """
+    Generate the python code for each file.
+    """
+    for file in files:
+        file.gen(context)
+
+
+def gen_program_header_lines(program_lines):
+    """
+    Generate any imports we need.
+    """
+    program_lines.append("current_file = \"\"")
+
+
+def gen_supplied_property_vals(properties, program_lines):
+    """
+    Generate user-specified entries for input values instead of
+    generating input prompts.
+    """
+    for name, val in properties.iteritems():
+        program_line = name + " = \"" + val + "\""
+        program_lines.append(program_line)
+
+
+def gen_initial_property_vals(input_lines, program_lines):
+    """
+    Generate null or default entries for input values, so we don't
+    have undefined variables.
+    """
+    for line in input_lines:
+        if isinstance(line, InputLineGroup):
+            gen_initial_property_vals(line.group, program_lines)
+            continue
+
+        if isinstance(line, InputLine):
+            try:
+                name = line.props["name"]
+                try:
+                    default_val = "\"" + line.props["default"] + "\""
+                except:
+                    default_val = "\"\""
+                program_line = name + " = " + default_val
+                program_lines.append(program_line)
+            except KeyError:
+                pass
+
+
+def gen_program_input_lines(input_lines, program_lines, context, in_group = False):
+    """
+    Generate only the input lines used for prompting the user.  For
+    that, we only have input lines and CodeLines that affect the next
+    input line.
+    """
+    indent = new_indent = 0
+
+    for line in input_lines:
+        if isinstance(line, InputLineGroup):
+            gen_program_input_lines(line.group, program_lines, context, True)
+            continue
+        if not line.line.strip():
+            continue
+
+        genline = line.gen(context)
+        if not genline:
+            continue
+        if genline.endswith(":"):
+            new_indent += 1
+        else:
+            if indent > 1 or (not in_group and indent):
+                new_indent -= 1
+
+        line.generated_line = (indent * INDENT_STR) + genline
+        program_lines.append(line.generated_line)
+
+        indent = new_indent
+
+
+def gen_program_lines(target_files, program_lines):
+    """
+    Generate the program lines that make up the BSP generation
+    program.  This appends the generated lines of all target_files to
+    program_lines, and skips input lines, which are dealt with
+    separately, or omitted.
+    """
+    for file in target_files:
+        if file.filename.endswith("noinstall"):
+            continue
+
+        for line in file.expanded_lines:
+            if isinstance(line, InputLine):
+                continue
+            if line.discard:
+                continue
+
+            program_lines.append(line.generated_line)
+
+
+def create_context(machine, arch, scripts_path):
+    """
+    Create a context object for use in deferred function invocation.
+    """
+    context = {}
+
+    context["machine"] = machine
+    context["arch"] = arch
+    context["scripts_path"] = scripts_path
+
+    return context
+
+
+def capture_context(context):
+    """
+    Create a context object for use in deferred function invocation.
+    """
+    captured_context = {}
+
+    captured_context["machine"] = context["machine"]
+    captured_context["arch"] = context["arch"]
+    captured_context["scripts_path"] = context["scripts_path"]
+
+    return captured_context
+
+
+def expand_targets(context, bsp_output_dir, expand_common=True):
+    """
+    Expand all the tags in both the common and machine-specific
+    'targets'.
+
+    If expand_common is False, don't expand the common target (this
+    option is used to create special-purpose layers).
+    """
+    target_files = []
+
+    machine = context["machine"]
+    arch = context["arch"]
+    scripts_path = context["scripts_path"]
+
+    lib_path = scripts_path + '/lib'
+    bsp_path = lib_path + '/bsp'
+    arch_path = bsp_path + '/substrate/target/arch'
+
+    if expand_common:
+        common = os.path.join(arch_path, "common")
+        expand_target(common, target_files, bsp_output_dir)
+
+    arches = os.listdir(arch_path)
+    if arch not in arches or arch == "common":
+        print "Invalid karch, exiting\n"
+        sys.exit(1)
+
+    target = os.path.join(arch_path, arch)
+    expand_target(target, target_files, bsp_output_dir)
+
+    gen_target(target_files, context)
+
+    return target_files
+
+
+def yocto_common_create(machine, target, scripts_path, layer_output_dir, codedump, properties_file, properties_str="", expand_common=True):
+    """
+    Common layer-creation code
+
+    machine - user-defined machine name (if needed, will generate 'machine' var)
+    target - the 'target' the layer will be based on, must be one in
+           scripts/lib/bsp/substrate/target/arch
+    scripts_path - absolute path to yocto /scripts dir
+    layer_output_dir - dirname to create for layer
+    codedump - dump generated code to bspgen.out
+    properties_file - use values from this file if nonempty i.e no prompting
+    properties_str - use values from this string if nonempty i.e no prompting
+    expand_common - boolean, use the contents of (for bsp layers) arch/common
+    """
+    if os.path.exists(layer_output_dir):
+        print "\nlayer output dir already exists, exiting. (%s)" % layer_output_dir
+        sys.exit(1)
+
+    properties = None
+
+    if properties_file:
+        try:
+            infile = open(properties_file, "r")
+        except IOError:
+            print "Couldn't open properties file %s for reading, exiting" % properties_file
+            sys.exit(1)
+
+        properties = json.load(infile)
+
+    if properties_str and not properties:
+        properties = json.loads(properties_str)
+
+    os.mkdir(layer_output_dir)
+
+    context = create_context(machine, target, scripts_path)
+    target_files = expand_targets(context, layer_output_dir, expand_common)
+
+    input_lines = gather_inputlines(target_files)
+
+    program_lines = []
+
+    gen_program_header_lines(program_lines)
+
+    gen_initial_property_vals(input_lines, program_lines)
+
+    if properties:
+        gen_supplied_property_vals(properties, program_lines)
+
+    gen_program_machine_lines(machine, program_lines)
+
+    if not properties:
+        gen_program_input_lines(input_lines, program_lines, context)
+
+    gen_program_lines(target_files, program_lines)
+
+    run_program_lines(program_lines, codedump)
+
+
+def yocto_layer_create(layer_name, scripts_path, layer_output_dir, codedump, properties_file, properties=""):
+    """
+    Create yocto layer
+
+    layer_name - user-defined layer name
+    scripts_path - absolute path to yocto /scripts dir
+    layer_output_dir - dirname to create for layer
+    codedump - dump generated code to bspgen.out
+    properties_file - use values from this file if nonempty i.e no prompting
+    properties - use values from this string if nonempty i.e no prompting
+    """
+    yocto_common_create(layer_name, "layer", scripts_path, layer_output_dir, codedump, properties_file, properties, False)
+
+    print "\nNew layer created in %s.\n" % (layer_output_dir)
+    print "Don't forget to add it to your BBLAYERS (for details see %s\README)." % (layer_output_dir)
+
+
+def yocto_bsp_create(machine, arch, scripts_path, bsp_output_dir, codedump, properties_file, properties=None):
+    """
+    Create bsp
+
+    machine - user-defined machine name
+    arch - the arch the bsp will be based on, must be one in
+           scripts/lib/bsp/substrate/target/arch
+    scripts_path - absolute path to yocto /scripts dir
+    bsp_output_dir - dirname to create for BSP
+    codedump - dump generated code to bspgen.out
+    properties_file - use values from this file if nonempty i.e no prompting
+    properties - use values from this string if nonempty i.e no prompting
+    """
+    yocto_common_create(machine, arch, scripts_path, bsp_output_dir, codedump, properties_file, properties)
+
+    print "\nNew %s BSP created in %s" % (arch, bsp_output_dir)
+
+
+def print_dict(items, indent = 0):
+    """
+    Print the values in a possibly nested dictionary.
+    """
+    for key, val in items.iteritems():
+        print "    "*indent + "\"%s\" :" % key,
+        if type(val) == dict:
+            print "{"
+            print_dict(val, indent + 1)
+            print "    "*indent + "}"
+        else:
+            print "%s" % val
+
+
+def get_properties(input_lines):
+    """
+    Get the complete set of properties for all the input items in the
+    BSP, as a possibly nested dictionary.
+    """
+    properties = {}
+
+    for line in input_lines:
+        if isinstance(line, InputLineGroup):
+            statement = line.group[0].line
+            group_properties = get_properties(line.group)
+            properties[statement] = group_properties
+            continue
+
+        if not isinstance(line, InputLine):
+            continue
+
+        if isinstance(line, ChoiceInputLine):
+            continue
+
+        props = line.props
+        item = {}
+        name = props["name"]
+        for key, val in props.items():
+            if not key == "name":
+                item[key] = val
+        properties[name] = item
+
+    return properties
+
+
+def yocto_layer_list_properties(arch, scripts_path, properties_file, expand_common=True):
+    """
+    List the complete set of properties for all the input items in the
+    layer.  If properties_file is non-null, write the complete set of
+    properties as a nested JSON object corresponding to a possibly
+    nested dictionary.
+    """
+    context = create_context("unused", arch, scripts_path)
+    target_files = expand_targets(context, "unused", expand_common)
+
+    input_lines = gather_inputlines(target_files)
+
+    properties = get_properties(input_lines)
+    if properties_file:
+        try:
+            of = open(properties_file, "w")
+        except IOError:
+            print "Couldn't open properties file %s for writing, exiting" % properties_file
+            sys.exit(1)
+
+        json.dump(properties, of)
+
+    print_dict(properties)
+
+
+def split_nested_property(property):
+    """
+    A property name of the form x.y describes a nested property
+    i.e. the property y is contained within x and can be addressed
+    using standard JSON syntax for nested properties.  Note that if a
+    property name itself contains '.', it should be contained in
+    double quotes.
+    """
+    splittable_property = ""
+    in_quotes = False
+    for c in property:
+        if c == '.' and not in_quotes:
+            splittable_property += '\n'
+            continue
+        if c == '"':
+            in_quotes = not in_quotes
+        splittable_property += c
+
+    split_properties = splittable_property.split('\n')
+
+    if len(split_properties) > 1:
+        return split_properties
+
+    return None
+
+
+def find_input_line_group(substring, input_lines):
+    """
+    Find and return the InputLineGroup containing the specified substring.
+    """
+    for line in input_lines:
+        if isinstance(line, InputLineGroup):
+            if substring in line.group[0].line:
+                return line
+
+    return None
+
+
+def find_input_line(name, input_lines):
+    """
+    Find the input line with the specified name.
+    """
+    for line in input_lines:
+        if isinstance(line, InputLineGroup):
+            l = find_input_line(name, line.group)
+            if l:
+                return l
+
+        if isinstance(line, InputLine):
+            try:
+                if line.props["name"] == name:
+                    return line
+                if line.props["name"] + "_" + line.props["nameappend"] == name:
+                    return line
+            except KeyError:
+                pass
+
+    return None
+
+
+def print_values(type, values_list):
+    """
+    Print the values in the given list of values.
+    """
+    if type == "choicelist":
+        for value in values_list:
+            print "[\"%s\", \"%s\"]" % (value[0], value[1])
+    elif type == "boolean":
+        for value in values_list:
+            print "[\"%s\", \"%s\"]" % (value[0], value[1])
+
+
+def yocto_layer_list_property_values(arch, property, scripts_path, properties_file, expand_common=True):
+    """
+    List the possible values for a given input property.  If
+    properties_file is non-null, write the complete set of properties
+    as a JSON object corresponding to an array of possible values.
+    """
+    context = create_context("unused", arch, scripts_path)
+    context["name"] = property
+
+    target_files = expand_targets(context, "unused", expand_common)
+
+    input_lines = gather_inputlines(target_files)
+
+    properties = get_properties(input_lines)
+
+    nested_properties = split_nested_property(property)
+    if nested_properties:
+        # currently the outer property of a nested property always
+        # corresponds to an input line group
+        input_line_group = find_input_line_group(nested_properties[0], input_lines)
+        if input_line_group:
+            input_lines[:] = input_line_group.group[1:]
+            # The inner property of a nested property name is the
+            # actual property name we want, so reset to that
+            property = nested_properties[1]
+
+    input_line = find_input_line(property, input_lines)
+    if not input_line:
+        print "Couldn't find values for property %s" % property
+        return
+
+    values_list = []
+
+    type = input_line.props["type"]
+    if type == "boolean":
+        values_list.append(["y", "n"])
+    elif type == "choicelist" or type == "checklist":
+        try:
+            gen_fn = input_line.props["gen"]
+            if nested_properties:
+                context["filename"] = nested_properties[0]
+                try:
+                    context["branches_base"] = input_line.props["branches_base"]
+                except KeyError:
+                    context["branches_base"] = None
+            values_list = input_line.gen_choices_list(context, False)
+        except KeyError:
+            for choice in input_line.choices:
+                choicepair = []
+                choicepair.append(choice.val)
+                choicepair.append(choice.desc)
+                values_list.append(choicepair)
+
+    if properties_file:
+        try:
+            of = open(properties_file, "w")
+        except IOError:
+            print "Couldn't open properties file %s for writing, exiting" % properties_file
+            sys.exit(1)
+
+        json.dump(values_list, of)
+    
+    print_values(type, values_list)
+
+
+def yocto_bsp_list(args, scripts_path, properties_file):
+    """
+    Print available architectures, or the complete list of properties
+    defined by the BSP, or the possible values for a particular BSP
+    property.
+    """
+    if len(args) < 1:
+        return False
+
+    if args[0] == "karch":
+        lib_path = scripts_path + '/lib'
+        bsp_path = lib_path + '/bsp'
+        arch_path = bsp_path + '/substrate/target/arch'
+        print "Architectures available:"
+        for arch in os.listdir(arch_path):
+            if arch == "common" or arch == "layer":
+                continue
+            print "    %s" % arch
+        return True
+    else:
+        arch = args[0]
+
+    if len(args) < 2 or len(args) > 3:
+        return False
+
+    if len(args) == 2:
+        if args[1] == "properties":
+            yocto_layer_list_properties(arch, scripts_path, properties_file)
+        else:
+            return False
+
+    if len(args) == 3:
+        if args[1] == "property":
+            yocto_layer_list_property_values(arch, args[2], scripts_path, properties_file)
+        else:
+            return False
+
+    return True
+
+
+def yocto_layer_list(args, scripts_path, properties_file):
+    """
+    Print the complete list of input properties defined by the layer,
+    or the possible values for a particular layer property.
+    """
+    if len(args) < 1:
+        return False
+
+    if len(args) < 1 or len(args) > 2:
+        return False
+
+    if len(args) == 1:
+        if args[0] == "properties":
+            yocto_layer_list_properties("layer", scripts_path, properties_file, False)
+        else:
+            return False
+
+    if len(args) == 2:
+        if args[0] == "property":
+            yocto_layer_list_property_values("layer", args[1], scripts_path, properties_file, False)
+        else:
+            return False
+
+    return True
+
+
+def map_standard_kbranch(need_new_kbranch, new_kbranch, existing_kbranch):
+    """
+    Return the linux-yocto bsp branch to use with the specified
+    kbranch.  This handles the -standard variants for 3.4 and 3.8; the
+    other variants don't need mappings.
+    """
+    if need_new_kbranch == "y":
+        kbranch = new_kbranch
+    else:
+        kbranch = existing_kbranch
+
+    if kbranch.startswith("standard/common-pc-64"):
+        return "bsp/common-pc-64/common-pc-64-standard.scc"
+    if kbranch.startswith("standard/common-pc"):
+        return "bsp/common-pc/common-pc-standard.scc"
+    else:
+        return "ktypes/standard/standard.scc"
+
+
+def map_preempt_rt_kbranch(need_new_kbranch, new_kbranch, existing_kbranch):
+    """
+    Return the linux-yocto bsp branch to use with the specified
+    kbranch.  This handles the -preempt-rt variants for 3.4 and 3.8;
+    the other variants don't need mappings.
+    """
+    if need_new_kbranch == "y":
+        kbranch = new_kbranch
+    else:
+        kbranch = existing_kbranch
+
+    if kbranch.startswith("standard/preempt-rt/common-pc-64"):
+        return "bsp/common-pc-64/common-pc-64-preempt-rt.scc"
+    if kbranch.startswith("standard/preempt-rt/common-pc"):
+        return "bsp/common-pc/common-pc-preempt-rt.scc"
+    else:
+        return "ktypes/preempt-rt/preempt-rt.scc"
+
+
+def map_tiny_kbranch(need_new_kbranch, new_kbranch, existing_kbranch):
+    """
+    Return the linux-yocto bsp branch to use with the specified
+    kbranch.  This handles the -tiny variants for 3.4 and 3.8; the
+    other variants don't need mappings.
+    """
+    if need_new_kbranch == "y":
+        kbranch = new_kbranch
+    else:
+        kbranch = existing_kbranch
+
+    if kbranch.startswith("standard/tiny/common-pc"):
+        return "bsp/common-pc/common-pc-tiny.scc"
+    else:
+        return "ktypes/tiny/tiny.scc"
diff --git a/scripts/lib/bsp/help.py b/scripts/lib/bsp/help.py
new file mode 100644
index 0000000..4cce100
--- /dev/null
+++ b/scripts/lib/bsp/help.py
@@ -0,0 +1,1044 @@
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# Copyright (c) 2012, Intel Corporation.
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# DESCRIPTION
+# This module implements some basic help invocation functions along
+# with the bulk of the help topic text for the Yocto BSP Tools.
+#
+# AUTHORS
+# Tom Zanussi <tom.zanussi (at] intel.com>
+#
+
+import subprocess
+import logging
+
+
+def subcommand_error(args):
+    logging.info("invalid subcommand %s" % args[0])
+
+
+def display_help(subcommand, subcommands):
+    """
+    Display help for subcommand.
+    """
+    if subcommand not in subcommands:
+        return False
+
+    help = subcommands.get(subcommand, subcommand_error)[2]
+    pager = subprocess.Popen('less', stdin=subprocess.PIPE)
+    pager.communicate(help)
+
+    return True
+
+
+def yocto_help(args, usage_str, subcommands):
+    """
+    Subcommand help dispatcher.
+    """
+    if len(args) == 1 or not display_help(args[1], subcommands):
+        print(usage_str)
+
+
+def invoke_subcommand(args, parser, main_command_usage, subcommands):
+    """
+    Dispatch to subcommand handler borrowed from combo-layer.
+    Should use argparse, but has to work in 2.6.
+    """
+    if not args:
+        logging.error("No subcommand specified, exiting")
+        parser.print_help()
+    elif args[0] == "help":
+        yocto_help(args, main_command_usage, subcommands)
+    elif args[0] not in subcommands:
+        logging.error("Unsupported subcommand %s, exiting\n" % (args[0]))
+        parser.print_help()
+    else:
+        usage = subcommands.get(args[0], subcommand_error)[1]
+        subcommands.get(args[0], subcommand_error)[0](args[1:], usage)
+
+
+##
+# yocto-bsp help and usage strings
+##
+
+yocto_bsp_usage = """
+
+ Create a customized Yocto BSP layer.
+
+ usage: yocto-bsp [--version] [--help] COMMAND [ARGS]
+
+ Current 'yocto-bsp' commands are:
+    create            Create a new Yocto BSP
+    list              List available values for options and BSP properties
+
+ See 'yocto-bsp help COMMAND' for more information on a specific command.
+"""
+
+yocto_bsp_help_usage = """
+
+ usage: yocto-bsp help <subcommand>
+
+ This command displays detailed help for the specified subcommand.
+"""
+
+yocto_bsp_create_usage = """
+
+ Create a new Yocto BSP
+
+ usage: yocto-bsp create <bsp-name> <karch> [-o <DIRNAME> | --outdir <DIRNAME>]
+            [-i <JSON PROPERTY FILE> | --infile <JSON PROPERTY_FILE>]
+
+ This command creates a Yocto BSP based on the specified parameters.
+ The new BSP will be a new Yocto BSP layer contained by default within
+ the top-level directory specified as 'meta-bsp-name'.  The -o option
+ can be used to place the BSP layer in a directory with a different
+ name and location.
+
+ The value of the 'karch' parameter determines the set of files that
+ will be generated for the BSP, along with the specific set of
+ 'properties' that will be used to fill out the BSP-specific portions
+ of the BSP.  The possible values for the 'karch' paramter can be
+ listed via 'yocto-bsp list karch'.
+
+ NOTE: Once created, you should add your new layer to your
+ bblayers.conf file in order for it to be subsequently seen and
+ modified by the yocto-kernel tool.
+
+ See 'yocto bsp help create' for more detailed instructions.
+"""
+
+yocto_bsp_create_help = """
+
+NAME
+    yocto-bsp create - Create a new Yocto BSP
+
+SYNOPSIS
+    yocto-bsp create <bsp-name> <karch> [-o <DIRNAME> | --outdir <DIRNAME>]
+        [-i <JSON PROPERTY FILE> | --infile <JSON PROPERTY_FILE>]
+
+DESCRIPTION
+    This command creates a Yocto BSP based on the specified
+    parameters.  The new BSP will be a new Yocto BSP layer contained
+    by default within the top-level directory specified as
+    'meta-bsp-name'.  The -o option can be used to place the BSP layer
+    in a directory with a different name and location.
+
+    The value of the 'karch' parameter determines the set of files
+    that will be generated for the BSP, along with the specific set of
+    'properties' that will be used to fill out the BSP-specific
+    portions of the BSP.  The possible values for the 'karch' paramter
+    can be listed via 'yocto-bsp list karch'.
+
+    The BSP-specific properties that define the values that will be
+    used to generate a particular BSP can be specified on the
+    command-line using the -i option and supplying a JSON object
+    consisting of the set of name:value pairs needed by the BSP.
+
+    If the -i option is not used, the user will be interactively
+    prompted for each of the required property values, which will then
+    be used as values for BSP generation.
+
+    The set of properties available for a given architecture can be
+    listed using the 'yocto-bsp list' command.
+
+    Specifying -c causes the Python code generated and executed to
+    create the BSP to be dumped to the 'bspgen.out' file in the
+    current directory, and is useful for debugging.
+
+    NOTE: Once created, you should add your new layer to your
+    bblayers.conf file in order for it to be subsequently seen and
+    modified by the yocto-kernel tool.
+
+    For example, assuming your poky repo is at /path/to/poky, your new
+    BSP layer is at /path/to/poky/meta-mybsp, and your build directory
+    is /path/to/build:
+
+    $ gedit /path/to/build/conf/bblayers.conf
+
+    BBLAYERS ?= " \\
+      /path/to/poky/meta \\
+      /path/to/poky/meta-yocto \\
+      /path/to/poky/meta-mybsp \\
+      "
+"""
+
+yocto_bsp_list_usage = """
+
+ usage: yocto-bsp list karch
+        yocto-bsp list <karch> properties
+                [-o <JSON PROPERTY FILE> | --outfile <JSON PROPERTY_FILE>]
+        yocto-bsp list <karch> property <xxx>
+                [-o <JSON PROPERTY FILE> | --outfile <JSON PROPERTY_FILE>]
+
+ This command enumerates the complete set of possible values for a
+ specified option or property needed by the BSP creation process.
+
+ The first form enumerates all the possible values that exist and can
+ be specified for the 'karch' parameter to the 'yocto bsp create'
+ command.
+
+ The second form enumerates all the possible properties that exist and
+ must have values specified for them in the 'yocto bsp create' command
+ for the given 'karch'.
+
+ The third form enumerates all the possible values that exist and can
+ be specified for any of the enumerable properties of the given
+ 'karch' in the 'yocto bsp create' command.
+
+ See 'yocto-bsp help list' for more details.
+"""
+
+yocto_bsp_list_help = """
+
+NAME
+    yocto-bsp list - List available values for options and BSP properties
+
+SYNOPSIS
+    yocto-bsp list karch
+    yocto-bsp list <karch> properties
+            [--o <JSON PROPERTY FILE> | -outfile <JSON PROPERTY_FILE>]
+    yocto-bsp list <karch> property <xxx>
+            [--o <JSON PROPERTY FILE> | -outfile <JSON PROPERTY_FILE>]
+
+DESCRIPTION
+    This command enumerates the complete set of possible values for a
+    specified option or property needed by the BSP creation process.
+
+    The first form enumerates all the possible values that exist and
+    can be specified for the 'karch' parameter to the 'yocto bsp
+    create' command.  Example output for the 'list karch' command:
+
+    $ yocto-bsp list karch
+    Architectures available:
+        arm
+        powerpc
+        i386
+        mips
+        mips64
+        x86_64
+        qemu
+
+    The second form enumerates all the possible properties that exist
+    and must have values specified for them in the 'yocto bsp create'
+    command for the given 'karch'.  This command is mainly meant to
+    allow the development user interface alternatives to the default
+    text-based prompting interface.  If the -o option is specified,
+    the list of properties, in addition to being displayed, will be
+    written to the specified file as a JSON object.  In this case, the
+    object will consist of the set of name:value pairs corresponding
+    to the (possibly nested) dictionary of properties defined by the
+    input statements used by the BSP.  Some example output for the
+    'list properties' command:
+
+    $ yocto-bsp list arm properties
+    "touchscreen" : {
+        "msg" : Does your BSP have a touchscreen? (y/N)
+        "default" : n
+        "type" : boolean
+    }
+    "uboot_loadaddress" : {
+        "msg" : Please specify a value for UBOOT_LOADADDRESS.
+        "default" : 0x80008000
+        "type" : edit
+        "prio" : 40
+    }
+    "kernel_choice" : {
+        "prio" : 10
+        "default" : linux-yocto_3.2
+        "depends-on" : use_default_kernel
+        "depends-on-val" : n
+        "msg" : Please choose the kernel to use in this BSP =>
+        "type" : choicelist
+        "gen" : bsp.kernel.kernels
+    }
+    "if kernel_choice == "linux-yocto_3.0":" : {
+        "base_kbranch_linux_yocto_3_0" : {
+            "prio" : 20
+            "default" : yocto/standard
+            "depends-on" : new_kbranch_linux_yocto_3_0
+            "depends-on-val" : y
+            "msg" : Please choose a machine branch to base this BSP on =>
+            "type" : choicelist
+            "gen" : bsp.kernel.all_branches
+    }
+    .
+    .
+    .
+
+    Each entry in the output consists of the name of the input element
+    e.g. "touchscreen", followed by the properties defined for that
+    element enclosed in braces.  This information should provide
+    sufficient information to create a complete user interface with.
+    Two features of the scheme provide for conditional input.  First,
+    if a Python "if" statement appears in place of an input element
+    name, the set of enclosed input elements apply and should be
+    presented to the user only if the 'if' statement evaluates to
+    true.  The test in the if statement will always reference another
+    input element in the list, which means that the element being
+    tested should be presented to the user before the elements
+    enclosed by the if block.  Secondly, in a similar way, some
+    elements contain "depends-on" and depends-on-val" tags, which mean
+    that the affected input element should only be presented to the
+    user if the element it depends on has already been presented to
+    the user and the user has selected the specified value for that
+    element.
+
+    The third form enumerates all the possible values that exist and
+    can be specified for any of the enumerable properties of the given
+    'karch' in the 'yocto bsp create' command.  If the -o option is
+    specified, the list of values for the given property, in addition
+    to being displayed, will be written to the specified file as a
+    JSON object.  In this case, the object will consist of the set of
+    name:value pairs corresponding to the array of property values
+    associated with the property.
+
+    $ yocto-bsp list i386 property xserver_choice
+        ["xserver_vesa", "VESA xserver support"]
+        ["xserver_i915", "i915 xserver support"]
+
+    $ yocto-bsp list arm property base_kbranch_linux_yocto_3_0
+        Getting branches from remote repo git://git.yoctoproject.org/linux-yocto-3.0...
+        ["yocto/base", "yocto/base"]
+        ["yocto/eg20t", "yocto/eg20t"]
+        ["yocto/gma500", "yocto/gma500"]
+        ["yocto/pvr", "yocto/pvr"]
+        ["yocto/standard/arm-versatile-926ejs", "yocto/standard/arm-versatile-926ejs"]
+        ["yocto/standard/base", "yocto/standard/base"]
+        ["yocto/standard/cedartrail", "yocto/standard/cedartrail"]
+        .
+        .
+        .
+        ["yocto/standard/qemu-ppc32", "yocto/standard/qemu-ppc32"]
+        ["yocto/standard/routerstationpro", "yocto/standard/routerstationpro"]
+
+    The third form as well is meant mainly for developers of
+    alternative interfaces - it allows the developer to fetch the
+    possible values for a given input element on-demand.  This
+    on-demand capability is especially valuable for elements that
+    require relatively expensive remote operations to fulfill, such as
+    the example that returns the set of branches available in a remote
+    git tree above.
+
+"""
+
+##
+# yocto-kernel help and usage strings
+##
+
+yocto_kernel_usage = """
+
+ Modify and list Yocto BSP kernel config items and patches.
+
+ usage: yocto-kernel [--version] [--help] COMMAND [ARGS]
+
+ Current 'yocto-kernel' commands are:
+   config list       List the modifiable set of bare kernel config options for a BSP
+   config add        Add or modify bare kernel config options for a BSP
+   config rm         Remove bare kernel config options from a BSP
+   patch list        List the patches associated with a BSP
+   patch add         Patch the Yocto kernel for a BSP
+   patch rm          Remove patches from a BSP
+   feature list      List the features used by a BSP
+   feature add       Have a BSP use a feature
+   feature rm        Have a BSP stop using a feature
+   features list     List the features available to BSPs
+   feature describe  Describe a particular feature
+   feature create    Create a new BSP-local feature
+   feature destroy   Remove a BSP-local feature
+
+ See 'yocto-kernel help COMMAND' for more information on a specific command.
+
+"""
+
+
+yocto_kernel_help_usage = """
+
+ usage: yocto-kernel help <subcommand>
+
+ This command displays detailed help for the specified subcommand.
+"""
+
+yocto_kernel_config_list_usage = """
+
+ List the modifiable set of bare kernel config options for a BSP
+
+ usage: yocto-kernel config list <bsp-name>
+
+ This command lists the 'modifiable' config items for a BSP i.e. the
+ items which are eligible for modification or removal by other
+ yocto-kernel commands.
+
+ 'modifiable' config items are the config items contained a BSP's
+ user-config.cfg base config.
+"""
+
+
+yocto_kernel_config_list_help = """
+
+NAME
+    yocto-kernel config list - List the modifiable set of bare kernel
+    config options for a BSP
+
+SYNOPSIS
+    yocto-kernel config list <bsp-name>
+
+DESCRIPTION
+    This command lists the 'modifiable' config items for a BSP
+    i.e. the items which are eligible for modification or removal by
+    other yocto-kernel commands.
+"""
+
+
+yocto_kernel_config_add_usage = """
+
+ Add or modify bare kernel config options for a BSP
+
+ usage: yocto-kernel config add <bsp-name> [<CONFIG_XXX=x> ...]
+
+ This command adds one or more CONFIG_XXX=x items to a BSP's user-config.cfg
+ base config.
+"""
+
+
+yocto_kernel_config_add_help = """
+
+NAME
+    yocto-kernel config add - Add or modify bare kernel config options
+    for a BSP
+
+SYNOPSIS
+    yocto-kernel config add <bsp-name> [<CONFIG_XXX=x> ...]
+
+DESCRIPTION
+    This command adds one or more CONFIG_XXX=x items to a BSP's
+    foo.cfg base config.
+
+    NOTE: It's up to the user to determine whether or not the config
+    options being added make sense or not - this command does no
+    sanity checking or verification of any kind to ensure that a
+    config option really makes sense and will actually be set in in
+    the final config.  For example, if a config option depends on
+    other config options, it will be turned off by kconfig if the
+    other options aren't set correctly.
+"""
+
+
+yocto_kernel_config_rm_usage = """
+
+ Remove bare kernel config options from a BSP
+
+ usage: yocto-kernel config rm <bsp-name>
+
+ This command removes (turns off) one or more CONFIG_XXX items from a
+ BSP's user-config.cfg base config.
+
+ The set of config items available to be removed by this command for a
+ BSP is listed and the user prompted for the specific items to remove.
+"""
+
+
+yocto_kernel_config_rm_help = """
+
+NAME
+    yocto-kernel config rm - Remove bare kernel config options from a
+    BSP
+
+SYNOPSIS
+    yocto-kernel config rm <bsp-name>
+
+DESCRIPTION
+    This command removes (turns off) one or more CONFIG_XXX items from a
+    BSP's user-config.cfg base config.
+
+    The set of config items available to be removed by this command
+    for a BSP is listed and the user prompted for the specific items
+    to remove.
+"""
+
+
+yocto_kernel_patch_list_usage = """
+
+ List the patches associated with the kernel for a BSP
+
+ usage: yocto-kernel patch list <bsp-name>
+
+ This command lists the patches associated with a BSP.
+
+ NOTE: this only applies to patches listed in the kernel recipe's
+ user-patches.scc file (and currently repeated in its SRC_URI).
+"""
+
+
+yocto_kernel_patch_list_help = """
+
+NAME
+    yocto-kernel patch list - List the patches associated with the kernel
+    for a BSP
+
+SYNOPSIS
+    yocto-kernel patch list <bsp-name>
+
+DESCRIPTION
+    This command lists the patches associated with a BSP.
+
+    NOTE: this only applies to patches listed in the kernel recipe's
+    user-patches.scc file (and currently repeated in its SRC_URI).
+"""
+
+
+yocto_kernel_patch_add_usage = """
+
+ Patch the Yocto kernel for a specific BSP
+
+ usage: yocto-kernel patch add <bsp-name> [<PATCH> ...]
+
+ This command adds one or more patches to a BSP's machine branch.  The
+ patch will be added to the BSP's linux-yocto kernel user-patches.scc
+ file (and currently repeated in its SRC_URI) and will be guaranteed
+ to be applied in the order specified.
+"""
+
+
+yocto_kernel_patch_add_help = """
+
+NAME
+    yocto-kernel patch add - Patch the Yocto kernel for a specific BSP
+
+SYNOPSIS
+    yocto-kernel patch add <bsp-name> [<PATCH> ...]
+
+DESCRIPTION
+    This command adds one or more patches to a BSP's machine branch.
+    The patch will be added to the BSP's linux-yocto kernel
+    user-patches.scc file (and currently repeated in its SRC_URI) and
+    will be guaranteed to be applied in the order specified.
+
+    NOTE: It's up to the user to determine whether or not the patches
+    being added makes sense or not - this command does no sanity
+    checking or verification of any kind to ensure that a patch can
+    actually be applied to the BSP's kernel branch; it's assumed that
+    the user has already done that.
+"""
+
+
+yocto_kernel_patch_rm_usage = """
+
+ Remove a patch from the Yocto kernel for a specific BSP
+
+ usage: yocto-kernel patch rm <bsp-name>
+
+ This command removes one or more patches from a BSP's machine branch.
+ The patch will be removed from the BSP's linux-yocto kernel
+ user-patches.scc file (and currently repeated in its SRC_URI) and
+ kernel SRC_URI dir.
+
+ The set of patches available to be removed by this command for a BSP
+ is listed and the user prompted for the specific patches to remove.
+"""
+
+
+yocto_kernel_patch_rm_help = """
+
+NAME
+    yocto-kernel patch rm - Remove a patch from the Yocto kernel for a specific BSP
+
+SYNOPSIS
+    yocto-kernel patch rm <bsp-name>
+
+DESCRIPTION
+    This command removes one or more patches from a BSP's machine
+    branch.  The patch will be removed from the BSP's linux-yocto
+    kernel user-patches.scc file (and currently repeated in its
+    SRC_URI).
+
+    The set of patches available to be removed by this command for a
+    BSP is listed and the user prompted for the specific patches to
+    remove.
+"""
+
+yocto_kernel_feature_list_usage = """
+
+ List the BSP features that are being used by a BSP
+
+ usage: yocto-kernel feature list <bsp-name>
+
+ This command lists the features being used by a BSP i.e. the features
+ which are eligible for modification or removal by other yocto-kernel
+ commands.
+
+ 'modifiable' features are the features listed in a BSP's
+ user-features.scc file.
+"""
+
+
+yocto_kernel_feature_list_help = """
+
+NAME
+    yocto-kernel feature list - List the modifiable set of features
+    being used by a BSP
+
+SYNOPSIS
+    yocto-kernel feature list <bsp-name>
+
+DESCRIPTION
+    This command lists the 'modifiable' features being used by a BSP
+    i.e. the features which are eligible for modification or removal
+    by other yocto-kernel commands.
+"""
+
+
+yocto_kernel_feature_add_usage = """
+
+ Add to or modify the list of features being used for a BSP
+
+ usage: yocto-kernel feature add <bsp-name> [/xxxx/yyyy/feature.scc ...]
+
+ This command adds one or more feature items to a BSP's kernel
+ user-features.scc file, which is the file used to manage features in
+ a yocto-bsp-generated BSP.  Features to be added must be specified as
+ fully-qualified feature names.
+"""
+
+
+yocto_kernel_feature_add_help = """
+
+NAME
+    yocto-kernel feature add - Add to or modify the list of features
+    being used for a BSP
+
+SYNOPSIS
+    yocto-kernel feature add <bsp-name> [/xxxx/yyyy/feature.scc ...]
+
+DESCRIPTION
+    This command adds one or more feature items to a BSP's
+    user-features.scc file, which is the file used to manage features
+    in a yocto-bsp-generated BSP.  Features to be added must be
+    specified as fully-qualified feature names.
+"""
+
+
+yocto_kernel_feature_rm_usage = """
+
+ Remove a feature from the list of features being used for a BSP
+
+ usage: yocto-kernel feature rm <bsp-name>
+
+ This command removes (turns off) one or more features from a BSP's
+ user-features.scc file, which is the file used to manage features in
+ a yocto-bsp-generated BSP.
+
+ The set of features available to be removed by this command for a BSP
+ is listed and the user prompted for the specific items to remove.
+"""
+
+
+yocto_kernel_feature_rm_help = """
+
+NAME
+    yocto-kernel feature rm - Remove a feature from the list of
+    features being used for a BSP
+
+SYNOPSIS
+    yocto-kernel feature rm <bsp-name>
+
+DESCRIPTION
+    This command removes (turns off) one or more features from a BSP's
+    user-features.scc file, which is the file used to manage features
+    in a yocto-bsp-generated BSP.
+
+    The set of features available to be removed by this command for a
+    BSP is listed and the user prompted for the specific items to
+    remove.
+"""
+
+
+yocto_kernel_available_features_list_usage = """
+
+ List the set of kernel features available to a BSP
+
+ usage: yocto-kernel features list <bsp-name>
+
+ This command lists the complete set of kernel features available to a
+ BSP.  This includes the features contained in linux-yocto meta
+ branches as well as recipe-space features defined locally to the BSP.
+"""
+
+
+yocto_kernel_available_features_list_help = """
+
+NAME
+    yocto-kernel features list - List the set of kernel features
+    available to a BSP
+
+SYNOPSIS
+    yocto-kernel features list <bsp-name>
+
+DESCRIPTION
+     This command lists the complete set of kernel features available
+     to a BSP.  This includes the features contained in linux-yocto
+     meta branches as well as recipe-space features defined locally to
+     the BSP.
+"""
+
+
+yocto_kernel_feature_describe_usage = """
+
+ Print the description and compatibility information for a given kernel feature
+
+ usage: yocto-kernel feature describe <bsp-name> [/xxxx/yyyy/feature.scc ...]
+
+ This command prints the description and compatibility of a specific
+ feature in the format 'description [compatibility].
+"""
+
+
+yocto_kernel_feature_describe_help = """
+
+NAME
+    yocto-kernel feature describe - print the description and
+    compatibility information for a given kernel feature
+
+SYNOPSIS
+    yocto-kernel feature describe <bsp-name> [/xxxx/yyyy/feature.scc ...]
+
+DESCRIPTION
+    This command prints the description and compatibility of a
+    specific feature in the format 'description [compatibility].  If
+    the feature doesn't define a description or compatibility, a
+    string with generic unknown values will be printed.
+"""
+
+
+yocto_kernel_feature_create_usage = """
+
+ Create a recipe-space kernel feature in a BSP
+
+ usage: yocto-kernel feature create <bsp-name> newfeature.scc \
+        "Feature Description" capabilities [<CONFIG_XXX=x> ...] [<PATCH> ...]
+
+ This command creates a new kernel feature from the bare config
+ options and patches specified on the command-line.
+"""
+
+
+yocto_kernel_feature_create_help = """
+
+NAME
+    yocto-kernel feature create - create a recipe-space kernel feature
+    in a BSP
+
+SYNOPSIS
+    yocto-kernel feature create <bsp-name> newfeature.scc \
+        "Feature Description" capabilities [<CONFIG_XXX=x> ...] [<PATCH> ...]
+
+DESCRIPTION
+    This command creates a new kernel feature from the bare config
+    options and patches specified on the command-line.  The new
+    feature will be created in recipe-space, specifically in either
+    the kernel .bbappend's /files/cfg or /files/features subdirectory,
+    depending on whether or not the feature contains config items only
+    or config items along with patches.  The named feature must end
+    with .scc and must not contain a feature directory to contain the
+    feature (this will be determined automatically), and a feature
+    decription in double-quotes along with a capabilities string
+    (which for the time being can be one of: 'all' or 'board').
+"""
+
+
+yocto_kernel_feature_destroy_usage = """
+
+ Destroy a recipe-space kernel feature in a BSP
+
+ usage: yocto-kernel feature destroy <bsp-name> feature.scc
+
+ This command destroys a kernel feature defined in the specified BSP's
+ recipe-space kernel definition.
+"""
+
+
+yocto_kernel_feature_destroy_help = """
+
+NAME
+    yocto-kernel feature destroy <bsp-name> feature.scc - destroy a
+    recipe-space kernel feature in a BSP
+
+SYNOPSIS
+    yocto-kernel feature destroy <bsp-name> feature.scc
+
+DESCRIPTION
+    This command destroys a kernel feature defined in the specified
+    BSP's recipe-space kernel definition.  The named feature must end
+    with .scc and must not contain a feature directory to contain the
+    feature (this will be determined automatically).  If the kernel
+    feature is in use by a BSP, it can't be removed until the BSP
+    stops using it (see yocto-kernel feature rm to stop using it).
+"""
+
+##
+# yocto-layer help and usage strings
+##
+
+yocto_layer_usage = """
+
+ Create a generic Yocto layer.
+
+ usage: yocto-layer [--version] [--help] COMMAND [ARGS]
+
+ Current 'yocto-layer' commands are:
+    create            Create a new generic Yocto layer
+    list              List available values for input options and properties
+
+ See 'yocto-layer help COMMAND' for more information on a specific command.
+"""
+
+yocto_layer_help_usage = """
+
+ usage: yocto-layer help <subcommand>
+
+ This command displays detailed help for the specified subcommand.
+"""
+
+yocto_layer_create_usage = """
+
+ Create a new generic Yocto layer
+
+ usage: yocto-layer create <layer-name> [layer_priority]
+            [-o <DIRNAME> | --outdir <DIRNAME>]
+            [-i <JSON PROPERTY FILE> | --infile <JSON PROPERTY_FILE>]
+
+ This command creates a generic Yocto layer based on the specified
+ parameters.  The new layer will be a new Yocto layer contained by
+ default within the top-level directory specified as
+ 'meta-layer-name'.  The -o option can be used to place the layer in a
+ directory with a different name and location.
+
+ If layer_priority is specified, a simple layer will be created using
+ the given layer priority, and the user will not be prompted for
+ further input.
+
+ NOTE: Once created, you should add your new layer to your
+ bblayers.conf file in order for it to be subsequently seen and
+ modified by the yocto-kernel tool.  Instructions for doing this can
+ be found in the README file generated in the layer's top-level
+ directory.
+
+ See 'yocto layer help create' for more detailed instructions.
+"""
+
+yocto_layer_create_help = """
+
+NAME
+    yocto-layer create - Create a new generic Yocto layer
+
+SYNOPSIS
+    yocto-layer create <layer-name> [layer_priority]
+        [-o <DIRNAME> | --outdir <DIRNAME>]
+        [-i <JSON PROPERTY FILE> | --infile <JSON PROPERTY_FILE>]
+
+DESCRIPTION
+    This command creates a generic Yocto layer based on the specified
+    parameters.  The new layer will be a new Yocto layer contained by
+    default within the top-level directory specified as
+    'meta-layer-name'.  The -o option can be used to place the layer
+    in a directory with a different name and location.
+
+    If layer_priority is specified, a simple layer will be created
+    using the given layer priority, and the user will not be prompted
+    for further input.
+
+    The layer-specific properties that define the values that will be
+    used to generate the layer can be specified on the command-line
+    using the -i option and supplying a JSON object consisting of the
+    set of name:value pairs needed by the layer.
+
+    If the -i option is not used, the user will be interactively
+    prompted for each of the required property values, which will then
+    be used as values for layer generation.
+
+    The set of properties available can be listed using the
+    'yocto-layer list' command.
+
+    Specifying -c causes the Python code generated and executed to
+    create the layer to be dumped to the 'bspgen.out' file in the
+    current directory, and is useful for debugging.
+
+    NOTE: Once created, you should add your new layer to your
+    bblayers.conf file in order for it to be subsequently seen and
+    modified by the yocto-kernel tool.  Instructions for doing this
+    can be found in the README file generated in the layer's top-level
+    directory.
+
+    For example, assuming your poky repo is at /path/to/poky, your new
+    layer is at /path/to/poky/meta-mylayer, and your build directory
+    is /path/to/build:
+
+    $ gedit /path/to/build/conf/bblayers.conf
+
+    BBLAYERS ?= " \\
+      /path/to/poky/meta \\
+      /path/to/poky/meta-yocto \\
+      /path/to/poky/meta-mylayer \\
+      "
+"""
+
+yocto_layer_list_usage = """
+
+ usage: yocto-layer list properties
+                [-o <JSON PROPERTY FILE> | --outfile <JSON PROPERTY_FILE>]
+        yocto-layer list property <xxx>
+                [-o <JSON PROPERTY FILE> | --outfile <JSON PROPERTY_FILE>]
+
+ This command enumerates the complete set of possible values for a
+ specified option or property needed by the layer creation process.
+
+ The first form enumerates all the possible properties that exist and
+ must have values specified for them in the 'yocto-layer create'
+ command.
+
+ The second form enumerates all the possible values that exist and can
+ be specified for any of the enumerable properties in the 'yocto-layer
+ create' command.
+
+ See 'yocto-layer help list' for more details.
+"""
+
+yocto_layer_list_help = """
+
+NAME
+    yocto-layer list - List available values for layer input options and properties
+
+SYNOPSIS
+    yocto-layer list properties
+            [--o <JSON PROPERTY FILE> | -outfile <JSON PROPERTY_FILE>]
+    yocto-layer list property <xxx>
+            [--o <JSON PROPERTY FILE> | -outfile <JSON PROPERTY_FILE>]
+
+DESCRIPTION
+    This command enumerates the complete set of possible values for a
+    specified option or property needed by the layer creation process.
+
+    The first form enumerates all the possible properties that exist
+    and must have values specified for them in the 'yocto-layer
+    create' command.  This command is mainly meant to aid the
+    development of user interface alternatives to the default
+    text-based prompting interface.  If the -o option is specified,
+    the list of properties, in addition to being displayed, will be
+    written to the specified file as a JSON object.  In this case, the
+    object will consist of the set of name:value pairs corresponding
+    to the (possibly nested) dictionary of properties defined by the
+    input statements used by the BSP.  Some example output for the
+    'list properties' command:
+
+    $ yocto-layer list properties
+    "example_bbappend_name" : {
+        "default" : example
+        "msg" : Please enter the name you'd like to use for your bbappend file:
+        "type" : edit
+        "prio" : 20
+        "filename" : /home/trz/yocto/yocto-layer-dev/scripts/lib/bsp/substrate/target/arch/layer/layer-questions.noinstall
+    }
+    "create_example_recipe" : {
+        "default" : n
+        "msg" : Would you like to have an example recipe created? (y/n)
+        "type" : boolean
+        "prio" : 20
+        "filename" : /home/trz/yocto/yocto-layer-dev/scripts/lib/bsp/substrate/target/arch/layer/layer-questions.noinstall
+    }
+    "example_recipe_name" : {
+        "default" : example
+        "msg" : Please enter the name you'd like to use for your example recipe:
+        "type" : edit
+        "prio" : 20
+        "filename" : /home/trz/yocto/yocto-layer-dev/scripts/lib/bsp/substrate/target/arch/layer/layer-questions.noinstall
+    }
+    "layer_priority" : {
+        "default" : 6
+        "msg" : Please enter the layer priority you'd like to use for the layer:
+        "type" : edit
+        "prio" : 20
+        "filename" : /home/trz/yocto/yocto-layer-dev/scripts/lib/bsp/substrate/target/arch/layer/layer-questions.noinstall
+    }
+    "create_example_bbappend" : {
+        "default" : n
+        "msg" : Would you like to have an example bbappend file created? (y/n)
+        "type" : boolean
+        "prio" : 20
+        "filename" : /home/trz/yocto/yocto-layer-dev/scripts/lib/bsp/substrate/target/arch/layer/layer-questions.noinstall
+    }
+    "example_bbappend_version" : {
+        "default" : 0.1
+        "msg" : Please enter the version number you'd like to use for your bbappend file (this should match the recipe you're appending to):
+        "type" : edit
+        "prio" : 20
+        "filename" : /home/trz/yocto/yocto-layer-dev/scripts/lib/bsp/substrate/target/arch/layer/layer-questions.noinstall
+    }
+
+    Each entry in the output consists of the name of the input element
+    e.g. "layer_priority", followed by the properties defined for that
+    element enclosed in braces.  This information should provide
+    sufficient information to create a complete user interface.  Two
+    features of the scheme provide for conditional input.  First, if a
+    Python "if" statement appears in place of an input element name,
+    the set of enclosed input elements apply and should be presented
+    to the user only if the 'if' statement evaluates to true.  The
+    test in the if statement will always reference another input
+    element in the list, which means that the element being tested
+    should be presented to the user before the elements enclosed by
+    the if block.  Secondly, in a similar way, some elements contain
+    "depends-on" and depends-on-val" tags, which mean that the
+    affected input element should only be presented to the user if the
+    element it depends on has already been presented to the user and
+    the user has selected the specified value for that element.
+
+    The second form enumerates all the possible values that exist and
+    can be specified for any of the enumerable properties in the
+    'yocto-layer create' command.  If the -o option is specified, the
+    list of values for the given property, in addition to being
+    displayed, will be written to the specified file as a JSON object.
+    In this case, the object will consist of the set of name:value
+    pairs corresponding to the array of property values associated
+    with the property.
+
+    $ yocto-layer list property layer_priority
+     [no output - layer_priority is a text field that has no enumerable values]
+
+    The second form as well is meant mainly for developers of
+    alternative interfaces - it allows the developer to fetch the
+    possible values for a given input element on-demand.  This
+    on-demand capability is especially valuable for elements that
+    require relatively expensive remote operations to fulfill, such as
+    the example that returns the set of branches available in a remote
+    git tree above.
+
+"""
+
+##
+# test code
+##
+
+test_bsp_properties = {
+    'smp': 'yes',
+    'touchscreen': 'yes',
+    'keyboard': 'no',
+    'xserver': 'yes',
+    'xserver_choice': 'xserver-i915',
+    'features': ['goodfeature', 'greatfeature'],
+    'tunefile': 'tune-quark',
+}
+
diff --git a/scripts/lib/bsp/kernel.py b/scripts/lib/bsp/kernel.py
new file mode 100644
index 0000000..ba68b60
--- /dev/null
+++ b/scripts/lib/bsp/kernel.py
@@ -0,0 +1,1071 @@
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# Copyright (c) 2012, Intel Corporation.
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# DESCRIPTION
+# This module implements the kernel-related functions used by
+# 'yocto-kernel' to manage kernel config items and patches for Yocto
+# BSPs.
+#
+# AUTHORS
+# Tom Zanussi <tom.zanussi (at] intel.com>
+#
+
+import sys
+import os
+import shutil
+from tags import *
+import glob
+import subprocess
+from engine import create_context
+
+
+def find_bblayers():
+    """
+    Find and return a sanitized list of the layers found in BBLAYERS.
+    """
+    try:
+        builddir = os.environ["BUILDDIR"]
+    except KeyError:
+        print "BUILDDIR not found, exiting. (Did you forget to source oe-init-build-env?)"
+        sys.exit(1)
+    bblayers_conf = os.path.join(builddir, "conf/bblayers.conf")
+
+    layers = []
+
+    bitbake_env_cmd = "bitbake -e"
+    bitbake_env_lines = subprocess.Popen(bitbake_env_cmd, shell=True,
+                                         stdout=subprocess.PIPE).stdout.read()
+
+    if not bitbake_env_lines:
+        print "Couldn't get '%s' output, exiting." % bitbake_env_cmd
+        sys.exit(1)
+
+    for line in bitbake_env_lines.split('\n'):
+        bblayers = get_line_val(line, "BBLAYERS")
+        if (bblayers):
+            break
+
+    if not bblayers:
+        print "Couldn't find BBLAYERS in %s output, exiting." % \
+            bitbake_env_cmd
+        sys.exit(1)
+
+    raw_layers = bblayers.split()
+
+    for layer in raw_layers:
+        if layer == 'BBLAYERS' or '=' in layer:
+            continue
+        layers.append(layer)
+
+    return layers
+
+
+def get_line_val(line, key):
+    """
+    Extract the value from the VAR="val" string
+    """
+    if line.startswith(key + "="):
+        stripped_line = line.split('=')[1]
+        stripped_line = stripped_line.replace('\"', '')
+        return stripped_line
+    return None
+
+
+def find_meta_layer():
+    """
+    Find and return the meta layer in BBLAYERS.
+    """
+    layers = find_bblayers()
+
+    for layer in layers:
+        if layer.endswith("meta"):
+            return layer
+
+    return None
+
+
+def find_bsp_layer(machine):
+    """
+    Find and return a machine's BSP layer in BBLAYERS.
+    """
+    layers = find_bblayers()
+
+    for layer in layers:
+        if layer.endswith(machine):
+            return layer
+
+    print "Unable to find the BSP layer for machine %s." % machine
+    print "Please make sure it is listed in bblayers.conf"
+    sys.exit(1)
+
+
+def gen_choices_str(choices):
+    """
+    Generate a numbered list of choices from a list of choices for
+    display to the user.
+    """
+    choices_str = ""
+
+    for i, choice in enumerate(choices):
+        choices_str += "\t" + str(i + 1) + ") " + choice + "\n"
+
+    return choices_str
+
+
+def open_user_file(scripts_path, machine, userfile, mode):
+    """
+    Find one of the user files (user-config.cfg, user-patches.scc)
+    associated with the machine (could be in files/,
+    linux-yocto-custom/, etc).  Returns the open file if found, None
+    otherwise.
+
+    The caller is responsible for closing the file returned.
+    """
+    layer = find_bsp_layer(machine)
+    linuxdir = os.path.join(layer, "recipes-kernel/linux")
+    linuxdir_list = os.listdir(linuxdir)
+    for fileobj in linuxdir_list:
+        fileobj_path = os.path.join(linuxdir, fileobj)
+        if os.path.isdir(fileobj_path):
+            userfile_name = os.path.join(fileobj_path, userfile)
+            try:
+                f = open(userfile_name, mode)
+                return f
+            except IOError:
+                continue
+    return None
+
+
+def read_config_items(scripts_path, machine):
+    """
+    Find and return a list of config items (CONFIG_XXX) in a machine's
+    user-defined config fragment [${machine}-user-config.cfg].
+    """
+    config_items = []
+
+    f = open_user_file(scripts_path, machine, machine+"-user-config.cfg", "r")
+    lines = f.readlines()
+    for line in lines:
+        s = line.strip()
+        if s and not s.startswith("#"):
+            config_items.append(s)
+    f.close()
+
+    return config_items
+
+
+def write_config_items(scripts_path, machine, config_items):
+    """
+    Write (replace) the list of config items (CONFIG_XXX) in a
+    machine's user-defined config fragment [${machine}=user-config.cfg].
+    """
+    f = open_user_file(scripts_path, machine, machine+"-user-config.cfg", "w")
+    for item in config_items:
+        f.write(item + "\n")
+    f.close()
+
+    kernel_contents_changed(scripts_path, machine)
+
+
+def yocto_kernel_config_list(scripts_path, machine):
+    """
+    Display the list of config items (CONFIG_XXX) in a machine's
+    user-defined config fragment [${machine}-user-config.cfg].
+    """
+    config_items = read_config_items(scripts_path, machine)
+
+    print "The current set of machine-specific kernel config items for %s is:" % machine
+    print gen_choices_str(config_items)
+
+
+def yocto_kernel_config_rm(scripts_path, machine):
+    """
+    Display the list of config items (CONFIG_XXX) in a machine's
+    user-defined config fragment [${machine}-user-config.cfg], prompt the user
+    for one or more to remove, and remove them.
+    """
+    config_items = read_config_items(scripts_path, machine)
+
+    print "Specify the kernel config items to remove:"
+    input = raw_input(gen_choices_str(config_items))
+    rm_choices = input.split()
+    rm_choices.sort()
+
+    removed = []
+
+    for choice in reversed(rm_choices):
+        try:
+            idx = int(choice) - 1
+        except ValueError:
+            print "Invalid choice (%s), exiting" % choice
+            sys.exit(1)
+        if idx < 0 or idx >= len(config_items):
+            print "Invalid choice (%d), exiting" % (idx + 1)
+            sys.exit(1)
+        removed.append(config_items.pop(idx))
+
+    write_config_items(scripts_path, machine, config_items)
+
+    print "Removed items:"
+    for r in removed:
+        print "\t%s" % r
+
+
+def yocto_kernel_config_add(scripts_path, machine, config_items):
+    """
+    Add one or more config items (CONFIG_XXX) to a machine's
+    user-defined config fragment [${machine}-user-config.cfg].
+    """
+    new_items = []
+    dup_items = []
+
+    cur_items = read_config_items(scripts_path, machine)
+
+    for item in config_items:
+        if not item.startswith("CONFIG") or (not "=y" in item and not "=m" in item):
+            print "Invalid config item (%s), exiting" % item
+            sys.exit(1)
+        if item not in cur_items and item not in new_items:
+            new_items.append(item)
+        else:
+            dup_items.append(item)
+
+    if len(new_items) > 0:
+        cur_items.extend(new_items)
+        write_config_items(scripts_path, machine, cur_items)
+        print "Added item%s:" % ("" if len(new_items)==1 else "s")
+        for n in new_items:
+            print "\t%s" % n
+
+    if len(dup_items) > 0:
+        output="The following item%s already exist%s in the current configuration, ignoring %s:" % \
+            (("","s", "it") if len(dup_items)==1 else ("s", "", "them" ))
+        print output
+        for n in dup_items:
+            print "\t%s" % n
+
+def find_current_kernel(bsp_layer, machine):
+    """
+    Determine the kernel and version currently being used in the BSP.
+    """
+    machine_conf = os.path.join(bsp_layer, "conf/machine/" + machine + ".conf")
+
+    preferred_kernel = preferred_kernel_version = preferred_version_varname = None
+
+    f = open(machine_conf, "r")
+    lines = f.readlines()
+    for line in lines:
+        if line.strip().startswith("PREFERRED_PROVIDER_virtual/kernel"):
+            preferred_kernel = line.split()[-1]
+            preferred_kernel = preferred_kernel.replace('\"','')
+            preferred_version_varname = "PREFERRED_VERSION_" + preferred_kernel
+        if preferred_version_varname and line.strip().startswith(preferred_version_varname):
+            preferred_kernel_version = line.split()[-1]
+            preferred_kernel_version = preferred_kernel_version.replace('\"','')
+            preferred_kernel_version = preferred_kernel_version.replace('%','')
+
+    if preferred_kernel and preferred_kernel_version:
+        return preferred_kernel + "_" + preferred_kernel_version
+    elif preferred_kernel:
+        return preferred_kernel
+
+
+def find_filesdir(scripts_path, machine):
+    """
+    Find the name of the 'files' dir associated with the machine
+    (could be in files/, linux-yocto-custom/, etc).  Returns the name
+    of the files dir if found, None otherwise.
+    """
+    layer = find_bsp_layer(machine)
+    filesdir = None
+    linuxdir = os.path.join(layer, "recipes-kernel/linux")
+    linuxdir_list = os.listdir(linuxdir)
+    for fileobj in linuxdir_list:
+        fileobj_path = os.path.join(linuxdir, fileobj)
+        if os.path.isdir(fileobj_path):
+            # this could be files/ or linux-yocto-custom/, we have no way of distinguishing
+            # so we take the first (and normally only) dir we find as the 'filesdir'
+            filesdir = fileobj_path
+
+    return filesdir
+
+
+def read_patch_items(scripts_path, machine):
+    """
+    Find and return a list of patch items in a machine's user-defined
+    patch list [${machine}-user-patches.scc].
+    """
+    patch_items = []
+
+    f = open_user_file(scripts_path, machine, machine+"-user-patches.scc", "r")
+    lines = f.readlines()
+    for line in lines:
+        s = line.strip()
+        if s and not s.startswith("#"):
+            fields = s.split()
+            if not fields[0] == "patch":
+                continue
+            patch_items.append(fields[1])
+    f.close()
+
+    return patch_items
+
+
+def write_patch_items(scripts_path, machine, patch_items):
+    """
+    Write (replace) the list of patches in a machine's user-defined
+    patch list [${machine}-user-patches.scc].
+    """
+    f = open_user_file(scripts_path, machine, machine+"-user-patches.scc", "w")
+    for item in patch_items:
+        f.write("patch " + item + "\n")
+    f.close()
+
+    kernel_contents_changed(scripts_path, machine)
+
+
+def yocto_kernel_patch_list(scripts_path, machine):
+    """
+    Display the list of patches in a machine's user-defined patch list
+    [${machine}-user-patches.scc].
+    """
+    patches = read_patch_items(scripts_path, machine)
+
+    print "The current set of machine-specific patches for %s is:" % machine
+    print gen_choices_str(patches)
+
+
+def yocto_kernel_patch_rm(scripts_path, machine):
+    """
+    Remove one or more patches from a machine's user-defined patch
+    list [${machine}-user-patches.scc].
+    """
+    patches = read_patch_items(scripts_path, machine)
+
+    print "Specify the patches to remove:"
+    input = raw_input(gen_choices_str(patches))
+    rm_choices = input.split()
+    rm_choices.sort()
+
+    removed = []
+
+    filesdir = find_filesdir(scripts_path, machine)
+    if not filesdir:
+        print "Couldn't rm patch(es) since we couldn't find a 'files' dir"
+        sys.exit(1)
+
+    for choice in reversed(rm_choices):
+        try:
+            idx = int(choice) - 1
+        except ValueError:
+            print "Invalid choice (%s), exiting" % choice
+            sys.exit(1)
+        if idx < 0 or idx >= len(patches):
+            print "Invalid choice (%d), exiting" % (idx + 1)
+            sys.exit(1)
+        filesdir_patch = os.path.join(filesdir, patches[idx])
+        if os.path.isfile(filesdir_patch):
+            os.remove(filesdir_patch)
+        removed.append(patches[idx])
+        patches.pop(idx)
+
+    write_patch_items(scripts_path, machine, patches)
+
+    print "Removed patches:"
+    for r in removed:
+        print "\t%s" % r
+
+
+def yocto_kernel_patch_add(scripts_path, machine, patches):
+    """
+    Add one or more patches to a machine's user-defined patch list
+    [${machine}-user-patches.scc].
+    """
+    existing_patches = read_patch_items(scripts_path, machine)
+
+    for patch in patches:
+        if os.path.basename(patch) in existing_patches:
+            print "Couldn't add patch (%s) since it's already been added" % os.path.basename(patch)
+            sys.exit(1)
+
+    filesdir = find_filesdir(scripts_path, machine)
+    if not filesdir:
+        print "Couldn't add patch (%s) since we couldn't find a 'files' dir to add it to" % os.path.basename(patch)
+        sys.exit(1)
+
+    new_patches = []
+
+    for patch in patches:
+        if not os.path.isfile(patch):
+            print "Couldn't find patch (%s), exiting" % patch
+            sys.exit(1)
+        basename = os.path.basename(patch)
+        filesdir_patch = os.path.join(filesdir, basename)
+        shutil.copyfile(patch, filesdir_patch)
+        new_patches.append(basename)
+
+    cur_items = read_patch_items(scripts_path, machine)
+    cur_items.extend(new_patches)
+    write_patch_items(scripts_path, machine, cur_items)
+
+    print "Added patches:"
+    for n in new_patches:
+        print "\t%s" % n
+
+
+def inc_pr(line):
+    """
+    Add 1 to the PR value in the given bbappend PR line.  For the PR
+    lines in kernel .bbappends after modifications.  Handles PRs of
+    the form PR := "${PR}.1" as well as PR = "r0".
+    """
+    idx = line.find("\"")
+
+    pr_str = line[idx:]
+    pr_str = pr_str.replace('\"','')
+    fields = pr_str.split('.')
+    if len(fields) > 1:
+        fields[1] = str(int(fields[1]) + 1)
+        pr_str = "\"" + '.'.join(fields) + "\"\n"
+    else:
+        pr_val = pr_str[1:]
+        pr_str = "\"" + "r" + str(int(pr_val) + 1) + "\"\n"
+    idx2 = line.find("\"", idx + 1)
+    line = line[:idx] + pr_str
+    
+    return line
+
+
+def kernel_contents_changed(scripts_path, machine):
+    """
+    Do what we need to do to notify the system that the kernel
+    recipe's contents have changed.
+    """
+    layer = find_bsp_layer(machine)
+
+    kernel = find_current_kernel(layer, machine)
+    if not kernel:
+        print "Couldn't determine the kernel for this BSP, exiting."
+        sys.exit(1)
+
+    kernel_bbfile = os.path.join(layer, "recipes-kernel/linux/" + kernel + ".bbappend")
+    if not os.path.isfile(kernel_bbfile):
+        kernel_bbfile = os.path.join(layer, "recipes-kernel/linux/" + kernel + ".bb")
+        if not os.path.isfile(kernel_bbfile):
+            return
+    kernel_bbfile_prev = kernel_bbfile + ".prev"
+    shutil.copyfile(kernel_bbfile, kernel_bbfile_prev)
+
+    ifile = open(kernel_bbfile_prev, "r")
+    ofile = open(kernel_bbfile, "w")
+    ifile_lines = ifile.readlines()
+    for ifile_line in ifile_lines:
+        if ifile_line.strip().startswith("PR"):
+            ifile_line = inc_pr(ifile_line)
+        ofile.write(ifile_line)
+    ofile.close()
+    ifile.close()
+
+
+def kernels(context):
+    """
+    Return the list of available kernels in the BSP i.e. corresponding
+    to the kernel .bbappends found in the layer.
+    """
+    archdir = os.path.join(context["scripts_path"], "lib/bsp/substrate/target/arch/" + context["arch"])
+    kerndir = os.path.join(archdir, "recipes-kernel/linux")
+    bbglob = os.path.join(kerndir, "*.bbappend")
+
+    bbappends = glob.glob(bbglob)
+
+    kernels = []
+
+    for kernel in bbappends:
+        filename = os.path.splitext(os.path.basename(kernel))[0]
+        idx = filename.find(CLOSE_TAG)
+        if idx != -1:
+            filename = filename[idx + len(CLOSE_TAG):].strip()
+        kernels.append(filename)
+
+    kernels.append("custom")
+
+    return kernels
+
+
+def extract_giturl(file):
+    """
+    Extract the git url of the kernel repo from the kernel recipe's
+    SRC_URI.
+    """
+    url = None
+    f = open(file, "r")
+    lines = f.readlines()
+    for line in lines:
+        line = line.strip()
+        if line.startswith("SRC_URI"):
+            line = line[len("SRC_URI"):].strip()
+            if line.startswith("="):
+                line = line[1:].strip()
+                if line.startswith("\""):
+                    line = line[1:].strip()
+                    prot = "git"
+                    for s in line.split(";"):
+                        if s.startswith("git://"):
+                            url = s
+                        if s.startswith("protocol="):
+                            prot = s.split("=")[1]
+                    if url:
+                        url = prot + url[3:]
+    return url
+
+
+def find_giturl(context):
+    """
+    Find the git url of the kernel repo from the kernel recipe's
+    SRC_URI.
+    """
+    name = context["name"]
+    filebase = context["filename"]
+    scripts_path = context["scripts_path"]
+
+    meta_layer = find_meta_layer()
+
+    kerndir = os.path.join(meta_layer, "recipes-kernel/linux")
+    bbglob = os.path.join(kerndir, "*.bb")
+    bbs = glob.glob(bbglob)
+    for kernel in bbs:
+        filename = os.path.splitext(os.path.basename(kernel))[0]
+        if filename in filebase:
+            giturl = extract_giturl(kernel)
+            return giturl
+    
+    return None
+
+
+def read_features(scripts_path, machine):
+    """
+    Find and return a list of features in a machine's user-defined
+    features fragment [${machine}-user-features.scc].
+    """
+    features = []
+
+    f = open_user_file(scripts_path, machine, machine+"-user-features.scc", "r")
+    lines = f.readlines()
+    for line in lines:
+        s = line.strip()
+        if s and not s.startswith("#"):
+            feature_include = s.split()
+            features.append(feature_include[1].strip())
+    f.close()
+
+    return features
+
+
+def write_features(scripts_path, machine, features):
+    """
+    Write (replace) the list of feature items in a
+    machine's user-defined features fragment [${machine}=user-features.cfg].
+    """
+    f = open_user_file(scripts_path, machine, machine+"-user-features.scc", "w")
+    for item in features:
+        f.write("include " + item + "\n")
+    f.close()
+
+    kernel_contents_changed(scripts_path, machine)
+
+
+def yocto_kernel_feature_list(scripts_path, machine):
+    """
+    Display the list of features used in a machine's user-defined
+    features fragment [${machine}-user-features.scc].
+    """
+    features = read_features(scripts_path, machine)
+
+    print "The current set of machine-specific features for %s is:" % machine
+    print gen_choices_str(features)
+
+
+def yocto_kernel_feature_rm(scripts_path, machine):
+    """
+    Display the list of features used in a machine's user-defined
+    features fragment [${machine}-user-features.scc], prompt the user
+    for one or more to remove, and remove them.
+    """
+    features = read_features(scripts_path, machine)
+
+    print "Specify the features to remove:"
+    input = raw_input(gen_choices_str(features))
+    rm_choices = input.split()
+    rm_choices.sort()
+
+    removed = []
+
+    for choice in reversed(rm_choices):
+        try:
+            idx = int(choice) - 1
+        except ValueError:
+            print "Invalid choice (%s), exiting" % choice
+            sys.exit(1)
+        if idx < 0 or idx >= len(features):
+            print "Invalid choice (%d), exiting" % (idx + 1)
+            sys.exit(1)
+        removed.append(features.pop(idx))
+
+    write_features(scripts_path, machine, features)
+
+    print "Removed features:"
+    for r in removed:
+        print "\t%s" % r
+
+
+def yocto_kernel_feature_add(scripts_path, machine, features):
+    """
+    Add one or more features a machine's user-defined features
+    fragment [${machine}-user-features.scc].
+    """
+    new_items = []
+
+    for item in features:
+        if not item.endswith(".scc"):
+            print "Invalid feature (%s), exiting" % item
+            sys.exit(1)
+        new_items.append(item)
+
+    cur_items = read_features(scripts_path, machine)
+    cur_items.extend(new_items)
+
+    write_features(scripts_path, machine, cur_items)
+
+    print "Added features:"
+    for n in new_items:
+        print "\t%s" % n
+
+
+def find_feature_url(git_url):
+    """
+    Find the url of the kern-features.rc kernel for the kernel repo
+    specified from the BSP's kernel recipe SRC_URI.
+    """
+    feature_url = ""
+    if git_url.startswith("git://"):
+        git_url = git_url[len("git://"):].strip()
+        s = git_url.split("/")
+        if s[1].endswith(".git"):
+            s[1] = s[1][:len(s[1]) - len(".git")]
+        feature_url = "http://" + s[0] + "/cgit/cgit.cgi/" + s[1] + \
+            "/plain/meta/cfg/kern-features.rc?h=meta"
+
+    return feature_url
+
+
+def find_feature_desc(lines):
+    """
+    Find the feature description and compatibility in the passed-in
+    set of lines.  Returns a string string of the form 'desc
+    [compat]'.
+    """
+    desc = "no description available"
+    compat = "unknown"
+
+    for line in lines:
+        idx = line.find("KFEATURE_DESCRIPTION")
+        if idx != -1:
+            desc = line[idx + len("KFEATURE_DESCRIPTION"):].strip()
+            if desc.startswith("\""):
+                desc = desc[1:]
+                if desc.endswith("\""):
+                    desc = desc[:-1]
+        else:
+            idx = line.find("KFEATURE_COMPATIBILITY")
+            if idx != -1:
+                compat = line[idx + len("KFEATURE_COMPATIBILITY"):].strip()
+
+    return desc + " [" + compat + "]"
+
+
+def print_feature_descs(layer, feature_dir):
+    """
+    Print the feature descriptions for the features in feature_dir.
+    """
+    kernel_files_features = os.path.join(layer, "recipes-kernel/linux/files/" +
+                                         feature_dir)
+    for root, dirs, files in os.walk(kernel_files_features):
+        for file in files:
+            if file.endswith("~") or file.endswith("#"):
+                continue
+            if file.endswith(".scc"):
+                fullpath = os.path.join(layer, "recipes-kernel/linux/files/" +
+                                        feature_dir + "/" + file)
+                f = open(fullpath)
+                feature_desc = find_feature_desc(f.readlines())
+                print feature_dir + "/" + file + ": " + feature_desc
+
+
+def yocto_kernel_available_features_list(scripts_path, machine):
+    """
+    Display the list of all the kernel features available for use in
+    BSPs, as gathered from the set of feature sources.
+    """
+    layer = find_bsp_layer(machine)
+    kernel = find_current_kernel(layer, machine)
+    if not kernel:
+        print "Couldn't determine the kernel for this BSP, exiting."
+        sys.exit(1)
+
+    context = create_context(machine, "arch", scripts_path)
+    context["name"] = "name"
+    context["filename"] = kernel
+    giturl = find_giturl(context)
+    feature_url = find_feature_url(giturl)
+
+    feature_cmd = "wget -q -O - " + feature_url
+    tmp = subprocess.Popen(feature_cmd, shell=True, stdout=subprocess.PIPE).stdout.read()
+
+    print "The current set of kernel features available to %s is:\n" % machine
+
+    if tmp:
+        tmpline = tmp.split("\n")
+        in_kernel_options = False
+        for line in tmpline:
+            if not "=" in line:
+                if in_kernel_options:
+                    break
+                if "kernel-options" in line:
+                    in_kernel_options = True
+                continue
+            if in_kernel_options:
+                feature_def = line.split("=")
+                feature_type = feature_def[0].strip()
+                feature = feature_def[1].strip()
+                desc = get_feature_desc(giturl, feature)
+                print "%s: %s" % (feature, desc)
+
+    print "[local]"
+
+    print_feature_descs(layer, "cfg")
+    print_feature_descs(layer, "features")
+
+
+def find_feature_desc_url(git_url, feature):
+    """
+    Find the url of the kernel feature in the kernel repo specified
+    from the BSP's kernel recipe SRC_URI.
+    """
+    feature_desc_url = ""
+    if git_url.startswith("git://"):
+        git_url = git_url[len("git://"):].strip()
+        s = git_url.split("/")
+        if s[1].endswith(".git"):
+            s[1] = s[1][:len(s[1]) - len(".git")]
+        feature_desc_url = "http://" + s[0] + "/cgit/cgit.cgi/" + s[1] + \
+            "/plain/meta/cfg/kernel-cache/" + feature + "?h=meta"
+
+    return feature_desc_url
+
+
+def get_feature_desc(git_url, feature):
+    """
+    Return a feature description of the form 'description [compatibility]
+    BSPs, as gathered from the set of feature sources.
+    """
+    feature_desc_url = find_feature_desc_url(git_url, feature)
+    feature_desc_cmd = "wget -q -O - " + feature_desc_url
+    tmp = subprocess.Popen(feature_desc_cmd, shell=True, stdout=subprocess.PIPE).stdout.read()
+
+    return find_feature_desc(tmp.split("\n"))
+
+
+def yocto_kernel_feature_describe(scripts_path, machine, feature):
+    """
+    Display the description of a specific kernel feature available for
+    use in a BSP.
+    """
+    layer = find_bsp_layer(machine)
+
+    kernel = find_current_kernel(layer, machine)
+    if not kernel:
+        print "Couldn't determine the kernel for this BSP, exiting."
+        sys.exit(1)
+
+    context = create_context(machine, "arch", scripts_path)
+    context["name"] = "name"
+    context["filename"] = kernel
+    giturl = find_giturl(context)
+
+    desc = get_feature_desc(giturl, feature)
+
+    print desc
+
+
+def check_feature_name(feature_name):
+    """
+    Sanity-check the feature name for create/destroy.  Return False if not OK.
+    """
+    if not feature_name.endswith(".scc"):
+        print "Invalid feature name (must end with .scc) [%s], exiting" % feature_name
+        return False
+
+    if "/" in feature_name:
+        print "Invalid feature name (don't specify directory) [%s], exiting" % feature_name
+        return False
+
+    return True
+
+
+def check_create_input(feature_items):
+    """
+    Sanity-check the create input.  Return False if not OK.
+    """
+    if not check_feature_name(feature_items[0]):
+        return False
+
+    if feature_items[1].endswith(".patch") or feature_items[1].startswith("CONFIG_"):
+        print "Missing description and/or compatibilty [%s], exiting" % feature_items[1]
+        return False
+
+    if feature_items[2].endswith(".patch") or feature_items[2].startswith("CONFIG_"):
+        print "Missing description and/or compatibility [%s], exiting" % feature_items[1]
+        return False
+
+    return True
+
+
+def yocto_kernel_feature_create(scripts_path, machine, feature_items):
+    """
+    Create a recipe-space kernel feature in a BSP.
+    """
+    if not check_create_input(feature_items):
+        sys.exit(1)
+
+    feature = feature_items[0]
+    feature_basename = feature.split(".")[0]
+    feature_description = feature_items[1]
+    feature_compat = feature_items[2]
+
+    patches = []
+    cfg_items = []
+
+    for item in feature_items[3:]:
+        if item.endswith(".patch"):
+            patches.append(item)
+        elif item.startswith("CONFIG"):
+            if ("=y" in item or "=m" in item):
+                cfg_items.append(item)
+        else:
+            print "Invalid feature item (must be .patch or CONFIG_*) [%s], exiting" % item
+            sys.exit(1)
+
+    feature_dirname = "cfg"
+    if patches:
+        feature_dirname = "features"
+
+    filesdir = find_filesdir(scripts_path, machine)
+    if not filesdir:
+        print "Couldn't add feature (%s), no 'files' dir found" % feature
+        sys.exit(1)
+
+    featdir = os.path.join(filesdir, feature_dirname)
+    if not os.path.exists(featdir):
+        os.mkdir(featdir)
+
+    for patch in patches:
+        if not os.path.isfile(patch):
+            print "Couldn't find patch (%s), exiting" % patch
+            sys.exit(1)
+        basename = os.path.basename(patch)
+        featdir_patch = os.path.join(featdir, basename)
+        shutil.copyfile(patch, featdir_patch)
+
+    new_cfg_filename = os.path.join(featdir, feature_basename + ".cfg")
+    new_cfg_file = open(new_cfg_filename, "w")
+    for cfg_item in cfg_items:
+        new_cfg_file.write(cfg_item + "\n")
+    new_cfg_file.close()
+
+    new_feature_filename = os.path.join(featdir, feature_basename + ".scc")
+    new_feature_file = open(new_feature_filename, "w")
+    new_feature_file.write("define KFEATURE_DESCRIPTION \"" + feature_description + "\"\n")
+    new_feature_file.write("define KFEATURE_COMPATIBILITY " + feature_compat + "\n\n")
+
+    for patch in patches:
+        patch_dir, patch_file = os.path.split(patch)
+        new_feature_file.write("patch " + patch_file + "\n")
+
+    new_feature_file.write("kconf non-hardware " + feature_basename + ".cfg\n")
+    new_feature_file.close()
+
+    print "Added feature:"
+    print "\t%s" % feature_dirname + "/" + feature
+
+
+def feature_in_use(scripts_path, machine, feature):
+    """
+    Determine whether the specified feature is in use by the BSP.
+    Return True if so, False otherwise.
+    """
+    features = read_features(scripts_path, machine)
+    for f in features:
+        if f == feature:
+            return True
+    return False
+
+
+def feature_remove(scripts_path, machine, feature):
+    """
+    Remove the specified feature from the available recipe-space
+    features defined for the BSP.
+    """
+    features = read_features(scripts_path, machine)
+    new_features = []
+    for f in features:
+        if f == feature:
+            continue
+        new_features.append(f)
+    write_features(scripts_path, machine, new_features)
+
+
+def yocto_kernel_feature_destroy(scripts_path, machine, feature):
+    """
+    Remove a recipe-space kernel feature from a BSP.
+    """
+    if not check_feature_name(feature):
+        sys.exit(1)
+
+    if feature_in_use(scripts_path, machine, "features/" + feature) or \
+            feature_in_use(scripts_path, machine, "cfg/" + feature):
+        print "Feature %s is in use (use 'feature rm' to un-use it first), exiting" % feature
+        sys.exit(1)
+
+    filesdir = find_filesdir(scripts_path, machine)
+    if not filesdir:
+        print "Couldn't destroy feature (%s), no 'files' dir found" % feature
+        sys.exit(1)
+
+    feature_dirname = "features"
+    featdir = os.path.join(filesdir, feature_dirname)
+    if not os.path.exists(featdir):
+        print "Couldn't find feature directory (%s)" % feature_dirname
+        sys.exit(1)
+
+    feature_fqn = os.path.join(featdir, feature)
+    if not os.path.exists(feature_fqn):
+        feature_dirname = "cfg"
+        featdir = os.path.join(filesdir, feature_dirname)
+        if not os.path.exists(featdir):
+            print "Couldn't find feature directory (%s)" % feature_dirname
+            sys.exit(1)
+        feature_fqn = os.path.join(featdir, feature_filename)
+        if not os.path.exists(feature_fqn):
+            print "Couldn't find feature (%s)" % feature
+            sys.exit(1)
+
+    f = open(feature_fqn, "r")
+    lines = f.readlines()
+    for line in lines:
+        s = line.strip()
+        if s.startswith("patch ") or s.startswith("kconf "):
+            split_line = s.split()
+            filename = os.path.join(featdir, split_line[-1])
+            if os.path.exists(filename):
+                os.remove(filename)
+    f.close()
+    os.remove(feature_fqn)
+
+    feature_remove(scripts_path, machine, feature)
+
+    print "Removed feature:"
+    print "\t%s" % feature_dirname + "/" + feature
+
+
+def base_branches(context):
+    """
+    Return a list of the base branches found in the kernel git repo.
+    """
+    giturl = find_giturl(context)
+
+    print "Getting branches from remote repo %s..." % giturl
+
+    gitcmd = "git ls-remote %s *heads* 2>&1" % (giturl)
+    tmp = subprocess.Popen(gitcmd, shell=True, stdout=subprocess.PIPE).stdout.read()
+
+    branches = []
+
+    if tmp:
+        tmpline = tmp.split("\n")
+        for line in tmpline:
+            if len(line)==0:
+                break;
+            if not line.endswith("base"):
+                continue;
+            idx = line.find("refs/heads/")
+            kbranch = line[idx + len("refs/heads/"):]
+            if kbranch.find("/") == -1 and kbranch.find("base") == -1:
+                continue
+            idx = kbranch.find("base")
+            branches.append(kbranch[:idx - 1])
+
+    return branches
+
+
+def all_branches(context):
+    """
+    Return a list of all the branches found in the kernel git repo.
+    """
+    giturl = find_giturl(context)
+
+    print "Getting branches from remote repo %s..." % giturl
+
+    gitcmd = "git ls-remote %s *heads* 2>&1" % (giturl)
+    tmp = subprocess.Popen(gitcmd, shell=True, stdout=subprocess.PIPE).stdout.read()
+
+    branches = []
+
+    base_prefixes = None
+
+    try:
+        branches_base = context["branches_base"]
+        if branches_base:
+            base_prefixes = branches_base.split(":")
+    except KeyError:
+        pass
+
+    arch = context["arch"]
+
+    if tmp:
+        tmpline = tmp.split("\n")
+        for line in tmpline:
+            if len(line)==0:
+                break;
+            idx = line.find("refs/heads/")
+            kbranch = line[idx + len("refs/heads/"):]
+            kbranch_prefix = kbranch.rsplit("/", 1)[0]
+
+            if base_prefixes:
+                for base_prefix in base_prefixes:
+                    if kbranch_prefix == base_prefix:
+                        branches.append(kbranch)
+                continue
+
+            if (kbranch.find("/") != -1 and
+                (kbranch.find("standard") != -1 or kbranch.find("base") != -1) or
+                kbranch == "base"):
+                branches.append(kbranch)
+                continue
+
+    return branches
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/.gitignore b/scripts/lib/bsp/substrate/target/arch/arm/.gitignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/.gitignore
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/conf/machine/machine.conf b/scripts/lib/bsp/substrate/target/arch/arm/conf/machine/machine.conf
new file mode 100644
index 0000000..588367a
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/conf/machine/machine.conf
@@ -0,0 +1,102 @@
+# yocto-bsp-filename {{=machine}}.conf
+#@TYPE: Machine
+#@NAME: {{=machine}}
+
+#@DESCRIPTION: Machine configuration for {{=machine}} systems
+
+{{ input type:"boolean" name:"xserver" prio:"50" msg:"Do you need support for X? (y/n)" default:"y" }}
+{{ if xserver == "y": }}
+PREFERRED_PROVIDER_virtual/xserver ?= "xserver-xorg"
+XSERVER ?= "xserver-xorg \
+           xf86-input-evdev \
+           xf86-input-mouse \
+           xf86-video-fbdev \
+           xf86-input-keyboard"
+
+MACHINE_EXTRA_RRECOMMENDS = " kernel-modules kernel-devicetree"
+
+EXTRA_IMAGEDEPENDS += "u-boot"
+
+{{ input type:"choicelist" name:"tunefile" prio:"40" msg:"Which machine tuning would you like to use?" default:"tune_cortexa8" }}
+{{ input type:"choice" val:"tune_arm1136jf_s" msg:"arm1136jf-s tuning optimizations" }}
+{{ input type:"choice" val:"tune_arm920t" msg:"arm920t tuning optimizations" }}
+{{ input type:"choice" val:"tune_arm926ejs" msg:"arm926ejs tuning optimizations" }}
+{{ input type:"choice" val:"tune_arm9tdmi" msg:"arm9tdmi tuning optimizations" }}
+{{ input type:"choice" val:"tune_cortexa5" msg:"cortexa5 tuning optimizations" }}
+{{ input type:"choice" val:"tune_cortexa7" msg:"cortexa7 tuning optimizations" }}
+{{ input type:"choice" val:"tune_cortexa8" msg:"cortexa8 tuning optimizations" }}
+{{ input type:"choice" val:"tune_cortexa9" msg:"cortexa9 tuning optimizations" }}
+{{ input type:"choice" val:"tune_cortexa15" msg:"cortexa15 tuning optimizations" }}
+{{ input type:"choice" val:"tune_cortexm1" msg:"cortexm1 tuning optimizations" }}
+{{ input type:"choice" val:"tune_cortexm3" msg:"cortexm3 tuning optimizations" }}
+{{ input type:"choice" val:"tune_cortexr4" msg:"cortexr4 tuning optimizations" }}
+{{ input type:"choice" val:"tune_ep9312" msg:"ep9312 tuning optimizations" }}
+{{ input type:"choice" val:"tune_iwmmxt" msg:"iwmmxt tuning optimizations" }}
+{{ input type:"choice" val:"tune_strongarm1100" msg:"strongarm1100 tuning optimizations" }}
+{{ input type:"choice" val:"tune_xscale" msg:"xscale tuning optimizations" }}
+{{ if tunefile == "tune_arm1136jf_s": }}
+include conf/machine/include/tune-arm1136jf-s.inc
+{{ if tunefile == "tune_arm920t": }}
+include conf/machine/include/tune-arm920t.inc
+{{ if tunefile == "tune_arm926ejs": }}
+include conf/machine/include/tune-arm926ejs.inc
+{{ if tunefile == "tune_arm9tdmi": }}
+include conf/machine/include/tune-arm9tdmi.inc
+{{ if tunefile == "tune_cortexa5": }}
+include conf/machine/include/tune-cortexa5.inc
+{{ if tunefile == "tune_cortexa7": }}
+include conf/machine/include/tune-cortexa7.inc
+{{ if tunefile == "tune_cortexa8": }}
+DEFAULTTUNE ?= "cortexa8hf-neon"
+include conf/machine/include/tune-cortexa8.inc
+{{ if tunefile == "tune_cortexa9": }}
+include conf/machine/include/tune-cortexa9.inc
+{{ if tunefile == "tune_cortexa15": }}
+include conf/machine/include/tune-cortexa15.inc
+{{ if tunefile == "tune_cortexm1": }}
+include conf/machine/include/tune-cortexm1.inc
+{{ if tunefile == "tune_cortexm3": }}
+include conf/machine/include/tune-cortexm3.inc
+{{ if tunefile == "tune_cortexr4": }}
+include conf/machine/include/tune-cortexr4.inc
+{{ if tunefile == "tune_ep9312": }}
+include conf/machine/include/tune-ep9312.inc
+{{ if tunefile == "tune_iwmmxt": }}
+include conf/machine/include/tune-iwmmxt.inc
+{{ if tunefile == "tune_strongarm1100": }}
+include conf/machine/include/tune-strongarm1100.inc
+{{ if tunefile == "tune_xscale": }}
+include conf/machine/include/tune-xscale.inc
+
+IMAGE_FSTYPES += "tar.bz2 jffs2"
+EXTRA_IMAGECMD_jffs2 = "-lnp "
+
+SERIAL_CONSOLE = "115200 ttyO0"
+
+{{ if kernel_choice == "custom": preferred_kernel = "linux-yocto-custom" }}
+{{ if kernel_choice == "linux-yocto-dev": preferred_kernel = "linux-yocto-dev" }}
+{{ if kernel_choice == "custom" or kernel_choice == "linux-yocto-dev" : }}
+PREFERRED_PROVIDER_virtual/kernel ?= "{{=preferred_kernel}}"
+
+{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": preferred_kernel = kernel_choice.split('_')[0] }}
+{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": preferred_kernel_version = kernel_choice.split('_')[1] }}
+{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": }}
+PREFERRED_PROVIDER_virtual/kernel ?= "{{=preferred_kernel}}"
+PREFERRED_VERSION_{{=preferred_kernel}} ?= "{{=preferred_kernel_version}}%"
+
+KERNEL_IMAGETYPE = "uImage"
+KERNEL_DEVICETREE = "am335x-bone.dtb am335x-boneblack.dtb"
+KERNEL_EXTRA_ARGS += "LOADADDR=${UBOOT_ENTRYPOINT}"
+
+SPL_BINARY = "MLO"
+UBOOT_SUFFIX = "img"
+{{ input type:"edit" name:"uboot_machine" prio:"40" msg:"Please specify a value for UBOOT_MACHINE:" default:"am335x_evm_config" }}
+UBOOT_MACHINE = "{{=uboot_machine}}"
+{{ input type:"edit" name:"uboot_entrypoint" prio:"40" msg:"Please specify a value for UBOOT_ENTRYPOINT:" default:"0x80008000" }}
+UBOOT_ENTRYPOINT = "{{=uboot_entrypoint}}"
+{{ input type:"edit" name:"uboot_loadaddress" prio:"40" msg:"Please specify a value for UBOOT_LOADADDRESS:" default:"0x80008000" }}
+UBOOT_LOADADDRESS = "{{=uboot_loadaddress}}"
+
+MACHINE_FEATURES = "usbgadget usbhost vfat alsa"
+
+IMAGE_BOOT_FILES ?= "u-boot.${UBOOT_SUFFIX} MLO"
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-graphics/xorg-xserver/xserver-xf86-config/machine.noinstall b/scripts/lib/bsp/substrate/target/arch/arm/recipes-graphics/xorg-xserver/xserver-xf86-config/machine.noinstall
new file mode 100644
index 0000000..b442d02
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-graphics/xorg-xserver/xserver-xf86-config/machine.noinstall
@@ -0,0 +1 @@
+# yocto-bsp-dirname {{=machine}}
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-graphics/xorg-xserver/xserver-xf86-config/machine/xorg.conf b/scripts/lib/bsp/substrate/target/arch/arm/recipes-graphics/xorg-xserver/xserver-xf86-config/machine/xorg.conf
new file mode 100644
index 0000000..bc52893
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-graphics/xorg-xserver/xserver-xf86-config/machine/xorg.conf
@@ -0,0 +1,34 @@
+# yocto-bsp-filename {{ if xserver == "y": }} this
+Section "Module"
+	Load	"extmod"
+	Load	"dbe"
+	Load	"glx"
+	Load	"freetype"
+	Load	"type1"
+	Load	"record"
+	Load	"dri"
+EndSection
+
+Section "Monitor"
+	Identifier	"Builtin Default Monitor"
+EndSection
+
+Section "Device"
+	Identifier	"Builtin Default fbdev Device 0"
+	Driver		"omapfb"
+EndSection
+
+Section "Screen"
+	Identifier	"Builtin Default fbdev Screen 0"
+	Device		"Builtin Default fbdev Device 0"
+	Monitor		"Builtin Default Monitor"
+EndSection
+
+Section "ServerLayout"
+	Identifier	"Builtin Default Layout"
+	Screen		"Builtin Default fbdev Screen 0"
+EndSection
+
+Section "ServerFlags"
+	Option		"DontZap"  "0"
+EndSection
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-graphics/xorg-xserver/xserver-xf86-config_0.1.bbappend b/scripts/lib/bsp/substrate/target/arch/arm/recipes-graphics/xorg-xserver/xserver-xf86-config_0.1.bbappend
new file mode 100644
index 0000000..3083003
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-graphics/xorg-xserver/xserver-xf86-config_0.1.bbappend
@@ -0,0 +1,2 @@
+# yocto-bsp-filename {{ if xserver == "y": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files.noinstall b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files.noinstall
new file mode 100644
index 0000000..1e0d92c
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files.noinstall
@@ -0,0 +1 @@
+# yocto-bsp-dirname {{ if kernel_choice != "custom": }} files
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine-non_hardware.cfg b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine-non_hardware.cfg
new file mode 100644
index 0000000..9bfc90c
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine-non_hardware.cfg
@@ -0,0 +1,31 @@
+# yocto-bsp-filename {{=machine}}-non_hardware.cfg
+#
+# Miscellaneous filesystems
+#
+CONFIG_NFS_DEF_FILE_IO_SIZE=1024
+
+#
+# Multiple Device Support
+#
+# CONFIG_MD is not set
+
+# Kernel Features
+#
+CONFIG_NO_HZ=y
+
+#
+# CPUIdle
+#
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_FS=y
+
+#
+# Power management options
+#
+CONFIG_PM_DEBUG=y
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine-preempt-rt.scc b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine-preempt-rt.scc
new file mode 100644
index 0000000..ca5f3b5
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine-preempt-rt.scc
@@ -0,0 +1,14 @@
+# yocto-bsp-filename {{=machine}}-preempt-rt.scc
+define KMACHINE {{=machine}}
+define KTYPE preempt-rt
+define KARCH arm
+
+include {{=map_preempt_rt_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
+{{ if need_new_kbranch == "y": }}
+branch {{=machine}}
+
+include {{=machine}}.scc
+
+# default policy for preempt-rt kernels
+include features/latencytop/latencytop.scc
+include features/profiling/profiling.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine-standard.scc b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine-standard.scc
new file mode 100644
index 0000000..9014c2c
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine-standard.scc
@@ -0,0 +1,14 @@
+# yocto-bsp-filename {{=machine}}-standard.scc
+define KMACHINE {{=machine}}
+define KTYPE standard
+define KARCH arm
+
+include {{=map_standard_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
+{{ if need_new_kbranch == "y": }}
+branch {{=machine}}
+
+include {{=machine}}.scc
+
+# default policy for standard kernels
+include features/latencytop/latencytop.scc
+include features/profiling/profiling.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine-tiny.scc b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine-tiny.scc
new file mode 100644
index 0000000..3f1c252
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine-tiny.scc
@@ -0,0 +1,10 @@
+# yocto-bsp-filename {{=machine}}-tiny.scc
+define KMACHINE {{=machine}}
+define KTYPE tiny
+define KARCH arm
+
+include {{=map_tiny_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
+{{ if need_new_kbranch == "y": }}
+branch {{=machine}}
+
+include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine-user-config.cfg b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine-user-config.cfg
new file mode 100644
index 0000000..47489e4
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine-user-config.cfg
@@ -0,0 +1 @@
+# yocto-bsp-filename {{=machine}}-user-config.cfg
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine-user-features.scc b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine-user-features.scc
new file mode 100644
index 0000000..582759e
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine-user-features.scc
@@ -0,0 +1 @@
+# yocto-bsp-filename {{=machine}}-user-features.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine-user-patches.scc b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine-user-patches.scc
new file mode 100644
index 0000000..97f747f
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine-user-patches.scc
@@ -0,0 +1 @@
+# yocto-bsp-filename {{=machine}}-user-patches.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine.cfg b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine.cfg
new file mode 100644
index 0000000..a2e1ae0
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine.cfg
@@ -0,0 +1,321 @@
+# yocto-bsp-filename {{=machine}}.cfg
+#
+# System Type
+#
+CONFIG_ARCH_OMAP=y
+
+#
+# TI OMAP Implementations
+#
+# CONFIG_ARCH_OMAP2 is not set
+CONFIG_ARCH_OMAP3=y
+
+#
+# TI OMAP Common Features
+#
+CONFIG_ARCH_OMAP2PLUS=y
+
+#
+# OMAP Feature Selections
+#
+CONFIG_OMAP_32K_TIMER=y
+CONFIG_OMAP_32K_TIMER_HZ=128
+CONFIG_OMAP_DM_TIMER=y
+CONFIG_OMAP_RESET_CLOCKS=y
+CONFIG_OMAP_SMARTREFLEX=y
+CONFIG_OMAP_SMARTREFLEX_CLASS3=y
+CONFIG_OMAP_MBOX_FWK=m
+CONFIG_OMAP_MBOX_KFIFO_SIZE=256
+
+#
+# OMAP Board Type
+#
+CONFIG_MACH_OMAP3_BEAGLE=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMBEE=y
+CONFIG_ARM_ERRATA_430973=y
+
+#
+# Kernel Features
+#
+CONFIG_LEDS=y
+
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_OMAP=y
+CONFIG_SERIAL_OMAP_CONSOLE=y
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_NEON=y
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_PM_RUNTIME=y
+
+#
+# Generic Driver Options
+#
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+
+#
+# Disk-On-Chip Device Drivers
+#
+CONFIG_MTD_NAND=y
+
+CONFIG_MTD_NAND_OMAP2=y
+
+CONFIG_MTD_UBI=y
+
+#
+# SCSI device support
+#
+CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_SMSC911X=y
+CONFIG_USB_NET_SMSC95XX=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_EVDEV=y
+
+#
+# Input Device Drivers
+#
+CONFIG_KEYBOARD_TWL4030=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_I2C=y
+CONFIG_I2C_OMAP=y
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_OMAP24XX=y
+
+#
+# I2C GPIO expanders:
+#
+CONFIG_GPIO_TWL4030=y
+
+#
+# SPI GPIO expanders:
+#
+CONFIG_OMAP_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Multifunction device drivers
+#
+CONFIG_TWL4030_CORE=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_DUMMY=y
+CONFIG_REGULATOR_TWL4030=y
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+CONFIG_DRM=m
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_TMIO is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set
+CONFIG_OMAP2_VRAM=y
+CONFIG_OMAP2_VRFB=y
+CONFIG_OMAP2_DSS=y
+CONFIG_OMAP2_VRAM_SIZE=14
+CONFIG_OMAP2_DSS_DEBUG_SUPPORT=y
+# CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS is not set
+CONFIG_OMAP2_DSS_DPI=y
+# CONFIG_OMAP2_DSS_RFBI is not set
+CONFIG_OMAP2_DSS_VENC=y
+# CONFIG_OMAP2_DSS_SDI is not set
+CONFIG_OMAP2_DSS_DSI=y
+# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set
+CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0
+CONFIG_FB_OMAP2=y
+CONFIG_FB_OMAP2_DEBUG_SUPPORT=y
+CONFIG_FB_OMAP2_NUM_FBS=2
+
+#
+# OMAP2/3 Display Device Drivers
+#
+CONFIG_PANEL_GENERIC_DPI=y
+CONFIG_PANEL_DVI=y
+CONFIG_PANEL_SHARP_LS037V7DW01=y
+# CONFIG_PANEL_LGPHILIPS_LB035Q02 is not set
+# CONFIG_PANEL_TAAL is not set
+CONFIG_PANEL_TPO_TD043MTEA1=m
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+
+#
+# Console display driver support
+#
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+# CONFIG_VGA_CONSOLE is not set
+
+# DMA Devices
+CONFIG_DMADEVICES=y
+CONFIG_DMA_OMAP=y
+CONFIG_DMA_OF=y
+
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_OMAP_SOC=y
+CONFIG_SND_OMAP_SOC_OMAP_TWL4030=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB=y
+CONFIG_USB_SUPPORT=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_OTG=y
+# CONFIG_USB_OTG_WHITELIST is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_OMAP2PLUS=y
+CONFIG_USB_OMAP=y
+
+#
+# OMAP 343x high speed USB support
+#
+CONFIG_USB_MUSB_OTG=y
+CONFIG_USB_GADGET_MUSB_HDRC=y
+CONFIG_USB_MUSB_HDRC_HCD=y
+CONFIG_USB_INVENTRA_DMA=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_OTG_UTILS=y
+CONFIG_TWL4030_USB=y
+
+# USB gadget modules
+CONFIG_USB_G_NCM=y
+CONFIG_USB_MASS_STORAGE=y
+
+CONFIG_MMC=y
+
+#
+# MMC/SD Host Controller Drivers
+#
+CONFIG_MMC_OMAP_HS=y
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_TWL4030=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_VFAT_FS=y
+
+#
+# Multimedia core support
+#
+
+# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
+
+#
+# Advanced Power Management Emulation support
+#
+CONFIG_APM_EMULATION=y
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine.scc b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine.scc
new file mode 100644
index 0000000..828400d
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/files/machine.scc
@@ -0,0 +1,8 @@
+# yocto-bsp-filename {{=machine}}.scc
+kconf hardware {{=machine}}.cfg
+kconf non-hardware {{machine}}-non_hardware.cfg
+
+include features/usb-net/usb-net.scc
+
+kconf hardware {{=machine}}-user-config.cfg
+include {{=machine}}-user-patches.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/kernel-list.noinstall b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/kernel-list.noinstall
new file mode 100644
index 0000000..811d695
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/kernel-list.noinstall
@@ -0,0 +1,5 @@
+{{ if kernel_choice != "custom": }}
+{{ input type:"boolean" name:"use_default_kernel" prio:"10" msg:"Would you like to use the default (3.19) kernel? (y/n)" default:"y"}}
+
+{{ if kernel_choice != "custom" and use_default_kernel == "n": }}
+{{ input type:"choicelist" name:"kernel_choice" gen:"bsp.kernel.kernels" prio:"10" msg:"Please choose the kernel to use in this BSP:" default:"linux-yocto_3.19"}}
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/linux-yocto-dev.bbappend b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/linux-yocto-dev.bbappend
new file mode 100644
index 0000000..2fa6231
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/linux-yocto-dev.bbappend
@@ -0,0 +1,26 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto-dev": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Would you like SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-standard.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/linux-yocto-rt_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/linux-yocto-rt_3.14.bbappend
new file mode 100644
index 0000000..5f8db03
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/linux-yocto-rt_3.14.bbappend
@@ -0,0 +1,33 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto-rt_3.14": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-preempt-rt.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
+
+# uncomment and replace these SRCREVs with the real commit ids once you've had
+# the appropriate changes committed to the upstream linux-yocto repo
+#SRCREV_machine_pn-linux-yocto-rt_{{=machine}} ?= "f35992f80c81dc5fa1a97165dfd5cbb84661f7cb"
+#SRCREV_meta_pn-linux-yocto-rt_{{=machine}} ?= "1b534b2f8bbe9b8a773268cfa30a4850346f6f5f"
+#LINUX_VERSION = "3.14"
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/linux-yocto-tiny_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/linux-yocto-tiny_3.14.bbappend
new file mode 100644
index 0000000..471ccbc
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/linux-yocto-tiny_3.14.bbappend
@@ -0,0 +1,33 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto-tiny_3.14": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-tiny.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
+
+# uncomment and replace these SRCREVs with the real commit ids once you've had
+# the appropriate changes committed to the upstream linux-yocto repo
+#SRCREV_machine_pn-linux-yocto-tiny_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
+#SRCREV_meta_pn-linux-yocto-tiny_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
+#LINUX_VERSION = "3.14"
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/linux-yocto-tiny_3.19.bbappend b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/linux-yocto-tiny_3.19.bbappend
new file mode 100644
index 0000000..4de82fa
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/linux-yocto-tiny_3.19.bbappend
@@ -0,0 +1,33 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto-tiny_3.19": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-tiny.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
+
+# uncomment and replace these SRCREVs with the real commit ids once you've had
+# the appropriate changes committed to the upstream linux-yocto repo
+#SRCREV_machine_pn-linux-yocto-tiny_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
+#SRCREV_meta_pn-linux-yocto-tiny_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
+#LINUX_VERSION = "3.19"
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/linux-yocto_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/linux-yocto_3.14.bbappend
new file mode 100644
index 0000000..1e1cc51
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/linux-yocto_3.14.bbappend
@@ -0,0 +1,33 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto_3.14": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-standard.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
+
+# uncomment and replace these SRCREVs with the real commit ids once you've had
+# the appropriate changes committed to the upstream linux-yocto repo
+#SRCREV_machine_pn-linux-yocto_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
+#SRCREV_meta_pn-linux-yocto_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
+#LINUX_VERSION = "3.14"
\ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/linux-yocto_3.19.bbappend b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/linux-yocto_3.19.bbappend
new file mode 100644
index 0000000..97e1bb8
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/linux-yocto_3.19.bbappend
@@ -0,0 +1,33 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto_3.19": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-standard.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
+
+# uncomment and replace these SRCREVs with the real commit ids once you've had
+# the appropriate changes committed to the upstream linux-yocto repo
+#SRCREV_machine_pn-linux-yocto_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
+#SRCREV_meta_pn-linux-yocto_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
+#LINUX_VERSION = "3.19"
\ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/common/COPYING.MIT b/scripts/lib/bsp/substrate/target/arch/common/COPYING.MIT
new file mode 100644
index 0000000..fb950dc
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/COPYING.MIT
@@ -0,0 +1,17 @@
+Permission is hereby granted, free of charge, to any person obtaining a copy 
+of this software and associated documentation files (the "Software"), to deal 
+in the Software without restriction, including without limitation the rights 
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
+copies of the Software, and to permit persons to whom the Software is 
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in 
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
+THE SOFTWARE.
diff --git a/scripts/lib/bsp/substrate/target/arch/common/README b/scripts/lib/bsp/substrate/target/arch/common/README
new file mode 100644
index 0000000..928659f
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/README
@@ -0,0 +1,118 @@
+This README file contains information on building the meta-{{=machine}}
+BSP layer, and booting the images contained in the /binary directory.
+Please see the corresponding sections below for details.
+
+
+Dependencies
+============
+
+This layer depends on:
+
+  URI: git://git.openembedded.org/bitbake
+  branch: master
+
+  URI: git://git.openembedded.org/openembedded-core
+  layers: meta
+  branch: master
+
+  URI: git://git.yoctoproject.org/xxxx
+  layers: xxxx
+  branch: master
+
+
+Patches
+=======
+
+Please submit any patches against this BSP to the Yocto mailing list
+(yocto@yoctoproject.org) and cc: the maintainer:
+
+Maintainer: XXX YYYYYY <xxx.yyyyyy@zzzzz.com>
+
+Please see the meta-xxxx/MAINTAINERS file for more details.
+
+
+Table of Contents
+=================
+
+  I. Building the meta-{{=machine}} BSP layer
+ II. Booting the images in /binary
+
+
+I. Building the meta-{{=machine}} BSP layer
+========================================
+
+--- replace with specific instructions for your layer ---
+
+In order to build an image with BSP support for a given release, you
+need to download the corresponding BSP tarball from the 'Board Support
+Package (BSP) Downloads' page of the Yocto Project website.
+
+Having done that, and assuming you extracted the BSP tarball contents
+at the top-level of your yocto build tree, you can build a
+{{=machine}} image by adding the location of the meta-{{=machine}}
+layer to bblayers.conf, along with any other layers needed (to access
+common metadata shared between BSPs) e.g.:
+
+  yocto/meta-xxxx \
+  yocto/meta-xxxx/meta-{{=machine}} \
+
+To enable the {{=machine}} layer, add the {{=machine}} MACHINE to local.conf:
+
+  MACHINE ?= "{{=machine}}"
+
+You should then be able to build a {{=machine}} image as such:
+
+  $ source oe-init-build-env
+  $ bitbake core-image-sato
+
+At the end of a successful build, you should have a live image that
+you can boot from a USB flash drive (see instructions on how to do
+that below, in the section 'Booting the images from /binary').
+
+As an alternative to downloading the BSP tarball, you can also work
+directly from the meta-xxxx git repository.  For each BSP in the
+'meta-xxxx' repository, there are multiple branches, one corresponding
+to each major release starting with 'laverne' (0.90), in addition to
+the latest code which tracks the current master (note that not all
+BSPs are present in every release).  Instead of extracting a BSP
+tarball at the top level of your yocto build tree, you can
+equivalently check out the appropriate branch from the meta-xxxx
+repository at the same location.
+
+
+II. Booting the images in /binary
+=================================
+
+--- replace with specific instructions for your platform ---
+
+This BSP contains bootable live images, which can be used to directly
+boot Yocto off of a USB flash drive.
+
+Under Linux, insert a USB flash drive.  Assuming the USB flash drive
+takes device /dev/sdf, use dd to copy the live image to it.  For
+example:
+
+# dd if=core-image-sato-{{=machine}}-20101207053738.hddimg of=/dev/sdf
+# sync
+# eject /dev/sdf
+
+This should give you a bootable USB flash device.  Insert the device
+into a bootable USB socket on the target, and power on.  This should
+result in a system booted to the Sato graphical desktop.
+
+If you want a terminal, use the arrows at the top of the UI to move to
+different pages of available applications, one of which is named
+'Terminal'.  Clicking that should give you a root terminal.
+
+If you want to ssh into the system, you can use the root terminal to
+ifconfig the IP address and use that to ssh in.  The root password is
+empty, so to log in type 'root' for the user name and hit 'Enter' at
+the Password prompt: and you should be in.
+
+----
+
+If you find you're getting corrupt images on the USB (it doesn't show
+the syslinux boot: prompt, or the boot: prompt contains strange
+characters), try doing this first:
+
+# dd if=/dev/zero of=/dev/sdf bs=1M count=512
diff --git a/scripts/lib/bsp/substrate/target/arch/common/README.sources b/scripts/lib/bsp/substrate/target/arch/common/README.sources
new file mode 100644
index 0000000..3c4cb7b
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/README.sources
@@ -0,0 +1,17 @@
+The sources for the packages comprising the images shipped with this
+BSP can be found at the following location:
+
+http://downloads.yoctoproject.org/mirror/sources/
+
+The metadata used to generate the images shipped with this BSP, in
+addition to the code contained in this BSP, can be found at the
+following location:
+
+http://www.yoctoproject.org/downloads/yocto-1.1/poky-edison-6.0.tar.bz2
+
+The metadata used to generate the images shipped with this BSP, in
+addition to the code contained in this BSP, can also be found at the
+following locations:
+
+git://git.yoctoproject.org/poky.git
+git://git.yoctoproject.org/meta-xxxx
diff --git a/scripts/lib/bsp/substrate/target/arch/common/binary/.gitignore b/scripts/lib/bsp/substrate/target/arch/common/binary/.gitignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/binary/.gitignore
diff --git a/scripts/lib/bsp/substrate/target/arch/common/conf/layer.conf b/scripts/lib/bsp/substrate/target/arch/common/conf/layer.conf
new file mode 100644
index 0000000..5529f45
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/conf/layer.conf
@@ -0,0 +1,10 @@
+# We have a conf and classes directory, add to BBPATH
+BBPATH .= ":${LAYERDIR}"
+
+# We have a recipes-* directories, add to BBFILES
+BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
+	${LAYERDIR}/recipes-*/*/*.bbappend"
+
+BBFILE_COLLECTIONS += "{{=machine}}"
+BBFILE_PATTERN_{{=machine}} = "^${LAYERDIR}/"
+BBFILE_PRIORITY_{{=machine}} = "6"
diff --git a/scripts/lib/bsp/substrate/target/arch/common/recipes-bsp/formfactor/formfactor/machine.noinstall b/scripts/lib/bsp/substrate/target/arch/common/recipes-bsp/formfactor/formfactor/machine.noinstall
new file mode 100644
index 0000000..b442d02
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/recipes-bsp/formfactor/formfactor/machine.noinstall
@@ -0,0 +1 @@
+# yocto-bsp-dirname {{=machine}}
diff --git a/scripts/lib/bsp/substrate/target/arch/common/recipes-bsp/formfactor/formfactor/machine/machconfig b/scripts/lib/bsp/substrate/target/arch/common/recipes-bsp/formfactor/formfactor/machine/machconfig
new file mode 100644
index 0000000..3b85d38
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/recipes-bsp/formfactor/formfactor/machine/machconfig
@@ -0,0 +1,5 @@
+# Assume a USB mouse and keyboard are connected
+{{ input type:"boolean" name:"touchscreen" msg:"Does your BSP have a touchscreen? (y/n)" default:"n" }}
+HAVE_TOUCHSCREEN={{=touchscreen}}
+{{ input type:"boolean" name:"keyboard" msg:"Does your BSP have a keyboard? (y/n)" default:"y" }}
+HAVE_KEYBOARD={{=keyboard}}
diff --git a/scripts/lib/bsp/substrate/target/arch/common/recipes-bsp/formfactor/formfactor_0.0.bbappend b/scripts/lib/bsp/substrate/target/arch/common/recipes-bsp/formfactor/formfactor_0.0.bbappend
new file mode 100644
index 0000000..6d4804d
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/recipes-bsp/formfactor/formfactor_0.0.bbappend
@@ -0,0 +1,2 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
diff --git a/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/kernel-list.noinstall b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/kernel-list.noinstall
new file mode 100644
index 0000000..663dddb
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/kernel-list.noinstall
@@ -0,0 +1,26 @@
+{{ if kernel_choice == "custom": }}
+{{ input type:"boolean" name:"custom_kernel_remote" prio:"20" msg:"Is the custom kernel you'd like to use in a remote git repo? (y/n)" default:"y"}}
+
+{{ if kernel_choice == "custom" and custom_kernel_remote == "y": }}
+{{ input type:"edit-git-repo" name:"custom_kernel_remote_path" prio:"20" msg:"Please enter the full URI to the remote git repo (the default corresponds to linux-stable v3.16.3)" default:"git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git"}}
+
+{{ if kernel_choice == "custom" and custom_kernel_remote == "n": }}
+{{ input type:"edit-git-repo" name:"custom_kernel_local_path" prio:"20" msg:"You've indicated that you're not using a remote git repo.  Please enter the full path to the local git repo you want to use (the default assumes a local linux-stable v3.16.3)" default:"/home/trz/yocto/kernels/linux-stable.git"}}
+
+{{ if kernel_choice == "custom": }}
+{{ input type:"boolean" name:"custom_kernel_need_kbranch" prio:"20" msg:"Do you need to use a specific (non-master) branch? (y/n)" default:"n"}}
+
+{{ if kernel_choice == "custom" and custom_kernel_need_kbranch == "y": }}
+{{ input type:"edit" name:"custom_kernel_kbranch" prio:"20" msg:"Please enter the branch you want to use (the default branch corresponds to the linux-stable 'linux-3.16.y' branch):" default:"linux-3.16.y"}}
+
+{{ if kernel_choice == "custom": }}
+{{ input type:"edit" name:"custom_kernel_srcrev" prio:"20" msg:"Please enter the SRCREV (commit id) you'd like to use (use '${AUTOREV}' to track the current HEAD):" default:"${AUTOREV}"}}
+
+{{ if kernel_choice == "custom": }}
+{{ input type:"edit" name:"custom_kernel_linux_version" prio:"20" msg:"Please enter the Linux version of the kernel you've specified:" default:"3.16.3"}}
+
+{{ if kernel_choice == "custom": }}
+{{ input type:"edit" name:"custom_kernel_linux_version_extension" prio:"20" msg:"Please enter a Linux version extension if you want (it will show up at the end of the kernel name shown by uname):" default:"-custom"}}
+
+{{ if kernel_choice == "custom": }}
+{{ input type:"edit-file" name:"custom_kernel_defconfig" prio:"20" msg:"It's recommended (but not required) that custom kernels be built using a defconfig.  Please enter the full path to the defconfig for your kernel (NOTE: if you don't specify a defconfig the kernel probably won't build or boot):" default:""}}
diff --git a/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/linux-yocto-custom.bb b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/linux-yocto-custom.bb
new file mode 100644
index 0000000..fda955b
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/linux-yocto-custom.bb
@@ -0,0 +1,57 @@
+# yocto-bsp-filename {{ if kernel_choice == "custom": }} this
+# This file was derived from the linux-yocto-custom.bb recipe in
+# oe-core.
+#
+# linux-yocto-custom.bb:
+#
+#   A yocto-bsp-generated kernel recipe that uses the linux-yocto and
+#   oe-core kernel classes to apply a subset of yocto kernel
+#   management to git managed kernel repositories.
+#
+# Warning:
+#
+#   Building this kernel without providing a defconfig or BSP
+#   configuration will result in build or boot errors. This is not a
+#   bug.
+#
+# Notes:
+#
+#   patches: patches can be merged into to the source git tree itself,
+#            added via the SRC_URI, or controlled via a BSP
+#            configuration.
+#
+#   example configuration addition:
+#            SRC_URI += "file://smp.cfg"
+#   example patch addition:
+#            SRC_URI += "file://0001-linux-version-tweak.patch
+#   example feature addition:
+#            SRC_URI += "file://feature.scc"
+#
+
+inherit kernel
+require recipes-kernel/linux/linux-yocto.inc
+
+{{ if kernel_choice == "custom" and custom_kernel_remote == "y": }}
+SRC_URI = "{{=custom_kernel_remote_path}};protocol=git;bareclone=1;branch=${KBRANCH}"
+{{ if kernel_choice == "custom" and custom_kernel_remote == "n": }}
+SRC_URI = "git://{{=custom_kernel_local_path}};protocol=file;bareclone=1;branch=${KBRANCH}"
+
+SRC_URI += "file://defconfig"
+
+SRC_URI += "file://{{=machine}}.scc \
+            file://{{=machine}}.cfg \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+           "
+
+{{ if kernel_choice == "custom" and custom_kernel_need_kbranch == "y" and custom_kernel_kbranch and custom_kernel_kbranch != "master": }}
+KBRANCH = "{{=custom_kernel_kbranch}}"
+
+LINUX_VERSION ?= "{{=custom_kernel_linux_version}}"
+LINUX_VERSION_EXTENSION ?= "{{=custom_kernel_linux_version_extension}}"
+
+SRCREV="{{=custom_kernel_srcrev}}"
+
+PV = "${LINUX_VERSION}+git${SRCPV}"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
diff --git a/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/linux-yocto-custom.noinstall b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/linux-yocto-custom.noinstall
new file mode 100644
index 0000000..017d206
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/linux-yocto-custom.noinstall
@@ -0,0 +1 @@
+# yocto-bsp-dirname {{ if kernel_choice == "custom": }} linux-yocto-custom
diff --git a/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/linux-yocto-custom/defconfig b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/linux-yocto-custom/defconfig
new file mode 100644
index 0000000..ceb0ffa
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/linux-yocto-custom/defconfig
@@ -0,0 +1,5 @@
+#
+# Placeholder for custom default kernel configuration.  yocto-bsp will
+# replace this file with a user-specified defconfig.
+#
+{{ if custom_kernel_defconfig: replace_file(of, custom_kernel_defconfig) }}
diff --git a/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/linux-yocto-custom/machine-user-config.cfg b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/linux-yocto-custom/machine-user-config.cfg
new file mode 100644
index 0000000..922309d
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/linux-yocto-custom/machine-user-config.cfg
@@ -0,0 +1,9 @@
+# yocto-bsp-filename {{=machine}}-user-config.cfg
+#
+# Used by yocto-kernel to manage config options.
+#
+# yocto-kernel may change the contents of this file in any
+# way it sees fit, including removing comments like this,
+# so don't manually make any modifications you don't want
+# to lose.
+#
diff --git a/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/linux-yocto-custom/machine-user-patches.scc b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/linux-yocto-custom/machine-user-patches.scc
new file mode 100644
index 0000000..6d1138f
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/linux-yocto-custom/machine-user-patches.scc
@@ -0,0 +1,9 @@
+# yocto-bsp-filename {{=machine}}-user-patches.scc
+#
+# Used by yocto-kernel to manage patches.
+#
+# yocto-kernel may change the contents of this file in any
+# way it sees fit, including removing comments like this,
+# so don't manually make any modifications you don't want
+# to lose.
+#
diff --git a/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/linux-yocto-custom/machine.cfg b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/linux-yocto-custom/machine.cfg
new file mode 100644
index 0000000..1ba8201
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/linux-yocto-custom/machine.cfg
@@ -0,0 +1,4 @@
+# yocto-bsp-filename {{=machine}}.cfg
+#
+# A convenient place to add config options, nothing more.
+#
diff --git a/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/linux-yocto-custom/machine.scc b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/linux-yocto-custom/machine.scc
new file mode 100644
index 0000000..0b6b413
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/linux-yocto-custom/machine.scc
@@ -0,0 +1,18 @@
+# yocto-bsp-filename {{=machine}}.scc
+#
+# The top-level 'feature' for the {{=machine}} custom kernel.
+#
+# Essentially this is a convenient top-level container or starting
+# point for adding lower-level config fragements and features.
+#
+
+# {{=machine}}.cfg in the linux-yocto-custom subdir is just a
+# convenient place for adding random config fragments.
+
+kconf hardware {{=machine}}.cfg
+
+# These are used by yocto-kernel to add config fragments and features.
+# Don't remove if you plan on using yocto-kernel with this BSP.
+
+kconf hardware {{=machine}}-user-config.cfg
+include {{=machine}}-user-patches.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/conf/machine/machine.conf b/scripts/lib/bsp/substrate/target/arch/i386/conf/machine/machine.conf
new file mode 100644
index 0000000..7189341
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/conf/machine/machine.conf
@@ -0,0 +1,77 @@
+# yocto-bsp-filename {{=machine}}.conf
+#@TYPE: Machine
+#@NAME: {{=machine}}
+
+#@DESCRIPTION: Machine configuration for {{=machine}} systems
+
+{{ if kernel_choice == "custom": preferred_kernel = "linux-yocto-custom" }}
+{{ if kernel_choice == "linux-yocto-dev": preferred_kernel = "linux-yocto-dev" }}
+{{ if kernel_choice == "custom" or kernel_choice == "linux-yocto-dev" : }}
+PREFERRED_PROVIDER_virtual/kernel ?= "{{=preferred_kernel}}"
+
+{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": preferred_kernel = kernel_choice.split('_')[0] }}
+{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": preferred_kernel_version = kernel_choice.split('_')[1] }}
+{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": }}
+PREFERRED_PROVIDER_virtual/kernel ?= "{{=preferred_kernel}}"
+PREFERRED_VERSION_{{=preferred_kernel}} ?= "{{=preferred_kernel_version}}%"
+
+{{ input type:"choicelist" name:"tunefile" prio:"40" msg:"Which machine tuning would you like to use?" default:"tune_core2" }}
+{{ input type:"choice" val:"tune_i586" msg:"i586 tuning optimizations" }}
+{{ input type:"choice" val:"tune_atom" msg:"Atom tuning optimizations" }}
+{{ input type:"choice" val:"tune_core2" msg:"Core2 tuning optimizations" }}
+{{ if tunefile == "tune_i586": }}
+require conf/machine/include/tune-i586.inc
+{{ if tunefile == "tune_atom": }}
+require conf/machine/include/tune-atom.inc
+{{ if tunefile == "tune_core2": }}
+DEFAULTTUNE="core2-32"
+require conf/machine/include/tune-core2.inc
+
+require conf/machine/include/x86-base.inc
+
+MACHINE_FEATURES += "wifi efi pcbios"
+
+{{ input type:"boolean" name:"xserver" prio:"50" msg:"Do you need support for X? (y/n)" default:"y" }}
+
+{{ if xserver == "y" and (kernel_choice == "linux-yocto_3.19" or kernel_choice == "linux-yocto_3.14"): }}
+{{ input type:"choicelist" name:"xserver_choice" prio:"50" msg:"Please select an xserver for this machine:" default:"xserver_vesa" }}
+{{ input type:"choice" val:"xserver_vesa" msg:"VESA xserver support" }}
+{{ input type:"choice" val:"xserver_i915" msg:"i915 xserver support" }}
+{{ input type:"choice" val:"xserver_i965" msg:"i965 xserver support" }}
+{{ input type:"choice" val:"xserver_fbdev" msg:"fbdev xserver support" }}
+{{ input type:"choice" val:"xserver_modesetting" msg:"modesetting xserver support" }}
+
+{{ if xserver == "y" and kernel_choice == "custom": }}
+{{ input type:"choicelist" name:"xserver_choice" prio:"50" msg:"Please select an xserver for this machine:" default:"xserver_vesa" }}
+{{ input type:"choice" val:"xserver_vesa" msg:"VESA xserver support" }}
+{{ input type:"choice" val:"xserver_i915" msg:"i915 xserver support" }}
+{{ input type:"choice" val:"xserver_i965" msg:"i965 xserver support" }}
+{{ input type:"choice" val:"xserver_fbdev" msg:"fbdev xserver support" }}
+{{ input type:"choice" val:"xserver_modesetting" msg:"modesetting xserver support" }}
+
+{{ if xserver == "y" and kernel_choice != "linux-yocto_3.19" and kernel_choice != "linux-yocto_3.14" and kernel_choice != "custom": xserver_choice = "xserver_i915" }}
+
+{{ if xserver == "y": }}
+XSERVER ?= "${XSERVER_X86_BASE} \
+           ${XSERVER_X86_EXT} \
+{{ if xserver == "y" and xserver_choice == "xserver_vesa": }}
+           ${XSERVER_X86_VESA} \
+{{ if xserver == "y" and xserver_choice == "xserver_i915": }}
+           ${XSERVER_X86_I915} \
+{{ if xserver == "y" and xserver_choice == "xserver_i965": }}
+           ${XSERVER_X86_I965} \
+{{ if xserver == "y" and xserver_choice == "xserver_fbdev": }}
+           ${XSERVER_X86_FBDEV} \
+{{ if xserver == "y" and xserver_choice == "xserver_modesetting": }}
+           ${XSERVER_X86_MODESETTING} \
+{{ if xserver == "y": }}
+           "
+
+MACHINE_EXTRA_RRECOMMENDS += "linux-firmware v86d eee-acpi-scripts"
+
+EXTRA_OECONF_append_pn-matchbox-panel-2 = " --with-battery=acpi"
+
+GLIBC_ADDONS = "nptl"
+
+{{ if xserver == "y" and xserver_choice == "xserver_vesa": }}
+APPEND += "video=vesafb vga=0x318"
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-graphics/xorg-xserver/xserver-xf86-config/machine.noinstall b/scripts/lib/bsp/substrate/target/arch/i386/recipes-graphics/xorg-xserver/xserver-xf86-config/machine.noinstall
new file mode 100644
index 0000000..b442d02
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-graphics/xorg-xserver/xserver-xf86-config/machine.noinstall
@@ -0,0 +1 @@
+# yocto-bsp-dirname {{=machine}}
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-graphics/xorg-xserver/xserver-xf86-config/machine/xorg.conf b/scripts/lib/bsp/substrate/target/arch/i386/recipes-graphics/xorg-xserver/xserver-xf86-config/machine/xorg.conf
new file mode 100644
index 0000000..ac9a0f1
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-graphics/xorg-xserver/xserver-xf86-config/machine/xorg.conf
@@ -0,0 +1 @@
+# yocto-bsp-filename {{ if xserver == "y": }} this
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-graphics/xorg-xserver/xserver-xf86-config_0.1.bbappend b/scripts/lib/bsp/substrate/target/arch/i386/recipes-graphics/xorg-xserver/xserver-xf86-config_0.1.bbappend
new file mode 100644
index 0000000..3083003
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-graphics/xorg-xserver/xserver-xf86-config_0.1.bbappend
@@ -0,0 +1,2 @@
+# yocto-bsp-filename {{ if xserver == "y": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files.noinstall b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files.noinstall
new file mode 100644
index 0000000..1e0d92c
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files.noinstall
@@ -0,0 +1 @@
+# yocto-bsp-dirname {{ if kernel_choice != "custom": }} files
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files/machine-preempt-rt.scc b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files/machine-preempt-rt.scc
new file mode 100644
index 0000000..619ee3f
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files/machine-preempt-rt.scc
@@ -0,0 +1,16 @@
+# yocto-bsp-filename {{=machine}}-preempt-rt.scc
+define KMACHINE {{=machine}}
+define KTYPE preempt-rt
+define KARCH i386
+
+include {{=map_preempt_rt_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
+{{ if need_new_kbranch == "y": }}
+branch {{=machine}}
+
+include {{=machine}}.scc
+
+# default policy for preempt-rt kernels
+include cfg/usb-mass-storage.scc
+include cfg/boot-live.scc
+include features/latencytop/latencytop.scc
+include features/profiling/profiling.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files/machine-standard.scc b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files/machine-standard.scc
new file mode 100644
index 0000000..682012f
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files/machine-standard.scc
@@ -0,0 +1,16 @@
+# yocto-bsp-filename {{=machine}}-standard.scc
+define KMACHINE {{=machine}}
+define KTYPE standard
+define KARCH i386
+
+include {{=map_standard_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
+{{ if need_new_kbranch == "y": }}
+branch {{=machine}}
+
+include {{=machine}}.scc
+
+# default policy for standard kernels
+include cfg/usb-mass-storage.scc
+include cfg/boot-live.scc
+include features/latencytop/latencytop.scc
+include features/profiling/profiling.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files/machine-tiny.scc b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files/machine-tiny.scc
new file mode 100644
index 0000000..cc75196
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files/machine-tiny.scc
@@ -0,0 +1,10 @@
+# yocto-bsp-filename {{=machine}}-tiny.scc
+define KMACHINE {{=machine}}
+define KTYPE tiny
+define KARCH i386
+
+include {{=map_tiny_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
+{{ if need_new_kbranch == "y": }}
+branch {{=machine}}
+
+include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files/machine-user-config.cfg b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files/machine-user-config.cfg
new file mode 100644
index 0000000..69efdcc
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files/machine-user-config.cfg
@@ -0,0 +1 @@
+# yocto-bsp-filename {{=machine}}-user-config.cfg
\ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files/machine-user-features.scc b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files/machine-user-features.scc
new file mode 100644
index 0000000..85be26d
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files/machine-user-features.scc
@@ -0,0 +1 @@
+# yocto-bsp-filename {{=machine}}-user-features.scc
\ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files/machine-user-patches.scc b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files/machine-user-patches.scc
new file mode 100644
index 0000000..4c59daa
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files/machine-user-patches.scc
@@ -0,0 +1 @@
+# yocto-bsp-filename {{=machine}}-user-patches.scc
\ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files/machine.cfg b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files/machine.cfg
new file mode 100644
index 0000000..3b168b7
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files/machine.cfg
@@ -0,0 +1,55 @@
+# yocto-bsp-filename {{=machine}}.cfg
+CONFIG_X86_32=y
+CONFIG_MATOM=y
+CONFIG_PRINTK=y
+
+# Basic hardware support for the box - network, USB, PCI, sound
+CONFIG_NETDEVICES=y
+CONFIG_ATA=y
+CONFIG_ATA_GENERIC=y
+CONFIG_ATA_SFF=y
+CONFIG_PCI=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_R8169=y
+CONFIG_PATA_SCH=y
+CONFIG_MMC_SDHCI_PCI=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_NET=y
+CONFIG_USB_UHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_HDA_INTEL=y
+CONFIG_SATA_AHCI=y
+CONFIG_AGP=y
+CONFIG_PM=y
+CONFIG_ACPI=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_INPUT=y
+
+# Make sure these are on, otherwise the bootup won't be fun
+CONFIG_EXT3_FS=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_MODULES=y
+CONFIG_SHMEM=y
+CONFIG_TMPFS=y
+CONFIG_PACKET=y
+
+# Needed for booting (and using) USB memory sticks
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+
+CONFIG_RD_GZIP=y
+
+# Needed for booting (and using) CD images
+CONFIG_BLK_DEV_SR=y
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files/machine.scc b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files/machine.scc
new file mode 100644
index 0000000..3d32f11
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/files/machine.scc
@@ -0,0 +1,21 @@
+# yocto-bsp-filename {{=machine}}.scc
+kconf hardware {{=machine}}.cfg
+
+include features/intel-e1xxxx/intel-e100.scc
+include features/intel-e1xxxx/intel-e1xxxx.scc
+
+{{ if xserver == "y" and xserver_choice == "xserver_i915" or xserver_choice == "xserver_i965": }}
+include features/i915/i915.scc
+
+include features/serial/8250.scc
+include features/ericsson-3g/f5521gw.scc
+
+{{ if xserver == "y" and xserver_choice == "xserver_vesa": }}
+include cfg/vesafb.scc
+
+include cfg/usb-mass-storage.scc
+include cfg/boot-live.scc
+include features/power/intel.scc
+
+kconf hardware {{=machine}}-user-config.cfg
+include {{=machine}}-user-patches.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/kernel-list.noinstall b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/kernel-list.noinstall
new file mode 100644
index 0000000..811d695
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/kernel-list.noinstall
@@ -0,0 +1,5 @@
+{{ if kernel_choice != "custom": }}
+{{ input type:"boolean" name:"use_default_kernel" prio:"10" msg:"Would you like to use the default (3.19) kernel? (y/n)" default:"y"}}
+
+{{ if kernel_choice != "custom" and use_default_kernel == "n": }}
+{{ input type:"choicelist" name:"kernel_choice" gen:"bsp.kernel.kernels" prio:"10" msg:"Please choose the kernel to use in this BSP:" default:"linux-yocto_3.19"}}
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/linux-yocto-dev.bbappend b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/linux-yocto-dev.bbappend
new file mode 100644
index 0000000..2fa6231
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/linux-yocto-dev.bbappend
@@ -0,0 +1,26 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto-dev": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Would you like SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-standard.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/linux-yocto-rt_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/linux-yocto-rt_3.14.bbappend
new file mode 100644
index 0000000..5f8db03
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/linux-yocto-rt_3.14.bbappend
@@ -0,0 +1,33 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto-rt_3.14": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-preempt-rt.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
+
+# uncomment and replace these SRCREVs with the real commit ids once you've had
+# the appropriate changes committed to the upstream linux-yocto repo
+#SRCREV_machine_pn-linux-yocto-rt_{{=machine}} ?= "f35992f80c81dc5fa1a97165dfd5cbb84661f7cb"
+#SRCREV_meta_pn-linux-yocto-rt_{{=machine}} ?= "1b534b2f8bbe9b8a773268cfa30a4850346f6f5f"
+#LINUX_VERSION = "3.14"
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/linux-yocto-tiny_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/linux-yocto-tiny_3.14.bbappend
new file mode 100644
index 0000000..471ccbc
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/linux-yocto-tiny_3.14.bbappend
@@ -0,0 +1,33 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto-tiny_3.14": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-tiny.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
+
+# uncomment and replace these SRCREVs with the real commit ids once you've had
+# the appropriate changes committed to the upstream linux-yocto repo
+#SRCREV_machine_pn-linux-yocto-tiny_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
+#SRCREV_meta_pn-linux-yocto-tiny_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
+#LINUX_VERSION = "3.14"
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/linux-yocto-tiny_3.19.bbappend b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/linux-yocto-tiny_3.19.bbappend
new file mode 100644
index 0000000..4de82fa
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/linux-yocto-tiny_3.19.bbappend
@@ -0,0 +1,33 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto-tiny_3.19": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-tiny.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
+
+# uncomment and replace these SRCREVs with the real commit ids once you've had
+# the appropriate changes committed to the upstream linux-yocto repo
+#SRCREV_machine_pn-linux-yocto-tiny_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
+#SRCREV_meta_pn-linux-yocto-tiny_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
+#LINUX_VERSION = "3.19"
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/linux-yocto_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/linux-yocto_3.14.bbappend
new file mode 100644
index 0000000..fbb49ed
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/linux-yocto_3.14.bbappend
@@ -0,0 +1,33 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto_3.14": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard:standard/common-pc" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard:standard/common-pc" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-standard.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
+
+# uncomment and replace these SRCREVs with the real commit ids once you've had
+# the appropriate changes committed to the upstream linux-yocto repo
+#SRCREV_machine_pn-linux-yocto_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
+#SRCREV_meta_pn-linux-yocto_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
+#LINUX_VERSION = "3.14"
\ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/linux-yocto_3.19.bbappend b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/linux-yocto_3.19.bbappend
new file mode 100644
index 0000000..0c2cb5a
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/linux-yocto_3.19.bbappend
@@ -0,0 +1,33 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto_3.19": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard:standard/common-pc" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard:standard/common-pc" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-standard.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
+
+# uncomment and replace these SRCREVs with the real commit ids once you've had
+# the appropriate changes committed to the upstream linux-yocto repo
+#SRCREV_machine_pn-linux-yocto_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
+#SRCREV_meta_pn-linux-yocto_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
+#LINUX_VERSION = "3.19"
\ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/layer/COPYING.MIT b/scripts/lib/bsp/substrate/target/arch/layer/COPYING.MIT
new file mode 100644
index 0000000..89de354
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/layer/COPYING.MIT
@@ -0,0 +1,17 @@
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/scripts/lib/bsp/substrate/target/arch/layer/README b/scripts/lib/bsp/substrate/target/arch/layer/README
new file mode 100644
index 0000000..943dfc4
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/layer/README
@@ -0,0 +1,64 @@
+This README file contains information on the contents of the
+{{=layer_name}} layer.
+
+Please see the corresponding sections below for details.
+
+
+Dependencies
+============
+
+This layer depends on:
+
+  URI: git://git.openembedded.org/bitbake
+  branch: master
+
+  URI: git://git.openembedded.org/openembedded-core
+  layers: meta
+  branch: master
+
+  URI: git://git.yoctoproject.org/xxxx
+  layers: xxxx
+  branch: master
+
+
+Patches
+=======
+
+Please submit any patches against the {{=layer_name}} layer to the
+xxxx mailing list (xxxx@zzzz.org) and cc: the maintainer:
+
+Maintainer: XXX YYYYYY <xxx.yyyyyy@zzzzz.com>
+
+
+Table of Contents
+=================
+
+  I. Adding the {{=layer_name}} layer to your build
+ II. Misc
+
+
+I. Adding the {{=layer_name}} layer to your build
+=================================================
+
+--- replace with specific instructions for the {{=layer_name}} layer ---
+
+In order to use this layer, you need to make the build system aware of
+it.
+
+Assuming the {{=layer_name}} layer exists at the top-level of your
+yocto build tree, you can add it to the build system by adding the
+location of the {{=layer_name}} layer to bblayers.conf, along with any
+other layers needed. e.g.:
+
+  BBLAYERS ?= " \
+    /path/to/yocto/meta \
+    /path/to/yocto/meta-yocto \
+    /path/to/yocto/meta-yocto-bsp \
+    /path/to/yocto/meta-{{=layer_name}} \
+    "
+
+
+II. Misc
+========
+
+--- replace with specific information about the {{=layer_name}} layer ---
diff --git a/scripts/lib/bsp/substrate/target/arch/layer/conf/layer.conf b/scripts/lib/bsp/substrate/target/arch/layer/conf/layer.conf
new file mode 100644
index 0000000..bdffe17
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/layer/conf/layer.conf
@@ -0,0 +1,10 @@
+# We have a conf and classes directory, add to BBPATH
+BBPATH .= ":${LAYERDIR}"
+
+# We have recipes-* directories, add to BBFILES
+BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
+	${LAYERDIR}/recipes-*/*/*.bbappend"
+
+BBFILE_COLLECTIONS += "{{=layer_name}}"
+BBFILE_PATTERN_{{=layer_name}} = "^${LAYERDIR}/"
+BBFILE_PRIORITY_{{=layer_name}} = "{{=layer_priority}}"
diff --git a/scripts/lib/bsp/substrate/target/arch/layer/layer-questions.noinstall b/scripts/lib/bsp/substrate/target/arch/layer/layer-questions.noinstall
new file mode 100644
index 0000000..e2a89c3
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/layer/layer-questions.noinstall
@@ -0,0 +1,14 @@
+{{ input type:"edit" name:"layer_priority" prio:"20" msg:"Please enter the layer priority you'd like to use for the layer:" default:"6"}}
+
+{{ input type:"boolean" name:"create_example_recipe" prio:"20" msg:"Would you like to have an example recipe created? (y/n)" default:"n"}}
+
+{{ if create_example_recipe == "y": }}
+{{ input type:"edit" name:"example_recipe_name" prio:"20" msg:"Please enter the name you'd like to use for your example recipe:" default:"example"}}
+
+{{ input type:"boolean" name:"create_example_bbappend" prio:"20" msg:"Would you like to have an example bbappend file created? (y/n)" default:"n"}}
+
+{{ if create_example_bbappend == "y": }}
+{{ input type:"edit" name:"example_bbappend_name" prio:"20" msg:"Please enter the name you'd like to use for your bbappend file:" default:"example"}}
+
+{{ if create_example_bbappend == "y": }}
+{{ input type:"edit" name:"example_bbappend_version" prio:"20" msg:"Please enter the version number you'd like to use for your bbappend file (this should match the recipe you're appending to):" default:"0.1"}}
diff --git a/scripts/lib/bsp/substrate/target/arch/layer/recipes-example-bbappend.noinstall b/scripts/lib/bsp/substrate/target/arch/layer/recipes-example-bbappend.noinstall
new file mode 100644
index 0000000..3594e65
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/layer/recipes-example-bbappend.noinstall
@@ -0,0 +1 @@
+# yocto-bsp-dirname {{ if create_example_bbappend == "y": }} recipes-example-bbappend
diff --git a/scripts/lib/bsp/substrate/target/arch/layer/recipes-example-bbappend/example-bbappend/example-bbappend-version.bbappend b/scripts/lib/bsp/substrate/target/arch/layer/recipes-example-bbappend/example-bbappend/example-bbappend-version.bbappend
new file mode 100644
index 0000000..3531330
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/layer/recipes-example-bbappend/example-bbappend/example-bbappend-version.bbappend
@@ -0,0 +1,9 @@
+# yocto-bsp-filename {{=example_bbappend_name}}_{{=example_bbappend_version}}.bbappend
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}-${PV}:"
+
+#
+# This .bbappend doesn't yet do anything - replace this text with
+# modifications to the example_0.1.bb recipe, or whatever recipe it is
+# that you want to modify with this .bbappend (make sure you change
+# the recipe name (PN) and version (PV) to match).
+#
diff --git a/scripts/lib/bsp/substrate/target/arch/layer/recipes-example-bbappend/example-bbappend/example-bbappend-version.noinstall b/scripts/lib/bsp/substrate/target/arch/layer/recipes-example-bbappend/example-bbappend/example-bbappend-version.noinstall
new file mode 100644
index 0000000..46df8a8
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/layer/recipes-example-bbappend/example-bbappend/example-bbappend-version.noinstall
@@ -0,0 +1 @@
+# yocto-bsp-dirname {{=example_bbappend_name}}-{{=example_bbappend_version}}
diff --git a/scripts/lib/bsp/substrate/target/arch/layer/recipes-example-bbappend/example-bbappend/example-bbappend-version/example.patch b/scripts/lib/bsp/substrate/target/arch/layer/recipes-example-bbappend/example-bbappend/example-bbappend-version/example.patch
new file mode 100644
index 0000000..2000a34
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/layer/recipes-example-bbappend/example-bbappend/example-bbappend-version/example.patch
@@ -0,0 +1,12 @@
+#
+# This is a non-functional placeholder file, here for example purposes
+# only.
+#
+# If you had a patch for your recipe, you'd put it in this directory
+# and reference it from your recipe's SRC_URI:
+#
+#  SRC_URI += "file://example.patch"
+#
+# Note that you could also rename the directory containing this patch
+# to remove the version number or simply rename it 'files'.  Doing so
+# allows you to use the same directory for multiple recipes.
diff --git a/scripts/lib/bsp/substrate/target/arch/layer/recipes-example.noinstall b/scripts/lib/bsp/substrate/target/arch/layer/recipes-example.noinstall
new file mode 100644
index 0000000..b0069b1
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/layer/recipes-example.noinstall
@@ -0,0 +1 @@
+# yocto-bsp-dirname {{ if create_example_recipe == "y": }} recipes-example
diff --git a/scripts/lib/bsp/substrate/target/arch/layer/recipes-example/example/example-recipe-0.1.bb b/scripts/lib/bsp/substrate/target/arch/layer/recipes-example/example/example-recipe-0.1.bb
new file mode 100644
index 0000000..5fbf594
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/layer/recipes-example/example/example-recipe-0.1.bb
@@ -0,0 +1,23 @@
+# yocto-bsp-filename {{=example_recipe_name}}_0.1.bb
+#
+# This file was derived from the 'Hello World!' example recipe in the
+# Yocto Project Development Manual.
+#
+
+SUMMARY = "Simple helloworld application"
+SECTION = "examples"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
+
+SRC_URI = "file://helloworld.c"
+
+S = "${WORKDIR}"
+
+do_compile() {
+	     ${CC} helloworld.c -o helloworld
+}
+
+do_install() {
+	     install -d ${D}${bindir}
+	     install -m 0755 helloworld ${D}${bindir}
+}
diff --git a/scripts/lib/bsp/substrate/target/arch/layer/recipes-example/example/example-recipe-0.1.noinstall b/scripts/lib/bsp/substrate/target/arch/layer/recipes-example/example/example-recipe-0.1.noinstall
new file mode 100644
index 0000000..c319c19
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/layer/recipes-example/example/example-recipe-0.1.noinstall
@@ -0,0 +1 @@
+# yocto-bsp-dirname {{=example_recipe_name}}-0.1
diff --git a/scripts/lib/bsp/substrate/target/arch/layer/recipes-example/example/example-recipe-0.1/example.patch b/scripts/lib/bsp/substrate/target/arch/layer/recipes-example/example/example-recipe-0.1/example.patch
new file mode 100644
index 0000000..2000a34
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/layer/recipes-example/example/example-recipe-0.1/example.patch
@@ -0,0 +1,12 @@
+#
+# This is a non-functional placeholder file, here for example purposes
+# only.
+#
+# If you had a patch for your recipe, you'd put it in this directory
+# and reference it from your recipe's SRC_URI:
+#
+#  SRC_URI += "file://example.patch"
+#
+# Note that you could also rename the directory containing this patch
+# to remove the version number or simply rename it 'files'.  Doing so
+# allows you to use the same directory for multiple recipes.
diff --git a/scripts/lib/bsp/substrate/target/arch/layer/recipes-example/example/example-recipe-0.1/helloworld.c b/scripts/lib/bsp/substrate/target/arch/layer/recipes-example/example/example-recipe-0.1/helloworld.c
new file mode 100644
index 0000000..71f2e46
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/layer/recipes-example/example/example-recipe-0.1/helloworld.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+    printf("Hello World!\n");
+
+    return 0;
+}
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/.gitignore b/scripts/lib/bsp/substrate/target/arch/mips/.gitignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/.gitignore
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/conf/machine/machine.conf b/scripts/lib/bsp/substrate/target/arch/mips/conf/machine/machine.conf
new file mode 100644
index 0000000..b319d62
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/conf/machine/machine.conf
@@ -0,0 +1,39 @@
+# yocto-bsp-filename {{=machine}}.conf
+#@TYPE: Machine
+#@NAME: {{=machine}}
+
+#@DESCRIPTION: Machine configuration for {{=machine}} systems
+
+require conf/machine/include/tune-mips32.inc
+
+MACHINE_FEATURES = "screen keyboard pci usbhost ext2 ext3 serial"
+
+KERNEL_IMAGETYPE = "vmlinux"
+KERNEL_ALT_IMAGETYPE = "vmlinux.bin"
+KERNEL_IMAGE_STRIP_EXTRA_SECTIONS  = ".comment"
+
+{{ if kernel_choice == "custom": preferred_kernel = "linux-yocto-custom" }}
+{{ if kernel_choice == "linux-yocto-dev": preferred_kernel = "linux-yocto-dev" }}
+{{ if kernel_choice == "custom" or kernel_choice == "linux-yocto-dev" : }}
+PREFERRED_PROVIDER_virtual/kernel ?= "{{=preferred_kernel}}"
+
+{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": preferred_kernel = kernel_choice.split('_')[0] }}
+{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": preferred_kernel_version = kernel_choice.split('_')[1] }}
+{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": }}
+PREFERRED_PROVIDER_virtual/kernel ?= "{{=preferred_kernel}}"
+PREFERRED_VERSION_{{=preferred_kernel}} ?= "{{=preferred_kernel_version}}%"
+
+{{ input type:"boolean" name:"xserver" prio:"50" msg:"Do you need support for X? (y/n)" default:"y" }}
+{{ if xserver == "y": }}
+PREFERRED_PROVIDER_virtual/xserver ?= "xserver-xorg"
+XSERVER ?= "xserver-xorg \
+            xf86-input-evdev \
+            xf86-video-fbdev"
+
+SERIAL_CONSOLE = "115200 ttyS0"
+USE_VT ?= "0"
+
+MACHINE_EXTRA_RRECOMMENDS = " kernel-modules"
+
+IMAGE_FSTYPES ?= "jffs2 tar.bz2"
+JFFS2_ERASEBLOCK = "0x10000"
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files.noinstall b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files.noinstall
new file mode 100644
index 0000000..1e0d92c
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files.noinstall
@@ -0,0 +1 @@
+# yocto-bsp-dirname {{ if kernel_choice != "custom": }} files
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files/machine-preempt-rt.scc b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files/machine-preempt-rt.scc
new file mode 100644
index 0000000..176190c
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files/machine-preempt-rt.scc
@@ -0,0 +1,10 @@
+# yocto-bsp-filename {{=machine}}-preempt-rt.scc
+define KMACHINE {{=machine}}
+define KTYPE preempt-rt
+define KARCH mips
+
+include {{=map_preempt_rt_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
+{{ if need_new_kbranch == "y": }}
+branch {{=machine}}
+
+include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files/machine-standard.scc b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files/machine-standard.scc
new file mode 100644
index 0000000..f05dd85
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files/machine-standard.scc
@@ -0,0 +1,10 @@
+# yocto-bsp-filename {{=machine}}-standard.scc
+define KMACHINE {{=machine}}
+define KTYPE standard
+define KARCH mips
+
+include {{=map_standard_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
+{{ if need_new_kbranch == "y": }}
+branch {{=machine}}
+
+include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files/machine-tiny.scc b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files/machine-tiny.scc
new file mode 100644
index 0000000..f71c775
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files/machine-tiny.scc
@@ -0,0 +1,10 @@
+# yocto-bsp-filename {{=machine}}-tiny.scc
+define KMACHINE {{=machine}}
+define KTYPE tiny
+define KARCH mips
+
+include {{=map_tiny_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
+{{ if need_new_kbranch == "y": }}
+branch {{=machine}}
+
+include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files/machine-user-config.cfg b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files/machine-user-config.cfg
new file mode 100644
index 0000000..47489e4
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files/machine-user-config.cfg
@@ -0,0 +1 @@
+# yocto-bsp-filename {{=machine}}-user-config.cfg
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files/machine-user-features.scc b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files/machine-user-features.scc
new file mode 100644
index 0000000..85be26d
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files/machine-user-features.scc
@@ -0,0 +1 @@
+# yocto-bsp-filename {{=machine}}-user-features.scc
\ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files/machine-user-patches.scc b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files/machine-user-patches.scc
new file mode 100644
index 0000000..97f747f
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files/machine-user-patches.scc
@@ -0,0 +1 @@
+# yocto-bsp-filename {{=machine}}-user-patches.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files/machine.cfg b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files/machine.cfg
new file mode 100644
index 0000000..2fe4766
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files/machine.cfg
@@ -0,0 +1,2 @@
+# yocto-bsp-filename {{=machine}}.cfg
+CONFIG_MIPS=y
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files/machine.scc b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files/machine.scc
new file mode 100644
index 0000000..f39dc3e
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/files/machine.scc
@@ -0,0 +1,8 @@
+# yocto-bsp-filename {{=machine}}.scc
+kconf hardware {{=machine}}.cfg
+
+include cfg/usb-mass-storage.scc
+include cfg/fs/vfat.scc
+
+kconf hardware {{=machine}}-user-config.cfg
+include {{=machine}}-user-patches.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/kernel-list.noinstall b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/kernel-list.noinstall
new file mode 100644
index 0000000..811d695
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/kernel-list.noinstall
@@ -0,0 +1,5 @@
+{{ if kernel_choice != "custom": }}
+{{ input type:"boolean" name:"use_default_kernel" prio:"10" msg:"Would you like to use the default (3.19) kernel? (y/n)" default:"y"}}
+
+{{ if kernel_choice != "custom" and use_default_kernel == "n": }}
+{{ input type:"choicelist" name:"kernel_choice" gen:"bsp.kernel.kernels" prio:"10" msg:"Please choose the kernel to use in this BSP:" default:"linux-yocto_3.19"}}
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/linux-yocto-dev.bbappend b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/linux-yocto-dev.bbappend
new file mode 100644
index 0000000..2fa6231
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/linux-yocto-dev.bbappend
@@ -0,0 +1,26 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto-dev": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Would you like SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-standard.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/linux-yocto-rt_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/linux-yocto-rt_3.14.bbappend
new file mode 100644
index 0000000..5f8db03
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/linux-yocto-rt_3.14.bbappend
@@ -0,0 +1,33 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto-rt_3.14": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-preempt-rt.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
+
+# uncomment and replace these SRCREVs with the real commit ids once you've had
+# the appropriate changes committed to the upstream linux-yocto repo
+#SRCREV_machine_pn-linux-yocto-rt_{{=machine}} ?= "f35992f80c81dc5fa1a97165dfd5cbb84661f7cb"
+#SRCREV_meta_pn-linux-yocto-rt_{{=machine}} ?= "1b534b2f8bbe9b8a773268cfa30a4850346f6f5f"
+#LINUX_VERSION = "3.14"
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/linux-yocto-tiny_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/linux-yocto-tiny_3.14.bbappend
new file mode 100644
index 0000000..c7e7989
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/linux-yocto-tiny_3.14.bbappend
@@ -0,0 +1,33 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto-tiny_3.14": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-tiny.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
+
+# uncomment and replace these SRCREVs with the real commit ids once you've had
+# the appropriate changes committed to the upstream linux-yocto repo
+#SRCREV_machine_pn-linux-yocto-tiny_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
+#SRCREV_meta_pn-linux-yocto-tiny_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
+#LINUX_VERSION = "3.14"
\ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/linux-yocto-tiny_3.19.bbappend b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/linux-yocto-tiny_3.19.bbappend
new file mode 100644
index 0000000..a9ba0ae
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/linux-yocto-tiny_3.19.bbappend
@@ -0,0 +1,33 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto-tiny_3.19": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-tiny.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
+
+# uncomment and replace these SRCREVs with the real commit ids once you've had
+# the appropriate changes committed to the upstream linux-yocto repo
+#SRCREV_machine_pn-linux-yocto-tiny_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
+#SRCREV_meta_pn-linux-yocto-tiny_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
+#LINUX_VERSION = "3.19"
\ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/linux-yocto_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/linux-yocto_3.14.bbappend
new file mode 100644
index 0000000..1e1cc51
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/linux-yocto_3.14.bbappend
@@ -0,0 +1,33 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto_3.14": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-standard.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
+
+# uncomment and replace these SRCREVs with the real commit ids once you've had
+# the appropriate changes committed to the upstream linux-yocto repo
+#SRCREV_machine_pn-linux-yocto_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
+#SRCREV_meta_pn-linux-yocto_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
+#LINUX_VERSION = "3.14"
\ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/linux-yocto_3.19.bbappend b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/linux-yocto_3.19.bbappend
new file mode 100644
index 0000000..97e1bb8
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/linux-yocto_3.19.bbappend
@@ -0,0 +1,33 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto_3.19": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-standard.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
+
+# uncomment and replace these SRCREVs with the real commit ids once you've had
+# the appropriate changes committed to the upstream linux-yocto repo
+#SRCREV_machine_pn-linux-yocto_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
+#SRCREV_meta_pn-linux-yocto_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
+#LINUX_VERSION = "3.19"
\ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/mips64/.gitignore b/scripts/lib/bsp/substrate/target/arch/mips64/.gitignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips64/.gitignore
diff --git a/scripts/lib/bsp/substrate/target/arch/mips64/conf/machine/machine.conf b/scripts/lib/bsp/substrate/target/arch/mips64/conf/machine/machine.conf
new file mode 100644
index 0000000..3afc5e0
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips64/conf/machine/machine.conf
@@ -0,0 +1,39 @@
+# yocto-bsp-filename {{=machine}}.conf
+#@TYPE: Machine
+#@NAME: {{=machine}}
+
+#@DESCRIPTION: Machine configuration for {{=machine}} systems
+
+require conf/machine/include/tune-mips64.inc
+
+MACHINE_FEATURES = "pci ext2 ext3 serial"
+
+KERNEL_IMAGETYPE = "vmlinux"
+KERNEL_ALT_IMAGETYPE = "vmlinux.bin"
+KERNEL_IMAGE_STRIP_EXTRA_SECTIONS  = ".comment"
+
+{{ if kernel_choice == "custom": preferred_kernel = "linux-yocto-custom" }}
+{{ if kernel_choice == "linux-yocto-dev": preferred_kernel = "linux-yocto-dev" }}
+{{ if kernel_choice == "custom" or kernel_choice == "linux-yocto-dev" : }}
+PREFERRED_PROVIDER_virtual/kernel ?= "{{=preferred_kernel}}"
+
+{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": preferred_kernel = kernel_choice.split('_')[0] }}
+{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": preferred_kernel_version = kernel_choice.split('_')[1] }}
+{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": }}
+PREFERRED_PROVIDER_virtual/kernel ?= "{{=preferred_kernel}}"
+PREFERRED_VERSION_{{=preferred_kernel}} ?= "{{=preferred_kernel_version}}%"
+
+{{ input type:"boolean" name:"xserver" prio:"50" msg:"Do you need support for X? (y/n)" default:"y" }}
+{{ if xserver == "y": }}
+PREFERRED_PROVIDER_virtual/xserver ?= "xserver-xorg"
+XSERVER ?= "xserver-xorg \
+            xf86-input-evdev \
+            xf86-video-fbdev"
+
+SERIAL_CONSOLE = "115200 ttyS0"
+USE_VT ?= "0"
+
+MACHINE_EXTRA_RRECOMMENDS = " kernel-modules"
+
+IMAGE_FSTYPES ?= "jffs2 tar.bz2"
+JFFS2_ERASEBLOCK = "0x10000"
diff --git a/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files.noinstall b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files.noinstall
new file mode 100644
index 0000000..1e0d92c
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files.noinstall
@@ -0,0 +1 @@
+# yocto-bsp-dirname {{ if kernel_choice != "custom": }} files
diff --git a/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files/machine-preempt-rt.scc b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files/machine-preempt-rt.scc
new file mode 100644
index 0000000..176190c
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files/machine-preempt-rt.scc
@@ -0,0 +1,10 @@
+# yocto-bsp-filename {{=machine}}-preempt-rt.scc
+define KMACHINE {{=machine}}
+define KTYPE preempt-rt
+define KARCH mips
+
+include {{=map_preempt_rt_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
+{{ if need_new_kbranch == "y": }}
+branch {{=machine}}
+
+include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files/machine-standard.scc b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files/machine-standard.scc
new file mode 100644
index 0000000..f05dd85
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files/machine-standard.scc
@@ -0,0 +1,10 @@
+# yocto-bsp-filename {{=machine}}-standard.scc
+define KMACHINE {{=machine}}
+define KTYPE standard
+define KARCH mips
+
+include {{=map_standard_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
+{{ if need_new_kbranch == "y": }}
+branch {{=machine}}
+
+include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files/machine-tiny.scc b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files/machine-tiny.scc
new file mode 100644
index 0000000..f71c775
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files/machine-tiny.scc
@@ -0,0 +1,10 @@
+# yocto-bsp-filename {{=machine}}-tiny.scc
+define KMACHINE {{=machine}}
+define KTYPE tiny
+define KARCH mips
+
+include {{=map_tiny_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
+{{ if need_new_kbranch == "y": }}
+branch {{=machine}}
+
+include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files/machine-user-config.cfg b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files/machine-user-config.cfg
new file mode 100644
index 0000000..69efdcc
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files/machine-user-config.cfg
@@ -0,0 +1 @@
+# yocto-bsp-filename {{=machine}}-user-config.cfg
\ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files/machine-user-features.scc b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files/machine-user-features.scc
new file mode 100644
index 0000000..85be26d
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files/machine-user-features.scc
@@ -0,0 +1 @@
+# yocto-bsp-filename {{=machine}}-user-features.scc
\ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files/machine-user-patches.scc b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files/machine-user-patches.scc
new file mode 100644
index 0000000..4c59daa
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files/machine-user-patches.scc
@@ -0,0 +1 @@
+# yocto-bsp-filename {{=machine}}-user-patches.scc
\ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files/machine.cfg b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files/machine.cfg
new file mode 100644
index 0000000..0cc906b
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files/machine.cfg
@@ -0,0 +1,66 @@
+# yocto-bsp-filename {{=machine}}.cfg
+#SOC
+CONFIG_CAVIUM_OCTEON_SOC=y
+CONFIG_CAVIUM_CN63XXP1=y
+CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE=2
+
+#Kernel
+CONFIG_SMP=y
+CONFIG_NR_CPUS=32
+#Executable file formats
+CONFIG_MIPS32_COMPAT=y
+CONFIG_MIPS32_O32=y
+CONFIG_MIPS32_N32=y
+
+
+#PCI
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+
+#I2C
+CONFIG_I2C=y
+CONFIG_I2C_OCTEON=y
+
+CONFIG_HW_RANDOM_OCTEON=y
+
+#SPI
+CONFIG_SPI=y
+CONFIG_SPI_OCTEON=y
+
+#Misc
+CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_AT25=y
+CONFIG_OCTEON_WDT=y
+
+CONFIG_STAGING=y
+
+#Ethernet
+CONFIG_OCTEON_ETHERNET=y
+CONFIG_OCTEON_MGMT_ETHERNET=y
+CONFIG_MDIO_OCTEON=y
+
+#PHY
+CONFIG_MARVELL_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_BCM87XX_PHY=y
+
+
+#USB
+CONFIG_USB=y
+CONFIG_OCTEON_USB=y
+CONFIG_USB_OCTEON_EHCI=y
+CONFIG_USB_OCTEON_OHCI=y
+CONFIG_USB_OCTEON2_COMMON=y
+
+CONFIG_MTD=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_8250_DW=y
+
diff --git a/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files/machine.scc b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files/machine.scc
new file mode 100644
index 0000000..f39dc3e
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/files/machine.scc
@@ -0,0 +1,8 @@
+# yocto-bsp-filename {{=machine}}.scc
+kconf hardware {{=machine}}.cfg
+
+include cfg/usb-mass-storage.scc
+include cfg/fs/vfat.scc
+
+kconf hardware {{=machine}}-user-config.cfg
+include {{=machine}}-user-patches.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/kernel-list.noinstall b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/kernel-list.noinstall
new file mode 100644
index 0000000..a04e6c7
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/kernel-list.noinstall
@@ -0,0 +1,5 @@
+{{ if kernel_choice != "custom": }}
+{{ input type:"boolean" name:"use_default_kernel" prio:"10" msg:"Would you like to use the default (3.14) kernel? (y/n)" default:"y"}}
+
+{{ if kernel_choice != "custom" and use_default_kernel == "n": }}
+{{ input type:"choicelist" name:"kernel_choice" gen:"bsp.kernel.kernels" prio:"10" msg:"Please choose the kernel to use in this BSP:" default:"linux-yocto_3.14"}}
diff --git a/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/linux-yocto-dev.bbappend b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/linux-yocto-dev.bbappend
new file mode 100644
index 0000000..2fa6231
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/linux-yocto-dev.bbappend
@@ -0,0 +1,26 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto-dev": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Would you like SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-standard.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
diff --git a/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/linux-yocto-rt_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/linux-yocto-rt_3.14.bbappend
new file mode 100644
index 0000000..5f8db03
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/linux-yocto-rt_3.14.bbappend
@@ -0,0 +1,33 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto-rt_3.14": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-preempt-rt.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
+
+# uncomment and replace these SRCREVs with the real commit ids once you've had
+# the appropriate changes committed to the upstream linux-yocto repo
+#SRCREV_machine_pn-linux-yocto-rt_{{=machine}} ?= "f35992f80c81dc5fa1a97165dfd5cbb84661f7cb"
+#SRCREV_meta_pn-linux-yocto-rt_{{=machine}} ?= "1b534b2f8bbe9b8a773268cfa30a4850346f6f5f"
+#LINUX_VERSION = "3.14"
diff --git a/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/linux-yocto-tiny_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/linux-yocto-tiny_3.14.bbappend
new file mode 100644
index 0000000..c7e7989
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/linux-yocto-tiny_3.14.bbappend
@@ -0,0 +1,33 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto-tiny_3.14": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-tiny.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
+
+# uncomment and replace these SRCREVs with the real commit ids once you've had
+# the appropriate changes committed to the upstream linux-yocto repo
+#SRCREV_machine_pn-linux-yocto-tiny_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
+#SRCREV_meta_pn-linux-yocto-tiny_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
+#LINUX_VERSION = "3.14"
\ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/linux-yocto-tiny_3.19.bbappend b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/linux-yocto-tiny_3.19.bbappend
new file mode 100644
index 0000000..a9ba0ae
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/linux-yocto-tiny_3.19.bbappend
@@ -0,0 +1,33 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto-tiny_3.19": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-tiny.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
+
+# uncomment and replace these SRCREVs with the real commit ids once you've had
+# the appropriate changes committed to the upstream linux-yocto repo
+#SRCREV_machine_pn-linux-yocto-tiny_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
+#SRCREV_meta_pn-linux-yocto-tiny_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
+#LINUX_VERSION = "3.19"
\ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/linux-yocto_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/linux-yocto_3.14.bbappend
new file mode 100644
index 0000000..fb6cdef
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/linux-yocto_3.14.bbappend
@@ -0,0 +1,33 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto_3.14": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/edgerouter" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/edgerouter" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-standard.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
+
+# uncomment and replace these SRCREVs with the real commit ids once you've had
+# the appropriate changes committed to the upstream linux-yocto repo
+SRCREV_machine_pn-linux-yocto_{{=machine}} ?= "dbe5b52e93ff114b2c0f5da6f6af91f52c18f2b8"
+SRCREV_meta_pn-linux-yocto_{{=machine}} ?= "6eddbf47875ef48ddc5864957a7b63363100782b"
+#LINUX_VERSION = "3.14"
\ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/linux-yocto_3.19.bbappend b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/linux-yocto_3.19.bbappend
new file mode 100644
index 0000000..134aeec
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel/linux/linux-yocto_3.19.bbappend
@@ -0,0 +1,33 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto_3.19": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/edgerouter" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/edgerouter" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-standard.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
+
+# uncomment and replace these SRCREVs with the real commit ids once you've had
+# the appropriate changes committed to the upstream linux-yocto repo
+#SRCREV_machine_pn-linux-yocto_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
+#SRCREV_meta_pn-linux-yocto_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
+#LINUX_VERSION = "3.19"
\ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/.gitignore b/scripts/lib/bsp/substrate/target/arch/powerpc/.gitignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/.gitignore
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/conf/machine/machine.conf b/scripts/lib/bsp/substrate/target/arch/powerpc/conf/machine/machine.conf
new file mode 100644
index 0000000..c94f7f9
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/conf/machine/machine.conf
@@ -0,0 +1,87 @@
+# yocto-bsp-filename {{=machine}}.conf
+#@TYPE: Machine
+#@NAME: {{=machine}}
+
+#@DESCRIPTION: Machine configuration for {{=machine}} systems
+
+TARGET_FPU = ""
+
+{{ input type:"choicelist" name:"tunefile" prio:"40" msg:"Which machine tuning would you like to use?" default:"tune_ppce300c3" }}
+{{ input type:"choice" val:"tune_ppc476" msg:"ppc476 tuning optimizations" }}
+{{ input type:"choice" val:"tune_ppc603e" msg:"ppc603e tuning optimizations" }}
+{{ input type:"choice" val:"tune_ppc7400" msg:"ppc7400 tuning optimizations" }}
+{{ input type:"choice" val:"tune_ppce300c2" msg:"ppce300c2 tuning optimizations" }}
+{{ input type:"choice" val:"tune_ppce300c3" msg:"ppce300c3 tuning optimizations" }}
+{{ input type:"choice" val:"tune_ppce500" msg:"ppce500 tuning optimizations" }}
+{{ input type:"choice" val:"tune_ppce500mc" msg:"ppce500mc tuning optimizations" }}
+{{ input type:"choice" val:"tune_ppce500v2" msg:"ppce500v2 tuning optimizations" }}
+{{ input type:"choice" val:"tune_ppce5500" msg:"ppce5500 tuning optimizations" }}
+{{ input type:"choice" val:"tune_ppce6500" msg:"ppce6500 tuning optimizations" }}
+{{ input type:"choice" val:"tune_power5" msg:"power5 tuning optimizations" }}
+{{ input type:"choice" val:"tune_power6" msg:"power6 tuning optimizations" }}
+{{ input type:"choice" val:"tune_power7" msg:"power7 tuning optimizations" }}
+{{ if tunefile == "tune_ppc476": }}
+include conf/machine/include/tune-ppc476.inc
+{{ if tunefile == "tune_ppc603e": }}
+include conf/machine/include/tune-ppc603e.inc
+{{ if tunefile == "tune_ppc7400": }}
+include conf/machine/include/tune-ppc7400.inc
+{{ if tunefile == "tune_ppce300c2": }}
+include conf/machine/include/tune-ppce300c2.inc
+{{ if tunefile == "tune_ppce300c3": }}
+include conf/machine/include/tune-ppce300c3.inc
+{{ if tunefile == "tune_ppce500": }}
+include conf/machine/include/tune-ppce500.inc
+{{ if tunefile == "tune_ppce500mc": }}
+include conf/machine/include/tune-ppce500mc.inc
+{{ if tunefile == "tune_ppce500v2": }}
+include conf/machine/include/tune-ppce500v2.inc
+{{ if tunefile == "tune_ppce5500": }}
+include conf/machine/include/tune-ppce5500.inc
+{{ if tunefile == "tune_ppce6500": }}
+include conf/machine/include/tune-ppce6500.inc
+{{ if tunefile == "tune_power5": }}
+include conf/machine/include/tune-power5.inc
+{{ if tunefile == "tune_power6": }}
+include conf/machine/include/tune-power6.inc
+{{ if tunefile == "tune_power7": }}
+include conf/machine/include/tune-power7.inc
+
+KERNEL_IMAGETYPE = "uImage"
+
+EXTRA_IMAGEDEPENDS += "u-boot"
+UBOOT_MACHINE_{{=machine}} = "MPC8315ERDB_config"
+
+SERIAL_CONSOLE = "115200 ttyS0"
+
+MACHINE_FEATURES = "keyboard pci ext2 ext3 serial"
+
+{{ if kernel_choice == "custom": preferred_kernel = "linux-yocto-custom" }}
+{{ if kernel_choice == "linux-yocto-dev": preferred_kernel = "linux-yocto-dev" }}
+{{ if kernel_choice == "custom" or kernel_choice == "linux-yocto-dev" : }}
+PREFERRED_PROVIDER_virtual/kernel ?= "{{=preferred_kernel}}"
+
+{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": preferred_kernel = kernel_choice.split('_')[0] }}
+{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": preferred_kernel_version = kernel_choice.split('_')[1] }}
+{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": }}
+PREFERRED_PROVIDER_virtual/kernel ?= "{{=preferred_kernel}}"
+PREFERRED_VERSION_{{=preferred_kernel}} ?= "{{=preferred_kernel_version}}%"
+
+{{ input type:"boolean" name:"xserver" prio:"50" msg:"Do you need support for X? (y/n)" default:"y" }}
+{{ if xserver == "y": }}
+PREFERRED_PROVIDER_virtual/xserver ?= "xserver-xorg"
+XSERVER ?= "xserver-xorg \
+           xf86-input-evdev \
+           xf86-video-fbdev"
+
+PREFERRED_VERSION_u-boot ?= "v2015.01%"
+{{ input type:"edit" name:"uboot_entrypoint" prio:"40" msg:"Please specify a value for UBOOT_ENTRYPOINT:" default:"0x00000000" }}
+UBOOT_ENTRYPOINT = "{{=uboot_entrypoint}}"
+
+{{ input type:"edit" name:"kernel_devicetree" prio:"40" msg:"Please specify a [arch/powerpc/boot/dts/xxx] value for KERNEL_DEVICETREE:" default:"mpc8315erdb.dts" }}
+KERNEL_DEVICETREE = "${S}/arch/powerpc/boot/dts/{{=kernel_devicetree}}"
+
+MACHINE_EXTRA_RRECOMMENDS = " kernel-modules"
+
+IMAGE_FSTYPES ?= "jffs2 tar.bz2"
+JFFS2_ERASEBLOCK = "0x4000"
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files.noinstall b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files.noinstall
new file mode 100644
index 0000000..1e0d92c
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files.noinstall
@@ -0,0 +1 @@
+# yocto-bsp-dirname {{ if kernel_choice != "custom": }} files
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files/machine-preempt-rt.scc b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files/machine-preempt-rt.scc
new file mode 100644
index 0000000..40c9267
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files/machine-preempt-rt.scc
@@ -0,0 +1,10 @@
+# yocto-bsp-filename {{=machine}}-preempt-rt.scc
+define KMACHINE {{=machine}}
+define KTYPE preempt-rt
+define KARCH powerpc
+
+include {{=map_preempt_rt_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
+{{ if need_new_kbranch == "y": }}
+branch {{=machine}}
+
+include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files/machine-standard.scc b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files/machine-standard.scc
new file mode 100644
index 0000000..7a1d35b
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files/machine-standard.scc
@@ -0,0 +1,10 @@
+# yocto-bsp-filename {{=machine}}-standard.scc
+define KMACHINE {{=machine}}
+define KTYPE standard
+define KARCH powerpc
+
+include {{=map_standard_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
+{{ if need_new_kbranch == "y": }}
+branch {{=machine}}
+
+include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files/machine-tiny.scc b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files/machine-tiny.scc
new file mode 100644
index 0000000..1bf94b2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files/machine-tiny.scc
@@ -0,0 +1,10 @@
+# yocto-bsp-filename {{=machine}}-tiny.scc
+define KMACHINE {{=machine}}
+define KTYPE tiny
+define KARCH powerpc
+
+include {{=map_tiny_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
+{{ if need_new_kbranch == "y": }}
+branch {{=machine}}
+
+include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files/machine-user-config.cfg b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files/machine-user-config.cfg
new file mode 100644
index 0000000..47489e4
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files/machine-user-config.cfg
@@ -0,0 +1 @@
+# yocto-bsp-filename {{=machine}}-user-config.cfg
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files/machine-user-features.scc b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files/machine-user-features.scc
new file mode 100644
index 0000000..582759e
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files/machine-user-features.scc
@@ -0,0 +1 @@
+# yocto-bsp-filename {{=machine}}-user-features.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files/machine-user-patches.scc b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files/machine-user-patches.scc
new file mode 100644
index 0000000..97f747f
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files/machine-user-patches.scc
@@ -0,0 +1 @@
+# yocto-bsp-filename {{=machine}}-user-patches.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files/machine.cfg b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files/machine.cfg
new file mode 100644
index 0000000..5bfe1fe
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files/machine.cfg
@@ -0,0 +1,164 @@
+# yocto-bsp-filename {{=machine}}.cfg
+..........................................................................
+.                                WARNING
+.
+. This file is a kernel configuration fragment, and not a full kernel
+. configuration file.  The final kernel configuration is made up of
+. an assembly of processed fragments, each of which is designed to
+. capture a specific part of the final configuration (e.g. platform
+. configuration, feature configuration, and board specific hardware
+. configuration).  For more information on kernel configuration, please
+. consult the product documentation.
+.
+..........................................................................
+CONFIG_PPC32=y
+CONFIG_PPC_OF=y
+CONFIG_PPC_UDBG_16550=y
+
+#
+# Processor support
+#
+CONFIG_PPC_83xx=y
+
+#
+# Platform support
+#
+CONFIG_MPC831x_RDB=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_PPC_PMAC is not set
+
+#
+# Bus options
+#
+CONFIG_PCI=y
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_PHYSMAP_OF=y
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=y
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_GIANFAR=y
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_8xxx_WDT=y
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_MPC=y
+
+CONFIG_SENSORS_LM75=y
+
+CONFIG_MISC_DEVICES=y
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_EEPROM_AT24=y
+
+#
+# SPI support
+#
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_MPC8xxx=y
+
+#
+# SPI Protocol Masters
+#
+CONFIG_HWMON=y
+
+#
+# SCSI device support
+#
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_SCSI_LOGGING=y
+
+CONFIG_ATA=y
+CONFIG_ATA_VERBOSE_ERROR=y
+CONFIG_SATA_FSL=y
+CONFIG_ATA_SFF=y
+
+#
+# USB support
+#
+CONFIG_USB=m
+CONFIG_USB_DEVICEFS=y
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_FSL=y
+CONFIG_USB_STORAGE=m
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_CLASS=y
+
+#
+# I2C RTC drivers
+#
+CONFIG_RTC_DRV_DS1307=y
+
+CONFIG_KGDB_8250=m
+
+CONFIG_CRYPTO_DEV_TALITOS=m
+
+CONFIG_FSL_DMA=y
+
+CONFIG_MMC=y
+CONFIG_MMC_SPI=m
+
+CONFIG_USB_FSL_MPH_DR_OF=y
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files/machine.scc b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files/machine.scc
new file mode 100644
index 0000000..7aac8b0
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/files/machine.scc
@@ -0,0 +1,10 @@
+# yocto-bsp-filename {{=machine}}.scc
+kconf hardware {{=machine}}.cfg
+
+include cfg/usb-mass-storage.scc
+include cfg/fs/vfat.scc
+
+include cfg/dmaengine.scc
+
+kconf hardware {{=machine}}-user-config.cfg
+include {{=machine}}-user-patches.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/kernel-list.noinstall b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/kernel-list.noinstall
new file mode 100644
index 0000000..811d695
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/kernel-list.noinstall
@@ -0,0 +1,5 @@
+{{ if kernel_choice != "custom": }}
+{{ input type:"boolean" name:"use_default_kernel" prio:"10" msg:"Would you like to use the default (3.19) kernel? (y/n)" default:"y"}}
+
+{{ if kernel_choice != "custom" and use_default_kernel == "n": }}
+{{ input type:"choicelist" name:"kernel_choice" gen:"bsp.kernel.kernels" prio:"10" msg:"Please choose the kernel to use in this BSP:" default:"linux-yocto_3.19"}}
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/linux-yocto-dev.bbappend b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/linux-yocto-dev.bbappend
new file mode 100644
index 0000000..2fa6231
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/linux-yocto-dev.bbappend
@@ -0,0 +1,26 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto-dev": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Would you like SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-standard.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/linux-yocto-rt_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/linux-yocto-rt_3.14.bbappend
new file mode 100644
index 0000000..7a25446
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/linux-yocto-rt_3.14.bbappend
@@ -0,0 +1,33 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto-rt_3.14": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-preempt-rt.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
+
+# uncomment and replace these SRCREVs with the real commit ids once you've had
+# the appropriate changes committed to the upstream linux-yocto repo
+#SRCREV_machine_pn-linux-yocto-rt_{{=machine}} ?= "f35992f80c81dc5fa1a97165dfd5cbb84661f7cb"
+#SRCREV_meta_pn-linux-yocto-rt_{{=machine}} ?= "1b534b2f8bbe9b8a773268cfa30a4850346f6f5f"
+#LINUX_VERSION = "3.14"
\ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/linux-yocto-tiny_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/linux-yocto-tiny_3.14.bbappend
new file mode 100644
index 0000000..471ccbc
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/linux-yocto-tiny_3.14.bbappend
@@ -0,0 +1,33 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto-tiny_3.14": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-tiny.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
+
+# uncomment and replace these SRCREVs with the real commit ids once you've had
+# the appropriate changes committed to the upstream linux-yocto repo
+#SRCREV_machine_pn-linux-yocto-tiny_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
+#SRCREV_meta_pn-linux-yocto-tiny_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
+#LINUX_VERSION = "3.14"
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/linux-yocto-tiny_3.19.bbappend b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/linux-yocto-tiny_3.19.bbappend
new file mode 100644
index 0000000..4de82fa
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/linux-yocto-tiny_3.19.bbappend
@@ -0,0 +1,33 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto-tiny_3.19": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-tiny.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
+
+# uncomment and replace these SRCREVs with the real commit ids once you've had
+# the appropriate changes committed to the upstream linux-yocto repo
+#SRCREV_machine_pn-linux-yocto-tiny_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
+#SRCREV_meta_pn-linux-yocto-tiny_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
+#LINUX_VERSION = "3.19"
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/linux-yocto_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/linux-yocto_3.14.bbappend
new file mode 100644
index 0000000..e688384
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/linux-yocto_3.14.bbappend
@@ -0,0 +1,33 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto_3.14": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-standard.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
+
+# uncomment and replace these SRCREVs with the real commit ids once you've had
+# the appropriate changes committed to the upstream linux-yocto repo
+#SRCREV_machine_pn-linux-yocto_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
+#SRCREV_meta_pn-linux-yocto_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
+#LINUX_VERSION = "3.14"
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/linux-yocto_3.19.bbappend b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/linux-yocto_3.19.bbappend
new file mode 100644
index 0000000..ded9e85
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/linux-yocto_3.19.bbappend
@@ -0,0 +1,33 @@
+# yocto-bsp-filename {{ if kernel_choice == "linux-yocto_3.19": }} this
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR := "${PR}.1"
+
+COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
+
+{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
+
+{{ if need_new_kbranch == "y": }}
+{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
+
+{{ if need_new_kbranch == "n": }}
+KBRANCH_{{=machine}}  = "{{=existing_kbranch}}"
+
+{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
+{{ if smp == "y": }}
+KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
+
+SRC_URI += "file://{{=machine}}-standard.scc \
+            file://{{=machine}}-user-config.cfg \
+            file://{{=machine}}-user-patches.scc \
+            file://{{=machine}}-user-features.scc \
+           "
+
+# uncomment and replace these SRCREVs with the real commit ids once you've had
+# the appropriate changes committed to the upstream linux-yocto repo
+#SRCREV_machine_pn-linux-yocto_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
+#SRCREV_meta_pn-linux-yocto_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
+#LINUX_VERSION = "3.19"
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/conf/machine/machine.conf b/scripts/lib/bsp/substrate/target/arch/qemu/conf/machine/machine.conf
new file mode 100644
index 0000000..67e1cbd
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/conf/machine/machine.conf
@@ -0,0 +1,74 @@
+# yocto-bsp-filename {{=machine}}.conf
+#@TYPE: Machine
+#@NAME: {{=machine}}
+
+#@DESCRIPTION: Machine configuration for {{=machine}} systems
+
+{{ if kernel_choice == "custom": preferred_kernel = "linux-yocto-custom" }}
+{{ if kernel_choice == "linux-yocto-dev": preferred_kernel = "linux-yocto-dev" }}
+{{ if kernel_choice == "custom" or kernel_choice == "linux-yocto-dev" : }}
+PREFERRED_PROVIDER_virtual/kernel ?= "{{=preferred_kernel}}"
+
+{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": preferred_kernel = kernel_choice.split('_')[0] }}
+{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": preferred_kernel_version = kernel_choice.split('_')[1] }}
+{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": }}
+PREFERRED_PROVIDER_virtual/kernel ?= "{{=preferred_kernel}}"
+PREFERRED_VERSION_{{=preferred_kernel}} ?= "{{=preferred_kernel_version}}%"
+
+{{ if qemuarch == "i386" or qemuarch == "x86_64": }}
+PREFERRED_PROVIDER_virtual/xserver ?= "xserver-xorg"
+PREFERRED_PROVIDER_virtual/libgl ?= "mesa"
+PREFERRED_PROVIDER_virtual/libgles1 ?= "mesa"
+PREFERRED_PROVIDER_virtual/libgles2 ?= "mesa"
+
+{{ input type:"choicelist" name:"qemuarch" prio:"5" msg:"Which qemu architecture would you like to use?" default:"i386" }}
+{{ input type:"choice" val:"i386" msg:"i386    (32-bit)" }}
+{{ input type:"choice" val:"x86_64" msg:"x86_64  (64-bit)" }}
+{{ input type:"choice" val:"arm" msg:"ARM     (32-bit)" }}
+{{ input type:"choice" val:"powerpc" msg:"PowerPC (32-bit)" }}
+{{ input type:"choice" val:"mips" msg:"MIPS    (32-bit)" }}
+{{ input type:"choice" val:"mips64" msg:"MIPS64  (64-bit)" }}
+{{ if qemuarch == "i386": }}
+require conf/machine/include/qemu.inc
+require conf/machine/include/tune-i586.inc
+{{ if qemuarch == "x86_64": }}
+require conf/machine/include/qemu.inc
+DEFAULTTUNE ?= "core2-64"
+require conf/machine/include/tune-core2.inc
+{{ if qemuarch == "arm": }}
+require conf/machine/include/qemu.inc
+require conf/machine/include/tune-arm926ejs.inc
+{{ if qemuarch == "powerpc": }}
+require conf/machine/include/qemu.inc
+require conf/machine/include/tune-ppc7400.inc
+{{ if qemuarch == "mips": }}
+require conf/machine/include/qemu.inc
+require conf/machine/include/tune-mips32.inc
+{{ if qemuarch == "mips64": }}
+require conf/machine/include/qemu.inc
+require conf/machine/include/tune-mips64.inc
+
+{{ if qemuarch == "i386" or qemuarch == "x86_64": }}
+MACHINE_FEATURES += "x86"
+KERNEL_IMAGETYPE = "bzImage"
+SERIAL_CONSOLE = "115200 ttyS0"
+XSERVER = "xserver-xorg \
+           ${@bb.utils.contains('DISTRO_FEATURES', 'opengl', 'mesa-driver-swrast', '', d)} \
+           xf86-input-vmmouse \
+           xf86-input-keyboard \
+           xf86-input-evdev \
+           xf86-video-vmware"
+
+{{ if qemuarch == "arm": }}
+KERNEL_IMAGETYPE = "zImage"
+SERIAL_CONSOLE = "115200 ttyAMA0"
+
+{{ if qemuarch == "powerpc": }}
+KERNEL_IMAGETYPE = "vmlinux"
+SERIAL_CONSOLE = "115200 ttyS0"
+
+{{ if qemuarch == "mips" or qemuarch == "mips64": }}
+KERNEL_IMAGETYPE = "vmlinux"
+KERNEL_ALT_IMAGETYPE = "vmlinux.bin"
+SERIAL_CONSOLE = "115200 ttyS0"
+MACHINE_EXTRA_RRECOMMENDS = " kernel-modules"
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-core/init-ifupdown/init-ifupdown/machine.noinstall b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-core/init-ifupdown/init-ifupdown/machine.noinstall
new file mode 100644
index 0000000..b442d02
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-core/init-ifupdown/init-ifupdown/machine.noinstall
@@ -0,0 +1 @@
+# yocto-bsp-dirname {{=machine}}
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-core/init-ifupdown/init-ifupdown/machine/interfaces b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-core/init-ifupdown/init-ifupdown/machine/interfaces
new file mode 100644
index 0000000..1696776
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-core/init-ifupdown/init-ifupdown/machine/interfaces
@@ -0,0 +1,5 @@
+# /etc/network/interfaces -- configuration file for ifup(8), ifdown(8)
+ 
+# The loopback interface
+auto lo
+iface lo inet loopback
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-core/init-ifupdown/init-ifupdown_1.0.bbappend b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-core/init-ifupdown/init-ifupdown_1.0.bbappend
new file mode 100644
index 0000000..72d991c
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-core/init-ifupdown/init-ifupdown_1.0.bbappend
@@ -0,0 +1 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-graphics/xorg-xserver/xserver-xf86-config/machine.noinstall b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-graphics/xorg-xserver/xserver-xf86-config/machine.noinstall
new file mode 100644
index 0000000..b442d02
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-graphics/xorg-xserver/xserver-xf86-config/machine.noinstall
@@ -0,0 +1 @@
+# yocto-bsp-dirname {{=machine}}
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-graphics/xorg-xserver/xserver-xf86-config/machine/xorg.conf b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-graphics/xorg-xserver/xserver-xf86-config/machine/xorg.conf
new file mode 100644
index 0000000..3bdde79
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-graphics/xorg-xserver/xserver-xf86-config/machine/xorg.conf
@@ -0,0 +1,77 @@
+
+Section "Files"
+EndSection
+
+Section "InputDevice"
+    Identifier    "Generic Keyboard"
+    Driver        "evdev"
+    Option        "CoreKeyboard"
+    Option        "Device"      "/dev/input/by-path/platform-i8042-serio-0-event-kbd"
+    Option        "XkbRules"    "xorg"
+    Option        "XkbModel"    "evdev"
+    Option        "XkbLayout"    "us"
+EndSection
+
+Section "InputDevice"
+    Identifier    "Configured Mouse"
+{{ if qemuarch == "arm" or qemuarch == "powerpc" or qemuarch == "mips" or qemuarch == "mips64": }}
+    Driver        "mouse"
+{{ if qemuarch == "i386" or qemuarch == "x86_64": }}
+    Driver        "vmmouse"
+
+    Option        "CorePointer"
+    Option        "Device"        "/dev/input/mice"
+    Option        "Protocol"        "ImPS/2"
+    Option        "ZAxisMapping"        "4 5"
+    Option        "Emulate3Buttons"    "true"
+EndSection
+
+Section "InputDevice"
+    Identifier    "Qemu Tablet"
+    Driver        "evdev"
+    Option        "CorePointer"
+    Option        "Device"        "/dev/input/touchscreen0"
+    Option        "USB"           "on"
+EndSection
+
+Section "Device"
+    Identifier    "Graphics Controller"
+{{ if qemuarch == "arm" or qemuarch == "powerpc" or qemuarch == "mips" or qemuarch == "mips64": }}
+    Driver        "fbdev"
+{{ if qemuarch == "i386" or qemuarch == "x86_64": }}
+    Driver        "vmware"
+
+EndSection
+
+Section "Monitor"
+    Identifier    "Generic Monitor"
+    Option        "DPMS"
+    # 1024x600 59.85 Hz (CVT) hsync: 37.35 kHz; pclk: 49.00 MHz
+    Modeline "1024x600_60.00"   49.00  1024 1072 1168 1312  600 603 613 624 -hsync +vsync
+    # 640x480 @ 60Hz (Industry standard) hsync: 31.5kHz
+    ModeLine "640x480"    25.2  640  656  752  800    480  490  492  525 -hsync -vsync
+    # 640x480 @ 72Hz (VESA) hsync: 37.9kHz
+    ModeLine "640x480"    31.5  640  664  704  832    480  489  491  520 -hsync -vsync
+    # 640x480 @ 75Hz (VESA) hsync: 37.5kHz
+    ModeLine "640x480"    31.5  640  656  720  840    480  481  484  500 -hsync -vsync
+    # 640x480 @ 85Hz (VESA) hsync: 43.3kHz
+    ModeLine "640x480"    36.0  640  696  752  832    480  481  484  509 -hsync -vsync
+EndSection
+
+Section "Screen"
+    Identifier    "Default Screen"
+    Device        "Graphics Controller"
+    Monitor        "Generic Monitor"
+    SubSection "Display"
+        Modes     "640x480"
+    EndSubSection
+EndSection
+
+Section "ServerLayout"
+    Identifier    "Default Layout"
+    Screen        "Default Screen"
+    InputDevice    "Generic Keyboard"
+    # InputDevice    "Configured Mouse"
+    InputDevice    "QEMU Tablet"
+    Option         "AllowEmptyInput" "no"
+EndSection
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-graphics/xorg-xserver/xserver-xf86-config_0.1.bbappend b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-graphics/xorg-xserver/xserver-xf86-config_0.1.bbappend
new file mode 100644
index 0000000..72d991c
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-graphics/xorg-xserver/xserver-xf86-config_0.1.bbappend
@@ -0,0 +1 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/files.noinstall b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/files.noinstall
new file mode 100644
index 0000000..0fb5283
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/files.noinstall
@@ -0,0 +1 @@
+# yocto-bsp-dirname {{ if kernel_choice != "custom": }} files
\ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/files/machine-preempt-rt.scc b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/files/machine-preempt-rt.scc
new file mode 100644
index 0000000..6aaffb8
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/files/machine-preempt-rt.scc
@@ -0,0 +1,10 @@
+# yocto-bsp-filename {{=machine}}-preempt-rt.scc
+define KMACHINE {{=machine}}
+define KTYPE preempt-rt
+define KARCH {{=qemuarch}}
+
+include {{=map_preempt_rt_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
+{{ if need_new_kbranch == "y": }}
+branch {{=machine}}
+
+include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/files/machine-standard.scc b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/files/machine-standard.scc
new file mode 100644
index 0000000..d2a03ec
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/files/machine-standard.scc
@@ -0,0 +1,19 @@
+# yocto-bsp-filename {{=machine}}-standard.scc
+define KMACHINE {{=machine}}
+define KTYPE standard
+define KARCH {{=qemuarch}}
+
+{{ if qemuarch == "i386" or qemuarch == "x86_64": }}
+include {{=map_standard_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
+{{ if qemuarch == "arm": }}
+include bsp/arm-versatile-926ejs/arm-versatile-926ejs-standard
+{{ if qemuarch == "powerpc": }}
+include bsp/qemu-ppc32/qemu-ppc32-standard
+{{ if qemuarch == "mips": }}
+include bsp/mti-malta32/mti-malta32-be-standard
+{{ if qemuarch == "mips64": }}
+include bsp/mti-malta64/mti-malta64-be-standard
+{{ if need_new_kbranch == "y": }}
+branch {{=machine}}
+
+include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/files/machine-tiny.scc b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/files/machine-tiny.scc
new file mode 100644
index 0000000..6c098fe
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/files/machine-tiny.scc
@@ -0,0 +1,10 @@
+# yocto-bsp-filename {{=machine}}-tiny.scc
+define KMACHINE {{=machine}}
+define KTYPE tiny
+define KARCH {{=qemuarch}}
+
+include {{=map_tiny_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
+{{ if need_new_kbranch == "y": }}
+branch {{=machine}}
+
+include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/files/machine-user-config.cfg b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/files/machine-user-config.cfg
new file mode 100644
index 0000000..69efdcc
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/files/machine-user-config.cfg
@@ -0,0 +1 @@
+# yocto-bsp-filename {{=machine}}-user-config.cfg
\ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/files/machine-user-features.scc b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/files/machine-user-features.scc
new file mode 100644
index 0000000..582759e
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/files/machine-user-features.scc
@@ -0,0 +1 @@
+# yocto-bsp-filename {{=machine}}-user-features.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/files/machine-user-patches.scc b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/files/machine-user-patches.scc
new file mode 100644
index 0000000..4c59daa
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/files/machine-user-patches.scc
@@ -0,0 +1 @@
+# yocto-bsp-filename {{=machine}}-user-patches.scc
\ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/files/machine.cfg b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/files/machine.cfg
new file mode 100644
index 0000000..d560784
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/files/machine.cfg
@@ -0,0 +1 @@
+# yocto-bsp-filename {{=machine}}.cfg
\ No newline at end of file
diff --git a/scrip