Warum unterscheiden sich die Linux-Systemrufnummern in x86 und x86_64?


35

Ich weiß, dass die Systemaufrufschnittstelle auf einer niedrigen Ebene implementiert ist und daher architektur- / plattformabhängiger, nicht "generischer" Code.

Ich kann jedoch nicht klar erkennen, warum Systemaufrufe in Linux-32-Bit-x86-Kerneln Nummern haben, die in der ähnlichen Architektur von Linux-64-Bit-x86_64 nicht gleich bleiben. Was ist die Motivation / der Grund für diese Entscheidung?

Meine erste Vermutung war, dass der Hintergrund darin bestand, 32-Bit-Anwendungen auf einem x86_64-System lauffähig zu halten, damit das System über einen angemessenen Versatz zur Systemrufnummer weiß, dass der Benutzerbereich 32-Bit oder 64-Bit ist beziehungsweise. Dies ist jedoch nicht der Fall. Zumindest scheint es mir, dass read () als Systemrufnummer 0 in x86_64 nicht mit diesem Gedanken in Einklang gebracht werden kann.

Eine andere Vermutung war, dass das Ändern der Systemrufnummern einen sicherheitsrelevanten Hintergrund haben könnte, was ich selbst nicht bestätigen konnte.

Da ich die Herausforderungen der Implementierung der architekturabhängigen Codeteile nicht kenne, frage ich mich immer noch, wie sich die Systemrufnummern ändern lassen , wenn es nicht nötig erscheint (da sogar ein 16-Bit-Register weitaus mehr als die derzeit ~ 346 Zahlen speichern würde, um alle darzustellen Anrufe), würde dazu beitragen, etwas anderes zu erreichen, als die Kompatibilität zu unterbrechen (obwohl die Verwendung der Systemaufrufe durch eine Bibliothek, libc, es mildert).


3
Ich denke, Sie stellen die falsche Frage. Die richtige Frage ist, warum sie gleich bleiben: Beantworten Sie die Kompatibilität. Wenn also x86 und x86_64 inkompatibel sind, gibt es keine Kräfte, die sie davon abhalten, sich zu ändern. Jetzt werden alle Kräfte der letzten 20 Jahre, die eine Veränderung wollten, dominieren (wir haben die Chance, sie zu verändern). [Beachten Sie, dass dies nur eine Meinung ist und nicht auf dem inneren Verstand der Designer des neuen Systems basiert.]
Strg-Alt-Delor

Antworten:


34

Was die Gründe für die spezifische Nummerierung betrifft, die mit keiner anderen Architektur übereinstimmt (außer "x32", das eigentlich nur Teil der x86_64-Architektur ist): In den frühen Tagen der x86_64-Unterstützung im Linux-Kernel gab es noch keine Aus Gründen der Abwärtskompatibilität wurden alle Systemaufrufe neu nummeriert , um sie auf der Ebene der Cacheline-Nutzung zu optimieren .

Ich weiß nicht genug über die Kernelentwicklung, um die spezifischen Grundlagen für diese Auswahlmöglichkeiten zu kennen, aber anscheinend steckt eine gewisse Logik dahinter, alles mit diesen bestimmten Zahlen neu zu nummerieren, anstatt einfach die Liste aus einer vorhandenen Architektur zu kopieren und die nicht verwendeten zu entfernen. Es sieht so aus, als ob die Reihenfolge davon abhängt, wie häufig sie aufgerufen werden - z. B. Lesen / Schreiben / Öffnen / Schließen im Vordergrund. Exit und Fork mögen "fundamental" erscheinen, aber sie werden jeweils nur einmal pro Prozess aufgerufen.

Es kann auch etwas los sein, um Systemaufrufe, die üblicherweise in derselben Cache-Zeile verwendet werden, beizubehalten (diese Werte sind nur Ganzzahlen, aber es gibt eine Tabelle im Kernel mit Funktionszeigern für jeden einzelnen, sodass jede Gruppe von 8 Systemaufrufen belegt eine 64-Byte-Cache-Zeile für diese Tabelle)


1
fork may seem "fundamental", but [...] called only once per process.UH, was? Ich verstehe Sie können erwarten , einmal Ausfahrt zu nennen, aber Sie können in den Eltern und Kind einer Gabel fork()Anruf
Katze

