Hasta hace una horas estaba con 2GB y la curiosidad era muy grande de los 4GB y sus problemas. Yo manejaba todo de haber leído de por ahí para tirar una ayuda a alguien y por mera curiosidad. Bueno, ahí va algunas pruebas.
Código:
Placa base: Asus M2N32-SLI DELUXE (BIOS Phoenix ver 1603 [12/17/2007])
Memoria: 4 x 1GB OCZ DDR2 PC2-6400 Platinum Rev2 (OCZ2P800R21G)
Procesador: AMD Athlon 64 X2 5200+ (ADA5200IAA6CS) (stepping F2)
Video: Gygabyte GeForce 7300 GT 256MB (GV-NX73T256P-RH)
En BIOS:
Código:
Installed memory: 4096 MB
Usable memory: 4095 MB
Configurado a mano (ya que las memos se ponen por seguridad en 5-5-5-15 y son en realidad 4-4-4-15):
Código:
Memory clock frecuency: DDR2-800
Tcl: 4
Trcd: 4
Trp: 4
Tras: 15
Memory Timming: 2T
Primero que nada, antes de hacer macanas: dos pasadas de memtest86+ 2.01, y cero errores.

Memtest86+
Desde no se que versión soporta PAE, con lo cual puede acceder a toda la memoria por arriba de los 4GB.
En los escaneos se ve que lo hace en tres partes: 128K - 2048M | 2048M - 3583M | 4096M - 4608M
Notar que 3583M = 4095 (memoria usable) - 512 (que es la memoria reservada por los PCI y demás chirimbolos).
Luego 4608M = 4096 + 512 (que es la memoria remapeada por encima de los 4GB)
Quiere decir que mi rango de mapa de memoria va a ir de 0GB a 4.5GB. Si le agrego otra placa de video es muy probable que remapee 1G y no 0.5G, con lo cual mi rango se expande de 0GB a 5GB.
Linux version 2.6.24.7 (original)
¿Como es mi mapa de memoria que me dice el BIOS?. Esto es totalmente independiente de si es 32 bits, 64 bits o lo que sea el sistema operativo.
Código:
BIOS-e820: 0000000000000000 - 000000000009f000 (usable) <<< 640 KB (exactamente 636 KB)
BIOS-e820: 000000000009f000 - 00000000000a0000 (reserved) <<< VIDEO RAM modo texto
BIOS-e820: 00000000000f0000 - 0000000000100000 (reserved) <<< BIOS ROM
BIOS-e820: 0000000000100000 - 00000000dfee0000 (usable) <<< 3667840 KB ~= 3581MB ~= 3.5 GB
BIOS-e820: 00000000dfee0000 - 00000000dfee3000 (ACPI NVS)
BIOS-e820: 00000000dfee3000 - 00000000dfef0000 (ACPI data)
BIOS-e820: 00000000dfef0000 - 00000000dff00000 (reserved)
BIOS-e820: 00000000f0000000 - 00000000f4000000 (reserved) <<< esto es la zona PCI MMCONFIG
BIOS-e820: 00000000fec00000 - 0000000100000000 (reserved) <<< aca se ubican todo lo que es PCI: video, sata, usb, hpet, etc...
BIOS-e820: 0000000100000000 - 0000000120000000 (usable) <<< 524288 KB = 512 MB = 0.5 GB
Haciendo un "zoom"

