diff --git a/metropolis/pkg/kmod/modinfo.go b/metropolis/pkg/kmod/modinfo.go
new file mode 100644
index 0000000..adaf5d1
--- /dev/null
+++ b/metropolis/pkg/kmod/modinfo.go
@@ -0,0 +1,206 @@
+package kmod
+
+import (
+	"bufio"
+	"bytes"
+	"debug/elf"
+	"errors"
+	"fmt"
+	"io"
+	"strings"
+)
+
+// ModuleInfo contains Linux kernel module metadata. It maps keys to a list
+// of values. For known keys accessor functions are provided.
+type ModuleInfo map[string][]string
+
+// Get returns the first value of the given key or an empty string if the key
+// does not exist.
+func (i ModuleInfo) Get(key string) string {
+	if len(i[key]) > 0 {
+		return i[key][0]
+	}
+	return ""
+}
+
+// Name returns the name of the module as defined in kbuild.
+func (i ModuleInfo) Name() string {
+	return i.Get("name")
+}
+
+// Authors returns the list of a authors of the module.
+func (i ModuleInfo) Authors() []string {
+	return i["author"]
+}
+
+// Description returns a human-readable description of the module or an empty
+// string if it is not available.
+func (i ModuleInfo) Description() string {
+	return i.Get("description")
+}
+
+// GetDependencies returns a list of module names which need to be loaded
+// before this one.
+func (i ModuleInfo) GetDependencies() []string {
+	if len(i["depends"]) == 1 && i["depends"][0] == "" {
+		return nil
+	}
+	return i["depends"]
+}
+
+type OptionalDependencies struct {
+	// Pre contains a list of module names to be optionally loaded before the
+	// module itself.
+	Pre []string
+	// Post contains a list of module names to be optionally loaded after the
+	// module itself.
+	Post []string
+}
+
+// GetOptionalDependencies returns a set of modules which are recommended to
+// be loaded before and after this module. These are optional, but enhance
+// the functionality of this module.
+func (i ModuleInfo) GetOptionalDependencies() OptionalDependencies {
+	var out OptionalDependencies
+	for _, s := range i["softdep"] {
+		tokens := strings.Fields(s)
+		const (
+			MODE_IDLE = 0
+			MODE_PRE  = 1
+			MODE_POST = 2
+		)
+		var state int = MODE_IDLE
+		for _, token := range tokens {
+			switch token {
+			case "pre:":
+				state = MODE_PRE
+			case "post:":
+				state = MODE_POST
+			default:
+				switch state {
+				case MODE_PRE:
+					out.Pre = append(out.Pre, token)
+				case MODE_POST:
+					out.Post = append(out.Post, token)
+				default:
+				}
+			}
+		}
+	}
+	return out
+}
+
+// Aliases returns a list of match expressions for matching devices handled
+// by this module. Every returned string consists of a literal as well as '*'
+// wildcards matching one or more characters. These should be matched against
+// the kobject MODALIAS field or the modalias sysfs file.
+func (i ModuleInfo) Aliases() []string {
+	return i["alias"]
+}
+
+// Firmware returns a list of firmware file paths required by this module.
+// These paths are usually relative to the root of a linux-firmware install
+// unless the firmware is non-redistributable.
+func (i ModuleInfo) Firmware() []string {
+	return i["firmware"]
+}
+
+// License returns the licenses use of this module is governed by. For mainline
+// modules, the list of valid license strings is documented in the kernel's
+// Documentation/process/license-rules.rst file under the `MODULE_LICENSE`
+// section.
+func (i ModuleInfo) Licenses() []string {
+	return i["license"]
+}
+
+// IsInTree returns true if the module was built in the Linux source tree and
+// not externally. This does not necessarily mean that the module is in the
+// mainline kernel.
+func (i ModuleInfo) IsInTree() bool {
+	return i.Get("intree") == "Y"
+}
+
+// vermagic and retpoline are intentionally not exposed here, if you need them
+// you should know how to get them out of the map yourself as AFAIK these
+// are not a stable interface and most programs should not process them.
+
+func nullByteSplit(data []byte, atEOF bool) (advance int, token []byte, err error) {
+	if atEOF && len(data) == 0 {
+		return 0, nil, nil
+	}
+	if i := bytes.IndexByte(data, 0x00); i >= 0 {
+		return i + 1, bytes.TrimLeft(data[0:i], "\x00"), nil
+	}
+	if atEOF {
+		return len(data), data, nil
+	}
+	return 0, nil, nil
+}
+
+// GetModuleInfo looks for a ".modinfo" section in the passed ELF Linux kernel
+// module and parses it into a ModuleInfo structure.
+func GetModuleInfo(e *elf.File) (ModuleInfo, error) {
+	for _, section := range e.Sections {
+		if section.Name == ".modinfo" {
+			out := make(ModuleInfo)
+			s := bufio.NewScanner(io.NewSectionReader(section, 0, int64(section.Size)))
+			s.Split(nullByteSplit)
+
+			for s.Scan() {
+				// Format is <key>=<value>
+				key, value, ok := bytes.Cut(s.Bytes(), []byte("="))
+				if !ok {
+					continue
+				}
+				keyStr := string(key)
+				out[keyStr] = append(out[keyStr], string(value))
+			}
+			return out, nil
+		}
+	}
+	return nil, errors.New("no .modinfo section found")
+}
+
+// GetBuiltinModulesInfo parses all modinfo structures for builtin modules from
+// a modinfo file (modules.builtin.modinfo).
+func GetBuiltinModulesInfo(f io.Reader) ([]ModuleInfo, error) {
+	var out []ModuleInfo
+	s := bufio.NewScanner(f)
+	s.Split(nullByteSplit)
+
+	currModule := make(ModuleInfo)
+	for s.Scan() {
+		if s.Err() != nil {
+			return nil, fmt.Errorf("failed scanning for next token: %w", s.Err())
+		}
+		// Format is <module>.<key>=<value>
+		modName, entry, ok := bytes.Cut(s.Bytes(), []byte{'.'})
+		if !ok {
+			continue
+		}
+		if string(modName) != currModule.Name() {
+			if currModule.Name() != "" {
+				out = append(out, currModule)
+			}
+			currModule = make(ModuleInfo)
+			currModule["name"] = []string{string(modName)}
+		}
+		key, value, ok := bytes.Cut(entry, []byte("="))
+		if !ok {
+			continue
+		}
+		keyStr := string(key)
+		currModule[keyStr] = append(currModule[keyStr], string(value))
+	}
+	if currModule.Name() != "" {
+		out = append(out, currModule)
+	}
+	seenModNames := make(map[string]bool)
+	for _, m := range out {
+		if seenModNames[m.Name()] {
+			return nil, fmt.Errorf("duplicate/out-of-order module metadata for module %q", m)
+		}
+		seenModNames[m.Name()] = true
+	}
+	return out, nil
+}
