(Courriels de diversion: <largueras@exterminerai-contacterions.com> <scieries@valsant-exportes.com> <reitereraient@logos-brocard.com> <rejoueront@fiscales-congeles.com> <limogent@pretexte-jugulerions.com> <decolores@reluira-muselerent.com> <empireront@nucleaires-calculettes.com> <susnomme@skiait-resultant.com> <insinuants@repartiras-pacifions.com> <vexons@gercee-deboucheront.com> )
Olivier Poitou wrote: > > Petite question subsidiaire : > Le noyau est-il capable de traduire une adresse > virtuelle en l'adresse physique correspondante (ce qui > implique qu'il reconnaisse le processus appelant, puis > qu'il utilise la MMU avec l'identifiant de ce processus > pour faire la traduction). Si oui (et je pense que > c'est le cas) connais-tu la fonction qui effectue ceci > (virt_to_phys aussi ? c'est ainsi que cela fonctionne > sous FreeBSD). > mmmm... ta question subsidiaire s'avere etre une jolie colle ;) Pour etre franc, je ne sais pas .. :( Je developpe des drivers temps-reel sous linux, et la question ne m'est jamais venu a l'esprit car pour moi je considere les espace d'@ virt totalement local au processus. Donc les seul parametres ayant reellement une signification d'un procees a un autre ( ou au kernel ) sont les adresses physiques. C'est la raison pour laquelle je ne transmet aucune adresse virtuelle. Ta solution a bien des inconvenients !!! -- comme tu le dis, il faut que le noyau trouve le processus appelant ... ( a part passer le pid du process en parametre, je ne vois pas vraiment d'autre solution ...) -- Utiliser le MMU pour traduire l'adresse !!! La je dis ATTENTION, car le MMU ne sert pas de traducteur. D'une part, il est deja en utilisation puisque le kernel accede a son espace virtuel, ce qui veut dire que si tu le deconfigure pour le reconfigurer tu perds ton espace virt !! de plus il n'est pas sure que ce soit une bonne methode car le MMU fonctionne suivant des requetes du style; je veux remapper @ sur x octets ( ou pages ) et le MMU renvoie l'@ virt. remappe ... et non l'inverse. Pour recuperer une equivalence @phys<->@virt pour un process il est alors plus judicieux, non pas de toucher au MMU ( risque de destabiliser le fonctionnement complet de linux ! ), mais de regarder dans les structures de gestion de memoire ou le kernel conserve les pages allouees, par qui, et quels @. Chris. NB: pourquoi cet obstination a vouloir passer une adresse virtuelle ???? Ajout apres relecture des fichiers sources de linux .... ######### fichier /usr/src/linux/include/linux/mm.h /* * This struct defines a memory VMM memory area. There is one of these * per VM-area/task. A VM area is any part of the process virtual memory * space that has a special rule for the page-fault handlers (ie a shared * library, the executable area etc). */ struct vm_area_struct { struct mm_struct * vm_mm; /* VM area parameters */ unsigned long vm_start; unsigned long vm_end; /* linked list of VM areas per task, sorted by address */ struct vm_area_struct *vm_next; pgprot_t vm_page_prot; unsigned short vm_flags; /* AVL tree of VM areas per task, sorted by address */ short vm_avl_height; struct vm_area_struct * vm_avl_left; struct vm_area_struct * vm_avl_right; /* For areas with inode, the list inode->i_mmap, for shm areas, * the list of attaches, otherwise unused. */ struct vm_area_struct *vm_next_share; struct vm_area_struct **vm_pprev_share; struct vm_operations_struct * vm_ops; unsigned long vm_offset; struct file * vm_file; unsigned long vm_pte; /* shared mem */ }; ######### fichier /usr/src/linux/include/linux/sched.h struct mm_struct { struct vm_area_struct *mmap; /* list of VMAs */ struct vm_area_struct *mmap_avl; /* tree of VMAs */ struct vm_area_struct *mmap_cache; /* last find_vma result */ pgd_t * pgd; atomic_t count; int map_count; /* number of VMAs */ struct semaphore mmap_sem; unsigned long context; unsigned long start_code, end_code, start_data, end_data; unsigned long start_brk, brk, start_stack; unsigned long arg_start, arg_end, env_start, env_end; unsigned long rss, total_vm, locked_vm; unsigned long def_flags; unsigned long cpu_vm_mask; unsigned long swap_cnt; /* number of pages to swap on next pass */ unsigned long swap_address; /* * This is an architecture-specific pointer: the portable * part of Linux does not know about any segments. */ void * segments; }; struct task_struct { /* these are hardcoded - don't touch */ volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ unsigned long flags; /* per process flags, defined below */ int sigpending; mm_segment_t addr_limit; /* thread address space: 0-0xBFFFFFFF for user-thead 0-0xFFFFFFFF for kernel-thread */ [...] /* memory management info */ struct mm_struct *mm; /* signal handlers */ spinlock_t sigmask_lock; /* Protects signal and blocked */ struct signal_struct *sig; sigset_t signal, blocked; struct signal_queue *sigqueue, **sigqueue_tail; unsigned long sas_ss_sp; size_t sas_ss_size; }; extern __inline__ struct task_struct *find_task_by_pid(int pid) { struct task_struct *p, **htable = &pidhash[pid_hashfn(pid)]; for(p = *htable; p && p->pid != pid; p = p->pidhash_next) ; return p; } ################ Et voila .... normalement avec les headers que je t'ai indique, tu devrais pouvoir : -- a partir du pid retrouver la structure task_struct correspondante. ( je ne m'avancerai pas , mais lorsque ton process appelle une fonction du kernel, il est toujours la tache courante, donc normale tu peux recuperer sa structure avec: 'struct task_struct actuel= aligned_data[cpu].schedule_data.curr ;' avec cpu=0 sur un systeme mono-processeur.) -- puis il te reste plus qu'a parcourir les vm_area_struct pour trouver l'adresse virtuelle recherche. Bon ... j'espere que cela vas te motiver a passer une @ physique ... ;) A+ -- Kumsta Christophe <kumsta@easynet.fr>Real-Time System developper RT-Linux/RTAI ( Use the Source Luck !) --------------------------------------------------------------------- Aide sur la liste: <URL:mailto:linux-31-help@savage.iut-blagnac.fr>Le CULTe sur le web: <URL:http://savage.iut-blagnac.fr/>