Código:
00000000-0009efff : System RAM
0009f000-0009ffff : reserved
000a0000-000bffff : Video RAM area
000c0000-000cebff : Video ROM
000cec00-000cffff : pnp 00:0c
000f0000-000fffff : System ROM
00100000-dfedffff : System RAM
00100000-00381baf : Kernel code
00381bb0-0040d133 : Kernel data
00442000-004714e7 : Kernel bss
dfee0000-dfee2fff : ACPI Non-volatile Storage
dfee3000-dfeeffff : ACPI Tables
dfef0000-dfefffff : reserved
e0000000-efffffff : PCI Bus #01
e0000000-efffffff : 0000:01:00.0
f0000000-f3ffffff : PCI MMCONFIG 0
f0000000-f3ffffff : reserved
fb000000-fdffffff : PCI Bus #01
fb000000-fbffffff : 0000:01:00.0
fb000000-fbffffff : nvidia
fc000000-fcffffff : 0000:01:00.0
fdfe0000-fdffffff : 0000:01:00.0
fe028000-fe02800f : 0000:00:10.0
fe028000-fe02800f : forcedeth
fe029000-fe0290ff : 0000:00:10.0
fe029000-fe0290ff : forcedeth
fe02a000-fe02afff : 0000:00:10.0
fe02a000-fe02afff : forcedeth
fe02b000-fe02bfff : 0000:00:0d.2
fe02b000-fe02bfff : sata_nv
fe02c000-fe02cfff : 0000:00:0d.1
fe02c000-fe02cfff : sata_nv
fe02d000-fe02dfff : 0000:00:0d.0
fe02d000-fe02dfff : sata_nv
fe02e000-fe02e0ff : 0000:00:0a.1
fe02e000-fe02e0ff : ehci_hcd
fe02f000-fe02ffff : 0000:00:0a.0
fe02f000-fe02ffff : ohci_hcd
fec00000-ffffffff : reserved
fefff000-fefff3ff : HPET 0
100000000-11fffffff : System RAM
Ahí se puede ver que lo usable son los famosos "640k" de ¿se acuerdan DOS?

Luego se ve unos 3.5GB usables, el groso groso, y finalmente unos 0.5GB.
Bien, a esos 0.5GB hay dos formas de acceder en 32 bits con PAE, o en 64 bits, que PAE es un requerimiento de los 64 bits, sino sólo voy a ver 3.5GB de RAM.
El gran tema es que hay ciertas configuraciones viejas que ese remapeo no lo hace, por lo que lo ocupado por el PCI se pierde, no importa que sistema operativo ponga.
Bien, antes dije que en mi vieja configuración disponía de 2GB, y con lo cual, para tener esos 2GB disponibles, tenía en principio dos alternativas:
* Usar una separación de memoria común usuario/kernel de 3G/1G + HIGHMEM, lo que da unos 896MB de LOWMEM + 128MB VMALLOC + 1024MB HIGHMEM para el resto, y en consecuencia teniendo cierta pérdida no sólo por esos 128MB para usar de "trampolin" entre la memoria baja y alta, sino que una perdida de performance para acceder a la memoria alta.
* Usar una separación sin HIGHMEM: de 2G/2G (pequeña perdida de 128MB) o 2G/2G_OPT (que en realidad es 2.125/1.875 para ser exacto) para ver completo estos 2GB como LOWMEM sin uso de HIGHMEM y por consiguiente sin perdida en rendimiento, eso sí, ninguna aplicación podía superar los 2GB, cosa que en mi caso nunca pasó.
Existen otras contras de usar un split distinto de 3G/1G, por ejemplo el Wine no funciona, y puede que ciertos drivers binarios cerrados no funcionen tampoco, no es es caso de NVIDIA.

Citar:
En conclusión yo usaba el 2G/2G_OPT.
¿Que pasa al arrancar un kernel de 32 bits con 2G/2G_OPT (sin HIGHMEM) y 4GB (bueno en realidad 4.5GB por el remapeo que se hace)
(este fue mi arranque inicial)
Código:
Warning only 2048MB will be used.
Use a HIGHMEM64G enabled kernel.
2048MB LOWMEM available.
Me da un aviso particular, me dice, que sólo voy a ver 2G

