[Kos-dev] Reponses

d2 kos-dev@enix.org
16 Jul 2001 11:25:39 +0200


Bonjour,

Ouf. Quelle inspiration ce Week End ! C'est que 33 messages de 200
lignes en moyenne, c'est long a lire.

Bon, j'ai lu vos reponses respectives sur BabelOS. Il semblerait que
en general vous voyiez en quoi consiste BabelOS par rapport a
Babel. Babel, ca definit ce qu'est une classe (interface) et un objet
(instance). Ca definit et implemente en plus un gestionnaire de
classes et d'objets, qui est lui meme un objet Babel. Babel est donc
un mecanisme generique de definition et de gestion d'objets tout a
fait generiques.

BabelOS, c'est une palette d'interfaces et d'instances Babel, a la
base de toutes les entites qu'on manipulera dans kos. C'est une boite
a outils Babel, adaptee a l'OS.

Pour jusitifier BabelOS, voila ce qu'on pourrait dire.

La force d'Unix (small is beautiful) provient de l'unification
(everything is a file). L'abstraction a l'origine est donc
quelque-chose :
  1/ de simple
  2/ qui unifie l'acces (depuis cpl3) a enoooooormement de ressources
     materielles
  3/ *de parfaitement defini* (VFS)

Le point 3/ pose le probleme de ioctl() : car le "parfaitement defini"
impose que c'est "parfaitement non-extensible". Donc, on manipule les
peripheriques exotiques (carte son, cartes SCSI, ...) avec des ioctl
dans tous les sens.

Les objets Babel, sont a leur tour quelque-chose :
  1/ de simple
  2/ qui permet de representer n'importe quoi
  3/ qui laisse toute lattitude dans la definition des interfaces.

Ces 3 proprietes sont sympathiques puisque elles nous permettent de
nous affranchir de l'inconvenient lie au 3/ de l'approche Unix. *MAIS*
on a perdu la propriete fondamentale d'*unification* tant que l'on
reste dans le cas meta general absolu de l'Objet quelconque, concept
large et indefini par nature.

BabelOS a pour but de definir des interfaces et des instances Babel
qui permettent de retrouver la propriete d'unification d'acces. C'est
a dire qu'on accede aux systemes de fichiers de la meme facon, aux
cartes son de la meme facon : au sein de chaque "classe de service",
l'acces est unifie.

C'est pas magique : ca repose sur Babel, et ca nous donne les
proprietes suivantes :
  1/ C'est simple (et efficace : syscall a la Unix)
  2/ Ca unifie l'acces aux ressources au sein de chaque "classe de
     services"
  3/ Ca laisse toute lattitude dans la definition des classes de
     services

On retrouve donc l'unification Unix (2/) utile pour simplifier les
choses niveaux cpl3 et cpl0, et l'extensivite Babel (3/). Bref, rien
de revolutionnaire.

J'arrete la pour la discussion "conceptuelle" sur
BabelOS/Babel. J'espere qu'on en discutera dans 2 semaines.

Sinon, Fabrice a pose quelques questions interessantes. Posix d'abord :
Je pense qu'on va s'inspirer tres fortement de Posix parce que ca
correspond au "small is beautiful", et parce que c'est la source
d'inspiration la plus facile et la plus "inconsciente" pour nous : on
utilise tous Unix. Inconsciemment, on en est influences. Par contre,
la priorite n'est pas de respecter scrupuleusement Posix. On va donc
prendre la 2eme voie que tu proposes : on veut pouvoir compiler emacs
et gcc => faire une bibliotheque de compatibilite POSIX.

Pour ce qui est des problemes des read/write en presence de cache,
c'est independant de Babel(OS). Babel(OS) permet de definir des
interfaces de manipulation de ressources, et d'identifier des
ressources et des services. Tout ceci afin de servir de passerelle
entre cpl3 et cpl0. La gestion et l'utilisation des caches sera a la
charge des services BabelOS, et sera invisible au cpl3. Toute cette
cuisine (complexe) se passera au niveau du noyau (cpl0). La-dessus, on
aura les memes problemes et la meme approche que les Unix classiques.

