Guía DSDT- OSX86 - Solución problemas Time Machine

roisoft

New member
Guía DSDT- OSX86 - Solución problemas Time Machine

Time machine fix

En esta segunda guía, abordaremos como solucionar el problema que algunos usuarios tienen con los backups con Time machine, debido a que el sistema no reconoce la tarjeta de red como dispositivo EN0, para lo cual existen varias soluciones como por ejemplo, el añadir una cadena EFI al archivo com.apple.boot.plist, o tb utilizar el smbiosresolver.kext, pero para los mas "inquietos", os ofreceremos como realizarlo en el DSDT, teniendo asi siempre limpio nuestro com.apple.boot.plist, y de paso, introduciendo la técnica de edición de DSDT para nuestro próximo capítulo (Edición de DSDT para injectar dispositivos de video).


Es necesario decir que una vez que añadamos este fix será necesario eliminar la cadena EFI del boot.plist o en el caso del smbiosresolver eliminar del plist, la clave y cadena correspondiente al UUID. Una vez realizado esto reiniciamos y abrimos las preferencias del TM para volver a elegir de nuevo el disco que estamos usando para los backups ya con la nueva UUID fijada y actualizada.

Herramientas necesarias:
Ioregistry explorer



Contenido:

1. Como reconocer donde está nuestra tarjeta de red en el registro.
2. Descompilación del archivo DSDT.aml.
3. Estructura básica de dispositivos en el DSDT
4. Localización de nuestra tarjeta de red en el archivo DSDT.
5. Inclusión del codigo.
5a. Anadido del código que arregla el problema Time machine.
6. Compilación y prueba.




1. Como reconocer donde está nuestra tarjeta de red en el registro.

Una vez descargado el programa Ioregistry explorer, procedemos ejecutarlo, nos desplazaremos por el arbol de entradas hasta que encontremos la referencia de nuestra tarjeta de red, normalmente suele ser bastante claro:

Como vereis, no está marcada en verde la linea que corresponde a la tarjeta, sino la superior, y tiene su explicación: en el código DSDT no la encontraremos con su nombre, sino con la del dispositivo que la alberga.

Vamos a explicar un poco estos dispositivos:
Marcado en rojo está el dispositivo RP03, este dispositivo alberga un sub-dispositívo denominado PXS3, en el cual se halla nuestra tarjeta de red.
A su vez, el dispositivo RP03 es un sub-dispositívo del código correspondiente a los puertos Pci (PCI0)

Cuando añadamos nuestro código, tendremos que estar seguros que es dentro de PXS3 y que cerramos convenientemente el código para no producir errores en la compilación (se verá mas adelante), si os equivocáis y el código cae fuera de PXS3, es muy posible que quede huérfano como dispositívo PCI y que osx no sepa que hacer con el al no estar correctamente definido.

Procedamos ahora a descompilár nuestro DSDT.aml previamente creado.


2. Descompilación del archivo DSDT.aml.


Porqué descompilár el archivo DSDT.aml y no utilizar el DSDT.dsl que tenemos con anterioridad?
Pues porque el DSDT.aml es el archivo que ya contiene todos los parcheos previos (HPET y RTC y corrección de errores), así podemos estar seguros de que funciona (mas que nada porque ya lo habremos probado y estará funcionando).

Paso primero, hacer copia de seguridad del archivo DSDT.aml
Segundo, copia de seguridad de la carpeta debug dentro de la carpeta del parcher (por si acaso)
Mover una copia del archivo DSDT.aml dentro de la carpeta "tools" (que se halla dentro de la carpeta del parcher), estar seguros que se llama DSDT.aml.

Dentro de la carpeta "tools" encontraremos un binario llamado "iasl" bien mi recomendación es que copieis este archivo en /usr/bin con esto lo tendremos siempre disponible al abrir el terminal y no tendremos que estar recordadndo donde lo hemos puesto o arrastrarlo al terminal cada vez que queremos modificar nuestro archivo dst.dsl

