¿Cómo puedo instalar un kernel en tiempo real?

26

He leído muchos hilos con preguntas similares, pero después de leer las respuestas, estoy muy confundido. He encontrado en ellos muchas URL con repositorios, pero la gente discute sobre qué repositorios están hechos para una o dos versiones de ubuntu, pero no he encontrado nada sobre la versión 11.10. ¿Es demasiado pronto para pedir eso? ¿Debo degradar mi ubuntu para tener un kernel en tiempo real?

Jorge
fuente
3
¿Estás seguro de que quieres un kernel en tiempo real vs. baja latencia? ¿Cuáles son tus requisitos?
belacqua

Respuestas:

27

El objetivo a largo plazo del proyecto de kernel RT es terminar teniendo toda la funcionalidad RT en el kernel estándar, y esto está progresando bastante bien . El parche RT ha tenido versiones irregulares en el pasado, y el pirateo de kernel.org en agosto de 2011 hizo que la versión 3.0 fuera inaccesible durante meses, pero ahora las cosas se ven bien: hay un parche para 3.0, otro para 3.2 (que coincide con el kernel versiones en Ubuntu 11.10 y 12.04), y otra para 3.4, ver aquí .

Si está utilizando Precise, puede utilizar el PPA en tiempo real de Alessio Bogani , que ha empaquetado amablemente el núcleo de vainilla con el parche RT aplicado y lo mantiene sincronizado con los números de versión en Precise.

Si prefiere construir el núcleo RT a mano, primero instale los paquetes de software necesarios:

sudo apt-get install kernel-package fakeroot build-essential libncurses5-dev

Luego busque el kernel de vainilla y el parche RT (los números de versión son algo antiguos, modifique según sea necesario):

mkdir -p ~/tmp/linux-rt
cd ~/tmp/linux-rt
wget http://www.kernel.org/pub/linux/kernel/v3.x/linux-3.4.tar.bz2
# Alternatively, try http://mirror.be.gbxs.net/pub/linux/kernel/projects/rt/3.4/patch-3.4-rt7.patch.bz2
# if the following is not available:
wget http://www.kernel.org/pub/linux/kernel/projects/rt/3.4/patch-3.4-rt7.patch.bz2
tar xjvf linux-3.4.tar.bz2
cd linux-3.4
patch -p1 < <(bunzip2 -c ../patch-3.4-rt7.patch.bz2)

Luego configure el kernel usando:

cp /boot/config-$(uname -r) .config && make oldconfig

donde debe seleccionar "preferencia total" (opción 5) cuando se le solicite, y dejar todo lo demás en su valor predeterminado presionando enter en cada solicitud. La configuración del núcleo -lowlatency podría ser un mejor punto de partida que el del núcleo genérico.

Luego construya el núcleo con:

sed -rie 's/echo "\+"/#echo "\+"/' scripts/setlocalversion
make-kpkg clean
CONCURRENCY_LEVEL=$(getconf _NPROCESSORS_ONLN) fakeroot make-kpkg --initrd --revision=0 kernel_image kernel_headers

Y finalmente instale su nuevo núcleo con:

sudo dpkg -i ../linux-{headers,image}-3.4.0-rt7_0_*.deb

Debería poder reiniciar en su núcleo RT en este punto. Si su kernel no arranca, asegúrese de verificar dos veces los parámetros de arranque y editarlos en consecuencia en su gestor de arranque. Por ejemplo, las funciones ACPI pueden afectar su sistema en tiempo real (como se indica en rt.wiki.kernel.org). Agregar acpi = off puede ser una solución en tal caso.

Sin embargo, tenga en cuenta que el parche RT es incompatible con el controlador binario de Nvidia (pero vea la publicación del usuario "rt-kernel" a continuación, y esta pregunta para una solución alternativa), y que los parches del kernel de Ubuntu no estarán presentes, por lo que puede tener problemas de hardware que no tenías antes. Esto es cierto tanto para los paquetes PPA como para el núcleo compilado. Siempre puede iniciar en su núcleo genérico y desinstalar los paquetes del núcleo en tiempo real si le causan problemas, por supuesto.

