From dbafd058cfb0fae3b4ec211260e222d8a3733284 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 21 Nov 2024 23:30:28 +0100 Subject: [PATCH] m1n1: Handle BootArgs revisions 1, 2 and 3 Handle revision 0 as revision 1. Signed-off-by: Janne Grunau --- proxyclient/m1n1/hv/__init__.py | 7 ++++- proxyclient/m1n1/proxy.py | 4 +++ proxyclient/m1n1/proxyutils.py | 9 ++++-- proxyclient/m1n1/tgtypes.py | 56 +++++++++++++++++++++++++++++++-- proxyclient/tools/chainload.py | 9 ++++-- 5 files changed, 78 insertions(+), 7 deletions(-) diff --git a/proxyclient/m1n1/hv/__init__.py b/proxyclient/m1n1/hv/__init__.py index 6c87976d..1f223d97 100644 --- a/proxyclient/m1n1/hv/__init__.py +++ b/proxyclient/m1n1/hv/__init__.py @@ -1757,7 +1757,12 @@ class HV(Reloadable): if use_xnu_symbols == True: self.sym_offset = vmin - guest_base + self.tba.phys_base - self.tba.virt_base - self.iface.writemem(guest_base + self.bootargs_off, BootArgs.build(self.tba)) + if self.tba.revision <= 1: + self.iface.writemem(guest_base + self.bootargs_off, BootArgs_r1.build(self.tba)) + elif self.tba.revision == 2: + self.iface.writemem(guest_base + self.bootargs_off, BootArgs_r2.build(self.tba)) + elif self.tba.revision == 3: + self.iface.writemem(guest_base + self.bootargs_off, BootArgs_r3.build(self.tba)) print("Setting secondary CPU RVBARs...") rvbar = self.entry & ~0xfff diff --git a/proxyclient/m1n1/proxy.py b/proxyclient/m1n1/proxy.py index 8428c8f5..9a89fb61 100644 --- a/proxyclient/m1n1/proxy.py +++ b/proxyclient/m1n1/proxy.py @@ -721,6 +721,10 @@ class M1N1Proxy(Reloadable): self.request(self.P_CALL, addr, *args, reboot=True) def get_bootargs(self): return self.request(self.P_GET_BOOTARGS) + def get_bootargs_rev(self): + ba_addr = self.request(self.P_GET_BOOTARGS) + rev = self.read16(ba_addr) + return (ba_addr, rev) def get_base(self): return self.request(self.P_GET_BASE) def set_baud(self, baudrate): diff --git a/proxyclient/m1n1/proxyutils.py b/proxyclient/m1n1/proxyutils.py index 9b60063f..78569dd7 100644 --- a/proxyclient/m1n1/proxyutils.py +++ b/proxyclient/m1n1/proxyutils.py @@ -44,9 +44,14 @@ class ProxyUtils(Reloadable): self.iface = p.iface self.proxy = p self.base = p.get_base() - self.ba_addr = p.get_bootargs() + (self.ba_addr, self.ba_rev) = p.get_bootargs_rev() - self.ba = self.iface.readstruct(self.ba_addr, BootArgs) + if self.ba_rev <= 1: + self.ba = self.iface.readstruct(self.ba_addr, BootArgs_r1) + elif self.ba_rev == 2: + self.ba = self.iface.readstruct(self.ba_addr, BootArgs_r2) + elif self.ba_rev == 3: + self.ba = self.iface.readstruct(self.ba_addr, BootArgs_r3) # We allocate a 128MB heap, 128MB after the m1n1 heap, without telling it about it. # This frees up from having to coordinate memory management or free stuff after a Python diff --git a/proxyclient/m1n1/tgtypes.py b/proxyclient/m1n1/tgtypes.py index 9081c8df..1e47c28d 100644 --- a/proxyclient/m1n1/tgtypes.py +++ b/proxyclient/m1n1/tgtypes.py @@ -1,9 +1,35 @@ # SPDX-License-Identifier: MIT from construct import * -__all__ = ["BootArgs"] +__all__ = ["BootArgs_r1", "BootArgs_r2", "BootArgs_r3"] -BootArgs = Struct( +BootArgs_r1 = Struct( + "revision" / Hex(Int16ul), + "version" / Hex(Int16ul), + Padding(4), + "virt_base" / Hex(Int64ul), + "phys_base" / Hex(Int64ul), + "mem_size" / Hex(Int64ul), + "top_of_kernel_data" / Hex(Int64ul), + "video" / Struct( + "base" / Hex(Int64ul), + "display" / Hex(Int64ul), + "stride" / Hex(Int64ul), + "width" / Hex(Int64ul), + "height" / Hex(Int64ul), + "depth" / Hex(Int64ul), + ), + "machine_type" / Hex(Int32ul), + Padding(4), + "devtree" / Hex(Int64ul), + "devtree_size" / Hex(Int32ul), + "cmdline" / PaddedString(256, "ascii"), + Padding(4), + "boot_flags" / Hex(Int64ul), + "mem_size_actual" / Hex(Int64ul), +) + +BootArgs_r2 = Struct( "revision" / Hex(Int16ul), "version" / Hex(Int16ul), Padding(4), @@ -28,3 +54,29 @@ BootArgs = Struct( "boot_flags" / Hex(Int64ul), "mem_size_actual" / Hex(Int64ul), ) + +BootArgs_r3 = Struct( + "revision" / Hex(Int16ul), + "version" / Hex(Int16ul), + Padding(4), + "virt_base" / Hex(Int64ul), + "phys_base" / Hex(Int64ul), + "mem_size" / Hex(Int64ul), + "top_of_kernel_data" / Hex(Int64ul), + "video" / Struct( + "base" / Hex(Int64ul), + "display" / Hex(Int64ul), + "stride" / Hex(Int64ul), + "width" / Hex(Int64ul), + "height" / Hex(Int64ul), + "depth" / Hex(Int64ul), + ), + "machine_type" / Hex(Int32ul), + Padding(4), + "devtree" / Hex(Int64ul), + "devtree_size" / Hex(Int32ul), + "cmdline" / PaddedString(1024, "ascii"), + Padding(4), + "boot_flags" / Hex(Int64ul), + "mem_size_actual" / Hex(Int64ul), +) diff --git a/proxyclient/tools/chainload.py b/proxyclient/tools/chainload.py index 2639e531..22125132 100755 --- a/proxyclient/tools/chainload.py +++ b/proxyclient/tools/chainload.py @@ -17,7 +17,7 @@ parser.add_argument('boot_args', default=[], nargs="*") args = parser.parse_args() from m1n1.setup import * -from m1n1.tgtypes import BootArgs +from m1n1.tgtypes import BootArgs_r1, BootArgs_r2, BootArgs_r3 from m1n1.macho import MachO from m1n1 import asm @@ -113,7 +113,12 @@ if args.xnu: tba.virt_base = 0xfffffe0010000000 + (tba.phys_base & (32 * 1024 * 1024 - 1)) tba.devtree = u.ba.devtree - u.ba.virt_base + tba.virt_base -iface.writemem(image_addr + bootargs_off, BootArgs.build(tba)) +if tba.revision <= 1: + iface.writemem(image_addr + bootargs_off, BootArgs_r1.build(tba)) +elif tba.revision == 2: + iface.writemem(image_addr + bootargs_off, BootArgs_r2.build(tba)) +elif tba.revision == 3: + iface.writemem(image_addr + bootargs_off, BootArgs_r3.build(tba)) print(f"Copying stub...")