Dicho esto, y habiendo copiado el binario en donde hemos mencionado comenzamos con la descompilación del DSDT.aml:

Abrimos terminal, nos logueamos como root y accedemos a la carpeta en donde tenemos alamacenado el dsdt (cd "ruta a la carpeta")
una vez dentro tecleamos "iasl -d dsdt.aml"

Esto creará el archivo DSDT.dsl, hacemos una copia del mismo para tenerla como respaldo y la movemos fuera de la carpeta tools para no tener superpoblación de archivos.

Ahora ya prodemos editar l DSDT.dsl usando un editor de texto de nuestra elección (se sugiere textmate)



3. Estructura básica de dispositivos en el DSDT



Antes de empezar a insertar código, no está de más que sepamos como es la estructura del código para no perdernos al insertarlo, hechemos un vistazo al código DSDT de nuestra tarjeta de red:

El color rojo pertenece al dispositivo madre, se puede observar el corchete grande verde que abre el código para la definición de los dispositivos, y que no cierra hasta que termina la definición del device PXS3 (la tarjeta de red) y el método de trabajo de la misma.

El color azul oscuro corresponde a la cabezera de nuestra tarjeta de red, su definición está encapsulada por dos corchetes color azul marino.
El color morado corresponde al método que utilizará nuestra tarjeta de red para funcionar (encapsulado en corchetes morados).
Y finalmente un corchete verde que cierra toda la definición del codigo de RP03.
Debajo encontrareis la definición del primer puerto USB, que es dependiente de PCI0 (que no lo veis porque está mas arriba en el código), y que está fuera de todos nuestros corchetes de apertura y cierre.

Recomiendo que mireis detenidamente el código y lo examineis hasta que veais claro que código está contenido en cada par de corchetes (Relación madre/hijo)


4. Localización de nuestra tarjeta de red en el archivo DSDT.

Los ejemplos aquí propuestos están basados en un ordenador portátil Sony, el cual tiene la denominación PXS3 para la tarjeta de red, estad seguros de que en vuestros ordenadores, la denominación será diferente, por lo que tendréis que observar el nombre que tiene en vuestro registro y copiarlo para su búsqueda en el archivo DSDT.dsl


Una vez encontrado nuestro dispositivo de red en el Ioregistry explorer (o el que utilicéis vosotros) abrid el archivo DSDT.dsl con el editor de texto, abrid el menú "buscar" y ponéis el nombre del dispositivo en el campo "búsqueda", en este caso es PXS3, buscadlo hasta que la entrada que aparezca sea del tipo:

Device (PXS3) (o el que os corresponda a vosotros)


Ya tendremos localizado nuestro dispositivo y el dispositivo madre que lo contiene.


5. Inclusión del codigo.

Una vez que tengamos localizado el sitio correcto, ya solo nos quedará incluir el código que solucionará el problema del Time machine, pero aquí tenemos que parar un momento para explicar un concepto, el código foráneo y el cargador de código foraneo.

Basicaménte la explicación es esta:

Nuestro código no es ACPI, es una cadena de información que añadiremos al código ACPI, y si la ponemos tal cual, nuestro registro OSX no la cargará al no ser esta compatible ACPI, para que esta sea cargada, tendremos que utilizar un "cargador", que no es mas que un poco de código que definirá nuestra entrada de código y permitirá su carga por parte del sistema.

Donde insertar el "cargador"?

Esto es sencillo, debéis de buscar con el editor de texto una zona del código que se llama _WAK, y cuando termina la definición de la misma, encajar el código cargador.

Codigo cargador:

