[Kos-dev] Un peu de tout concernant KOS...

Thomas Petazzoni kos-dev@enix.org
Sun, 15 Jul 2001 17:02:20 +0200


Bonjour,

Tout d'abord, je souhaite m'excuser pour le sujet du message, un peu
stupide et surtout absolument pas explicite. En fait, je voulais
proposer differentes suggestions, completement independantes les unes
des autres. Je ne voulais pas faire un mail par suggestion, alors voici
le mail fourre-tout de mes reflexions des derniers jours.
Outline :
	1. Allocation par Slab
	2. Separation en modules de la gestion de la memoire
	3. Coherence des PDs du noyau
	4. Blocage de pages physiques en memoire physique
	5. Lancement de KOS (apres le noyau)
	

1. Allocation par Slab

Je viens de jeter un oeil du cote de mm/slab.c dans les sources de Linux
(2.4.5). d2 proposait d'implementer des slabs pour avoir une methode
rapide d'allouer des donnees. Mais en fait, je pense que ca ne va pas
etre la peine, car le kmalloc() existant est justement base sur ce
systeme de Slab.
En effet :

 * An implementation of the Slab Allocator as described in outline in;
 *      UNIX Internals: The New Frontiers by Uresh Vahalia
 *      Pub: Prentice Hall      ISBN 0-13-101908-2
 * or with a little more detail in;
 *      The Slab Allocator: An Object-Caching Kernel Memory Allocator
 *      Jeff Bonwick (Sun Microsystems).
 *      Presented at: USENIX Summer 1994 Technical Conference

Le deuxieme document (par ailleurs disponible sur le site de KOS me
semble-t-il) est celui qui a inspire Hlide pour l'algorythme de ce
kmalloc, et c'est ce meme document que j'ai relu lorsque j'ai implemente
le kmalloc().

Etant donne qu'on utilise deja ce principe de slab pour -toutes- les
allocations, est-ce bien necessaire de refaire un slab allocator ?

2. Separation en modules de la gestion memoire

Actuellement, tout ce qui est portable est dans mm, tout ce qui est non
portable dans mm-x86. J'aimerais mieux une autre repartition, du type :
	
mm-x86 (hat): 	
-------------
* specification des zones physiques non allouables (pas gore 			comme
actuellement dans mm/pmm.c)
* mapping virtuel->physique (et maintien des liens 			
physique->virtuel)
* changement des droits (r ou r/w) sur des zones de memoire
* GDT, TSS
* IMPORTANT : coherence des PDs du noyau lors des mappings
virtuel->physique
* Le double fault : ici ou dans idt/ ? A priori ici, car on a 			aussi
le prehandler de page fault, qu'il faudra renommer.

pmm :
-----
* maintien du GPFS (pile des pages physiques libres)
* alloc/desalloc de pages physiques
* lancement du swapper en cas de besoin
* swapper

vmm :
-----
* creation "as" (espace d'adressage)
* creation/suppression/modif region virtuelles (segments)
* gestion du page fault
* application de droits sur des ranges au sein de regions virtuelles
		
kmem :	
------	
* actuel kvalloc/kvfree (a renommer)
* actuel kmalloc/kfree (a renommer)
* pourquoi pas l'allocation des piles cpl0
(allocate/unallocate_cpl0_stack, dans task/_task_kstack.h)


3. Coherence des PDs du noyau

Nous avons differentes teams qui tournent dans le systeme, c'est a dire
differents espaces d'adressage, c'est a dire differents CR3, et par voie
de consequence differents PD. Neanmoins il faut ABSOLUMENT assurer la
coherence des differents PD concernant la partie noyau (0-2G) et ce a
tout instant.

Seule la coherence des PD est necessaire, car les PTs du noyau seront
les memes pour tous les espaces d'adressage.
J'explique un peu peut etre : l'espace noyau est defini par un ensemble
de PT, contenus dans des pages physiques connues. Ces PTs sont
references dans un PD, le PD de la team courante. Il suffit donc de
maintenir la coherence des PD (tableau de pointeur vers des PT) pour
maintenir la coherence de l'espace du noyau.

La maniere la plus simple, la plus elegante et surtout la plus rapide
(pas de changement de contexte) de faire ceci est de pouvoir acceder a
partir de n'importe quelle team aux PDs de toutes les autres teams.

Supposons qu'on limite le nombre de teams dans le systeme a 1024 (ce qui
me semble raisonnable). On peut alors utiliser le dernier PT de l'espace
noyau pour que chacun des PTE pointe vers les PDs de chaque team.
Ainsi les 4 derniers Mo de l'espace noyau seront en fait les PDs des
1024 teams potentiellement presentes dans le systeme. Ces PDs seront
accessibles sans changement de contexte, et une simple boucle (+ test
pour verifier si le PD existe) suffira a appliquer le changement sur
tous les PDs. Bien sur ca reste assez lourd, mais il faut bien se rendre
compte que cette manipulation n'a lieu qu'a chaque allocation d'un
nouveau PT pour le noyau, c'est a dire tous les 4 Mo d'allocation de
memoire. 

