Zarzadzanie zasilaniem komputera.
Autor: Bogdan Drozdowski, bogdandr (at) op.pl
Jesli zastanawialiscie sie kiedys, jak wylaczac dyski twarde lub resetowac
komputer uzywajac tylko oprogramowania (tj. nie naciskajac zadnych
przyciskow), to w tym artykule powinniscie znalezc odpowiedz na wszystkie
wasze pytania.
Zajmijmy sie najpierw teoria. Przerwanie, ktorym najpierw sie zajmiemy,
to.... int 10h, przerwanie sterownikow karty graficznej. Co one maja
wspolnego z energia? Otoz, mozna z uzyciem int 10h wylaczyc monitor.
Zajrzyjmy do RBIL, w opis funkcji numer 4F10h. Uruchomienie jej z BL=0
powinno nas upewnic, ze odpowiednie funkcje sa zainstalowane
(zwroci AL=4Fh):
================================
mov ax, 4f10h
mov bl, 0
xor di, di
mov es, di ; przerwanie zada ES:DI = 0
int 10h
cmp al, 4fh
jne wychodzimy ; gdy kleska....
================================
Teraz, jesli wiemy, ze ta funkcja dziala, to patrzymy na kolejna. Wpisujac
1 do BL mozemy zmienic aktualny stan zasilania. W BH podajemy, co chcemy
zrobic: 0-wlaczyc, 1-przelaczyc w stan oczekiwania, 2-zawiesic, 4-wylaczyc
monitor. Zanim jednak zaczniecie ochoczo pisac, dam wam rade: program
nalezy napisac tak, aby po jakims czasie monitor wracal jednak do stanu
wlaczonego (tj. bez resetowania komputera...). Wiem, ze potrafilibyscie
cos takiego sami napisac, ale podam tutaj gotowe (i sprawdzone - dziala
nawet pod Win98) rozwiazanie:
================================
; Program wylacza monitor
;
; Autor: Bogdan D.
; kontakt: bogdandr (at) op (dot) pl
;
; nasm -O999 -o mon_off.com -f bin mon_off.asm
org 100h
start:
mov ax,4f10h ; wybranie numeru funkcji
mov bx,0401h ; BL=1 - zmien stan. BH=4 - wylacz
int 10h
xor ah,ah
int 16h ; poczekaj na nacisniecie klawisza
mov ax,4f10h
mov bx,1 ; BL=1 - zmien stan. BH=0 - wlacz
int 10h
mov ax,4c00h
int 21h
================================
Z dyskami twardymi jest nieco gorzej. Tutaj trzeba sie znac na kontrolerze
HDD - na jego portach i wysylanych tam komendach. Dlatego posluze sie
gotowcem. Niestety, nie pamietam autora tej procedury (komentarze jednak
przetlumacze na jezyk polski). Ma ona przelaczac wskazany dysk twardy w
stan oczekiwania. Dla dokladniejszych opisow portow i ich komend spojrzcie
w plik "ports.lst" dolaczony do RBIL.
NIE TESTOWALEM TEJ PROCEDURY (i szczerze mowiac, Wam tego tez nie radze,
chyba ze jestescie calkowicie pewni, ze zadziala prawidlowo)!
================================
Spindown HD
ide_standby:
; uruchamiac z:
; al = master/slave (0 = master, 1=slave)
; dx = glowny port kontrolera (01F0h = Primary, 0170h = Secondary)
; zwraca:
; nic
; dysk twardy w stanie oczekiwania (stand-by)
cli ; wylaczamy przerwania
pusha ; zachowujemy wszystkie rejestry (push all)
push ds ; zachowujemy DS
push 040h ; wkladamy 40h na stos
pop ds ; DS=40h, BIOS Data Area - segment
; danych BIOSu
mov byte [08Eh],0 ; zerujemy status kontroli przerwania
; dysku twardego.
; nalezy tu wpisac zero, gdy zaczynamy
; operacje na dysku
; twardym. Gdy operacja sie zakonczy,
; kontroler wpisze tu 0FFh
shl al, 5 ; AL = numer dysku*32 = 32 lub zero
;; shl al, 4 ; powinno byc wedlug mnie.
or al, 0A0h ; konstruujemy strukture opisu dysku. Bit7 i
; bit5 musza byc=1.
; bit4 = numer dysku
; bit6=0 - tryb CHS zamiast LBA (nieistotne)
; bit 3-0 - wybor glowicy w CHS lub adres typu
; LBA (nieistotne)
add dx, 6 ; wybieramy port 1F6h (lub 176h)
; odpowiedniego kontrolera
out dx, al ; wysylamy wyliczona strukture opisujaca dysk
mov al, 094h ; AL = pierwsza czesc komendy "standby"
inc dx ; przechodzimy na kolejny port (1F7h / 177h)
out dx, al ; wysylamy czesc komendy "standby"
mov al, 0E0h
out dx, al ; wysylamy druga czesc komendy
mov cx, 64 ; szykujemy sie na oczekiwanie na odpowiedz
; dysku. Bedziemy
; czekac nie dluzej niz 64 tykniecia zegara
; (3.5 sekundy)
mov ax, word [06Ch] ; pobierz stan zegara
sti ; wlacz z powrotem przerwania
L1:
cmp ax, word [06Ch] ; sprawdz, czy stan zegara sie zmienil
setne bx ; gdy nie, to BX=1
sub cx, bx ; od CX odjemij BX (1 lub 0). Odejmiemy 1,
; gdy zegar tyknal.
jc L2 ; wyjdziemy, gdy CX < BX (czyli CX < 1) -
; czas sie skonczyl
hlt ; chwilka przerwy... (przerwie ja
; jakiekolwiek przerwanie)
cmp byte [08Eh], 0 ; sprawdzamy, czy dysk odpowiedzial, ze
; wykonal zadanie
jz L1 ; jesli nie (ciagle mamy 0), to wracamy
; do odmierzania czasu
L2: ; jesli dysk przeszedl w stan oczekiwania
; lub czas sie
; skonczyl, to pora wyjsc
mov byte [08Eh], 0 ; status przerwania = 0
pop ds ; przywracamy DS
popa ; przywracamy wszystkie rejestry (pop all)
ret ; juz nas tu nie ma.
================================
Parkowanie glowic twardego dysku jest sprawa prostsza, gdyz w tym przypadku
pomaga nam BIOS. Aby zaparkowac glowice pierwszego dysku twardego, uzyj
nastepujacego kodu:
================================
mov ah, 19h
mov dl, 80h
int 13h
jc blad ; nie pokazuje bledow pod Windowsem 98
================================
Jesli chcecie zaparkowac glowice drugiego dysku, zamiast 80h wpiszcie 81h,
jesli trzeciego - 82h itd.
---------------------------------------------------------------------------
Teraz ciekawsze sprawy - resetowanie komputera lub wylaczanie go. Na poczatek
"grzecznie" posluzymy sie przewaniem - bedzie to int15h, numery funkcji
5300h i 5307h (po szczegolowe opisy tych funkcji posylam oczywiscie
do RBIL). Najpierw sprawdzmy w ogole, czy Advanced Power Management
(APM) - bo o nim mowa - jest zainstalowane:
================================
mov ax, 5300h
xor bx, bx ; numer urzadzenia = 0 = BIOS
int 15h
jc niestety ; gdy cos poszlo nie tak (np. brak APM),
; to CF=1
================================
Teraz sprobujmy wylaczyc system:
================================
mov ax, 5307h ; funkcja APM
mov cx, 3 ; wylacz system. CX=2 - zawies system,
; CX=1 - przelacz system w
; stan oczekiwania (stand-by)
mov bx, 1 ; wszystkie urzadzenia
int 15h ; sprobujemy wylaczyc...
================================
Jesli istnieje mozliwosc wylaczenia pradu w systemie, to powyzszy kod
powinien to zalatwic.
Teraz przejdziemy do innych "grzecznych" sposobow na zresetowanie komputera.
W RBIL znalazlem:
================================
INT 16 - AMI BIOS - BIOS-FLASH Interface - GENERATE CPU RESET
AX = E0FFh
INT 14 - FOSSIL - REBOOT SYSTEM
AH = 17h
AL = method
00h = cold boot
01h = warm boot
================================
Jak widac, nie wyglada to skompliowanie. Niestety, zaden z powyzszych sposobow
nie dziala u mnie pod "czystym" DOSem, a pod Windowsem98 dziala jedynie
sposob z APM (int15h).
A teraz pokaze kilka "niegrzecznych" (ale za to sprawdzonych przeze mnie i
dzialajacych bez pudla) sposobow na zresetowanie komputera.
Pierwszym takim sposobem jest dlugi skok pod adres FFFF:0000 (tam znajduje
sie czesc BIOSu odpowiedzialna za operacje wykonywane przy starcie
komputera). Wczesniej do segmentu danych BIOSu (segment 40h), pod adres
72h nalezy wpisac 0, gdy chcemy zimny reset (taki, co obejmuje testy
pamieci i wszystko inne), a 1234h, gdy chcemy goracy reset.
Odpowiednie kawalki kodu wygladaja tak (przypominam, ze adres 0040h:0072h
= 0000:0472h - patrz czesc 2 mojego kursu):
================================
; zimny reset:
mov ax, 40h
mov ds, ax ; DS = 40h
mov word [ds:72h], 0 ; zimny reset
; niektore kompilatory (np. TASM) nie lubia instrukcji w stylu
; "jmp 0FFFFh:0000h", wiec
; zakoduje ja recznie
db 0eah ; kod instrukcji wziety z
; podrecznikow Intela
dw 0 ; offset
dw 0ffffh ; segment
; goracy reset:
xor ax, ax
mov ds, ax ; DS = 0
mov word [ds:472h], 1234h ; goracy reset
db 0eah ; kod instrukcji wziety z
; podrecznikow Intela
dw 0 ; offset
dw 0ffffh ; segment
================================
Drugim (i prostszym) sposobem jest zapisanie do jednego z portow
klawiatury (64h) jednego z bajtow F0-FE, ktory ma bit0 = 0 (jest takich
oczywiscie kilka, najczesciej stosuje sie FEh), chociaz ten sposob nie
jest zalecany.
Kod jest wyjatkowo prosty i wyglada tak:
================================
mov al, 0feh
out 64h, al
================================
Celowo nie wspominam tutaj o jednym: o przerwaniu int19h, ktore sluzy do
ponownego przeczytania bootsektorow i przeladowania systemu od nowa. Gdy
wkladacie niesystemowa dyskietke do stacji i resetujecie komputer, to
(o ile macie mozliwosc uruchomienia systemu z dyskietki) pojawia sie napis
informujacy o nieprawidlowym dysku systemowym. Po nacisnieciu Entera
uruchamiane jest wlasnie int19h, ktore nie wykonuje zadnych resetow, tylko
czyta bootsektory od nowa.
Nie wspominalem o int19h, gdyz jest ono niebezpieczne. Jezeli jakikolwiek
program przejal przerwanie np. zegara, to int19h nie przywroci poprzedniej
procedury, co jest nieprzewidywalne w skutkach!
Sposoby na wylaczanie urzadzen moga sie Wam przydac, gdy np. bedziecie pisac
wlasny wygaszacz ekranu, a mozliwosc zresetowania komputera przyda sie, gdy
Wasze oprogramowanie zostanie zainstalowane i musi zmienic np. zawartosc
pliku "autoexec.bat".
Informacje, ktore tutaj podalem moga sie Wam tez przydac przy pisaniu
boot-sektorow do wlasnych "mini-systemow operacyjnych".
Wyszukiwarka
Podobne podstrony:
DOS DIOD TUTPWR TUTPWR TUTDOS MYSZ TUTDOS GRAF TUTDOS SPKR TUTDOS CPU TUTDOS BOOT TUTDOS SYS TUTDOS BIBL TUTPWR TUTPWR TUTDOS TSR TUTDOS BMP TUTFUNFACE DOS OPISART121 tut 2więcej podobnych podstron