Method (DTGP, 5, NotSerialized)
{
If (LEqual (Arg0, Buffer (0x10)
{
/* 0000 */ 0xC6, 0xB7, 0xB5, 0xA0, 0x18, 0x13, 0x1C, 0x44,
/* 0008 */ 0xB0, 0xC9, 0xFE, 0x69, 0x5E, 0xAF, 0x94, 0x9B
}))
{
If (LEqual (Arg1, One))
{
If (LEqual (Arg2, Zero))
{
Store (Buffer (One)
{
0x03
}, Arg4)
Return (One)
}

If (LEqual (Arg2, One))
{
Return (One)
}
}
}

Store (Buffer (One)
{
0x00
}, Arg4)
Return (Zero)
}
Zona de carga:

El código de esta zona dependerá de la máquina, y basicaménte tenéis que buscar el final del código _WAK, que terminará así:
Return (Package (0x02)
{
Zero,
Zero
})
}
He incluir debajo el codigo cargador.

EJEMPLO:

Zona de carga mas cargador:

Method (_WAK, 1, NotSerialized)
{
P8XH (One, 0xAB)
If (LOr (LEqual (Arg0, 0x03), LEqual (Arg0, 0x04)))
{
If (And (CFGD, 0x01000000))
{
If (LAnd (And (CFGD, 0xF0), LEqual (OSYS, 0x07D1)))
{
TRAP (0x3D)
}
}
}

If (LEqual (RP2D, Zero))
{
Notify (\_SB.PCI0.RP02, Zero)
}

If (LEqual (Arg0, 0x03)) {}
If (LEqual (Arg0, 0x04))
{
\_SB.PCI0.LPCB.EC0.SELE ()
}

P8XH (Zero, 0xCD)
Return (Package (0x02)
{
Zero,
Zero
})
}

Method (DTGP, 5, NotSerialized)
{
If (LEqual (Arg0, Buffer (0x10)
{
/* 0000 */ 0xC6, 0xB7, 0xB5, 0xA0, 0x18, 0x13, 0x1C, 0x44,
/* 0008 */ 0xB0, 0xC9, 0xFE, 0x69, 0x5E, 0xAF, 0x94, 0x9B
}))
{
If (LEqual (Arg1, One))
{
If (LEqual (Arg2, Zero))
{
Store (Buffer (One)
{
0x03
}, Arg4)
Return (One)
}

If (LEqual (Arg2, One))
{
Return (One)
}
}
}

Store (Buffer (One)
{
0x00
}, Arg4)
Return (Zero)
}
Salváis el archivo y lo compilamos para ver si se han producido errores en el código.

Abrimos el terminal, nos logueamos como root y accedemos a la carpeta del dsdt (cd "ruta a la carpeta") seguidamente tecleamos

iasl -f dsdt.dsl

Si se producen errores, es que habéis puesto mal el cargador, si ocurren warnings, es que es posible que vengan de antes, no les hagáis mucho caso ahora.

Si no se producen errores, borrad el archivo DSDT.aml que se ha generado y proseguimos el trabajo dentro de DSDT.dsl


5a. Añadido del código que arregla el problema Time machine.

Nos desplazamos con la búsqueda dentro del editor de texto a nuestra tarjeta de red (en este caso PXS3)


Ahora que estamos en el sitio correcto, hecharémos un vistazo al código que arregla el problema:

Method (_DSM, 4, NotSerialized)
{
Store (Package (0x06)
{

"built-in",
Buffer (One)
{
0x01
},

"device_type",
Buffer (0x09)
{
"ethernet"
},

"name",
Buffer (0x24)
{
"Realtek RTL8111/8168B PCI-E Gigabit"
}
}, Local0)
DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
Return (Local0)
}
Si os fijáis en las letras en rojo que se sugiere, veréis que están marcadas el Buffer y el nombre de la tarjeta, ¿porque?, pues es simple, deberéis de cambiar el nombre de la tarjeta por el vuestro, y el buffer lo que indica es el número de caracteres (incluyendo los espacios) que hay en el nombre entrecomillado+1, si cambiáis el nombre, pero no el buffer, la compilación fallará.


