Witam,
[...] man outb odwołuje się do
outb(9) którego nie ma nigdzie (nawet na stronach z manualami w html.
ioperm też jest lakoniczny i nie bardzo wiadomo jak go wywołać.
Czy można poprosić o 2 proste funkcje, które beda odpowiednikiem
pascalowych
procedure send( a : byte );
begin
port[$0378]:=a;
end;
void send(char a)
{
if ( ioperm(0x0378, 1, 1) < 0 )
return;
outb(a, 0x0378);
ioperm(0x0378, 1, 0);
}
function receive : byte;
begin
result:=port[$0378];
end;
char receive(void)
{
char res;
if ( ioperm(0x0378, 1, 1) < 0 )
return(-1); /* cos trzeba zwrocic - moze zamienic na int receive() ? */
res = inb(0x0378);
ioperm(0x0378, 1, 0);
return(res);
}
z włączeniem tego ioperm
ioperm() sluzy do nadania/odebrania sobie dostepow do portow I/O,
poniewaz kazdy proces (nawet root-a) jest uruchamiany w tzw. 'user-space'
z IOPL == 0. Pierwszy parametr to poczatkowy port, drugi, to ilosc portow,
a trzeci, to 0 == zabierasz dostep, 1 == nadajesz dostep. Np. chcac nadac
sobie dostep do portow 0x0200-0x0204, wywolujesz:
ioperm(0x0200, 5, 1);
Nie zmienia Ci to IOPL lecz ustawia odpowiednie bity w masce. Jadro
nadal dostaje wyjatek o nieuprawnionym dostepie do portow I/O, ale,
gdy masz wlaczony dostep do danego portu, to jadro wysyla/odczytuje
odpowiednie wartosc.
Innym sposobem uprawniajacym do bezposredniego dostepu I/O jest
funkcja iopl(), ktora juz zmienia Ci IOPL (np. iopl(3) powoduje
nadanie uprawnien, iopl(0) - odebranie upranien do wszystkich portow I/O).
Jest to metoda efektywniejsza (dostep do portow jest natychmiastowy,
a nie przez obsluge wyjatkow jadra), ale mniej bezpieczna. iopl()
jest konieczna w przyadku numerow portow 0x03FF, bo maska
ustawiana przez ioperm() ma 128 bajtow (* 8 = 1024 bitow i tylez portow).
W ktoryms z poprzednich postow Wojciech Borczyk pisal, ze iopl() jest
dostepna rowniez na FreeBSD - wiec bardziej przenosna.
Jesli bedziesz kilkakrotnie przesylal/czytal dane, to chyba najlepiej:
ioperm(0x0378, 1, 1); /* lub iopl(3); */
outb(v1, 0x0378);
outb(v2, 0x0378);
v3 = inb(0x0378);
v4 = inb(0x0378);
outb(v5, 0x0378);
/* ......... itd. */
ioperm(0x0378, 1, 0); /* lub iopl(0); */
outb, inb sa typu extern inline, wiec musisz kompilowac z optymalizacja
(-O, -O2, itd.). Naglowek dla inb/outb to #include <asm/io.h
-- pozdrawiam