diff --git a/libc/kernel/tools/kernel.py b/libc/kernel/tools/kernel.py
new file mode 100644
index 0000000..9d9b5f0
--- /dev/null
+++ b/libc/kernel/tools/kernel.py
@@ -0,0 +1,338 @@
+# this file contains definitions related to the Linux kernel itself
+#
+
+# list here the macros that you know are always defined/undefined when including
+# the kernel headers
+#
+import sys, cpp, re, os.path, string, time
+from defaults import *
+
+verboseSearch = 0
+verboseFind   = 0
+
+########################################################################
+########################################################################
+#####                                                              #####
+#####           H E A D E R   S C A N N E R                        #####
+#####                                                              #####
+########################################################################
+########################################################################
+
+
+class HeaderScanner:
+    """a class used to non-recursively detect which Linux kernel headers are
+       used by a given set of input source files"""
+
+    # to use the HeaderScanner, do the following:
+    #
+    #    scanner = HeaderScanner()
+    #    for path in <your list of files>:
+    #        scanner.parseFile(path)
+    #
+    #    # get the set of Linux headers included by your files
+    #    headers = scanner.getHeaders()
+    #
+    #    # get the set of of input files that do include Linux headers
+    #    files   = scanner.getFiles()
+    #
+    #    note that the result of getHeaders() is a set of strings, each one
+    #    corresponding to a non-bracketed path name, e.g.:
+    #
+    #        set("linux/types","asm/types.h")
+    #
+
+    # the default algorithm is pretty smart and will analyze the input
+    # files with a custom C pre-processor in order to optimize out macros,
+    # get rid of comments, empty lines, etc..
+    #
+    # this avoids many annoying false positives... !!
+    #
+
+    # this regular expression is used to detect include paths that relate to
+    # the kernel, by default, it selects one of:
+    #    <linux/*>
+    #    <asm/*>
+    #    <asm-generic/*>
+    #    <mtd/*>
+    #
+    re_combined =\
+       re.compile(r"^.*<((%s)/[\d\w_\+\.\-/]*)>.*$" % string.join(kernel_dirs,"|") )
+    # some kernel files choose to include files with relative paths (x86 32/64
+    # dispatch for instance)
+    re_rel_dir = re.compile(r'^.*"([\d\w_\+\.\-/]+)".*$')
+
+    def __init__(self,config={}):
+        """initialize a HeaderScanner"""
+        self.reset()
+        self.config = config
+
+    def reset(self,config={}):
+        self.files    = set()  # set of files being parsed for headers
+        self.headers  = {}     # maps headers to set of users
+        self.config   = config
+
+    def checkInclude(self, line, from_file, kernel_root=None):
+        relative = False
+        m = HeaderScanner.re_combined.match(line)
+        if kernel_root and not m:
+            m = HeaderScanner.re_rel_dir.match(line)
+            relative = True
+        if not m: return
+
+        header = m.group(1)
+        if from_file:
+            self.files.add(from_file)
+            if kernel_root and relative:
+                hdr_dir = os.path.realpath(os.path.dirname(from_file))
+                hdr_dir = hdr_dir.replace("%s/" % os.path.realpath(kernel_root),
+                                          "")
+                if hdr_dir:
+                    _prefix = "%s/" % hdr_dir
+                else:
+                    _prefix = ""
+                header = "%s%s" % (_prefix, header)
+
+        if not header in self.headers:
+            self.headers[header] = set()
+
+        if from_file:
+            if verboseFind:
+                print "=== %s uses %s" % (from_file, header)
+            self.headers[header].add(from_file)
+
+    def parseFile(self, path, arch=None, kernel_root=None):
+        """parse a given file for Linux headers"""
+        if not os.path.exists(path):
+            return
+
+        # since tokenizing the file is very slow, we first try a quick grep
+        # to see if this returns any meaningful results. only if this is true
+        # do we do the tokenization"""
+        try:
+            f = open(path, "rt")
+        except:
+            print "!!! can't read '%s'" % path
+            return
+
+        hasIncludes = False
+        for line in f:
+            if (HeaderScanner.re_combined.match(line) or
+                (kernel_root and HeaderScanner.re_rel_dir.match(line))):
+                hasIncludes = True
+                break
+
+        if not hasIncludes:
+            if verboseSearch: print "::: " + path
+            return
+
+        if verboseSearch: print "*** " + path
+
+        list = cpp.BlockParser().parseFile(path)
+        if list:
+            #list.removePrefixed("CONFIG_",self.config)
+            macros = kernel_known_macros.copy()
+            if kernel_root:
+                macros.update(self.config)
+                if arch and arch in kernel_default_arch_macros:
+                    macros.update(kernel_default_arch_macros[arch])
+            list.optimizeMacros(macros)
+            list.optimizeIf01()
+            includes = list.findIncludes()
+            for inc in includes:
+                self.checkInclude(inc, path, kernel_root)
+
+    def getHeaders(self):
+        """return the set of all needed kernel headers"""
+        return set(self.headers.keys())
+
+    def getHeaderUsers(self,header):
+        """return the set of all users for a given header"""
+        return set(self.headers.get(header))
+
+    def getAllUsers(self):
+        """return a dictionary mapping heaaders to their user set"""
+        return self.headers.copy()
+
+    def getFiles(self):
+        """returns the set of files that do include kernel headers"""
+        return self.files.copy()
+
+
+##########################################################################
+##########################################################################
+#####                                                                #####
+#####           H E A D E R   F I N D E R                            #####
+#####                                                                #####
+##########################################################################
+##########################################################################
+
+
+class KernelHeaderFinder:
+    """a class used to scan the kernel headers themselves."""
+
+    # this is different
+    #  from a HeaderScanner because we need to translate the path returned by
+    #  HeaderScanner.getHeaders() into possibly architecture-specific ones.
+    #
+    # for example, <asm/XXXX.h> needs to be translated in <asm-ARCH/XXXX.h>
+    # where ARCH is appropriately chosen
+
+    # here's how to use this:
+    #
+    #    scanner = HeaderScanner()
+    #    for path in <your list of user sources>:
+    #        scanner.parseFile(path)
+    #
+    #    used_headers = scanner.getHeaders()
+    #    finder       = KernelHeaderFinder(used_headers, [ "arm", "x86" ],
+    #                                      "<kernel_include_path>")
+    #    all_headers  = finder.scanForAllArchs()
+    #
+    #   not that the result of scanForAllArchs() is a list of relative
+    #   header paths that are not bracketed
+    #
+
+    def __init__(self,headers,archs,kernel_root,kernel_config):
+        """init a KernelHeaderScanner,
+
+            'headers' is a list or set of headers,
+            'archs' is a list of architectures
+            'kernel_root' is the path to the 'include' directory
+             of your original kernel sources
+        """
+
+        if len(kernel_root) > 0 and kernel_root[-1] != "/":
+            kernel_root += "/"
+        #print "using kernel_root %s" % kernel_root
+        self.archs         = archs
+        self.searched      = set(headers)
+        self.kernel_root   = kernel_root
+        self.kernel_config = kernel_config
+        self.needed        = {}
+        self.setArch(arch=None)
+
+    def setArch(self,arch=None):
+        self.curr_arch = arch
+        self.arch_headers = set()
+        if arch:
+            self.prefix = "asm-%s/" % arch
+        else:
+            self.prefix = None
+
+    def pathFromHeader(self,header):
+        path = header
+        if self.prefix and path.startswith("asm/"):
+            path = "%s%s" % (self.prefix, path[4:])
+        return path
+
+    def pathToHeader(self,path):
+        if self.prefix and path.startswith(self.prefix):
+            path = "asm/%s" % path[len(self.prefix):]
+        return "%s" % path
+
+    def setSearchedHeaders(self,headers):
+        self.searched = set(headers)
+
+    def scanForArch(self):
+        fparser   = HeaderScanner(config=self.kernel_config)
+        workqueue = []
+        needed    = {}
+        for h in self.searched:
+            path = self.pathFromHeader(h)
+            if not path in needed:
+                needed[path] = set()
+            workqueue.append(path)
+
+        i = 0
+        while i < len(workqueue):
+            path = workqueue[i]
+            i   += 1
+            fparser.parseFile(self.kernel_root + path,
+                              arch=self.curr_arch, kernel_root=self.kernel_root)
+            for used in fparser.getHeaders():
+                path  = self.pathFromHeader(used)
+                if not path in needed:
+                    needed[path] = set()
+                    workqueue.append(path)
+                for user in fparser.getHeaderUsers(used):
+                    needed[path].add(user)
+
+        # now copy the arch-specific headers into the global list
+        for header in needed.keys():
+            users = needed[header]
+            if not header in self.needed:
+                self.needed[header] = set()
+
+            for user in users:
+                self.needed[header].add(user)
+
+    def scanForAllArchs(self):
+        """scan for all architectures and return the set of all needed kernel headers"""
+        for arch in self.archs:
+            self.setArch(arch)
+            self.scanForArch()
+
+        return set(self.needed.keys())
+
+    def getHeaderUsers(self,header):
+        """return the set of all users for a given header"""
+        return set(self.needed[header])
+
+    def getArchHeaders(self,arch):
+        """return the set of all <asm/...> headers required by a given architecture"""
+        return set()  # XXX: TODO
+
+#####################################################################################
+#####################################################################################
+#####                                                                           #####
+#####           C O N F I G   P A R S E R                                       #####
+#####                                                                           #####
+#####################################################################################
+#####################################################################################
+
+class ConfigParser:
+    """a class used to parse the Linux kernel .config file"""
+    re_CONFIG_ = re.compile(r"^(CONFIG_\w+)=(.*)$")
+
+    def __init__(self):
+        self.items = {}
+        self.duplicates = False
+
+    def parseLine(self,line):
+        line = string.strip(line)
+
+        # skip empty and comment lines
+        if len(line) == 0 or line[0] == "#":
+            return
+
+        m = ConfigParser.re_CONFIG_.match(line)
+        if not m: return
+
+        name  = m.group(1)
+        value = m.group(2)
+
+        if name in self.items:  # aarg, duplicate value
+            self.duplicates = True
+
+        self.items[name] = value
+
+    def parseFile(self,path):
+        f = file(path, "r")
+        for line in f:
+            if len(line) > 0:
+                if line[-1] == "\n":
+                    line = line[:-1]
+                    if len(line) > 0 and line[-1] == "\r":
+                        line = line[:-1]
+                self.parseLine(line)
+        f.close()
+
+    def getDefinitions(self):
+        """retrieve a dictionary containing definitions for CONFIG_XXX"""
+        return self.items.copy()
+
+    def __repr__(self):
+        return repr(self.items)
+
+    def __str__(self):
+        return str(self.items)