Como averiguar el buffer (que ademas está en hexadecimal).
Es bien sencillo, necesitamos un conversor decimal a hexadecimal y al contrario.

Una web que os puede venir muy conveniente es esta:

Entrar or Registrarse para completar la lectura

o esta:
Entrar or Registrarse para completar la lectura


Bien, empezemos:

*nota : Es necesario decir que la línea "Realtek RTL8111/8168B PCI-E Gigabit" no es necesaria para fijar TM lo hemos puesto porque nos sirve de ejmplo para que entendamos como se calcula el buffer (explicado a continuación), además nos servirá de información y localización en el ioreg y tb por que no decirlo, queda ciertamente profesional :)


"Realtek RTL8111/8168B PCI-E Gigabit" , el número de letras y espacios contenidos aqui es 35 (decimal), por seguridad, añadimos 1, lo que nos da 36, usando las webs arriba indicadas, ponemos 36 en decimal y nos dá como resultado 24 en hexadecimal, osea, el buffer empleado.

Buffer (0x24)

Ahora cambiaremos el nombre que viene en el código que arregla el TM, poniendo en este caso el que le corresponde:

"Realtek RTL8169 PCI-E"
Número de caracteres y espacios +1 = 22 (decimal)


Pasados a hexadecimal en las webs arriba indicadas: 16

Osea, nuestro buffer es:

Buffer (0x16)

Asi, el código que arregla el TM para esta tarjeta de red, quedaria:
Method (_DSM, 4, NotSerialized)
{
Store (Package (0x06)
{

"built-in",
Buffer (One)
{
0x01
},

"device_type",
Buffer (0x09)
{
"ethernet"
},

"name",
Buffer (0x16)
{
"Realtek RTL8169 PCI-E"
}
}, Local0)
DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
Return (Local0)
}
Lo cual ya es correcto y esta listo para su inserción en el código DSDT.

A proposito.... fijaros en las últimas lineas de código:
DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
Return (Local0)
Estas lineas son las que permiten que el código cargador identifique que es "nuestro" código y las cargue, si no estuviesen estas líneas, el código cargador no sabría que las tiene que cargar.

Insertemos nuestro código ahora que está correcto:


Como podréis observar, el código está insertado dentro de los corchetes azul celeste, que definen la tarjeta de red, especificando así para OSX los parámetros requeridos para que Time machine funcione correctamente y debajo de:
Name (_ADR, Zero)
Name (_PRW, Package (0x02)
{
0x09,
0x03
})
Que definen nuestra tarjeta de red.


6. Compilación y prueba.


Ahora solo nos quedará salvar el archivo y compilarlo ( recordad "iasl -f dsdt.dsl") para ver si tiene errores de sintaxis o no. (visto previamente)

Si los tiene, aseguraos de que no hayan quedado corchetes huérfanos o borrados.

Si no los tiene, renombrad el archivo DSDT.aml que tenéis en el root del sistema a "DSDTold.aml" y copiad el nuevo en la raíz del disco.

Si fallase el nuevo DSDT.aml, (por ejemplo se congela el sistema), podéis arrancar el sistema utilizando el comando DSDT=DSDTold.aml (introducidlo cuando veáis el arranque chameleon presionando F8 y seleccionando la instalación de Leopard).


Esperamos que os haya sido útil este segundo capitulo de la edición de DSDT, el próximo:

Inserción de cadenas de video en el dsdt y limpieza de DEVICES no funcionales en OSX.
 

roisoft

New member
Salu2!

Siguiendo el hilo de fijar TM via dsdt, os traigo otra posibilidad que he podido probar con resultados satisfactorios en mi GA-P35-DS4 , el código es extraido del dsdt de un mac real.

Abriremos el ioregistryexplorer y buscaremos el emplazamiento de nuestra ethernet, en mi caso su ubicación es PEX5