pablomme
fuente
1
Grandes instrucciones! Recomiendo instalar un núcleo de línea principal 3.4 antes de seguirlos, para obtener un archivo de configuración que coincida mejor. Además, los binarios no oficiales precompilados 3.4.29 para AMD64 están disponibles aquí como paquetes DEB (siguiendo estas instrucciones al pie de la letra
cmc
No pude ejecutar el núcleo compilado siguiendo estas instrucciones. Entonces, en lugar del núcleo de vainilla kernel.org, descargué el linux-sourcepaquete de Ubuntu usando apty funcionó con éxito en ese momento.
Melebius
3

Otra opción es instalar el RTKernel desde los repositorios de KXStudio. Mantiene un conjunto de paquetes destinados a producciones de audio y música y tiene paquetes en tiempo real y de baja latencia.

http://kxstudio.sourceforge.net/Main_Page https://launchpad.net/~kxstudio-team/+archive/kernel

Rafael Vega
fuente
2

Hasta donde sé, el desarrollo del kernel en tiempo real no ha seguido el ritmo del ciclo de lanzamiento de Ubuntu. Si debe ejecutar un kernel en tiempo real, probablemente tendrá que ejecutar una versión anterior.

Para obtener más información, consulte https://help.ubuntu.com/community/UbuntuStudio/RealTimeKernel .

Tenga en cuenta que parece haber al menos algún trabajo actual en el kernel de baja latencia: https://launchpad.net/~abogani/+archive/ppa?field.series_filter=oneiric .

belacqua
fuente
2

Si depende del uso del controlador binario nvidia, puede parchear el controlador original con este parche (solo para núcleos 3.4+ con parches rt). ¡Este parche no tiene garantía ni garantía! Úselo bajo su propio riesgo .->

Index: kernel/conftest.sh
===================================================================
--- kernel/conftest.sh.orig
+++ kernel/conftest.sh
@@ -95,7 +95,7 @@
         fi
     fi

-    CFLAGS="$CFLAGS $OUTPUT_CFLAGS -I$HEADERS $AUTOCONF_CFLAGS"
+    CFLAGS="$CFLAGS $OUTPUT_CFLAGS -I$HEADERS -I$OUTPUT/arch/x86/include/generated $AUTOCONF_CFLAGS"

     test_xen

@@ -126,7 +126,7 @@
     CFLAGS="$BASE_CFLAGS $MACH_CFLAGS $OUTPUT_CFLAGS -I$HEADERS $AUTOCONF_CFLAGS"

     if [ "$ARCH" = "i386" -o "$ARCH" = "x86_64" ]; then
-        CFLAGS="$CFLAGS -I$SOURCES/arch/x86/include -I$SOURCES/arch/x86/include/generated"
+        CFLAGS="$CFLAGS -I$SOURCES/arch/x86/include -I$OUTPUT/arch/x86/include/generated"
 elif [ "$ARCH" = "ARMv7" ]; then
     CFLAGS="$CFLAGS -I$SOURCES/arch/arm/include -I$SOURCES/arch/arm/include/generated"
     fi
@@ -512,7 +512,12 @@
             # and if it as an 'event' member.
             #
             echo "$CONFTEST_PREAMBLE
-            #include <asm/system.h>
+            #include <linux/version.h>
+       #if LINUX_VERSION_CODE > KERNEL_VERSION(3, 3, 0)
+         #include <asm/switch_to.h>
+       #else
+         #include <asm/system.h>
+       #endif
             #include <linux/pm.h>
             void conftest_pm_message_t(pm_message_t state) {
                 pm_message_t *p = &state;
@@ -965,11 +970,12 @@
             #
             echo "$CONFTEST_PREAMBLE
             #include <linux/acpi.h>
+            #include <acpi/acpixf.h>
             void conftest_acpi_walk_namespace(void) {
                 acpi_walk_namespace();
             }" > conftest$$.c

-            $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
+            #CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
             rm -f conftest$$.c

             if [ -f conftest$$.o ]; then
@@ -980,6 +986,7 @@

             echo "$CONFTEST_PREAMBLE
             #include <linux/acpi.h>
+       #include <acpi/acpixf.h>
             void conftest_acpi_walk_namespace(void) {
                 acpi_walk_namespace(0, NULL, 0, NULL, NULL, NULL, NULL);
             }" > conftest$$.c
@@ -996,6 +1003,7 @@

             echo "$CONFTEST_PREAMBLE
             #include <linux/acpi.h>
+            #include <acpi/acpixf.h>
             void conftest_acpi_walk_namespace(void) {
                 acpi_walk_namespace(0, NULL, 0, NULL, NULL, NULL);
             }" > conftest$$.c
@@ -1603,6 +1611,9 @@
                 fi
             fi
         fi
+
+   RET=0
+   SELECTED_MAKEFILE=Makefile.kbuild

         if [ "$RET" = "0" ]; then
             ln -s $SELECTED_MAKEFILE Makefile
Index: kernel/nv-linux.h
===================================================================
--- kernel/nv-linux.h.orig
+++ kernel/nv-linux.h
@@ -111,7 +111,11 @@
 #include <linux/timer.h>

 #include <asm/div64.h>              /* do_div()                         */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 3, 0)
+#include <asm/switch_to.h>
+#else
 #include <asm/system.h>             /* cli, sli, save_flags             */
+#endif
 #include <asm/io.h>                 /* ioremap, virt_to_phys            */
 #include <asm/uaccess.h>            /* access_ok                        */
 #include <asm/page.h>               /* PAGE_OFFSET                      */
@@ -291,17 +295,17 @@
 #endif
 #endif

-#if defined(CONFIG_PREEMPT_RT)
-typedef atomic_spinlock_t         nv_spinlock_t;
-#define NV_SPIN_LOCK_INIT(lock)   atomic_spin_lock_init(lock)
-#define NV_SPIN_LOCK_IRQ(lock)    atomic_spin_lock_irq(lock)
-#define NV_SPIN_UNLOCK_IRQ(lock)  atomic_spin_unlock_irq(lock)
-#define NV_SPIN_LOCK_IRQSAVE(lock,flags) atomic_spin_lock_irqsave(lock,flags)
+#if defined(CONFIG_PREEMPT_RT_FULL)
+typedef raw_spinlock_t            nv_spinlock_t;
+#define NV_SPIN_LOCK_INIT(lock)   raw_spin_lock_init(lock)
+#define NV_SPIN_LOCK_IRQ(lock)    raw_spin_lock_irq(lock)
+#define NV_SPIN_UNLOCK_IRQ(lock)  raw_spin_unlock_irq(lock)
+#define NV_SPIN_LOCK_IRQSAVE(lock,flags) raw_spin_lock_irqsave(lock,flags)
 #define NV_SPIN_UNLOCK_IRQRESTORE(lock,flags) \
-  atomic_spin_unlock_irqrestore(lock,flags)
-#define NV_SPIN_LOCK(lock)        atomic_spin_lock(lock)
-#define NV_SPIN_UNLOCK(lock)      atomic_spin_unlock(lock)
-#define NV_SPIN_UNLOCK_WAIT(lock) atomic_spin_unlock_wait(lock)
+  raw_spin_unlock_irqrestore(lock,flags)
+#define NV_SPIN_LOCK(lock)        raw_spin_lock(lock)
+#define NV_SPIN_UNLOCK(lock)      raw_spin_unlock(lock)
+#define NV_SPIN_UNLOCK_WAIT(lock) raw_spin_unlock_wait(lock)
 #else
 typedef spinlock_t                nv_spinlock_t;
 #define NV_SPIN_LOCK_INIT(lock)   spin_lock_init(lock)
@@ -956,8 +960,8 @@
     return ret;
 }

-#if defined(CONFIG_PREEMPT_RT)
-#define NV_INIT_MUTEX(mutex) semaphore_init(mutex)
+#if defined(CONFIG_PREEMPT_RT_FULL)
+#define NV_INIT_MUTEX(mutex) sema_init(mutex,1)
 #else
 #if !defined(__SEMAPHORE_INITIALIZER) && defined(__COMPAT_SEMAPHORE_INITIALIZER)
 #define __SEMAPHORE_INITIALIZER __COMPAT_SEMAPHORE_INITIALIZER

Guarde el parche como "nv295.33_for 3.3 + _rt.patch". Aplicar el parche->

sh NVIDIA-Linux-x86_64-295.33.run --apply-patch nv295.33_for 3.3+_rt.patch

Esto generará un nuevo instalador binario de nvidia llamado "NVIDIA-Linux-x86_64-295.33-custom.run".

Ejecute el instalador con

sh NVIDIA-Linux-x86_64-295.33-custom.run

¡Este parche viene sin garantía ni garantía! Úselo bajo su propio riesgo.

Reinicia y diviértete.

Encontrarás más información en el foro nv. Allí también puede encontrar una solución para la serie 295.40.

http://www.nvnews.net/vbulletin/showthread.php?p=2546508

rt-kernel
fuente
Ordenado. ¿Funciona también el controlador parcheado de nvidia con -generic? Sería útil saber cómo producir un .deb en lugar de usar el instalador.
pablomme
1
Al parche le faltan cuatro espacios al comienzo de la línea elif [ "$ARCH" = "ARMv7" ]; theny el siguiente: no se aplicará si esto no se soluciona. Además, es posible que desee mencionar que la versión 295.33 del controlador de nvidia se puede descargar desde nvidia.com/object/linux-display-amd64-295.33-driver.html (ya no es la última, pero a juzgar por un informe en phoronix. org de hoy puede ser mejor no usar 295.40 por el momento).
pablomme
sudofalta en el comando de instalación, así como la indicación de que necesita cambiar a un VT y hacerlo sudo killall Xorg && sudo stop lightdmantes de ejecutarlo porque insiste en que X no debe estar ejecutándose. Aparte de eso, todo funciona bien: ahora puedo evitar errores bugs.launchpad.net/bugs/920120 y ejecutar Ardor \ o / de doble pantalla. ¡Gracias por el parche!
pablomme
Esto no tiene nada que ver con la pregunta, ¿estoy equivocado?
Bruno Pereira