Sinon, on a parle de "prehandler cpl0" pour read/write et
cie. Non. Comme l'a indique Fabrice : les methodes associees a la
gestion d'une ressource (par exemple la ressource
":fs:local:/home/mejj/foo.bar") est determinee lors du open(). open()
est la seule methode qui disposera d'un prehandler cpl0, puisque c'est
elle qui se chargera du lookup des methodes et de la ressource.  Cote
cpl3, on a toujours 1 et 1 seul prehandler commun a tous les
services/ressources, charge de faire l'appel systeme. Sinon il faut
multiplier les call gates (1 call gate par syscall, ca fait
beaucoup). Voila un exemple de scenario :

  babelos_ressource res_id = open(":fs:local:/home/mejj/foo.bar");
    - passage cpl0 (call gate unique)
    - babelos_service *service = babel_services_manager->lookup_service(":fs:local");
    - resource_ptr = service->lookup_resource("/home/mejj/foo.bar");
    - retourne get_resource_cpl3_id(resource_ptr);

Une fois qu'on a fait ca, on accede aux methodes associees a la
ressource *directement*, ie sans prehandler du cote cpl0.

Par contre, on a plusieurs facons d'envisager la partie cpl3 de la
sauce :
    - Si res_id est un pointeur vers structure cpl3 contenant une
      sorte de table des methodes, alors ca fera :
       res_id->write(res_id, "salut\n", 6);
      qui en realite passera par le syscall :
       syscall(res_id, WRITE, "salut\n", 6);
    - Si res_id est un pur identifiant, faudra faire directement :
       syscall(res_id, WRITE, "salut\n", 6);

C'est le travail de la libc de faire en sorte que, au niveau
utilisateur, ca donne :
   write(res_id, "salut\n", 6);

Cote cpl0, une fois le syscall envoye cote cpl0, ca donnera (cote
cpl0) :
  babelos_resource *br = get_resource_cpl0_ptr(res_id);
  babelos_service  *service = br->get_service(); // ou br->service direct
  babel_method     *method = service->lookup_method(WRITE);
  method(br, "salut\n", 6);

Voila.

J'ai vu aussi que vous aviez bute dur le terme "depend de" dans mes
explications, concernant le fait que "les ressources dependent des
services". C'est une mauvaise formulation.

Pour resumer BabelOS en francais, on pourrait dire "Un _service_ est
un objet qui implante des operations donnees : il /possede/ une
interface donnee, qui s'appelle '_classe de services_'. Tous les
services d'une meme classe de services ont la meme interface. Un
service tout seul n'est alors qu'une suite de fonctions implementees
(codees), qui sait donc faire des choses. Un service fait des choses
sur quelque chose d'autre, sinon il ne sert a rien. Ce 'quelque chose
d'autre', c'est une _ressource_. A chaque service est donc associee
(variable locale) une _arborescence de ressources_, elle-meme
representee niveau utilisateur par un espace de nommage".

Les ressources sont associees a un service donnee : elles ne sont
relatives qu'a ce service donne. Chaque service doit etre capable
(methode lookup_resource()) d'identifier une de ses ressources a
partir d'un nom. Les ressources sont organisees en arborescence, pas
seulement au niveau de l'espace de nommage (arborescence
"truc/machin/bidule"), mais egalement en leur sein : on doit pouvoir
avoir acces aux sous-ressources a partir d'une ressource : methodes
speciales get_sub_resource() ou qqch comme ca. Un peu comme on a acces
aux sous-resertoires et aux fichiers a partir d'un repertoire.

Si on recapitule, on a 2 types Babel a la racine de la boite a outils
BabelOS : "service" (interface "classe de services"), et ressources
(stockees et idetnifiees sous la forme d'une arborescence). Chaque
service est l'instance d'une interface "classe de ressources", et
*possede* une arboresecence de ressources.

Bon, sinon, pour repondre a Thomas, quand je te parlais de slab, je te
disais pas que c'etait interessant /parce que/ ca accelererait les
choses pour kmalloc. Je te disais : on a deja 11 slabs pour kmem, et
avoir des slabs permet d'accelerer les choses lorsqu'on a a allouer
beaucoup de donnees de la meme taille (typiquement : semaphores,
...). Donc l'ideal serait de declarer une API officielle de gestion
des slabs, plutot que de garder ca caché pour kmem. Ca compliquerait
pas trop les choses, ca les clarifierait meme, et surtout ca pourrait
servir par la suite.

Pour les API de listes chainees, ca me parait une bonne idee. Mais en
macro.

Bonne journee,

-- 
d2