Usuarios de macOS Catalina y posteriores que utilizan SMBIOS de MacPro7,1 reciben un aviso de error al arrancar: MEMORY MODULES MISCONFIGURED – More than the maximum supported memory is installed in your Mac. El modelo MacPro7,1 fue puesto a la venta en 2019 y es el Mac Intel más potente y modular, con una orientación claramente profesional. Lleva una CPU Intel Xeon de 8 a 28 núcleos según modelos y tarjetas gráficas AMD Radeon Pro 580X. Carece de iGPU. Aunque no parece un modelo de SMBIOS adecuado a la mayoría de los hackintosh, algunos usuarios que han montado equipos de alto rendimiento con CPU potentes (sobre todo si no tienen gráfica integrada) y mucha memoria RAM lo utilizan.
Traducción con aportaciones propias de la guía Fixing MacPro7,1 Memory Errors, publicada por RTHPJM en GitHub, que es información ampliada de la guía original de Dortania.
No está claro el mecanismo por el que se genera el aviso. Hasta el lanzamiento de Big Sur, el plugin de Lilu MacProMemoryNotificationDisabler.kext desarrollado por IOIIIO solucionaba el problema y el aviso dejaba de aparecer. Pero esta kext no funciona en Big Sur. Lilu aplica los parches como el de esta kext en el espacio de usuario al que Big Sur no deja acceder para esta tarea por lo que ha dejado de funcionar.
Avisos de error que pueden aparecer en el Escritorio:
Actualmente la forma más sencilla (y la recomendada por los autores de OpenCore) de eliminar el error es usar la extensión del kernel RestrictEvents.kext. Sin embargo, RestrictEvents es una extensión multifunción y es posible que no necesites ni desees las funciones adicionales que proporciona la extensión. O simplemente deseas configurar la memoria de un modo manual. En este caso puedes recurrir a la función CustomMemory, disponible desde la versión 0.6.3 de OpenCore.
1.- Un poco de historia
macOS espera que el hardware subyacente sea hardware de Apple. Por lo tanto, al construir un Hackintosh debemos intentar que el hardware coincida lo más posible. En aquellas áreas en las que nuestro hardware difiere, debemos intentar convencer a macOS de que el hardware es compatible.
Considera tu placa base. Si estás emulando un MacPro7,1 entonces la placa base tiene 12 ranuras físicas de memoria RAM. Este modelo de Mac tiene un controlador específico para la memoria, es un controlador de 6 canales que soporta 12 ranuras de memoria DDR4 ECC y acepta módulos de 8 a 128GB hasta alcanzar un máximo de 1,5TB de RAM. Las 12 ranuras pueden estar ocupadas en su totalidad o no pero con un mínimo predefinido de 4 ranuras ocupadas.
Desde OC hay que configurar exactamente 12 ranuras rellenando con datos reales (obtenidos con la herramienta dmidecode) las que están ocupadas por módulos DIMM y con datos ficticios el resto como ranuras libres. La finalidad es que macOS vea las 12 ranuras que espera encontrar en un MacPro7,1, obteniendo de cada una valores reales o ficticios que le ayuden a configurar los módulos ocupados y libres.
Nuestras placas base muy probablemente tendrán menos ranuras de memoria física, 4 muy frecuentemente y algunas sólo 2. Usaremos la función CustomMemory de OpenCore para informar a macOS de 12 ranuras virtuales.
Echa un vistazo a Instalar y reemplazar unidades de memoria en el Mac Pro (2019). Los diagramas muestran cómo un MacPro7,1 espera que se instale la RAM física.
Ten en cuenta que un MacPro7,1 tiene un requisito mínimo de 4 módulos DIMM. Por lo tanto, se recomienda que tu sistema también tenga un mínimo de 4 DIMM físicos. Si tu sistema sólo tiene dos DIMM (por tener 2 de las 4 ranuras libres o quizás la placa base sólo tiene dos ranuras), entonces tendrás que configurar CustomMemory para presentar 4 DIMM aunque sólo tengas dos. La manera de hacerlo es reducir a la mitad el tamaño de los DIMM reales y presentar cuatro valores más pequeños (la mitad) en las ranuras virtuales de OpenCore. Por ejemplo, si tienes dos DIMM físicos de 16 GB, reduce a la mitad ese valor (8 GB) y presenta cuatro DIMM de 8 GB en las localizaciones correctas.
2.- Crear el mapa de nuestra memoria RAM
Usando el archivo plist sin rellenar de ejemplo (Custom Memory sin DIMM.plist), la sección de dispositivos de OpenCore se ve así:
El orden de los elementos de la matriz es importante y debe mantenerse tal como está. Así es como los ítems (Devices) de config.plist se corresponden con las ranuras físicas:
- Ítem 0:
- Representa la ranura 8 en la placa base del MacPro7,1,1, etiquetada como Channel A / DIMM 1
- Ítem 1:
- Representa la ranura 7 en la placa base del MacPro7,1, etiquetada como Channel A / DIMM 2
- Ítem 2:
- Representa la ranura 10 en la placa base del MacPro7,1, etiquetada como Channel B / DIMM 1
- Ítem 3:
- Representa la ranura 9 en la placa base del MacPro7,1, etiquetada como Channel B / DIMM 2
- Ítem 4:
- Representa la ranura 12 en la placa base del MacPro7,1, etiquetada como Channel C / DIMM 1
- Ítem 5:
- Representa la ranura 11 en la placa base del MacPro7,1, etiquetada como Channel C / DIMM 2
- Ítem 6:
- Representa la ranura 5 en la placa base del MacPro7,1, etiquetada como Channel D / DIMM 1
- Ítem 7:
- Representa la ranura 6 en la placa base del MacPro7,1, etiquetada como Channel D / DIMM 2
- Ítem 8:
- Representa la ranura 3 en la placa base del MacPro7,1, etiquetada como Channel E / DIMM 1
- Ítem 9:
- Representa la ranura 4 en la placa base del MacPro7,1, etiquetada como Channel E / DIMM 2
- Ítem 10:
- Representa la ranura 1 en la placa base del MacPro7,1, etiquetada como Channel F / DIMM 1
- Ítem 11:
- Representa la ranura 2 en la placa base del MacPro7,1, etiquetada como Channel F / DIMM 2.
Si una ranura de memoria no está ocupada en un MacPro7,1, el campo Manufacturer se establece en NO DIMM (texto). Este es un campo crítico para corregir el mensaje de error. Y los campos Size y Speed se ajustan al valor 0.
Descarga los archivo plist de ejemplo (Custom Memory sin DIMM.plist y Custom Memory 4 DIMM ocupados.plist): enlace.
3.- Nueva sección Memory en OpenCore 0.6.3
La sección PlatformInfo >> Memory apareció en OpenCore 0.6.3, en el archivo SampleConfig.plist. Memory sólo se utiliza si la clave PlatformInfo >> CustomMemory es True. Memory tiene varias subclaves relacionadas con la memoria RAM:
- DataWidth: ancho de banda en bits del bus, suele tener el valor de 64
- ErrorConnection: método primario de detección o corrección de errores (ninguno, paridad, ECC…)
- FormFactor: el tipo de módulo empleado (DIMM, SODIMM…)
- MaxCapacity: capacidad máxima de memoria, en bytes, soportada por la placa base
- TotalWidth: valor total del ancho del bus, en bits, incluidos los canales de corrección de errores si los hay; si no existen, el valor de TotalWidth es idéntico a DataWidth
- Type: tipo de memoria (DDR3, DDR4…)
- TypeDetail: información adicional sobre la memoria (Synchronous, Buffered, Unbuffered…)
- Devices: en esta sección se describen todos los bancos de memoria, ocupados o no, y se especifican características de cada uno de ellos:
- AssetTag: etiqueta de propiedad del módulo de memoria
- BankLocator: nombre del banco de memoria en que se aloja el módulo
- DeviceLocator: descripción de la posición del banco en la placa base
- Manufacturer: fabricante de la memoria
- PartNumber: código correspondiente al modelo de memoria
- SerialNumber: número de serie de cada módulo
- Size: tamaño en MB, 0 indica que está vacío
- Speed: velocidad máxima de la memoria en MT/s (megatransfers por segundo).
4.- Prerrequisitos
- dmidecode: herramienta proveniente del mundo Linux que proporciona información sobre el hardware tal como está descrito en BIOS según el estándar SMBIOS – DMI. Acidanthera tiene una versión específica para macOS, puedes obtenerlo en su sitio de GitHub. Se descarga como un archivo ejecutable que conviene copiar a la carpeta /usr/local/bin para que esté incluido en la variable PATH. Con esta herramienta obtenemos información de los parámetros SMBIOS del ordenador a través de I/O Registry.
- Archivo SampleConfig.plist de ejemplo, hay que rellenarlo con nuestros datos:
<key>PlatformInfo</key> <dict> <key>Memory</key> <dict> <key>DataWidth</key> <integer></integer> <key>ErrorCorrection</key> <integer></integer> <key>FormFactor</key> <integer></integer> <key>MaxCapacity</key> <integer></integer> <key></key> <integer></integer> <key>Type</key> <integer></integer> <key>TypeDetail</key> <integer></integer> <key>Devices</key> <array> <dict> <key>AssetTag</key> <string></string> <key>BankLocator</key> <string></string> <key>DeviceLocator</key> <string></string> <key>Manufacturer</key> <string></string> <key>PartNumber</key> <string></string> <key>SerialNumber</key> <string></string> <key>Size</key> <integer>0</integer> <key>Speed</key> <integer>0</integer> </dict> <dict> <key>AssetTag</key> <string></string> <key>BankLocator</key> <string></string> <key>DeviceLocator</key> <string></string> <key>Manufacturer</key> <string></string> <key>PartNumber</key> <string></string> <key>SerialNumber</key> <string></string> <key>Size</key> <integer>0</integer> <key>Speed</key> <integer>0</integer> </dict> <!-- sigue hasta 12 Devices en total --> </array> </dict> </dict>
5.- Detectar la memoria real de nuestro PC
Con dmidecode vamos a averiguar el valor de cada una de las propiedades enumeradas más arriba: DataWidth / ErrorConnection / FormFactor / MaxCapacity / TotalWidth / Type / TypeDetail / Devices. Y dentro de cada Device: AssetTag / BankLocator / DeviceLocator / Manufacturer / PartNumber / SerialNumber / Size / Speed.
En mi PC hay 4 ranuras de memoria, 2 de ellas están ocupadas por módulos DIMM DDR4 (16×2 = 32Gb en total) y 2 están vacías. Por ello he de generar 4 ranuras ocupadas (recurriendo al truco de dividir por la mitad el tamaño de cada uno de los 2 módulos) y 8 libres.
Desde Terminal podemos ejecutar dmidecode con el parámetro -t memory que produce una salida con todas las propiedades de todos los módulos de memoria RAM. Pero es más cómodo obtener cada propiedad por separado.
DataWidth
dmidecode -t memory | grep "Data Width:"
Data Width: 64 bits
Data Width: Unknown
Data Width: 64 bits
Data Width: Unknown
DataWitdh = 64.
ErrorCorrection
1 — Other
2 — Unknown
3 — None
4 — Parity
5 — Single-bit ECC
6 — Multi-bit ECC
7 — CRC.
dmidecode -t memory | grep "Error Correction Type:" Error Correction Type: None
ErrorCorrection = 3.
FormFactor
1 — Other
2 — Unknown
9 — DIMM
13 — SODIMM
15 — FB-DIMM.
dmidecode -t memory | grep "Form Factor:" Form Factor: DIMM Form Factor: DIMM Form Factor: DIMM Form Factor: DIMM
FormFactor = 9.
MaxCapacity
El valor de MaxCapacity depende del tipo de procesador instalado en un Apple MacPro7,1. Consulta Mac Pro (2019) memory specifications. El valor debe ser uno de los siguientes:
Máxima RAM admitida | Expresada en bytes |
768 GB | 824633720832 |
1.5 TB | 1649267441664 |
TotalWidth
- DataWidth = 64 y TotalWidth = 64 indica que el dispositivo tiene 64 bits de datos sin bits de corrección de errores.
- DataWidth = 64 y TotalWidth = 72 indica que el dispositivo tiene 64 bits de datos con 8 bits de corrección de errores.
- DataWidth = 64 y TotalWidth = 8 indica que el dispositivo se está utilizando únicamente para proporcionar 8 bits de corrección de errores.
dmidecode -t memory | grep "Total Width:" Total Width: 64 bits Total Width: Unknown Total Width: 64 bits Total Width: Unknown
TotalWidth = 64.
Type
1 — Other
2 — Unknown
15 — SDRAM
18 — DDR
19 — DDR2
20 — DDR2 FB-DIMM
24 — DDR3
26 — DDR4
27 — LPDDR
28 — LPDDR2
29 — LPDDR3
30 — LPDDR4.
dmidecode -t memory | grep "Type:" Type: DDR4 Type: Unknown Type: DDR4 Type: Unknown
Type = 26.
TypeDetail
Bit 0 — Reserved, set to 0
Bit 1 — Other
Bit 2 — Unknown
Bit 7 — Synchronous
Bit 13 — Registered (buffered)
Bit 14 — Unbuffered (unregistered).
Hay que combinar todos los bits que son aplicables, ejemplo:
Bit 13 — Registered (buffered) + Bit 14 — Unbuffered (unregistered) >> = TypeDetail = 27.
dmidecode -t memory | grep "Type Detail:" Type Detail: Synchronous Type Detail: None Type Detail: Synchronous Type Detail: None
TypeDetail = 7
Devices
Aquí es donde se definen las 12 ranuras de memoria. Las que están ocupadas se rellenan con datos obtenidos desde dmidecode. Las que están vacías se rellenan parcialmente con datos ficticios para que macOS interprete que también existen aunque sin DIMM. A las propiedades Size y Speed les asignamos el valor 0 (si se dejan en blanco hay error)..
AssetTag
dmidecode -t memory | grep "Asset Tag:" Asset Tag: 9876543210 Asset Tag: Unknown Asset Tag: 9876543210 Asset Tag: Unknown
Si dmidecode devuelve <BAD INDEX> o Not Specified, AssetTag se deja en blanco.
AssetTag = 987654321.
BankLocator
Aunque dmidecode puede devolver datos o Not Specified, este campo se deja en blanco en todos los Devices.
dmidecode -t memory | grep "Bank Locator:" Bank Locator: BANK 0 Bank Locator: BANK 1 Bank Locator: BANK 2 Bank Locator: BANK 3
DeviceLocator
No se utilizan los datos de dmidecode tal cual sino añadiendo el número de Slot. Por ejemplo, dmidecode devuelve:
dmidecode -t memory | grep "Locator:" Locator: ChannelA-DIMM0 Locator: ChannelA-DIMM1 Locator: ChannelB-DIMM0 Locator: ChannelB-DIMM1
Pero hemos de utilizar:
- Slot 8 (ChannelA / DIMM1)
- Slot 7 (ChannelA / DIMM2)
- Slot 10 (Channel B / DIMM 1)
- Slot 9 (Channel B / DIMM 2)
- Slot 12 (Channel C / DIMM 1)
- Slot 11 (Channel C / DIMM 2)
- Slot 5 (Channel D / DIMM 1)
- Slot 6 (Channel D / DIMM 2)
- Slot 3 (Channel E / DIMM 1)
- Slot 4 (Channel E / DIMM 2)
- Slot 1 (Channel F / DIMM 1)
- Slot 2 (Channel F / DIMM 2).
Manufacturer
dmidecode -t memory | grep "Manufacturer:"
Manufacturer: 029E o CORSAIR
Manufacturer: Unknown
Manufacturer: 029E o CORSAIR
Manufacturer: Unknown
Importante: Ajusta este valor como NO DIMM si la ranura está vacía.
PartNumber
dmidecode -t memory | grep "Part Number:" Part Number: CMK32GX4M2B3200C16 Part Number: Unknown Part Number: CMK32GX4M2B3200C16 Part Number: Unknown
Las ranuras vacías se dejan en blanco.
SerialNumber
dmidecode -t memory | grep "Serial Number:" Serial Number: 00000000 Serial Number: Unknown Serial Number: 00000000 Serial Number: Unknown
Las ranuras vacías se dejan en blanco.
Size (en MB)
- 1GB – 1024
- 2GB – 2048
- 4GB – 4096
- 8GB – 8192
- 16GB – 16384
- 32GB – 32768
- 64GB – 65536
- 128GB – 131072.
dmidecode -t memory | grep "Size:"
Size: 16 GB
Size: No Module Installed
Size: 16 GB
Size: No Module Installed
Importante: Las ranuras vacías se rellenan con 0.
En mi caso, en lugar de 2 Devices de 16384 MB he de crear 4 de 8192 MB.
Speed
dmidecode -t memory | grep "Speed:"
Speed: 2133 MT/s
Speed: Unknown
Speed: 2133 MT/s
Speed: Unknown
Importante: Las ranuras vacías se rellenan con 0.
6.- Editar el archivo config.plist de OpenCore
Ajusta el valor del campo PlatformInfo >> CustomMemory a True. Si la clave CustomMemory no está presente, añádela manualmente o cópiala desde uno de los archivos plist de ejemplo. En la sección PlatformInfo hay una sección Memory. Si la sección Memory no está presente, añádela manualmente o cópiala desde uno de los archivos plist de ejemplo. Ábrela y rellénala utilizando los valores que obtuviste de tu RAM física. Por ejemplo, utilizando los datos de ejemplo que vimos antes:
DataWidth = 64
ErrorCorrection = 3
FormFactor = 9
MaxCapacity = 824633720832
TotalWidth = 64
Type = 26
TypeDetail = 128.
En la sección Memory hay una sección Devices. Si la sección Devices no está presente, añádela manualmente o cópiala desde uno de los archivos plist de ejemplo. Vamos a llenar las 12 ranuras con cuatro DIMM. Volviendo a consultar Instalar y reemplazar unidades de memoria en el Mac Pro (2019) podemos ver que nuestros cuatro DIMM deben ir en las ranuras 3, 5, 8 y 10.
En la sección Devices del archivo config.plist:
- Ítem 0 es la ranura 8 referenciada como Channel A / DIMM 1
- Ítem 2 es la ranura 10 referenciada como Channel B / DIMM 1
- Ítem 6 es la ranura 5 referenciada como Channel D / DIMM 1
- Ítem 8 es la ranura 3 referenciada como Channel E / DIMM 1.
Todos los demás elementos deben ser ranuras vacías. ¡Importante!: la clave Manufacturer debe estar configurada como NO DIMM para ellas. Size y Speed deben estar configuradas como 0 para las ranuras vacías.
Guarda el archivo config.plist.
Borra la notificación si aún la tienes en la pantalla (de lo contrario, cuando reinicies, seguirá apareciendo incluso si la memoria ahora se presenta correctamente).
Reinicia el sistema.
Si todo va según lo planeado, lo primero que notarás es la ausencia de la notificación de error de memoria. Si eso no es suficiente, consulta la sección de memoria de Ajustes del Sistema o la de Información del Sistema.
7.- Avisos en macOS 13 y 14
En macOS Sonoma y Sequoia, independientemente de que utilicemos RestrictEvents.kext o CustomMemory, puede permanecer un aviso en menú Manzana -> Acerca de este Mac, el resto funciona bien pero este texto no desaparece.
Se ha propuesto ejecutar estos 2 comandos para deshacerse del aviso:
defaults delete com.apple.SlotNotificationsPref memoryBadgeCount
defaults delete com.apple.SlotNotificationsPref expansionBadgeCount
Pero no siempre se obtiene el resultado esperado, incluso puede ser que el dominio com.apple.SlotNotificationsPref ni siquiera exista:
defaults delete com.apple.SlotNotificationsPref memoryBadgeCount;defaults delete com.apple.SlotNotificationsPref expansionBadgeCount
Domain (com.apple.SlotNotificationsPref) not found.
Defaults have not been changed.
Domain (com.apple.SlotNotificationsPref) not found.
Defaults have not been changed.
8.- Config.plist
Perfecta guía, ya me tenía hasta el moño el mensajito de la memoria, no conseguí hacerlo con lo que encontré por ahí y, con este manual, a la primera, mil gracias.
Gracias. OpenCore tiene una extensión, RestrictEvents.kext, para resolver los avisos de memory misconfiguration. De esta forma puedes o bien rellenar bien la sección memory de config.plist o bien utilizar esta extensión que es la manera recomendada por los propios creadores de OpenCore.
RestrictEvents tiene otras funciones además de esta.
Hola. Puedes subir tu config.plist? Se agradece.
Buenos días, la añado al final del artículo, he quitado los números de serie, el resto está igual que la que a mí me funciona.Tengo 32gb de RAM en 2 módulos de 16. Si tienes otra configuración, has de modificarla en config.plist. Repasa con dmidecode y pon tus datos de la memoria si no son idénticos a los míos.
Hola Pol, muchas gracias por responder, entonces la diferencia sería si la gráfica es integrada o no? Sobre el funcionamiento de hardware, hay alguna diferencia?
Disculpa tanta preguntas, que tengas un buen día y gracias por tan valioso material.
Sí, dicho en pocas palabras, si usas gráfica integrada al monitor pones iMac, si es la gráfica dedicada la que lleva la imagen al monitor coges MacPro o iMacPro.
Hay otras diferencias pero esa es la principal.
El funcionamiento de discos SSD, wifi, bluetooth, audio, etc., suele ser igual en esas SMBIOS distintas. Eso no cambia.
Hola pol, soy nuevo en el mundo hackintosh y tengo una curiosidad, no sé si puedas informarme. Cuál es la diferencia entre una iMac 19.1 y un Macpro7.1? Yo tengo configurada mi hackintosh con iMac 19.1. Gracias de antemano.
Buenos días, Serghi. La diferencia fundamental es que utilizamos uno u otro modelo de SMBIOS dependiendo del hardware que utilizamos.
iMac19,1 es una buena opción para un equipo que tiene una CPU Intel de 8ª o 9ª generación (aquellas cuya numeración empieza por 8 o por 9, por ejemplo i7-8700 o i9-9700) y que tiene activada la tarjeta gráfica integrada en la CPU, usándola como salida para el monitor.
MacPro7,1 es una buena opción para un equipo cuya CPU Intel no tiene gráfica integrada (o si la tiene, está desactivada en BIOS) y en cambio utiliza una gráfica AMD (RX580, RX6600, etc.) como salida para el monitor.
Esta sería la diferencia principal. ¿Por qué? Por el tipo de ordenador Mac que usa cada modelo de SMBIOS. El Mac Pro de 2019 (MacPro7,1) tiene una CPU Xeon sin gráfica integrada y lleva una gráfica AMD Radeon Pro 580. El iMac de 2019 (iMac19,1) lleva CPU de las familias 8ª o 9ª con tarjeta gráfica integrada (Intel 630) aunque también lleva gráfica externa AMD Radeon Pro 570.
En resumen: si la gráfica integrada en la CPU lleva la imagen al monitor, usa iMac19,1. Si tienes una tarjeta AMD de los modelos RX580 o superior, usa MacPro7,1 pero también valdría iMacPro1,1.