Pour gerer cette ensemble de PTE, et savoir lequel est dispo pour
pointer vers un PD d'une nouvelle team, je pense qu'on va faire simple
et efficace : bitmap.

Le probleme de cette solution est qu'il impose de laisser les PD a la
meme place en memoire physique. De toute facon avec le mecanisme de la
pagination, il n'y a pas trop le choix (toutes les adresses des PD/PT
sont donnees en physique) et donc nos reves de pouvoir tout deplacer en
memoire physique s'effrondrent. Neanmoins on peut ameliorer le
fonctionnement de l'allocation de memoire physique pour trier les
allocations et se garder de grosses zones pour le DMA.

Qu'en pensez-vous ?

4. Blocage de pages physiques en memoire physque

On aura plusieurs types de pages physiques : les swappables (tout ce qui
est du cote user : code, donnees, librairies...), les non swappables et
deplacables (code, donnees noyau), les non swappables et difficilement
deplacables (PT, PD).

Il est indispensable de bloquer le code et les donnees du noyau en
memoire physique, sinon il y a risque de : j'ai besoin de la page X, je
veux donc la ramener en memoire, mais zut le code pour ramener cette
page X en memoire est sur cette page X...
Les PD ne sont pas deplacables : ils sont utilises dans notre espece
d'index des PDs des teams (pour la coherence), et ne sont donc pas
vraiment deplacables. Les PTs du noyau c'est la meme chose. 
Par contre, je pense qu'on peut se laisser aller a swapper le PT du code
ou des donnees d'un thread (tache). Je sais pas du tout ce que ca donner
au niveau de la detection pour le page fault, mais on verra sur le
moment.

Qu'en pensez-vous ?

5. Lancement de KOS (apres le noyau)

J'ai toujours eu un probleme meta physique concernant le demarrage du
systeme : comment on va creer la premiere tache, qui lance le premier
shell... J'ai donc essaye de reflechir un peu la dessus.

J'ai regarde les sources de Linux pour avoir des idees, mais je pense
que nous pouvons faire differement et profiter de notre architecture
modulaire.

Nous pourrions imaginer avoir une sorte de shell noyau (qui de toute
facon sera indispensable pour le debugging), que l'on appelera par la
suite kshell (oui julien, on pourra le renommer !). Ce kshell est l'un
des threads noyau, il permettrai notamment de charger des modules
dynamiquement, via un script d'initialisation. Ainsi au boot on ne
charge que les modules indispensables (idt,mm,task et au moins un
filesystem), et notre script d'initialisation peut ensuite charger
d'autres modules (babel, net, drivers, autres fs). Je ne sais pas
vraiment si cela peut servir a quelque chose, mais pourquoi pas ?

Une fois ces modules charges et linkes avec le reste des autres modules,
on peut alors envisager d'executer le premier thread CPL3. Ce premier
thread CPL3 sera contenu dans la kernel team, et peut etre compare au
/sbin/init de linux (cf appel dans /usr/src/linux/init/main.c, dernieres
lignes). Il lit alors les differents scripts d'initialisation du systeme
mais niveau utilisateur (lancement de serveurs, configuration...).
Ensuite, il ouvre les differents tty, et enfin plus important, il forke
(creation de nouvelles teams) pour avoir des threads login qui attente
qu'un utilisateur se logge.

Ce qui est ennuyeux, c'est d'etre oblige d'avoir une gestion d'un
systeme de fichiers assez rapidement (au cours du boot), pour pouvoir
charger le code du thread init.

Ce n'est pas encore tout a fait precis, mais j'aimerais avoir vos
suggestions, vos avis concernant ce point.

Je crois que j'en ai fini pour aujourd'hui !

Amicalement,

Thomas
-- 
PETAZZONI Thomas
thomas.petazzoni@meridon.com     UIN : 34937744
Projet KOS : http://kos.enix.org
Page Perso : http://www.enix.org/~thomas/