x86とx86_64のLinuxシステムコール番号が異なるのはなぜですか?


35

システムコールインターフェイスは低レベルで実装されているため、「ジェネリック」コードではなく、アーキテクチャ/プラットフォームに依存します。

しかし、Linux 32ビットx86カーネルのシステムコールに、同様のアーキテクチャのLinux 64ビットx86_64で同じ値が保持されない理由がはっきりとわかりません。この決定の背後にある動機/理由は何ですか?

私の最初の推測は、バックグラウンド化の理由が32ビットアプリケーションをx86_64システム上で実行可能な状態に維持することであったため、システムコール番号への妥当なオフセットを介して、システムはユーザースペースが32ビットまたは64ビットであることを認識しますそれぞれ。ただし、そうではありません。少なくとも、x86_64のシステムコール番号0であるread()は、この考えと一致しないように思われます。

もう1つの推測は、システムコール番号の変更にはセキュリティ/強化の背景があるかもしれないということです。

アーキテクチャに依存するコード部分の実装の課題に無知であるため、システムコール番号を変更する必要はないように思われます(16ビットのレジスタでさえ、すべてを表すために現在〜346の数値よりも多くを格納するため)呼び出し)、互換性を破る以外の何かを達成するのに役立ちます(ただし、ライブラリlibcを介してシステムコールを使用すると、軽減されます)。


3
あなたは間違った質問をしていると思います。正しい質問は、なぜそれらを同じに保つかということです:答えの互換性 したがって、x86とx86_64に互換性がない場合、それらを変更しないようにする力はありません。変化を望んでいた過去20年間のすべての勢力が支配するようになります(それらを変更する機会を得ます)。[これは単なる意見であり、新しいシステムの設計者の内心に基づくものではないことに注意してください。]
ctrl-alt-delor

回答:


34

特定の番号付けの背後にある理由については、他のどのアーキテクチャとも一致しません(x86_64アーキテクチャのほんの一部である「x32」を除く):Linuxカーネルでのx86_64サポートのごく初期には、深刻な後方互換性の制約により、すべてのシステムコールは、キャッシュラインの使用レベルで最適化するために番号が付け直されました

これらの選択の具体的な根拠を知るほどカーネル開発について十分な知識はありませんが、明らかに、既存のアーキテクチャからリストをコピーして未使用のものを削除するのではなく、これらの特定の番号ですべての番号を付け直すという選択肢の背後にあるロジックがあるようです。順序は、それらが呼び出される頻度に基づいているようです。exitとforkは「基本的」に見えるかもしれませんが、プロセスごとに1回だけ呼び出されます。

同じキャッシュライン内で一緒に使用される一般的なシステムコールを保持することについて何かが起こっているかもしれません(これらの値は単なる整数ですが、それぞれに関数ポインタを持つカーネル内のテーブルがあるため、8つのシステムコールの各グループが占有しますそのテーブルの64バイトのキャッシュライン)


1
fork may seem "fundamental", but [...] called only once per process.あ、何?私はあなたが一度終了を呼び出すことを期待することを理解し、しかし、あなたはの親と子の内側にforkしてfork()コール

5
@cat forkは、親プロセスではなく、子プロセスに説明されていると見なす(つまり、プロセス作成呼び出しと見なす)場合、Random832のステートメントは正しいです。
イカロス

4
@cat OK、fork()を2、3回呼び出すかもしれません。しかし、read()を何百万回、さらには何十億回も呼び出すことができます。
マイケルハンプトン

1
はい、それは私が意味したものです。フォークコールの数と、システムの寿命にわたってプロセスの数が同じになるだろう、などINIT、[プロセスまたはスレッドを作成することができる]クローン、などの詳細を無視
Random832

15

「amd64 linuxでシステムコール番号が異なるのはなぜですか」という質問に対する回答をご覧ください。スタックオーバーフロー。

まとめると、互換性のために、システムコールリストは安定しており、成長しかできません。x86 64アーキテクチャが登場したとき、ABI(引数の受け渡し、戻り値)が異なっていたため、カーネル開発者は長い間待ち望まれていた変更をもたらす機会を得ました。


クールな推測は正しかった。
ctrl-alt-delor

2
あなたがリンクする他の答えは投機的です:それは「Linuxの人たちが最も決定した可能性が高い ...」と言います(強調が追加されました)。ここでの回答が、証拠ではなく推測に基づいていることを示す何らかの情報が提供されれば、役立つと思います。ちなみに、リンクされた回答の下に投稿されたより最近のコメントは、本当の理由がクラフの一般的なクリーンアップではないという証拠を提供します(その答えは推測します)が、ここの他の回答で説明されいるように特に「キャッシュラインの使用」に関するものです
DW

-3

一言で言えば、誰かが「N+1それを行うことの不当に互換性のない方法はN方法よりも優れている」と考えたからです。歴史的なアーチの場合、syscall番号は通常、いくつかのレガシーな独自のUNIXに一致するように選択されました。しかし、x86_64の場合、カーネル開発者は好きな番号を自由に選択できました。単純な選択を行って既存の番号を再利用するのではなく、彼らは新しい標準を発明することを選択しました。その後、彼らはaarch64と他の多くのためにそれを再びしました。これは、Linuxカーネル開発で頻繁に繰り返されるパターンです。


3
変更は無償ではありませんでした。確かな技術的理由があります。下位互換性の要件がなければ、既存のアーキテクチャにも同様の変更が適用されていました。
ヨルグWミットタグ

番号付けの違いは100%無料です。特定の番号付けには技術的な利点はありません。
R ..

2
以下のように、この他の答えは説明し、システムコールは一般に一緒に使用されるシステムコールは、システムコールテーブルの同じキャッシュラインを共有するようにグループ化されます。また、システムコール番号は、そのテーブルへの単純なインデックスになるように選択されます。理論的には、インダイレクションのレイヤーを使用して、syscallテーブル内のsyscallの位置をsyscall番号から切り離すことができますが、ホットキャッシュを同じキャッシュラインに配置することで得られるパフォーマンス向上の一部を食いつぶす可能性があります。
ヨルグWミットタグ

@JörgWMittag:それは明らかに時期尚早な最適化であり、測定可能な改善ではありません。システムコールがどれだけのサイクルを要するか、そしてそれらが追い出すキャッシュラインの数を見てください。テーブルの順序付けからせいぜい1つのキャッシュラインを保存しても違いはありません。
R ..

2
@R ..「tpccカーネルプロファイリング情報の機能で、人気のあるDBMSと一部のネットワークおよびデスクトップアプリケーションのstrace出力で番号付けを選択しました。」確かに測定があったように聞こえます。しかし、著者は数を提供しなかったか、方法論を適切に説明しました。
user45891
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.