[Kos-dev] Compte rendu KOS
Thomas Petazzoni
kos-dev@enix.org
13 Apr 2002 18:58:17 +0200
Compte rendu KOS : du vendredi 5 au vendredi 12 avril
-----------------------------------------------------
Le premier travail du WE a ete de repondre aux diverses interrogations
qui etaient posees dans l'ordre du jour :
- en ce qui concerne le probleme de la lecture/ecriture de tailles de
blocs bizarres (octet 37 a 67), ce sera le cache qui permettra de
faire cela. Dans tous les cas, la solution actuelle (on copie
directement les donnees du controleur vers le buffer de destination)
ne pourra fonctionner, on devra temporiser quelque part, puis proceder
par recopie.
- concernant les file descriptors, nous decidons d'utiliser
directement l'adresse des resources. Ces resources sont maintenues
dans une liste chainee par team, pas besoin donc de tableau des file
descriptors. Des macros predefinies stdin, stdout et stderr
permettront de programmer au niveau utilisateur comme si on utilisait
les file descriptors 0, 1 et 2.
- pour l'acces aux methodes de base du noyau depuis le CPL3, il a ete
decide de creer une interface sys (modules/babel/sys). A l'heure
actuelle, cette interface exporte les methodes open() et fork(). Ceci
etant dit fork() ne restera surement pas dans cette interface, mais
sera deplace dans une interface team.
- au niveau de la structuration de kos-sys, pour l'instant nous
laissons tel quel, en important simplement dans un module CVS. Nous
verrons plus tard lorsqu'une vraie arborescence s'imposera : nous
n'avons pour l'instant qu'une petite application de test, et un
embryon de libc.
- pour la gestion des zones de memoires anonymes, il a ete decide de
dupliquer les shadow resources /dev/mem/zero, a chaque open() sur ce
peripherique. C'est le init_res de l'interface anon
(modules/vmm/_vmm_anon.c) qui se charge de faire cette
manipulation. Cette solution resout les problemes poses quant =E0 la
gestion de la memoire anonyme.
Au cours du WE nous avons donc travaille les points suivants :
- implementation de l'interface ANON pour les zones de memoires
anonymes, avec un init_res un peu special, qui duplique la shadow
resource.
- fignolage de la librarie libhash.
- refonte totale du systeme de gestion de l'espace de nommage de
Babel. Maintenant les shadow resources, en plus d'etre listes par
translator, forment entre elles un arbre, qui est celui de
l'arborescence. Ce systeme a grandement simplifie certaines
operations, et finalement accelere certaines operations. Avant, quand
on voulait faire open("/home/thomas/kos/foobar"), le driver FAT lisait
le repertoire racine pour trouver le repertoire thomas, lisait le
repertoire thomas pour trouver kos, etc... et en plus c'est le driver
fat qui se chargeait de decomposer le nom. Maintenant si on fait
open("/home/thomas/kos/foobar"), la fonction bbl_open_sr decompose le
nom (moins de duplication de code dans les drivers de fs) et a chaque
niveau cree une shadow resource dans l'arborescence des SR. Donc au
premier open("/home/thomas/kos/foobar"), on cree toutes les SR home,
thomas, kos, foobar (ce qui implique un temps tres legerement
superieur a la solution precedente), mais ensuite si on fait
open("/home/thomas/kos/truc"), les SR home, thomas et kos existant
deja, le driver FAT connait ou commence le repertoire kos et cherche
donc le fichier truc. Nettement plus rapide !
- cette refonte du systeme de gestion de l'espace de nommage a donne
lieu a la creation du fichier _tower_mount.c qui permet de monter des
systemes de fichiers.
- d'autre part, tout le code de Babel a ete securise vis a vis de la
synchronisation. Toutes les interfaces sont lockes par un lock global
(la granularite n'a pas besoin d'etre grande, on n'ajoute pas des
interfaces ni des translators tous les 4 matins). On a un lock par
translator pour controler l'ajout de shadow resource dans la liste du
translator, puis un lock par shadow resource, et enfin un lock par
resource. Les fonctions bbl_mount/umount et surtout bbl_open_sr ont
ete extremement complexes a realiser. (pour bbl_open_sr, se reporter
au commentaire au dessus de la fonction).
- implementation de primivites pour la gestion de semaphore
(kitc/_ksem.c), et de wait queues (kitc/_kwaitqueue.c).
- modification du driver FAT pour travailler conformement avec la
nouvelle facon de gerer l'espace de nommage (grosse simplification du
code).
- pour monter une partition, c'est simple : l'interface part propose
une methode mount, qu'il suffit d'appeler avec la chaine de caractere
representant le point de montage.
- systeme de detection automatique du systeme de fichier : chaque
driver de systeme de fichier doit proposer une methode
check_capability (cf fs/filesystem.h) qui est appelle pour chaque fs
dans le cas ou le fstype n'est pas specifie a l'appel de la fonction
mount. Des qu'on trouver un driver de fs susceptible de gerer la
partition, on l'utilise.
- creation d'un loader ELF extremement minimal : il cherche juste
l'adresse du point d'entree. Il faudra l'ameliorer pour qu'il regarde
quelles sont les sections read/write et celles read/only pour creer
les regions qui vont bien, et creer une region correspondant au BSS.
- grosse proprification de wolfgang.c, en vue de la sortie d'une
release.
- correction de bugs un peu partout : au niveau de kmsg (on faisait
des kmalloc pour allouer des struct kmsg_t, mais on faisait jamais de
kfree), au niveau de idt/_dst.c (initialisation des DST en
post_init_level, soit beaucoup trop tard -> on pouvait utiliser les
DST avant leur initialisation).
- amelioration de la libc au niveau utilisateur (module kos-sys), avec
utilisation plus propre de syscall.=20
- amelioration de _tower_syscall.c. On a quatre arguments pour le
syscall : l'adresse de la resource, l'identifiant de methodes, le
nombre d'arguments, un pointeur vers un tableau d'arguments.
- une page de memoire est allouee dans chaque espace user et contient
l'adresse de la resource systeme, et d'autres informations
importantes. Pour l'instant ceci est fait dans wolfgang.c. C'est le
fork() qui se chargera de mettre a jour cette page comme il le faut.
- implementation d'une libcmdline pour analyser les arguments fournis
par Grub au demarrage (obligation de fournir
wolfgang:root=3D/dev/disk/hda0 pour avoir un systeme de fichier
root). Modif au niveau du loader (loader/boot/cmdline.c) pour la
gestion de cette ligne de commande.
J'ai surement oublie quelques points, mais je crois que j'ai fait le
tour des principaux.
En bugs (connus), il reste :
- parfois un kernel_kvalloc_lock qui nous dit ASSERTION nb_writers =3D=
=3D
0 FAILED. (je crois qu'avec les threads de test kmem dans kmem/kmem.c)
ca le fait.
- le driver IDE marche mal sur la machine de Julien : la lecture du
premier secteur est OK, mais apres ca foire...
A faire :
- grosse reflexion sur comment le CPL3 va utiliser le CPL0.
- profiter de l'heritage des SR pour limiter l'espace memoire
utilise.
- creer une vraie kernel_methods_table, heritable.
Pour le reste, cf TODO
Voici le we-kos.txt ecrit pendant le WE :
- Identification de stdin/out/err
=3D> 1 page mappee dans l'espace utilisateur qvec : envp, qrgs ET
ID ressources stdin/out/err
ID ressource "0" (ie methodes fork/exec/.../lookup_method) : "sys"
Une ID ressource =3D { MAGIC, ptr ressource noyau }
=3D> Generation de MAGIC
- stubs generes a partir des .k
=3D> User : fonction dans libc (ou autre lib) qui fait :
__sys_read(res, args)
{
return syscall(res, id_method, args);
}
=3D> Kern : pr chq shadow_ressource =3D> tableau d'elements de type :
array[method_id] =3D { "nom methode", ptr methode }
+ code de la methode
CONTRAINTE =3D> conserver l'ordre des methodes malgre l'heritage
- methode lookup_method dans ressource "sys", qui retourne l'id de
la methode recherchee :
methode_id =3D __sys_lookup_method(ID ressource, "nom mthode");
Permet d'utiliser :
s =3D open("/dev/dsp"); /* Peut-etre plutot open(& s, "dev/dsp")..=
. */
id =3D lookup_method(s, "enable_3D_5:1_effect");
syscall(s, id, "toto");
- terminaison de team =3D> on doit scanner la liste de toutes les PD/PT
de l'AS de la team afin de mettre a jour les rmap. Du coup, on n'a
pas besoin de maintenir la liste des mappings anonymous (sans vraie
SR derriere), puisque de toutes facons on va scanner les pages et
mettre a jour les ref_cnt, afin d'eventuellement supprimer les
pages.
- syscalls et magics. Avoir un gros define MAGIC_RESOURCE global au
systeme, toutes tems, tous types de ressources, toutes ressources,
et stocker ce magic dans la ressource (res->magic).
=3D> Kern: do_syscall(resource res)
{
- verifier que res est mappee (ou swappee)
- verifier que res->magic vaut MAGIC_RESOURCE
- verifier que l'id methode est valide pour le type
de ressource considere
- faire le syscall
}
Je remercie encore une fois Julien et David d'etre venu a Paris passer
du temps a travailler sur KOS, ce fut tres agreable.
Bonne soiree,
Thomas
--=20
PETAZZONI Thomas - thomas.petazzoni@enix.org - UIN : 34937744
(Perso) http://www.enix.org/~thomas/
(KOS) http://kos.enix.org/=20
(Club LinUT) http://club-linut.enix.org