piątek, 1 stycznia 2010

Kompilacja kernela RTLinux

Jakiś czas żyłem w przekonaniu, że dostępna w repozytorium paczka linux-image-rt zawiera to samo jądro które jest podstawą RTLinuxa strona domowa RTLinux. Zatem aby skompilować jądro z patchem RTLinuxa będę musiał włożyć w to więcej wysiłku.
Zacząłem od ściągnięcia patcha RTLinux ze strony domowej, a następnie kodu źródłowego kernela z www.kernel.org. Dopiero po jakimś czasie zorientowałem się, że nie mogę używać kodu ostatniego kernela, bo nie ma dostępnego dla niego patcha. Musiałem więc ściągnąć kernel w wersji 2.6.9. Dalsze postępowanie wyglądało następująco:
Skopiowałem plik rtlinux-3.2-wr.tar.bz2 do katalogu /usr/src.
Rozpakowałem go poleceniem tar xjf rtlinux-3.2-wr.tar.bz2
Wszedłem do katalogu rtlinux-3.2-wr
Skopiowałem tu plik linux-2.6.9.tar.bz2 i rozpakowałem.
Utworzyłem dowiązanie symboliczne: ln -fs linux-2.6.9 linux
Wszedłem przez link linux do katalogu z rozpakowanymi źródłami kernela.
Teraz należy zaaplikować patch, który znajduje się tutaj. Inaczej otrzymamy błędy kompilacji w postaci:
{standard input}: Assembler messages:
{standard input}:607: Error: suffix or operands invalid for `mov'
{standard input}:630: Error: suffix or operands invalid for `mov'
{standard input}:1144: Error: suffix or operands invalid for `mov'
{standard input}:1145: Error: suffix or operands invalid for `mov'
{standard input}:1146: Error: suffix or operands invalid for `mov'
{standard input}:1147: Error: suffix or operands invalid for `mov'
make[1]: *** [arch/x86_64/kernel/process.o] Error 1
make: *** [arch/x86_64/kernel] Error 2
Rozwiązanie przyszło stąd. Zatem należy wykonać: patch -p1 < /sciezka/do/patcha/linux-2.6-seg-5.patch
Następnie zaaplikować patch RTLinuksa: patch -p1 < ../patches/kernel_patch-2.6.9-rtl3.2-rc1
Po tym wszystkim należe skonfigurować opcje kernela za pomocą jednego z poleceń: make menuconfig, make xconfig, make gconfig. Pojawi się menu w którym można wybrać czy dana opcja ma być wkompilowana w jądro czy doinstalowywana jako moduł lub całkowicie usunięta.
Teraz postępując dalej wg tej instrukcji: http://blog.0x1fff.com/2009/04/debian-gnulinux-kompilacja-jadra.html
Dostałem błąd o ponownie definiowanych makrach fake_stake_cośtam i unfake_stake_itd. Jak dowiedziałem się na jakimś forum należy otworzyć plik w którym makra są ponownie definiowane i po prostu je usunąć. Niestety zgubił mi się już link, gdzie to przeczytałem.

W tej chwili otrzymuję błędy o niepełnym typie tablicy.
In file included from fs/compat_ioctl.c:69,
from arch/x86_64/ia32/ia32_ioctl.c:14:
include/linux/i2c.h:58: error: array type has incomplete element type
include/linux/i2c.h:205: error: array type has incomplete element type
make[2]: *** [arch/x86_64/ia32/ia32_ioctl.o] Błąd 1
make[1]: *** [arch/x86_64/ia32] Błąd 2
make[1]: Opuszczenie katalogu `/usr/src/rtlinux-3.2-wr/linux-2.6.9'
make: *** [debian/stamp/build/kernel] Błąd 2
Powodowane jest to tym, że w czasach kernela 2.6.9 używało się starszych narzędzi kompilacji, które najwyraźniej były bardziej pobłażliwe niż obecne.
Zamieniłem linię 58 w incude/linux/i2c.h:
extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],int num);
na
extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msg,int num);
oraz
int (*master_xfer)(struct i2c_adapter *adap,struct i2c_msg msgs[],
int num);
na
int (*master_xfer)(struct i2c_adapter *adap,struct i2c_msg *msgs,
int num);
W pliku /include/linux/fb.h linia 751:
extern const struct fb_videomode vesa_modes[];
na
extern const struct fb_videomode *vesa_modes;

Teraz zatrzymałem się z błędem:
/usr/bin/ld: arch/x86_64/ia32/vsyscall-sysenter.so: Not enough room for program headers, try linking with -N
/usr/bin/ld: final link failed: Bad value
collect2: ld returned 1 exit status
make[2]: *** [arch/x86_64/ia32/vsyscall-sysenter.so] Błąd 1
make[1]: *** [arch/x86_64/ia32] Błąd 2
make[1]: Opuszczenie katalogu `/usr/src/rtlinux-3.2-wr/linux-2.6.9'
make: *** [debian/stamp/build/kernel] Błąd 2