|
From: Marcelo S. <ma...@he...> - 2004-07-08 16:57:25
|
eu estava analisando a questao dos devices, realmente o unix mesmo jah faz
uma interface similar ao que estamos pretendendo, embora ele mesmo nao a
torne padrao, por exemplo, para redes!
em qq unix vc pode tratar o frame buffer como um arquivo, no caso:
int fd=open("/dev/fb",O_RDWR);
read(fd,buffer,sizeof(buffer));
write(fd,buffer,sizeof(buffer));
ioctl(fd,&buffer,COMMAND);
close(fd);
uma API bem simples, nao eh ? eventualmente vc faz o truque do mmap(), q
nos podemos ter para *qualquer* io tb, ao menos no caso dos 68k:
char *p=mmap(fd, ... );
e entao temos o ponteiro *p para brincar direto na memoria de video:
p[y*fbwidth+x]=cor;
bem simples. mas a ethernet no unix nao sabe fazer isso, o q eu acho uma
burrice, eles criam uma nova API para o io de redes, por algum motivo
obscuro. talvez desenvolvendo, possamos compreender o porque, mas enfim, a
analogia seria:
int fd=open("/dev/eth0",O_RDWR);
read(fd,buffer,sizeof(buffer));
write(fd,buffer,sizeof(buffer));
ioctl(fd,&buffer,COMMAND);
close(fd);
nada muda neh. isso pode ser um driver q interfaceia a camada IP com o
dispositivo fisico, no lugar de /dev/eth0, podia ser /dev/ttyS0, etc. note
que ler e escrever com read/write pode assumir um buffer pequeno ou
grande, supomos que o buffer eh grande o suficiente para q read() leia de
fato um datagrama completo e write, de fato, escreva um datagrama
completo, nesse caso, buffer aponta realmente para um pacote IP, o
software q manipula isto esta fazendo isto na camada de pos-routing, quer
dizer, o pacote vai para a interface sem choro. o q entra, eh pre-routing,
usando uma conhecida analogia de um certo firewall q nao funciona muito
bem.
ah, mas e como o cara faz ppp ? nao eh ip-over-interface direto. de fato
nao sei, qdo vc abre uma /dev/eth0, esta disponivel o datagrama ethernet
de base, se vc abre uma /dev/ttyS0, esta disponivel comunicacao assincrona
caracter a caracter. num 68302, a /dev/ttyS0 eh muito inteligente, ao
ponto de dispor de HDLC e outros protocolos, mas nao ppp. entao sera q o
ppp deve ser uma atribuicao do dispositivo ou de uma camada extra ?
no caso de ser atribuicao do dispositivo:
struct INTERFACE config;
int fd=open("/dev/eth0",O_RDWR);
config.encapsulation=ENCAPSULATION_PPP;
ioctl(fd,&config,CONFIG);
a conexao ficaria:
IP router <-> device
a desvantagem eh q o engine ppp nao pode ser utilizado a nao ser em
interfaces, se o cara quiser usar um pipe para um sub-programa, eh dificil
fazer e teria q duplicar, criando um ppp na forma de uma app q funcione
com pipes gerais e nao apenas com devices :P
no caso de ser atribuicao de uma camada extra, eh possivel ter um daemon
que constroi os frames ppp, como um daemon generico:
struct PPPCONFIG config;
int fd=open("/dev/ppp",O_RDWR);
config.fd=open("/dev/ttyS0",O_RDWR);
config.dst.ip=0x7f000000;
ioctl(fd,&config,CONFIG);
read(fd,&buffer,sizeof(buffer));
write(fd,&buffer,sizeof(buffer));
close(fd);
neste caso vc linka o /dev/ttyS0 ao daemon ppp e depois o daemon ppp se
vira para gerenciar, ele, de fato, vc poderia linkar em qualquer especie
de fd, a conexao seria direta:
IP router <-> ppp daemon <-> device
uma vantagem de um daemon ppp:
IP router <-> ppp daemon <-> crypto engine <-> IP router
pq uma chamada ciclica ? simples, os packets daem do ip router para um
enlace ppp, q passa por um crypto engine, pode ser um ipsec, ou qq coisa
do genero. o resultado eh dado criptografado, q vai para o ip router
novamente, e este entrega para a saida real, q pode ser uma ethernet. do
ponto de vista logico, vc teria os devices e rotas:
0/0 gw /dev/eth0
192.168.0.0/16 gw /dev/ppp [crypto:200.200.200.1]
o ppp no caso funciona como um ppp over ethernet, mas com a camada extra
de criptografia, q eh um sub-processo conectado ao ppp e faz o seu
trabalho sem q o ppp se preocupe com isso.
apesar de parecer encher de camadas, devemos lembrar q tudo isso eh
paralelizado e bufferizado, criando uma especie de pipeline, assim,
durante o funcionamento normal do sistema, um device q recebe
continuamente packets, pode despachar para o daemon IP um volume continuo
de packets. se o daemon IP estiver ocupado, nao importa: ele vai entupindo
as queues! o daemon IP se vira e despacha os packets roteados para as
queues dos devices de saida.
imagine uma adaptacao de rate do tipo ethernet/10mbps <-> hdlc/64kbps,
embora os dados cheguem em bursts grandes pela ethernet, as queues seguram
a barra durante a entrada e saida do link hdlc ateh que ele consiga
despachar o trafego.
isso jah abre de cara a possibilidade do controle de trafego, uma vez q eh
possivel setar a interface para fazer descarte quando as queues estao
lotadas :)
uma vantagem q eu vejo dessa API, eh q generaliza tudo na forma de
syscalls padronizadas e tb recupera e tenta padronizar uma serie de APIs
do unix, em particular em cima de open/read/write/ioctl/close para nosso
sistema interprocesso. a economia eh imensa, no lugar de codificarmos
dezenas de APIs, fazemos apenas uma, generica, e que funciona bem.
outra coisa q ocorre eh que o daemon de fs seria responsavel, em parte,
pelo registro dos dispositivos. uma coisa q ocorre de fato no unix eh que
vc usa o fs para registrar as coisas!
o que liga o /dev/fb aos drivers do frame-buffer ? o unix de fato entende
apenas de numeros, mas o fs permite a aplicacao abrir o /dev/fb, puxar o
codigo do dispositivo e daih temos o registro do dispositivo, ou seja, o
fd do arquivo /dev/fb eh ligado no kernel ao numero de registro do
dispositivo.
no nosso caso, os daemons teriam q solicitar o registro do identificador e
o fs se encarregaria de ligar o path do open ao respectivo daemon, ou
seja, qdo o cara abre o /dev/fb, o fs le o registro, verifica as
permissoes e, estando ok, redireciona aquele fd para o daemon do
frame-buffer, por exemplo.
interessante q isto ocorre no unix, em certa escala, entao nao eh uma
ideia tao doida, soh estamos adaptando uma solucao monolitica para uma
solucao de microkernel, na pratica, o funcionamento nao precisa ser tao
diferente e tambem nao precisamos perder tempo codificando milhares de
APIs complexas (isto sera feito nos daemons, mas enfim).
outras opinioes ? (:
atenciosamente,
marcelo samsoniuk
|