2006-10-03

 

Realtid - grunder

I ett typiskt Linuxbaserat Audio/MIDI-system kan man hitta flera olika komponenter som måste samverka:
Jag ska försöka förklara allt detta under textens gång. Men vi börjar från grunden.


IRQ

IRQ står för Interrupt ReQuest. Detta innebär en avbrottskanal där enheter som behöver sända data påkallar uppmärksamhet. Processorn avbryter då för att ta emot data från den enhet som sänt IRQ.

I begynnelsen fanns AT-datorerna. Dessa hade 8 IRQ (0-7), som sedan utökades till 16 (0-15). När det fanns åtta IRQ var prioritetsordningen mellan dem så att lägst nummer hade högst prioritet och högst nummer hade lägst prioritet.

När IRQ utökades till 16 stycken, lade man in alla från 8-15 i platsen för IRQ 2, så nu ser prioritetsordningen ut som följer:

0, 1, (8, 9, 10, 11, 12, 13, 14, 15), 3, 4, 5, 6, 7

Detta innebär att IRQ 9, 10 och 11 är högre prioriterade än exempelvis 3 och 4. Detta går dock att ändra på.


PROCESS-PRIORITET

Man kan mycket förenklat säga att ju högre prioritet en process har, ju större chans är det att den kan köra ostört. Med en realtids-kärna har man möjlighet att låta IRQ-hanterare köras med lägre prioritet än användarapplikationer.

Det är, till exempel, möjligt att köra jackd med högre prioritet än alla IRQer för att säkerställa ostörd audio-hantering. Detta kan även inkludera IRQer för hårddisk och nätverkskort.

I en standard realtids-kärna har alla IRQ-hanterare en prioritet mellan 40-60. Genom att sätta jackd's prioritet till 70, gör vi så att JACK går före alla enheters begäran om åtkomst till processorn och databussen. Vi gör detta med jackd's -P switch:

# jackd -R -P 70 -d alsa ...

Det är ju allt väl, om det inte vore så att den IRQ som ljudkortet ligger på, och JACK använder sig av, bör ligga högre i prioritetsskalan än jackd.

Introduktion alltså för ett nytt program, som brukar ligga i ett paket som heter något liknande schedutils, chrt. Med chrt kan man ändra realtids-attributen för en viss process.

I realtidskärnan har varje IRQ ett process-ID (pid) för att det ska vara möjligt att manuellt ställa prioriteten på dem. För att lista ut vilka process-IDn som innehas av olika IRQer använder vi oss av programmet ps. ps är en typisk UNIX-förkortning som står för process och kommandot kan visa alla processer som för närvarande finns på systemet. För att bara visa de processer som har beskrivningen IRQ använder vi kommandot grep och filtrerar ps-kommandot genom det:

$ ps ax | grep IRQ
18 ? S< 0:00 [IRQ 9]
808 ? S< 0:00 [IRQ 12]
891 ? S< 0:00 [IRQ 1]
1724 ? S< 0:00 [IRQ 14]
1803 ? S< 0:00 [IRQ 10]
2837 ? S< 0:00 [IRQ 3]
2946 ? S< 0:00 [IRQ 8]
2960 ? S< 0:00 [IRQ 7]
3004 ? S< 0:00 [IRQ 6]
3080 ? S< 0:00 [IRQ 11]
5403 pts/0 R+ 0:00 grep IRQ

Om vi ska modifiera prioriteten på IRQ för ljudkortet, tittar vi först vilken IRQ som det använder sig av genom att lista den virtuella filen /proc/interrupts med kommandot cat:

$ cat /proc/interrupts
CPU0
0: 357694670 XT-PIC timer 0/94670
1: 192527 XT-PIC i8042 0/92527
2: 0 XT-PIC cascade 0/0
3: 3683355 XT-PIC CS46XX 0/83355 <
8: 12983156 XT-PIC rtc 0/83156
9: 203367747 XT-PIC ICE1712 0/67747 <
10: 18757427 XT-PIC eth0 0/57427
11: 652848 XT-PIC nvidia 0/52848
12: 3109504 XT-PIC i8042 0/9504
14: 1693997 XT-PIC ide0 0/93997
15: 3617940 XT-PIC ide1 0/17940
NMI: 0
ERR: 600

Eftersom de ljudkort som finns installerade har ICE1712-chip samt CS46xx-chip så kan man av listningen ovan sluta sig till att raderna markerade med < style="font-weight: bold;">IRQ 3 och 9.

Detta är inte alldeles enkelt för en nybörjare att klara av, så om du är en sån, ha gärna med dig en garvad nörd som du kan rådfråga med jämna mellanrum.

Processerna kan alltså ändras genom kommandot chrt med följande växlar, -p för prioritet 0-99 och -f för FIFO (First In First Out) policy, vilket är vad som bör användas i ljudsammanhang.

För enkelhetens skull kan man använda kommandot pidof som tar process-IDt från en process som matchar en viss textsträng.

# chrt -f -p 99 `pidof "IRQ 3"`

eller enligt ps-listningen en bit ovan:

# chrt -f -p 99 2837

Det är bra, för att inte säga en förutsättning, för ett lyckat resultat att ha ljudkortet på en egen IRQ. Om ljudkortet delar IRQ med till exempel nätverkskortet (exempelvis eth0) får detta lika hög prioritet som ljudkortet och hotar att dra en massa elände med sig.

Men det förutsätter som sagt att man lyckats kompilera sin egen kärna med realtids-patchning. Det går vi igenom i nästa avsnitt.

 

Realtidskärna - Ubuntu

Att kompilera sin egen kärna är inte alltid så enkelt. Det finns dock några knep för att underlätta för oss Ubuntu-användare också.

