Moin Steffen !

So - meine Kommentare zum Thema kernel-Treiber ... :

> kgi_mode_init(struct ggi_mode_request *request)
> /* ??? kannst Du hier Dein neues Schema einbauen - Ich hab mir
>    ??? verschiedene Treiber angeschaut, aber noch nicht so richtig
>    ??? mitgekriegt wie das funktionieren soll.*/
Eigentlich extrem einfach - das chipset_set_mode entscheidet alles und befragt
den Rest nach seiner Meinung - kannst Du so lassen,wie es ist:

*int _setmode(struct kgi_mode *tm)
*{ int rc;
*
*  if ((rc=kgi_chipset_check_mode(tm,CMD_NONE))) return(rc);
*  
*  if (!CurrState->bgmode)
*  { if (kgi_chipset_set_mode  (tm)==-1) return -ENOMODESUP_CHIP; }
*    return 0;
*}

> kgi_init(void)
>  if (kgi_monitor_init())		/* Chipset is ok. Now initialize     */
Warum schon als zweites ? Dass das schiefgeht ist ziemlich unwahrscheinlich ...

> kgi_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 
>	  unsigned long arg)

Agreed - Problem beim BROADCAST: 1. Was ist der RC und 2. man kann die Kette
nicht abbrechen und nicht steuern,wer das ganze am besten kann .

> /* ??? Was machen kgi_graphmap_close und kgi_graphmap_nopage und 
>    ??? wo werden die definiert (z.B. umbenennen in kgi_chipset_...
>    ??? falls die vom chipset abhaengen.) */

Waere wahrscheinlich sinnig.
Es sind die Funktionen, die bei gepagedten Karten den Linear Buffer erzeugen.

Inzwischen habe ich neu definiert : linearmap_* und pagedmap_*.

Ein Nopage-Handler (ruft der kernel per exception auf, wenn ein Zugriff auf 
RAM erfolgt,das im Moment nicht gemappt ist) jeweils fuer einen linearen 
Buffer und fuer einen gepageten (sonst wird das nichts mit der Kompatibilitaet
zu svgalib).

Je nachdem, ob die Karte linear mapping kann oder nicht, wird die eine oder
andere Routine etwas aufwendiger

> kgi_mmap(struct inode *inode, struct file *file, struct vm_area_struct *vma)
> /* ??? kann ich das so einbauen ? */

Jein - siehe neuen Code wegen MMAP_FRAME - das bisherige war nur ein 
"ugly hack" und funktionierte nicht 100%.
Wenn Du den linear Buffer der Karte benutzen willst, geht es etwas anders
als in meinem Treiber (die beiden Funktionen waeren ggf. sogar als NOP
implementierbar, eleganter ist aber so eine Art demand-mapping, das brauchen
wir sowieso, wenn wir das, was in IDEA steht machen wollen), aber das kann 
ich gerne coden, wenn Du willst.

> kgi_open(struct inode *inode, struct file *file)
> /* ??? das sollte man irgendwie aendern. Wir koennten die 
>    ??? minor IDs noch brauchen. */
>    if (MINOR(inode->i_rdev) != 0xab)	/* MAGIC for ugly hack ... */

Zustimmung - das Problem ist folgendes :

#warn "Vortrag ueber Speichermanagement folgt !"

Ich habe einen Patch in den Kernel gehaengt, der fuer meinen Zweck etwas
sehr sinnvolles tut (naemlich Zeit und RAM spart), aber sonst toedlich waere.

=> MAGIC als Schutz.

Es gibt einen anderen Ansatz, der statt NOPAGE die SWAPIN Funktion nutzt
(Michaels Ansatz) - der kommt ohne Patchen aus - ist aber (finde ich) nicht 
sehr elegant.

Das ganze funktioniert so:

Bei einem MMAP-Aufruf legt der kernel eine vm_struct fuer den (logischen)
Speicherbereich an, der gemmapt werden soll.

Dann muss der Treiber paging-tabellen fuer diesen Bereich anlegen und 
befuellen. Entweder mit Zeigern auf physischen Speicher (in unserem Falle
der Page-Frame) oder mit dem Vermerk "Keine Page gemappt" bzw. "Page
geswappt".

Greift jemand auf eine solche Page (mit Vermerk) zu, loest die CPU eine Trap 
aus. Diese landet dann im Kern und springt dann entweder auf den nopage
oder swapin handler der jeweiligen vma_struct.

Dabei frisst das Finden der richtigen struct schon ganz schoen Zeit.

Im Falle von Nopage (eigentlich gedacht fuer das demand-loading von
executables) wird nun normalerweise eine RAM-Page alloziert, von der
Nopage-routine befuellt und hinterher mit den entsprechenden Rechten
versehen.

Das brauche ich natuerlich alles nicht => der Patch bypasst das.
Wenn wir uns durchsetzen koennen, sollte es kein Problem sein, ein Flag
in der vm_struct einzufuegen bzw. einen zusaetzlichen |-Wert fuer ein
Feld zu definieren.

Der andere Ansatz kommt ohne so einen Patch aus, muss aber auch einige
bizarre Dinge veranstalten, um aehnliche Probleme zu umgehen.
Der kernel alloziert hier wohl wenigstens kein RAM, will aber trotzdem
hinterher an der paging-table rumfummeln, so dass man beim mappen
tierisch tricksen muss, damit hinterher das rauskommt, was man wollte.

Ich persoenlich bevorzuge die nopage-Variante, denn der noetige "Final-
Patch" ist absolut minimal:

+       if ( SOME_FLAG_IS_THERE && vma->vm_ops && vma->vm_ops->nopage )
+       { vma->vm_ops->nopage(vma, address, page,
+               write_access && !(vma->vm_flags & VM_SHARED));return; }

und ich habe keine "fake swapped out" pages (die bizarrerweise auch noch
unswappable sind, damit der Kern nicht bei Speichernot versucht, die Dinger
rauszuswappen) im Speicher rumhaengen wie bei der swapin-Variante.

Ausserdem ist das System brauchbar fuer weitere Treiber fuer beliebige
Devices, die irgendwo gepagetes/gebanktes RAM einblenden (EMS-Boards,
Video,Netz,...).

        
>  if (!   (current->tty) 
>       || (current->tty->device&0xff00) != 0x0400
> /* ??? was bedeuted die 0x400 */
Das ist die MAJOR der VTs.

>       || (current->tty->device&0xff)   >= 64)
>    return -ENOTTY;			/* controlling tty is not a VT */
Bis dahin gehen die minors ...

> /* ??? kann ein user Prozess file->private_data aendern ? */
>   file->private_data=&StateNow[x];
NJET - das ist der Vorteil gegenueber filepos (und der Nachteil ;-)

>   if (MOD_IN_USE)
>     printk("kgi: scrdrv module is still in use. Not removed.\n");
Braucht man meines Wissens nicht mehr.


CU,Andy