5
@cat Wenn Sie forkden Prozess als dem untergeordneten Prozess zugeordnet betrachten (dh als den Prozesserstellungsaufruf) und nicht als den übergeordneten Prozess, ist die Random832-Anweisung korrekt.
Ikarus

4
@cat OK, Sie können fork () zwei- oder dreimal aufrufen, vielleicht noch ein paar Mal. Aber Sie können read () millionenfach oder sogar milliardenfach aufrufen.
Michael Hampton

1
Ja das ist, was ich meinte. Die Anzahl der Fork-Aufrufe und die Anzahl der Prozesse über die
gesamte

15

Siehe diese Antwort auf die Frage "Warum unterscheiden sich die Systemrufnummern in amd64 linux?" auf Stapelüberlauf.

Fazit: Aus Kompatibilitätsgründen ist die Systemaufrufliste stabil und kann nur wachsen. Als die x86 64-Architektur erschien, war das ABI (Argument übergeben, Rückgabewert) anders, daher nutzten die Kernel-Entwickler die Gelegenheit, Änderungen vorzunehmen, auf die lange gewartet wurde.


Cool, meine Vermutung war richtig.
Strg-Alt-Delor

2
Die andere Antwort, auf die Sie verlinken, ist spekulativ: "Die Linux-Leute haben sich höchstwahrscheinlich entschieden ..." (Hervorhebung hinzugefügt). Ich denke, es wäre hilfreich, wenn Ihre Antwort hier Hinweise darauf liefern würde, dass sie anscheinend eher auf Spekulationen als auf Beweisen beruht. Übrigens liefert ein neuerer Kommentar, der unter der verknüpften Antwort veröffentlicht wurde, den Beweis, dass der wahre Grund nicht die allgemeine Bereinigung von Cruft (wie diese Antwort spekuliert) ist, sondern speziell die "Verwendung von Cacheline", wie in der anderen Antwort hier erläutert .
DW

-3

Kurz gesagt, weil jemand dachte, " N+1unbegründet inkompatible Methoden sind besser als NMethoden". Für historische Arches wurden die Syscall-Nummern normalerweise so gewählt, dass sie mit einigen proprietären Unix-Legacy-Versionen übereinstimmen. Aber für x86_64 konnten die Kernel-Entwickler eine beliebige Nummerierung wählen. Anstatt die einfache Wahl zu treffen und eine bestehende Nummerierung wiederzuverwenden, trafen sie die Wahl, einen neuen Standard zu erfinden. Dann machten sie es noch einmal für aarch64 und ein paar andere. Dies ist ein sich oft wiederholendes Muster in der Linux-Kernelentwicklung.


3
Die Änderung war nicht unbegründet. Es gibt solide technische Gründe. Ohne Abwärtskompatibilitätsanforderungen wären ähnliche Änderungen auch auf die vorhandenen Architekturen angewendet worden.
Jörg W Mittag

Der Unterschied in der Nummerierung ist zu 100% unbegründet. Eine bestimmte Nummerierung bietet keinen technischen Vorteil.
R ..

2
Wie diese andere Antwort erklärt, sind Syscalls so gruppiert, dass gemeinsam verwendete Syscalls dieselbe Cacheline in der Syscall-Tabelle verwenden. Und Syscall- Nummern werden so ausgewählt, dass sie einfache Indizes in dieser Tabelle sind. Theoretisch könnten wir eine Indirektionsebene verwenden, um die Position eines Syscalls in der Syscall-Tabelle von der Syscall-Nummer zu entkoppeln. Dies würde jedoch möglicherweise einen Teil des Leistungsgewinns verschlingen, den wir durch das Einfügen von Hot-Syscalls in dieselbe Cacheline erzielen.
Jörg W Mittag

@ JörgWMittag: Und das ist natürlich eine vorzeitige Optimierung und keine messbare Verbesserung. Schauen Sie sich nur an, wie viele Zyklen Syscalls dauern und wie viele Cache-Zeilen sie räumen. Das Speichern von höchstens einer Cache-Zeile aus der Reihenfolge der Tabelle wird keinen Unterschied machen.
R ..

2
@R .. "Ich habe die Nummerierung in Abhängigkeit von den TPCC-Kernel-Profilinformationen mit gängigem DBMS und der Strace-Ausgabe einiger Netzwerk- und Desktopanwendungen ausgewählt." sicherlich hört sich das so an, als gäbe es messungen. Der Autor gab jedoch keine Zahlen an oder erläuterte die Methodik angemessen.
user45891
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.