Lo que estás pidiendo se llama DMA. Necesita escribir un controlador para reservar esta memoria.
Sí, me doy cuenta de que dijiste que no querías que el sistema operativo interviniera, y que un controlador se convierte en parte del sistema operativo, pero en ausencia de una reserva del controlador, el núcleo cree que toda la memoria le pertenece. (A menos que le diga al núcleo que ignore el bloque de memoria, según la respuesta de Aaron, eso es).
El Capítulo 15 (PDF) de " Controladores de dispositivos Linux, 3 / e " de Rubini, Corbet y Kroah-Hartmann cubre DMA y temas relacionados.
Si desea una versión HTML de esto, encontré la versión de la segunda edición del capítulo en otra parte en línea. Tenga en cuenta que la segunda edición tiene más de una década, ya que salió cuando el kernel 2.4 era nuevo. Ha habido mucho trabajo en el subsistema de administración de memoria del núcleo desde aquellos días, por lo que puede que ya no se aplique muy bien.
Si desea que el sistema operativo lo ignore por completo , debe hacer un agujero de memoria con "
memmap
." Ver esta referencia . Por ejemplo, si desea 512M en la barrera de 2GB, puede poner "memmap=512M$2G
" en la línea de comando del núcleo.Deberá verificar su
dmesg
para encontrar un agujero contiguo para robar para que no pisotee ningún dispositivo; eso es específico para su placa base + tarjetas.Esta no es la forma recomendada de hacer las cosas: consulte la respuesta de Warren Young sobre cómo hacerlo correctamente (controladores de kernel + DMA). Estoy respondiendo la pregunta exacta que hiciste. Si planeas hacer esto para los usuarios finales, te odiarán si les haces esto ... confía en mí, esa es la única razón por la que sabía esta respuesta.
Editar: Si está utilizando grub2 w / grubby (por ejemplo, CentOS 7), debe asegurarse de escapar de $ . Debería haber un solo
\
antes$
. Ejemplo:fuente
uint8_t *ptr = 0x8000000
" con mi ejemplo? O eso puede ser por defecto ... Huh, realmente no lo sé. Nuevamente, sabía la respuesta porque era un usuario final de una tarjeta PCI mal diseñada donde tenía que asignar manualmente un búfer debajo de la marca 4G y luego decirle a un conductor dónde estaba ese espacio; Es posible que no sea posible desde el usuario.MMAP_FIXED | MMAP_ANON
. Sin un dispositivo DMA personalizado aquí para jugar, no puedo decir si realmente hace lo que el OP quería, pero mi caja CentOS felizmente me dio un bloque de 8 MB a 512 MB cuando dijememmap=8M$512M
en GRUB. Ni siquiera requiere acceso de root, como había temido que pudiera. Pero incluso si esto hace lo correcto, sigo pensando que probablemente necesitará un controlador para manejar las interrupciones y demás.mmap()
las páginas d se ponen a cero antes de que el código de usuario las vea. Se hace por seguridad, para que los datos no se filtren de un proceso a otro. Otra razón para usar un controlador, ya que es posible que deba conservar el contenido del búfer DMA en el momento de la carga del controlador. Ah, y por cierto, lammap()
llamada localizada arbitrariamente tiene éxito incluso sin lamemmap
opción de arranque del kernel, al menos siempre que nadie esté usando la memoria ubicada donde solicitó. La opción de arranque sin duda aumenta las posibilidades de éxito, pero no es estrictamente necesario.Para reservar un bloque de memoria del kernel en Linux basado en ARM, también puede usar un
reserved-memory
nodo en el archivo de árbol de su dispositivo (dts). En la documentación del kernel (ver aquí ), hay un ejemplo:fuente
Primero ingrese este comando, para verificar su configuración actual:
Para cambiar el valor establecido, edite
/etc/sysctl.conf
. Busca la línea:Si no existe, créelo (junto con su valor deseado). Los siguientes valores son aceptables:
8M es extremadamente conservador; Puede sentarse cómodamente a 16M. Una vez que cambie el valor, ejecute esto y no es necesario reiniciar:
fuente