2016-06-27 12 views
2

Ich habe einen Char-Treiber, in dem eine der Schnittstellenfunktionen, die ich hinzugefügt habe, alloc_contig(int order) ist, wo Reihenfolge log2 der gewünschten Anzahl von 4K-Seiten ist. Diese Funktion weist den zusammenhängenden physischen Speicher zu und ordnet ihn für die Verwendung des Benutzerbereichs unter Verwendung der remap_pfn_range-Funktion zu. Ich versuche, Funktion zu schreiben, die diesen Speicher freigibt dealloc_contig(va) jetzt im Kernel Ich habe die virtuelle Adresse vom Benutzer frei gegeben und ich muss die zugrunde liegende physikalische Adresse zu erhalten, also habe ich versucht, virt_to_phys zu verwenden, aber es gibt mir nicht die gewünschte Adresse. Log:Virtuelle zu Kernel logische Adresse

//allocating 
page address is ffff880868764000 //allocated using alloc_pages 
//deallocating 
virtual address from user 7f4c7e095000 
when converted to PA using virt_to_phys got f74c7e095000 instead of ffff880868764000 

Können Sie mir bitte helfen?

Antwort

1

Schnell Antwort: Sie haben do_munmap() verwenden, um die Seiten aus dem Benutzerprozess unmap.
virt_to_phys() kann diesen Job nicht erledigen. Es wird vom Kernel verwendet, um die virtuelle Kernel-Adresse (keine virtuelle Benutzeradresse) in die physikalische Adresse zu übersetzen.

Benutzerraum Memories sind durch VMA Regionen organisiert. (struct vm_area_struct * VMA). Sie können unter struct mm_struct pro Prozessbasis gefunden werden. Die Prozesse haben ihre eigenen mm_structs, so dass für verschiedene Prozesse die gleiche virtuelle Adresse auf verschiedene physikalische Adressen abgebildet wird.

Was Sie tun müssen, ist, die virtuelle Adresse zu bekommen. Dann müssen Sie im Kernel-Bereich herausfinden, welche vma diese Adresse gehört, dann den Adressbereich aus dem vma auflösen und die Seiten zurückfordern (Das ist, was do_munmap() tun.).

Ein weiterer erwähnenswerter Punkt ist, weil Prozesse ihr eigenes mm_struct haben, also ihre eigenen vma-Regionen. do_munmap() muss unter dem "richtigen" Benutzerprozess conext aufgerufen werden oder es wird das falsche mm_struct erhalten.

Sum up die Schritte:
1.User Prozess, der die Region Aufruf Ihre Schnittstelle die virtuelle Adresse freizugeben zugeordnet haben. 2. Systemaufruf zum Kernelraum (Dies steht im Kontext Ihres Benutzerprozesses). Ihr Treiberhandleraufruf do_munmap() zu die virtuelle Adresse auflösen.
3.Dein Treiber die Seiten frei.

Hoffe, das hilft!

+0

Vielen Dank für Ihre hilfreiche Antwort. Kannst du mir bitte, wenn möglich, helfen, die passende vma struct zu finden? Wie ich gesehen habe, gibt es in mm_strct einen rotschwarzen Baum namens mm_rb, der vma-Strukturen enthält. Wie greife ich auf mm_struct des Prozesses und wie suche ich in diesem Baum? –

+0

Hallo, Dies wird gemacht von do_munmap() -> find_vma(), Sie können den Quellcode unter diesem Link ansehen. http://lxr.free-electronics.com/source/mm/mmap.c#L2411 – Lin