, y pero que si quiero ver toda la RAM habilite HIGHMEM64G.
Dice HIGHMEM64G, y no, el HIGHMEM4G porque hay memoria por arriba de los 4GB, y para acceder a la misma es necesario PAE.
Al fin y al cabo la memoria que dispongo es:
Código:
Memory: 2075060k/2097152k available (2552k kernel code, 21580k reserved, 559k data, 188k init, 0k highmem)
Citar:
Que son 2026MB.
Compilo mi kernel cambiando a 3G/1G sin HIGHMEM (sólo por diversión)
Arranco:
Código:
Warning only 896MB will be used.
Use a HIGHMEM64G enabled kernel.
896MB LOWMEM available.
Y sólo ve otro número famoso que es 896MB de RAM (1024MB - 128MB de VMALLOC)
Código:
Memory: 905524k/917504k available (2552k kernel code, 11580k reserved, 559k data, 188k init, 0k highmem)
Citar:
Que son unos 885MB.
De aquí en más sigo con el split standard de memoria de 3G/1G.
Bien, avancemos un poco habilito HIGHMEM4G.
Código:
Warning only 4GB will be used.
Use a HIGHMEM64G enabled kernel.
3200MB HIGHMEM available.
896MB LOWMEM available.
Código:
Memory: 3630456k/4194304k available (2554k kernel code, 37276k reserved, 558k data, 188k init, 2751360k highmem)
Citar:
Que son unos 3546MB.~= 3.5GB

Pero yo quiero mis 4GB!

OK, habilito PAE. (HIGHMEM64G)
Código:
3712MB HIGHMEM available.
896MB LOWMEM available.
Código:
Memory: 4150620k/4718592k available (2566k kernel code, 41384k reserved, 557k data, 188k init, 3275648k highmem)
Citar:
Que son unos 4053MB ~= 4GB

Sí, no son 4096MB, desde ya que no, el kernel ocupa espacio junto con otras estructuras internas que se detallan ahí, tampoco en 1G tenes 1G ni en 2G tenes 2G, etc.
Fijense la diferencia importante del segundo número de estas razones 2075060k/2097152k | 905524k/917504k | 3630456k/4194304k | 4150620k/4718592k.
Código:
2097152 = 2048MB = 2.0GB (2G/2G_OPT) = (1.875/2.125)
917504 = 896MB < 1.0GB (3/1)
4194304 = 4096MB = 4.0GB (3/1) + HIGHMEM de 4G
4718592 = 4608MB = 4.5GB (3/1) + HIGHMEM de 64G [PAE]
Otro split típico es del de 3G/1G_OPT que es en realidad 2.75/1.25 para tener FULL 1GB de RAM en máquinas con 1GB de RAM. Existe uno de 1G/3G, pero realmente es muy chico. Ves unos 3GB-128MB de RAM, pero tus apps no pueden superar 1GB.
La regla es: "lo que yo le asigno al kernel en la separación de memoria es lo que voy a tener de LOWMEM, lo demás será visible sólo si habilito HIGHMEM"
OK, pasemos a 64 bits

errores de acceso a dispositivos, PCI (sata, usb, etc etc etc).... y.....
KERNEL PANIC no encuentra el /
Bien, yo tenía ajustadito el kernel, entonces no tenía habilitado el IOMMU (GART de AMD)
¿Que es masomenos el IOMMU? Bueno, permite acceder utilizando un método especial a los dispositivos PCI que son de 32 bits cuando se está en 64 bits.
AMD tiene un IOMMU simulado con un AGP GART, Intel no dispone de tal circuito y la solución es usa un área de memoria RAM de "bounce buffer" (conocido como "double buffer" en entornos Windows) para de ahí hacer las transferencias.
¿Ambas soluciones se comen memoria? Sí.
¿Que hago? arranco el kernel con mem=4G o mem=3G (lo mismo da, mientras sea 32 bits máximo) con esto el kernel arranca perfecto.
Recompilo el kernel con IOMMU GART AMD.
Bien, ahora juego...
Parametros del kernel mem=4G iommu=off
Código:
CPU 0: aperture @ 10000000 size 32 MB
Aperture too small (32 MB)
No AGP bridge found
Memory: 3607556k/3668864k available (2892k kernel code, 60740k reserved, 751k data, 196k init)
Citar:
El sistema ve 3668864k ~= 3583MB como es esperado, y tengo disponibles para uso: 3523MB
Notar la diferencia con lo anterior en cuanto a la "visibilidad" debido al mem=4G y que en 64 bits no existe el concepto de memoria LOW y HIGH

