   #Start Contents English version

                       Zarzadzanie zasilaniem komputera

   Jesli zastanawialiscie sie kiedys, jak wylaczac dyski twarde lub
   resetowac komputer uzywajac tylko oprogramowania (nie naciskajac
   zadnych przyciskow), to w tym artykule powinniscie znalezc odpowiedz
   na wszystkie wasze pytania.
     _________________________________________________________________

Dyski twarde.

   (przeskocz dyski twarde)

   Oczywiscie, jak na porzadny system przystalo, nie mozemy operowac
   bezposrednio na dysku twardym. Ale umozliwi na to sam system, poprzez
   funkcje systemowa sys_ioctl.

   Ponizej przedstawiam dzialajacy (choc, aby otworzyc plik urzadzenia
   dysku twardego, musialem miec uprawnienia roota) kod zatrzymujacy dysk
   twardy. Kod ten napisalem dzieki analizie kodu zrodlowego programu
   hdparm (i tam, oraz do stron podrecznika man: ioctl, ioctl_list,
   odsylam po szczegoly). Dla tych, ktorzy nie korzystaja z mojej
   biblioteki, podaje liczbowe odpowiedniki stalych.

   Oto program (skladnia NASM):
   (przeskocz program zatrzymujacy dysk twardy)
%include "bibl/incl/linuxbsd/nasm/n_system.inc"         ; stale systemowe

section .text

global _start

_start:
        mov     eax, sys_open                   ; =5. otwieramy plik....
        mov     ebx, dysk                       ; ....twardego dysku
        mov     ecx, O_RDONLY|O_NONBLOCK        ; 04000q osemkowo
        int     80h

        cmp     eax, 0
        jle     koniec                          ; jesli wystapil blad,
                                                ; wychodzimy od razu

        mov     ebx, eax                ; zachowujemy deskryptor pliku

        mov     eax, sys_ioctl                  ; =54
        ; EBX = deskryptor pliku
        mov     ecx, 0x031f                     ; komenda specjalna dysku
        mov     edx, args1                      ; pierwsze argumenty
        int     80h

        mov     eax, sys_ioctl
        ; EBX = deskryptor pliku
        mov     ecx, 0x031f                     ; komenda specjalna dysku
        mov     edx, args2                      ; drugie argumenty
        int     80h

        mov     eax, sys_close                  ; =6
        ; EBX = deskryptor pliku
        int     80h                             ; zamykamy otwarty plik

koniec:
        mov     eax, sys_exit                   ; =1
        xor     ebx, ebx
        int     80h                             ; wychodzimy z programu

section .data
args1   db      0e6h, 0, 0, 0                   ; skopiowane z hdparm.c
args2   db      99h, 0, 0, 0                    ; tez skopiowane
dysk    db      "/dev/hda",0                    ; pierwszy dysk,hdb = drugi

   UWAGA: nalezy odczekac chwile, az program sie zakonczy. Przez czas
   dzialania programu komputer moze przestac reagowac.
   Po zatrzymaniu twardego dysku mozna go uruchomic wykonujac dowolna
   operacje na systemie plikow (na przyklad wyswietlic zawartosc
   biezacego katalogu).
     _________________________________________________________________

Resetowanie komputera lub wylaczanie go.

   (przeskocz resetowanie komputera)

   Do zresetowania komputera posluzy nam funkcja systemowa sys_reboot,
   ktorej podamy odpowiednie parametry. Oto program natychmiast
   resetujacy komputer:
   (przeskocz program resetujacy komputer)
%include "bibl/incl/linuxbsd/nasm/n_system.inc"

section .text

global _start

