Como posso instalar um kernel em tempo real?


26

Eu li muitos tópicos com perguntas semelhantes, mas depois de ler as respostas, estou muito confuso. Eu encontrei neles muitos URLs com repositórios, mas as pessoas discutem sobre quais repositórios são feitos para uma ou duas versões do ubuntu, mas não encontrei nada sobre a versão 11.10. É muito cedo para pedir isso? Devo fazer o downgrade do meu ubuntu para ter um kernel em tempo real?


3
Tem certeza de que deseja um kernel em tempo real versus baixa latência? Quais são os seus requisitos?
Belacqua

Respostas:


27

O objetivo a longo prazo do projeto do kernel RT é acabar com toda a funcionalidade do RT no kernel padrão, e isso está progredindo bem . O patch RT teve lançamentos irregulares no passado, e os hackers do kernel.org em agosto de 2011 tornaram a versão 3.0 inacessível por meses, mas agora as coisas estão boas: há um patch para o 3.0 e outro para o 3.2 (coincidindo com o kernel versões no Ubuntu 11.10 e 12.04) e outra no 3.4, veja aqui .

Se você estiver usando o Precise, poderá usar o PPA Realtime de Alessio Bogani , que gentilmente empacotou o kernel vanilla com o patch RT aplicado e o mantém sincronizado com os números de versão no Precise.

Se você preferir construir o kernel RT manualmente, instale primeiro os pacotes de software necessários:

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

Em seguida, busque o kernel da baunilha e o patch RT (os números da versão são um pouco antigos, ajuste conforme necessário):

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)

Em seguida, configure o kernel usando:

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

onde você deve selecionar "preempção completa" (opção 5) quando solicitado e deixar todo o resto em seu valor padrão pressionando enter a cada prompt. A configuração do kernel -lowlatency pode ser um ponto de partida melhor que o do kernel -generic.

Então construa o kernel com:

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

E finalmente instale seu novo kernel com:

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

Você deve conseguir reiniciar o kernel RT neste momento. Se o seu kernel falhar na inicialização, verifique os parâmetros de inicialização e edite-os adequadamente no seu gerenciador de inicialização. Por exemplo, as funções da ACPI podem afetar seu sistema em tempo real (conforme indicado em rt.wiki.kernel.org). Adicionar acpi = off pode ser uma solução nesse caso.

Observe, porém, que o patch RT é incompatível com o driver binário da Nvidia (mas veja a postagem do usuário "rt-kernel" abaixo, e esta pergunta para uma solução alternativa), e que os patches do kernel do Ubuntu não estarão presentes, portanto, você pode ter problemas de hardware que você não tinha antes. Isso vale para os pacotes PPA e o kernel compilado. Você sempre pode inicializar no seu kernel -generic e desinstalar os pacotes do kernel em tempo real, se houver problemas, é claro.


1
Ótimas instruções! Eu recomendo instalar um kernel da linha principal 3.4 antes de segui-los, para obter um arquivo de configuração que melhor corresponda. Além disso, não oficiais pré-compilados 3.4.29 binários para AMD64 estão disponíveis aqui como pacotes DEB (seguindo as instruções ao pé da letra
CMC

Não consegui executar o kernel compilado seguindo estas instruções. Então, ao invés do kernel vanilla kernel.org, baixei o linux-sourcepacote do Ubuntu usando apte funcionou com sucesso.
Melebius 18/03/14

3

Outra opção é instalar o RTKernel dos repositórios do KXStudio. Ele mantém um conjunto de pacotes voltados para produções de áudio e música e possui pacotes em tempo real e de baixa latência.

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


2

Até onde eu sei, o desenvolvimento do kernel em tempo real não acompanhou o ciclo de lançamento do Ubuntu. Se você precisar executar um kernel em tempo real, provavelmente precisará executar uma versão mais antiga.

Para mais informações, consulte https://help.ubuntu.com/community/UbuntuStudio/RealTimeKernel .

Observe que parece haver pelo menos algum trabalho atual no kernel de baixa latência: https://launchpad.net/~abogani/+archive/ppa?field.series_filter=oneiric .


2

Se você depende do uso do driver binário da nvidia, pode corrigir o driver original com este patch (para 3.4+ kernels apenas com rt-patches) Esse patch é fornecido sem garantia ou garantia! Use-o por sua conta e risco .->

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

Salve o patch como "nv295.33_for 3.3 + _rt.patch". Aplique o patch->

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

Isso criará um novo instalador binário da nvidia chamado "NVIDIA-Linux-x86_64-295.33-custom.run".

Execute o instalador com

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

Este patch vem sem garantia! Use-o por sua conta e risco.

Reinicie e divirta-se.

Você encontrará mais informações no fórum nv. Lá você pode encontrar uma solução para a série 295.40 também.

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


Arrumado. O driver da nvidia corrigido também funciona com -generic? Seria útil saber como produzir um .deb em vez de usar o instalador.
Pablomme

1
Seu patch está faltando quatro espaços no início da linha elif [ "$ARCH" = "ARMv7" ]; thene no seguinte - ele não será aplicado se isso não for corrigido. Além disso, você pode mencionar que a versão 295.33 do driver da nvidia pode ser baixada em nvidia.com/object/linux-display-amd64-295.33-driver.html (não é a mais recente, mas a julgar por um relatório no phoronix. org de hoje, talvez seja melhor não usar 295,40 por enquanto).
Pablomme

sudoestá ausente no comando de instalação, bem como na indicação de que você precisa mudar para um VT e fazê- sudo killall Xorg && sudo stop lightdmlo antes de executá-lo, porque insiste em que o X não deve estar em execução. Fora isso, tudo funciona bem - agora posso evitar os erros bugs.launchpad.net/bugs/920120 e executar o Ardour de tela dupla \ o / Obrigado pelo patch!
Pablomme #

Isso não tem nada a ver com a pergunta, estou errado?
Bruno Pereira
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.