Ahora sí, sí o sí IOMMU si quiero esos 0.5GB extras, de lo contrario KERNEL PANIC, no es posible una comunicación con el PCI.
Bien, sin parámetros:
Código:
Checking aperture...
CPU 0: aperture @ 8000000 size 32 MB
Aperture too small (32 MB)
No AGP bridge found
Your BIOS doesn't leave a aperture memory hole
Please enable the IOMMU option in the BIOS setup
This costs you 64 MB of RAM
Mapping aperture over 65536 KB of RAM @ 8000000
Memory: 4051968k/4718592k available (2892k kernel code, 140628k reserved, 751k data, 196k init)
Mi placa no tiene AGP, por lo que no tengo una forma de configurar una apertura de memoria, el kernel dice, 32MB que hay actualmente son muy chicos, lo subo a 64MB y los pongo en la dirección 8000000.
Citar:
Memoria visible 4718592 = 4.5GB, usable = 3957MB
Bien, se puede leer por varios lados, errores FEOS pero muy FEOS y con corrupción de datos, al llenarse esta memoria de IOMMU, por lo que se recomienda para solventar el problema agrandarla. El error del que hablo es "PCI-DMA: Out of IOMMU space for XXXXXX bytes at device NNNN:NN:NN.N"
Por lo visto se da en transferencias altas de datos.
La solución es agrandar este espacio default de 64MB por soft en caso de que el BIOS no lo permita, ¿como? con un parámetro del kernel ( Documentation/x86_64/boot-options.txt )
Citar:
iommu=memaper=2 (para 128MB) o iommu=memaper=3 (para 256MB)
(La regla es 32 << N , 00010000 desplazamiento a izquiera N lugares

)
Bueno, arranco con 256MB de apertura, por las dudas (128 lo salteo)
Código:
Checking aperture...
CPU 0: aperture @ 8000000 size 32 MB
Aperture too small (32 MB)
Your BIOS doesn't leave a aperture memory hole
Please enable the IOMMU option in the BIOS setup
This costs you 256 MB of RAM
Mapping aperture over 262144 KB of RAM @ 10000000
Memory: 3855360k/4718592k available (2892k kernel code, 337236k reserved, 751k data, 196k init)
Citar:
Lo mismo: Memoria visible 4718592 = 4.5GB, usable = 3765MB
Resumiendo un poco lo que sirve: ¡memoria usable por mis aplicaciones!
Código:
32 bits (HIGHMEM4G): 3546 MB
32 bits (HIGHMEM64G [PAE]): 4053 MB (*)
64 bits (mem=4G NOIOMMU): 3523 MB (**)
64 bits (IOMMU: 64 MB): 3957 MB (***)
64 bits (IOMMU: 256MB): 3765 MB (****)
(*) Gano 507MB, realmente no se que tanto rendimiento pierdo por un nivel más en direccionamiento por PAE, supongo que actualmente es despreciable, 64 bits siempre PAE y no nos quejamos...)
(**) Uso 64 bits 3.5GB de RAM y me quedo tranquilo de que no va a ver temas de corrupción de datos al no usar el IOMMU (si este se desborda)
(***) 64 bits, 3.9GB casi 4GB) pero.... corro el riesgo de corrupción de datos
(****) 64 bits, 3.7GB casi +256MB que (**) pero uso un IOMMU, que SUPONGO YO, con 256MB no hay problema de corrupción de datos.
Y para terminar, creo, me parece, digo... En un sistema con 4GB, y que si el GART, como leí por ahí, puede dar quilombos (no lo se si con 256MB ocurre), creo que vale la pena sacrificar 256MB menos y no usar el IOMMU.
Ahora la cosa cambia claro, cuando mi sistema dispone de más de 4GB, ahí, sí o sí tengo que usar IOMMU y es cuestión de probar si con 256MB de GART no hay problema.
Tema importante, no se si existe en "desktop", tengo que informarme mejor. El PCI soporta un modo que es DAC (Dual Address Cycle) esto permite en 64 bits, partir la dirección de 64 bits en dos, enviando en un ciclo una parte de 32 bits y en el otro la que resta.
Espero que sea de ayuda y aclaración.
Cualquier duda, sugerencia, experimento (que no ponga en riesgo mis datos) será bienvenido.
Son las 2:45 de la matina ¡ME VOY A DORMIR!
¡Buena salud y buen sexo!
PD: Ahora sí, acabé con la curiosidad, una especie de nirvana
