Wenn die Funktion einen Zeiger empfängt zu User-Space-Daten müssen Sie copy_from_user()
verwenden um die Daten, auf die gezeigt wird, aus dem Benutzerbereich in den Kernelbereich zu kopieren (und umgekehrt).
Beachten Sie, dass der Zeigerwert selbst als Wert übergeben wird (wie alle C-Parameter), sodass Sie keine copy_from_user()
ausführen müssen um den Zeigerwert zu erhalten, bevor Sie copy_from_user()
können die Daten, auf die es zeigt.
Numerische Argumente funktionieren genauso wie Zeigerargumente; in C-Termen sind sie beide Skalare. Sie müssen copy_from_user()
nicht verwenden um den Wert des Parameters zu kopieren; das ist schon kopiert. Sie müssen es nur verwenden, um Daten zu kopieren, auf die ein übergebener Zeiger zeigt.
Wenn Sie also einen Parameter vom Typ int
haben , können Sie es direkt verwenden. Wenn Ihr Parameter auf int
zeigt , dann die int
Das Objekt befindet sich im Benutzerbereich, und Sie müssen copy_to_user
verwenden um den Wert dieses Objekts in den Kernel-Space zu kopieren.
Wenn ein Benutzer Daten an den Kernelspace übergibt, können diese Daten auf mehrere Seiten aufgeteilt werden, und diese Seiten können sogar im ausgelagerten Speicher liegen . In diesen Fällen müssen Sie warten, bis der Kernel die Seite einwechselt und Zugriff auf die Seite erhält, auf der sich die Daten befinden. Bei elementaren Datentypen (wie int oder Zeigern) gilt auch, dass einige Architekturen (insbesondere x86 Intel) zwingen den Benutzer nicht, die Daten auszurichten, sodass sogar eine Ganzzahl um einen Seitenrand herum aufgeteilt werden kann. Sie können auf den ersten Teil Ihrer Ganzzahl zugreifen, aber warten, bis der zweite Teil vom Speichermanager eingelagert wird, bevor auf das Ganze zugegriffen wird.
Sie können einige Roundtrips sparen, indem Sie alle Benutzerdaten in eine Struktur stecken, deren Zeiger an den Kernel übergeben werden. Sie können es als Sperre kopieren_von_Benutzer und Zugriffe speichern (und laufen Gefahr, mehrmals gesperrt zu werden)
Also, und als Fazit, benutzen Sie die Funktionen auch für grundlegende Typen , da es viele davon gibt. Gehen Sie nicht davon aus, wo sich die Benutzerdaten befinden können, wenn Sie im Kernelmodus ausgeführt werden. Sie haben Zugriff darauf, aber die virtuellen Kerneladressen der Benutzerdaten haben nichts mit den virtuellen Adressen zu tun, die im Benutzermodus angezeigt werden.