Men först måste vi skapa förutsättningar för att kunna kompilera kärnan.


FÖRUTSÄTTNINGAR

För att över huvud taget kunna kompilera något behöver vi paketet build-essential som är ett meta-paket som installerar alla nödvändiga utvecklingspaket för att kompilera, och för att konfigurera kärnan krävs paketet libncurses5-dev för att få ett fint litet menysystem att rodda runt i.

Installera dessa genom att skriva:

sudo apt-get install build-essential libncurses5-dev

i en terminal.


PATCHA KÄRNAN

Sen är det dags att plocka hem källkoden till kärnan och allt som hör till. Detta gör vi genom att ta ner den senaste RT-patchen från Ingo Molnars hemsida

http://people.redhat.com/mingo/realtime-preempt/

och välj näst senaste utgåva i katalogen older/.

Själv hämtade jag patch-2.6.17-rt8 och det har fungerat bra hittills.

Sen är det dags att hämta källkoden till kärnan. Då gäller endast "hela" versionsnummer, alltså 2.6.17, inte 2.6.17.1, inte 2.6.17.8 eller något annat. Dessutom är det bara den officiella kärnan från kernel.org som ska användas, inte Ubuntus egenpaketerade.

Denna finns tillgänglig som linux-2.6.17.tar.gz i

ftp://ftp.kernel.org/pub/linux/kernel/v2.6/

Spara den i /usr/src och utför följande kommandon för att packa upp källkodsträdet:

# tar zxvf linux-2.6.17.tar.gz
# mv linux-2.6.17 linux-2.6.17-rt8
# mv linux linux.old
# ln -s linux-2.6.17-rt8/ linux

För Ubuntu krävs dessutom en speciell patch för diskhanteringen (EVMS - Enterprise Volume Management System) som installeras på följande sätt:

# apt-get install kernel-patch-evms
# gunzip kernel-patches/diffs/evms-bd-claim/2.6-bd-claim.patch.gz

Kontrollera dessutom att källkoden för realtime-lsm inte ligger och skräpar någonstans, för då kommer inte kompileringen av kärnan att fungera. Detta kan göras genom att se huruvida det finns en katalog som heter något liknande /usr/src/modules/realtime-lsm med kommandot

ls /usr/src/modules/

Om den katalogen inte finns kan ni vara lugna.

Sen är det alltså dags att patcha. Det är viktigt att vi står i katalogen /usr/src/. För att göra ett testskott så provar vi med växeln --dry-run och ser så att det inte blir några fel:

# patch --dry-run -p1 < sökväg/till/patch-2.6.17-rt8

Om det inte blir det kan vi köra på med fullt drag. Om vi sparat patchen i /usr/src/-katalogen blir det sålunda:

# patch -p1 < /usr/src/patch-2.6.17-rt8

Vi gör samma procedur med evms-patchen när vi står i /usr/src/-katalogen:

# patch --dry-run -p1 < ../kernel-patches/diffs/evms-bd-claim/2.6-bd-claim.patch

och om det inte blev några fel, kör vi på den med:

# patch -p1 < ../kernel-patches/diffs/evms-bd-claim/2.6-bd-claim.patch


KONFIGURERA KÄRNAN

När detta väl är gjort ska vi kopiera den befintliga konfigurationsfilen för kärnan. Denna ligger i katalogen /boot och heter något i stil med config-2.6.xx-xx-386. Denna skall kopieras till filen /usr/src/linux/.config

För att få den senaste kör vi cp-kommandot såhär, under förutsättning att vi står i katalogen /usr/src/linux:

cp /boot/config-`uname -r` .config

Sen kör vi ett kommando för att konfigurera kärnan. Det som rekommenderas är:

make menuconfig

som gör att man får ett menysystem som är hyfsat lätt att navigera i som ser ut som nedan:


Figur 1. Bild på menuconfig

Här finns två menyalternativ som skall ändras i, nämligen:
Navigering sker med piltangenterna, val gör du med Enter-tangenten eller Mellanslag. I Processor type and features finns fem val som ska göras:
Det finns fyra val att göra gällande Preemtion-läge. För att få bästa möjliga förutsättningar rekommenderas (eller beordras, beroende på hur man ser det) det nedersta alternativet, Complete preemption:



Figur 2. Val av realtids-läge

I Kernel Hacking-sektionen är det ett val som skall kryssas bort och det är
Sen är det bara att trycka på Exit och svara Yes på att spara konfigurationen.


KOMPILERA KÄRNAN

För att kompilera kärnan i Debian-baserade system som Ubuntu behövs paketet kernel-package, vilket vi kan installera med

# apt-get install kernel-package

Sen, stående i /usr/src/linux, kör vi kommandona

# make-kpkg clean
# make-kpkg modules_clean
# make-kpkg --revision 1 --initrd kernel_image kernel_headers modules_image

och ber en stilla bön att det inte blir några fel någonstans.


INSTALLERA KÄRNAN

Blir det inte det, kan vi installera paketen genom att

# cd ..
# dpkg -i *2.6.17-rt8*.deb

Detta kommer att lägga kärnan högst upp i hierarkin i bootmanagern Grub, vilket innebär att om du inte trycker på Esc-knappen vid uppstart så kommer den att boota in i den nya RT-kärnan. Det kan vara bra att veta om det inte går så bra.

Genom att trycka på Esc-knappen vid Grub-prompten, får du upp en lista över de installerade kärnorna. Det är där möjligt att välja en gammal kärna om RT-kärnan vägrar att starta.


TA BORT KÄRNAN

För att ta bort RT-kärnan kan du skriva kommandot

# apt-get remove kernel-image-2.6.17-rt8 kernel-headers-2.6.17-rt8

This page is powered by Blogger. Isn't yours?