El código a añadir es
Device (LAN)
{
Name (_ADR, Zero)
Name (_PRW, Package (0x02)
{
0x09,
0x03
})
Method (EWOL, 1, NotSerialized)
{
If (LEqual (Arg0, One))
{
Or (GP9, One, GP9)
}
Else
{
And (GP9, Zero, GP9)
}

If (LEqual (Arg0, GP9))
{
Return (Zero)
}
Else
{
Return (One)
}
}
}
Bien si sólo hacemos esto y nos disponemos a compilar, iasl nos marcaría un error de "GP9 etc......" tendremos que añadir esta variable bajo

Scope (\)
{
OperationRegion (WIN1, SystemIO, 0x2E, 0x02)
Field (WIN1, ByteAcc, NoLock, Preserve)
{
INDP, 8,
DATP, 8
}

OperationRegion (GPIO, SystemIO, 0x0800, 0x06)
Field (GPIO, ByteAcc, NoLock, Preserve)
{
GO01, 8,
GO02, 8,
GO03, 8,
GO04, 8,
GO05, 8,
GP9_, 1
}
Lo que buscamos con esto es que OSX detecte nuestra ethernet en en0 y como nativa (built-in)


salu2 !!
 
Hola roisoft,

Gracias por el manual, está todo muy bien explicado.

Tengo problemas con mi nueva placa GA-EP45C-DS3.

He insertado el código y el cargador en mi dsdt, y Time Machine sigue sin funcionar.

No obtengo errores al compilar, solamente un Warning. El mismo que apareció desde el principio:

dsdt.dsl 222: Method (_WAK, 1, NotSerialized)
Warning 1080 - ^ Reserved method must return a value (_WAK)


Mi placa tiene 2 Ethernet, PEX4 y PEX5 así que añadí el cargador 1 vez y el código 2 veces.

Lo del segundo post también lo he probado pero tengo dudas.

- Si lo pongo tal cual me da error de sintaxis. (creo que falta cerrar una llave)
- Para usar el 2º código ¿tengo que usar el cargador y quitar el código de del post 1 o se supone que es ACPI?
- Cuando pongo la llave (con el segundo código) me aparecen 19 errores:

Código:
bash-3.2# iasl -f dsdt.dsl

Intel ACPI Component Architecture
ASL Optimizing Compiler version 20080926 [Oct  4 2008]
Copyright (C) 2000 - 2008 Intel Corporation
Supports ACPI Specification Revision 3.0a

dsdt.dsl   222:     Method (_WAK, 1, NotSerialized)
Warning  1080 -                ^ Reserved method must return a value (_WAK)

dsdt.dsl  1610:                 OperationRegion (WIN1, SystemIO, 0x2E, 0x02)
Error    4056 -        Name already exists in scope ^  (WIN1)

dsdt.dsl  1613:                 INDP, 8, 
Error    4056 -                    ^ Name already exists in scope (INDP)

dsdt.dsl  1614:                 DATP, 8
Error    4056 -                    ^ Name already exists in scope (DATP)

dsdt.dsl  1617:                 OperationRegion (GPIO, SystemIO, 0x0800, 0x06)
Error    4056 -        Name already exists in scope ^  (GPIO)

dsdt.dsl  1620:                 GO01, 8, 
Error    4056 -                    ^ Name already exists in scope (GO01)

dsdt.dsl  1621:                 GO02, 8, 
Error    4056 -                    ^ Name already exists in scope (GO02)

dsdt.dsl  1622:                 GO03, 8, 
Error    4056 -                    ^ Name already exists in scope (GO03)

dsdt.dsl  1623:                 GO04, 8, 
Error    4056 -                    ^ Name already exists in scope (GO04)

dsdt.dsl  1624:                 GO05, 8, 
Error    4056 -                    ^ Name already exists in scope (GO05)

dsdt.dsl  1625:                 GP9_, 1
Error    4056 -                    ^ Name already exists in scope (GP9_)

dsdt.dsl  3312:                     OperationRegion (WIN1, SystemIO, 0x2E, 0x02)
Error    4056 -            Name already exists in scope ^  (WIN1)

dsdt.dsl  3315:                         INDP,   8, 
Error    4056 -                            ^ Name already exists in scope (INDP)

dsdt.dsl  3316:                         DATP,   8
Error    4056 -                            ^ Name already exists in scope (DATP)

dsdt.dsl  3319:                     OperationRegion (GPIO, SystemIO, 0x0800, 0x05)
Error    4056 -            Name already exists in scope ^  (GPIO)

dsdt.dsl  3322:                         GO01,   8, 
Error    4056 -                            ^ Name already exists in scope (GO01)

dsdt.dsl  3323:                         GO02,   8, 
Error    4056 -                            ^ Name already exists in scope (GO02)

dsdt.dsl  3324:                         GO03,   8, 
Error    4056 -                            ^ Name already exists in scope (GO03)

dsdt.dsl  3325:                         GO04,   8, 
Error    4056 -                            ^ Name already exists in scope (GO04)

dsdt.dsl  3326:                         GO05,   8
Error    4056 -                            ^ Name already exists in scope (GO05)

ASL Input:  dsdt.dsl - 5759 lines, 188648 bytes, 2363 keywords
AML Output: dsdt.aml - 18399 bytes, 679 named objects, 1684 executable opcodes

Compilation complete. 19 Errors, 1 Warnings, 0 Remarks, 31 Optimizations

No tienes porque ayudarme pero por si tienes curiosidad, te adjunto mi dsdt.dsl y una captura del IORegistryExplorer.
Ver archivo adjunto 2440


Saludos
 

roisoft

New member
Salu2!

Necesitas añadir un fake device "LAN" en la _ADR 0 de tus device PEX4/5 para que el código TM te funcione, ya que tal y como lo has hecho, solo añades un codigo que dice que tus puertos pci-e 4/5 son de una forma determinada (built-in, nombre tal....)

añade esto en ambos casos, reincia y reselecciona el disco de TM, debería de funcionar perfectamente...
Device (LAN)
{
Name (_ADR, Zero)
Name (_PRW, Package (0x02)
{
0x0B,
0x04
})
Method (_DSM, 4, NotSerialized)
{
Store (Package (0x08)
{
"built-in",
Buffer (One)
{
0x00
},

"device_type",
Buffer (0x09)
{
"ethernet"
},

"model",
Buffer (0x0E)
{
"Realtek 8111C"
}
}, Local0)
DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
Return (Local0)
}
}

en cuanto al _WAK añade Return (0x00) antes de cerrar el metodo.

..
..
..
Notify (\_SB.PCI0.USB0, Zero)
Notify (\_SB.PCI0.USB1, Zero)
Notify (\_SB.PCI0.USB2, Zero)
Notify (\_SB.PCI0.USB3, Zero)
Notify (\_SB.PCI0.USB4, Zero)
Notify (\_SB.PCI0.USB5, Zero)
Return (0x00)
}
 

roisoft

New member
me alegro de que te haya funcionado. He conseguido que el IntelCPU funcione perfectamente en los desktop activando el Vanilla SpeedStep a través del fijado del SSDT y DSDT . En breve ampliaré información con una guía detallada, decir que funciona tanto en leo como en el ultimo Snow 354

os muestro una captura del ioreg en snow, donde se pueden apreciar los PerformanceArray y Steps.... he conseguido bajar entre 8/10 ºC las temps en mi Quad y que oscile desde 1600 a 2600


si os apetece pasaros por el irc , hemos creado un nuevo canal para discutir estas y otras cosas. #EvOsx86 (mods, perdon por el spam :p si os parece mal, borradlo sin problema alguno)
 
¡Estoy impaciente! ;)

Este tipo de "spam" interesa a los usuarios. Espero y tengo la esperanza de que los mods NO lo quiten jeje.

Saludos
 
Arriba