Skip to content

Instantly share code, notes, and snippets.

@doraeric
Last active May 19, 2025 16:47
Show Gist options
  • Save doraeric/919045bc2af9b669a5f768cb8b3c192d to your computer and use it in GitHub Desktop.
Save doraeric/919045bc2af9b669a5f768cb8b3c192d to your computer and use it in GitHub Desktop.

Revisions

  1. doraeric revised this gist May 19, 2025. 1 changed file with 0 additions and 2 deletions.
    2 changes: 0 additions & 2 deletions grub-2.12 debug
    Original file line number Diff line number Diff line change
    @@ -1,3 +1 @@
    # https://fourdollars.blogspot.com/2013/07/grub2.html

    debug=acpi,affs,ahci,appleload,arcdisk,archelp,ata,atkeyb,badram,bsd,btrfs,cache,cbfs,chain,cros,cros_keyboard,crypt,cryptodisk,datetime,devalias,disk,diskfilter,dl,dns,drivemap,efi,efidisk,efiemu,ehci,elf,exfat,expand,fat,fdt,fdtbus,fixvideo,font,fs,geli,gpt,hostdisk,http,ieee1275,init,jpeg,keystatus,linux,loader,luks,luks2,memdisk,mmap,modules,multiboot_loader,nativedisk,net,ohci,partition,pata,plainmount,play,pmtimer,png,regions,reiserfs,reiserfs_blocktype,reiserfs_tree,relocator,scsi,sections,serial,smbios,syslinux,tftp,tga,tpm,ubootdisk,uhci,usb,usb_keyboard,usbms,verify,video,xen,xen_loader,xfs,xnu,zfs
  2. doraeric revised this gist May 19, 2025. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions grub-2.12 debug
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,3 @@
    # https://fourdollars.blogspot.com/2013/07/grub2.html

    debug=acpi,affs,ahci,appleload,arcdisk,archelp,ata,atkeyb,badram,bsd,btrfs,cache,cbfs,chain,cros,cros_keyboard,crypt,cryptodisk,datetime,devalias,disk,diskfilter,dl,dns,drivemap,efi,efidisk,efiemu,ehci,elf,exfat,expand,fat,fdt,fdtbus,fixvideo,font,fs,geli,gpt,hostdisk,http,ieee1275,init,jpeg,keystatus,linux,loader,luks,luks2,memdisk,mmap,modules,multiboot_loader,nativedisk,net,ohci,partition,pata,plainmount,play,pmtimer,png,regions,reiserfs,reiserfs_blocktype,reiserfs_tree,relocator,scsi,sections,serial,smbios,syslinux,tftp,tga,tpm,ubootdisk,uhci,usb,usb_keyboard,usbms,verify,video,xen,xen_loader,xfs,xnu,zfs
  3. doraeric created this gist May 18, 2025.
    93 changes: 93 additions & 0 deletions grub-deps.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,93 @@
    #!/usr/bin/env python3
    import argparse
    import re
    import subprocess
    import tempfile
    from pathlib import Path
    from queue import Queue

    not_all_video_mods = [
    "efi_gop",
    "efi_uga",
    "ieee1275_fb",
    "vbe",
    "vga",
    "video_bochs",
    "video_cirrus",
    ]


    def get_deps(mod: str) -> dict[str, list[str]]:
    deps = {}
    q = Queue()
    q.put(mod)
    while not q.empty():
    mod = q.get()
    deps[mod] = []
    with tempfile.TemporaryDirectory() as tmpdir:
    sections = subprocess.check_output(
    ["objdump", "-h", f"/boot/grub/x86_64-efi/{mod}.mod"]
    ).splitlines()[5:]
    sections = b"\n".join(sections)
    if b".moddeps" not in sections:
    continue

    subprocess.run(
    [
    "objcopy",
    "--dump-section",
    f".moddeps={tmpdir}/out",
    f"/boot/grub/x86_64-efi/{mod}.mod",
    "/dev/null",
    ]
    )
    with Path(tmpdir, "out").open() as f:
    lines = f.read().split("\0")
    lines = [line for line in lines if line]
    deps[mod] = lines
    for dep in deps[mod]:
    if dep not in deps:
    q.put(dep)
    return deps


    insmod_pattern = r"insmod\s+([\w]+)"


    def read_grub_cfg(path: str):
    mod_counter = {}
    with Path(path).open() as f:
    for line in f:
    line = line.strip()
    if "insmod" in line:
    match = re.search(insmod_pattern, line)
    mod = match.group(1)
    mod_counter[mod] = mod_counter.get(mod, 0) + 1
    for neg_mod in not_all_video_mods:
    if neg_mod in mod_counter:
    mod_counter[neg_mod] -= 1
    if mod_counter[neg_mod] == 0:
    del mod_counter[neg_mod]
    return list(mod_counter.keys())


    def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("-i", "--input", required=True, help="grub.cfg file")
    args = parser.parse_args()
    mods = read_grub_cfg(args.input)
    flatten = []
    for mod in mods:
    deps = get_deps(mod)
    for key, values in deps.items():
    if key not in flatten:
    flatten.append(key)
    for value in values:
    if value not in flatten:
    flatten.append(value)
    flatten.sort()
    print(" ".join(flatten))


    if __name__ == "__main__":
    main()