aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-05-06 06:34:29 +0000
committerFelix Morgner <felix.morgner@ost.ch>2026-05-06 06:34:29 +0000
commit858c177d1b96ad6306edcda744e49d0cee906aff (patch)
tree7a0d1a867dbd96de53a0e8eca2b4e1f7c7eb6e19 /scripts
parent1e9daa3ccda0a39a8b260649ddc3c75f95a88bdf (diff)
downloadkernel-858c177d1b96ad6306edcda744e49d0cee906aff.tar.xz
kernel-858c177d1b96ad6306edcda744e49d0cee906aff.zip
debug: refactor dump_mb2i tool
Diffstat (limited to 'scripts')
-rw-r--r--scripts/gdb/teachos/dump_mb2i.py199
1 files changed, 135 insertions, 64 deletions
diff --git a/scripts/gdb/teachos/dump_mb2i.py b/scripts/gdb/teachos/dump_mb2i.py
index 41a2932..06f4531 100644
--- a/scripts/gdb/teachos/dump_mb2i.py
+++ b/scripts/gdb/teachos/dump_mb2i.py
@@ -1,30 +1,72 @@
import gdb
import struct
+from enum import IntEnum
+
+
+class TagType(IntEnum):
+ END = 0
+ CMDLINE = 1
+ BOOT_LOADER_NAME = 2
+ MODULE = 3
+ BASIC_MEMINFO = 4
+ BOOTDEV = 5
+ MMAP = 6
+ VBE = 7
+ FRAMEBUFFER = 8
+ ELF_SECTIONS = 9
+ APM = 10
+ EFI32_SYSTEM_TABLE_POINTER = 11
+ EFI64_SYSTEM_TABLE_POINTER = 12
+ SMBIOS_TABLES = 13
+ ACPI_OLD = 14
+ ACPI_NEW = 15
+ NETWORKING = 16
+ EFI_MEMORY_MAP = 17
+ EFI_BOOT_SERVICES_NOT_TERMINATED = 18
+ EFI32_IMAGE_HANDLE_POINTER = 19
+ EFI64_IMAGE_HANDLE_POINTER = 20
+ LOAD_BASE_ADDR = 21
+
+
+class MemoryType(IntEnum):
+ AVAILABLE = 1
+ RESERVED = 2
+ ACPI_RECLAIM = 3
+ NVS = 4
+ BAD = 5
TAG_NAMES = {
- 0: "End of Tags",
- 1: "Boot Command Line",
- 2: "Boot Loader Name",
- 3: "Boot Module",
- 4: "Basic Memory Information",
- 5: "BIOS Boot Device",
- 6: "Memory Map",
- 7: "VBE Info",
- 8: "Framebuffer Info",
- 9: "ELF Symbols",
- 10: "APM Table",
- 14: "ACPI old RSDP (1.0)",
- 15: "ACPI new RSDP (2.0+)",
- 21: "Image Load Base Physical Address",
+ TagType.END: "End of Tags",
+ TagType.CMDLINE: "Boot Command Line",
+ TagType.BOOT_LOADER_NAME: "Boot Loader Name",
+ TagType.MODULE: "Boot Module",
+ TagType.BASIC_MEMINFO: "Basic Memory Information",
+ TagType.BOOTDEV: "BIOS Boot Device",
+ TagType.MMAP: "Memory Map",
+ TagType.VBE: "VBE Info",
+ TagType.FRAMEBUFFER: "Framebuffer Info",
+ TagType.ELF_SECTIONS: "ELF Symbols",
+ TagType.APM: "APM Table",
+ TagType.EFI32_SYSTEM_TABLE_POINTER: "EFI 32-bit System Table Pointer",
+ TagType.EFI64_SYSTEM_TABLE_POINTER: "EFI 64-bit System Table Pointer",
+ TagType.SMBIOS_TABLES: "SMBIOS Tables",
+ TagType.ACPI_OLD: "ACPI old RSDP (1.0)",
+ TagType.ACPI_NEW: "ACPI new RSDP (2.0+)",
+ TagType.NETWORKING: "Networking Information",
+ TagType.EFI_MEMORY_MAP: "EFI Memory Map",
+ TagType.EFI_BOOT_SERVICES_NOT_TERMINATED: "EFI Boot Services Not Terminated",
+ TagType.EFI32_IMAGE_HANDLE_POINTER: "EFI 32-bit Image Handle Pointer",
+ TagType.EFI64_IMAGE_HANDLE_POINTER: "EFI 64-bit Image Handle Pointer",
+ TagType.LOAD_BASE_ADDR: "Image Load Base Physical Address",
}
MEMORY_TYPES = {
- 1: "Available",
- 2: "Reserved",
- 3: "ACPI Reclaim",
- 4: "Non-volatile storage",
- 5: "Bad Memory",
+ MemoryType.AVAILABLE: "Available",
+ MemoryType.RESERVED: "Reserved",
+ MemoryType.ACPI_RECLAIM: "ACPI Reclaim",
+ MemoryType.NVS: "Non-volatile storage",
+ MemoryType.BAD: "Bad Memory",
}
INDENT = f"{' '*11}"
@@ -64,7 +106,9 @@ class DumpMB2I(gdb.Command):
return
if total_size < 8 or total_size > 1024 * 1024:
- gdb.write("Warning: suspicious total size ({total_size} bytes). Aborting.")
+ gdb.write(
+ f"Warning: suspicious total size ({total_size} bytes). Aborting.\n"
+ )
return
gdb.write(f"+{'-'*70}+\n")
@@ -86,11 +130,11 @@ class DumpMB2I(gdb.Command):
)
break
- self._print_tag(inferior, tag_address, tag_type, tag_size)
-
- if tag_type == 0 and tag_size == 0:
+ if tag_type == TagType.END and tag_size == 8:
break
+ self._print_tag(inferior, tag_address, tag_type, tag_size)
+
offset += (tag_size + 7) & ~7
def _format_size(self, size):
@@ -104,50 +148,77 @@ class DumpMB2I(gdb.Command):
def _print_tag(self, inferior, tag_address, tag_type, tag_size):
name = TAG_NAMES.get(tag_type, f"Unknown Tag")
- gdb.write(f"[Tag {tag_type:#04x}] {name} (size: {self._format_size(tag_size)})\n")
+ gdb.write(
+ f"[Tag {tag_type:#04x}] {name} (size: {self._format_size(tag_size)})\n"
+ )
- if tag_size <= 8 and tag_type != 0:
+ if tag_size <= 8 and tag_type != TagType.END:
return
try:
- if tag_type in (1, 2):
- data = inferior.read_memory(tag_address + 8, tag_size - 8).tobytes()
- text = data.split(b"\x00")[0].decode("ascii", "replace")
- gdb.write(f'{INDENT}"{text}"\n')
- elif tag_type == 3:
- data = inferior.read_memory(tag_address + 8, tag_size - 8).tobytes()
- start, end = struct.unpack_from("<II", data)
- string = data[8:].split(b"\x00")[0].decode("ascii", "replace")
- gdb.write(
- f"{INDENT}start: {start:#010x} | end: {end:#010x} | size: {self._format_size(end - start)}\n"
- )
- if string:
- gdb.write(f'{INDENT}string: "{string}"\n')
- elif tag_type == 5:
- data = inferior.read_memory(tag_address + 8, tag_size - 8).tobytes()
- device, partition, sub_partition = struct.unpack_from("<III", data)
- gdb.write(
- f"{INDENT}device: {device:#04x} | partition: {partition:#06x} | sub-partion: {sub_partition:#06x}\n"
- )
- elif tag_type == 6:
- data = inferior.read_memory(tag_address + 8, tag_size - 8).tobytes()
- entry_size, entry_version = struct.unpack_from("<II", data)
- if entry_size < 24:
- return
- num_entries = (tag_size - 16) // entry_size
- for i in range(num_entries):
- entry_offset = 8 + i * entry_size
- base, length, memory_type = struct.unpack_from(
- "<QQI", data, entry_offset
- )
- type_string = MEMORY_TYPES.get(memory_type, "Unknown")
- gdb.write(
- f"{INDENT}[{i:02d}] {base:#018x} - {base + length:#018x} | {self._format_size(length)} | type: {type_string}\n"
- )
- elif tag_type == 21:
- data = inferior.read_memory(tag_address + 8, tag_size - 8).tobytes()
- base = struct.unpack("<I", data)[0]
- gdb.write(f"{INDENT}address: {base:#010x}\n")
+ data = inferior.read_memory(tag_address + 8, tag_size - 8).tobytes()
+
+ handlers = {
+ TagType.CMDLINE: self._write_string_tag,
+ TagType.BOOT_LOADER_NAME: self._write_string_tag,
+ TagType.MODULE: self._write_module_tag,
+ TagType.BASIC_MEMINFO: self._write_basic_memory_info_tag,
+ TagType.BOOTDEV: self._write_boot_device_tag,
+ TagType.MMAP: self._write_memory_map_tag,
+ TagType.LOAD_BASE_ADDR: self._write_image_load_base_physical_address_tag,
+ TagType.FRAMEBUFFER: self._write_framebuffer_info_tag,
+ }
+
+ handler = handlers.get(tag_type)
+ if handler:
+ handler(data)
except Exception as e:
- gdb.write(f"{INDENT}<failed to decode tag: {e}>\n")
+ gdb.write(
+ f"{INDENT}<failed to decode tag: {e} ({tag_type:#04x} | {tag_size:#06x})>\n"
+ )
+
+ def _write_string_tag(self, data):
+ text = data.split(b"\x00")[0].decode("ascii", "replace")
+ gdb.write(f'{INDENT}"{text}"\n')
+
+ def _write_module_tag(self, data):
+ start, end = struct.unpack_from("<II", data)
+ string = data[8:].split(b"\x00")[0].decode("ascii", "replace")
+ gdb.write(
+ f"{INDENT}start: {start:#010x} | end: {end:#010x} | size: {self._format_size(end - start)}\n"
+ )
+ if string:
+ gdb.write(f'{INDENT}string: "{string}"\n')
+
+ def _write_basic_memory_info_tag(self, data):
+ lower, upper = struct.unpack_from("<II", data)
+ gdb.write(
+ f"{INDENT}upper memory: {self._format_size(upper * 1024)} | lower memory: {self._format_size(lower * 1024)}\n"
+ )
+
+ def _write_boot_device_tag(self, data):
+ device, partition, sub_partition = struct.unpack_from("<III", data)
+ gdb.write(
+ f"{INDENT}device: {device:#04x} | partition: {partition:#06x} | sub-partition: {sub_partition:#06x}\n"
+ )
+
+ def _write_memory_map_tag(self, data):
+ entry_size, entry_version = struct.unpack_from("<II", data)
+ if entry_size < 24:
+ return
+ num_entries = (len(data) - 8) // entry_size
+ for i in range(num_entries):
+ entry_offset = 8 + i * entry_size
+ base, length, memory_type = struct.unpack_from("<QQI", data, entry_offset)
+ type_string = MEMORY_TYPES.get(memory_type, "Unknown")
+ gdb.write(
+ f"{INDENT}[{i:02d}] {base:#018x} - {base + length:#018x} | {self._format_size(length)} | type: {type_string}\n"
+ )
+
+ def _write_image_load_base_physical_address_tag(self, data):
+ base = struct.unpack("<I", data)[0]
+ gdb.write(f"{INDENT}address: {base:#010x}\n")
+
+ def _write_framebuffer_info_tag(self, data):
+ pass