Wake-On-Lan i nVidia nForce
Opublikował siefca
Wake-On-LAN to mechanizm, który pozwala obudzić komputer ze stanu wstrzymania lub zawieszenia (suspend) wysyłając do niego przez sieć odpowiednią porcję danych. W rzeczywistości musi to być odpowiednio skonstruowana ramka Ethernet. Gdy korzystałem jeszcze ze swojej starej płyty głównej i sytemu PLD Linux napotkałem problem z mechanizmem wybudzania swojego komputera magicznym pakietem. Bardzo chciałem mieć możliwość włączania w razie potrzeby domowego komputera, dlatego, że w końcu sprawiłem sobie urządzenie – bazujący na kernelu Linux router pełniący rolę bramki zdolnej wysyłać komunikaty budzące komputery. Niestety nie chciało to działać z moją kartą i postanowiłem sprawdzić dlaczego.
Problem
W przypadku mechanizmu WOL ważne jest, aby karta sieciowa po wyłączeniu maszyny czuwała, a nie wyłączała się zupełnie. W przypadku nieco starszych płyt nVidii z chipsetem nForce tak się niestety nie dzieje. Poszukałem w Sieci i okazało się, że nie tylko mi ten mechanizm nie działał i że są propozycje obejścia. Przyczyną problemu jest linuksowy sterownik zintegrowanej karty sieciowej o nazwie forcedeth. Driver ten nie ustawia stanu karty na “śpiący” (ang. sleeping) tuż przed wyłączeniem się systemu. W efekcie próby włączenia maszyny nic nie dają, bo karta nie wie o tym, że ma czuwać (dostarczać zasilanie do obwodów odpowiedzialnych za odbieranie ramek).
Rozwiązanie
Nie istnieje rozwiązanie problemu. Nowsze wydania sterownika i nowsze karty zintegrowane z płytami nVidii są wolne od usterki.
Obejście
Istnieje obejście, które polega na stworzeniu patcha i zmodyfikowaniu skryptów RC odpowiedzialnych za wyłączanie systemu.
Poprawka polega na delikatnej zmianie w module do kernela, ściągnięciu jednego prostego programiku i wydaniu paru poleceń tuż przed wstrzymaniem pracy systemu. Rozwiązanie jest opisane na tej stronie lub zamieszczone poniżej.
- Jeśli masz PLD-Linux albo inną dystrybucję używającą RPM spróbuj odpowiedniego pakietu
- Jeśli chcesz stworzyć pakiet dla swojej dystrybucji przykład znajdziesz w repozytorium SVN
- Więcej zasobów związanych z tym tematem znajdziesz na moim FTP
Instrukcje
Poniżej znajdziesz instrukcje obsługi patcha włączającego funkcjonalność Wake-On-LAN dla kart sieciowych zintegrowanych z płytami nVidia nForce. Zrób sobie herbatę, coś słodkiego i przystąp do dalszego czytania. Wykonanie instrukcji zajmuje od pięciu minut do pół godziny.
- This list will contain the toc (it doesn’t matter what you write here) {:toc}
Urządzenia {#urzadzenia}
Dotyczy urządzeń:
- nForce Ethernet Controller
- nForce2 Ethernet Controller
- nForce3 Ethernet Controller
- CK804 Ethernet Controller
- MCP04 Ethernet Controller
- MCP51 Ethernet Controller
- MCP55 Ethernet Controller
Wymagania {#wymagania}
Poprawka wymaga modyfikacji w dwóch miejscach:
- w module do jądra o nazwie
forcedeth - w skryptach zatrzymujących system
Wprowadzanie poprawki wymaga posiadania następujących narzędzi:
wgetpatchdiffmakegcc
Jeśli używasz dystrybucji PLD Linux to sprawdź, czy nie masz tego już w systemie używając poleceń:
grep -qi forcedeth_workaround /etc/rc.d/rc.shutdown && \ echo mam wsparcie w skryptach! [ -f /etc/init.d/forcedeth-wol ] && \ echo mam wsparcie w skryptach! /sbin/modinfo -F description forcedeth | \ grep -qi "timerirq disabled" && echo mam wsparcie w module!
Ok, jeśli gdzieś masz wsparcie i już trochę się orientujesz to będziesz wiedział, które punkty pominąć.
Instrukcje {#instrukcje}
Instalacja dodatkowych narzędzi {#narzedzia}
- Zainstaluj narzędzie
ethtool, a jeśli w twojej dystrybucji go nie ma pobierz ze strony projektu gkernel - Upewnij się, że polecenie
ethtooljest w/sbinlub w/usr/sbin - Postaraj się o źródła jądra którego używasz (mają być w /usr/src/linux)
Kompilacja narzędzi i nakładanie łaty {#kompilacja}
Wykonaj jako administrator:
cd /tmp && mkdir cosik && cd cosik wget ftp://ftp.pld-linux.org/people/siefca/\ patches/nvidia/pci-config.c wget ftp://ftp.pld-linux.org/people/siefca/\ patches/nvidia/forcedeth_sleep.sh kver=`uname -r | awk -F'[ .]' '{print $1"."$2"."$3}'` export kver wget -O linux-forcedeth-WON.patch \ ftp://ftp.pld-linux.org/people/siefca/\ patches/nvidia/linux-${kver}-forcedeth-WON.patch gcc -O2 ./pci-config.c -o ./pci-config strip ./pci-config mv ./pci-config /sbin [ -d /etc/rc.d ] || mkdir /etc/rc.d mv forcedeth_sleep.sh /etc/rc.d chmod a+rx /etc/rc.d/forcedeth_sleep.sh /sbin/pci-config
Weryfikacja instalacji {#weryfikacja}
Spójrz czy w bieżacym katalogu powstał plik o nazwie linux-forcedeth-WON.patch.
- Jeśli powstał przejdź do sekcji Łatanie modułu.
- Jeśli nie powstał przejdź do kolejnego kroku.
Samodzielne poprawki modułu {#samodzielne}
Musisz samodzielnie przygotować poprawki do modułu jądra. To jest łatwe i polega na wyszukaniu kilku łańcuchów i zastąpieniu ich innymi. Przejdź do katalogu: /usr/src/linux/drivers/net i wykonaj:
cp forcedeth.c forcedeth.c.orig
Następnie otwórz edytorem plik forcedeth.c i zmień linijkę:
#define DEV_NEED_TIMERIRQ 0x0001 /* set the timer irq flag in the irq mask */
na takie dwie:
#define DEV_NEED_TIMERIRQ 0x0000 /* work-around for Wake-On-Lan */ #define DEV_NEED_TIMERIRQ_ORIG 0x0001 /* set the timer irq flag in the irq mask */
Potem zmień linijkę:
if (id->driver_data & DEV_NEED_TIMERIRQ)
na taką:
if (id->driver_data & DEV_NEED_TIMERIRQ_ORIG)
I na koniec zmień linijkę:
MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver");
na:
MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver (TIMERIRQ DISABLED)");
Ok. Już prawie. :)
Tworzenie łaty {#tworzenie}
Wykonaj:
diff -Nu forcedeth.c.orig forcedeth.c >./linux-${kver}-forcedeth-WON.patch
Wyślij mi e-mailem (na dole strony) plik który powstał. Pomożesz w ten sposób innym. Jeśli nie znasz nazwy użyj polecenia ls linux-*forcedeth*. Stworzony moduł możesz zachować w bezpiecznym miejscu, bo może kiedyś się przydać. Pozostaw łatę lub jej kopię (plik linux-*numerek*-forcedeth.patch) w bieżącym katalogu i przywróć poprzednią wersję kodu modułu wykonując:
cp ./linux-*-forcedeth-WON.patch ./linux-forcedeth-WON.patch
cat forcedeth.c.orig > forcedeth.c
Łatanie modułu {#latanie}
Wykonaj:
# tu czesc zwiazana z modulem do kernela cp ./linux-*-forcedeth-WON.patch ./linux-forcedeth-WON.patch mv linux-forcedeth-WON.patch /usr/src/linux cd /usr/src/linux && patch -p1 <./linux-forcedeth-WON.patch
Kompilacja i instalacja modułu {#instalacja}
Wykonaj:
# kompilujemy modul do kernela cd /usr/src/linux make menuconfig # powyższe polecenie wykonaj jeśli nie kompilowałeś wcześniej # tego kernela, a dopiero co go ściągnąłeś # -- wyjdź z menu, gdy tylko się pojawi # odpowiadając twierdząco na pytanie o to czy zapisać # zmiany w konfiguracji make make modules
A następnie:
# instalujemy modul do kernela
cd /usr/src/linux
make modules install
depmod -a
Restart systemu z nowym modułem {#restart}
Zrestartuj system, aby przy starcie wczytany został z nowy moduł:
ifdown twój_kłopotliwy_interface rmmod forcedeth reboot
Modyfikowanie skryptów RC
Teraz ważna rzecz – trzeba włączyć funkcjonalność w pliku odpowiedzialnym za wyłączanie systemu. Znajdź taki plik u siebie (u mnie to jest /etc/rc.d/rc.shutdown) i dodaj w nim, w odpowiednim miejscu wywołanie /etc/rc.d/forcedeth_sleep.sh.
Po prostu poszukaj wewnątrz /etc/rc.d, pliku zawierającego komunikat w stylu Turning off swap i ponad tym poleceniem (odmontowywania przestrzeni wymiany w tym przypadku) dopisz linijkę:
/etc/rc.d/forcedeth_sleep.sh
Na przykład u mnie wyglądało to tak:
/etc/rc.d/forcedeth_sleep.sh # Turn off swap, then unmount file systems. run_cmd "Turning off swap" swapoff -a [ -x /etc/rc.d/rc.acct ] && /etc/rc.d/rc.acct stop
Jeśli nie wiesz jak to zrobić powyższe to zapytaj kogoś kto się zna. :) Spytaj w którym momencie i w jakim pliku są odmontowywane systemy plików przy zatrzymywaniu pracy systemu. Musisz wstawić wywołanie skryptu tuż przed tym.
Konfiguracja karty {#konfigurowanie}
Na koniec nie zapomnij powiedzieć swojej karcie, że ma czuwać, gdy komputer jest wyłączony wydając polecenie:
ethtool -s nazwa_interfejsu wol g
Sprawdź czy działa!
For english instructions please look at address: http://ftp.pld-linux.org/people/siefca/patches/nvidia/README.en.txt