_start:
        mov     eax, sys_reboot                 ; =88
        mov     ebx, 0fee1deadh                 ; wymagana stala
        mov     ecx, 672274793                  ; wymagana stala
                                ; EDX = tryb restartu. U nas: zwykly reset
        mov     edx, LINUX_REBOOT_CMD_RESTART   ; =0x01234567
        int     80h

        ; to, co jest ponizej nigdy nie zostanie wykonane.
        mov     eax, sys_exit                   ; =1
        xor     ebx, ebx
        int     80h

   A oto program natychmiast wylaczajacy komputer:
   (przeskocz program wylaczajacy komputer)
%include "bibl/incl/linuxbsd/nasm/n_system.inc"

section .text

global _start

_start:
        mov     eax, sys_reboot                 ; =88
        mov     ebx, 0fee1deadh                 ; wymagana stala
        mov     ecx, 672274793                  ; wymagana stala
                        ; EDX = tryb restartu. U nas: wylaczenie pradu
        mov     edx, LINUX_REBOOT_CMD_POWER_OFF ; =0x4321FEDC
        int     80h

        ; to, co jest ponizej nigdy nie zostanie wykonane.
        mov     eax, sys_exit                   ; =1
        xor     ebx, ebx
        int     80h

   UWAGA: ze wzgledu na to, ze podane programy wylaczaja/resetuja
   komputer natychmiast po uruchomieniu, NIE zalecam ich stosowania, gdyz
   moze to byc niezdrowe dla systemu plikow.
     _________________________________________________________________

Wylaczanie monitora.

   No moze nie zupelnie bedzie to wylaczenie monitora, ale istotnie,
   obrazu nie bedzie. Do wylaczenia obrazu wykorzystamy biblioteke
   svgalib (do kompilacji potrzebny bedzie tez pakiet svgalib-devel).

   Calosc jest bardzo prosta: inicjujemy biblioteke funkcja vga_init,
   wylaczamy obraz funkcja vga_screenoff, czekamy na klawisz (funkcja
   systemowa sys_read czytajaca ze standardowego wejscia) i ponownie
   wlaczamy obraz funkcja vga_screenon. Funkcje vga nie przyjmuja zadnych
   argumentow.

   Caly program wyglada tak:
   (przeskocz program wylaczajacy monitor)
; Program wylaczajacy monitor z wykorzystaniem SVGAlib
;
; Autor: Bogdan D., bogdandr (at) op.pl
; kompilacja:
;   nasm -O999 -f elf -o mon_off.o mon_off.asm
;   gcc -o mon_off mon_off.o -lvga

section .text
global  main

extern  vga_screenoff
extern  vga_screenon
extern  vga_init

%idefine        stdin           0
%idefine        sys_read        3

main:
        call    vga_init
        call    vga_screenoff

        mov     eax, sys_read   ; funkcja czytania z pliku
        mov     ebx, stdin      ; standardowe wejscie
        mov     ecx, znak       ; adres, dokad czytac
        mov     edx, 1          ; wczytaj 1 bajt
        int     80h

        call    vga_screenon

        ret

section .data

znak            db      0

   Zwroccie uwage na sposob kompilacji. Skoro korzystamy z bibliotek
   jezyka C, to do kompilacji uzyjemy GCC. Wtedy zas funkcja glowna musi
   sie nazywac main - tak samo, jak w programach w jezyku C (i tak samo,
   jak w C, mozna ja zakonczyc instrukcja RET). Potrzebne funkcje po
   prostu deklarujemy jako zewnetrzne (extern).

   Program ten uruchomilem tez w srodowisku graficznym. Nic zlego sie nie
   stalo, ale po zakonczeniu programu nalezy przejsc na konsole tekstowa
   i wrocic na graficzna, aby odzyskac obraz.

   Do dzialania programu pod X-ami potrzebne moga byc uprawnienia do
   pliku /dev/console a pod konsola tekstowa - do pliku /dev/mem.

   Spis tresci off-line (klawisz dostepu 1)
   Spis tresci on-line (klawisz dostepu 2)
   Ulatwienia dla niepelnosprawnych (klawisz dostepu 0)
