Linux, таблица системных вызовов, 32 и x64 - PullRequest
3 голосов
/ 14 октября 2011

Я не понимаю, ясно 1. Являются ли адреса системных вызовов одинаковыми для всех компьютеров Linux (или они зависят от параметров компиляции) 2. 32х86 и х64 имеют одинаковые адреса системных вызовов? Я нашел некоторые ссылки в Интернете, например, swapon имеет адрес x87, но не указано, 32-битная или 64-битная версия ядра

Ответы [ 2 ]

5 голосов
/ 14 октября 2011

Я думаю, что вы путаете два довольно важных понятия здесь. Есть два разных «адреса» как таковых для понимания:

  1. Фактически, в адресах памяти. Они будут различаться в зависимости от компиляции ядра и, если намеренно не исправлены (я не верю, что они есть), будут различаться в зависимости от используемого компилятора. Каждое новое ядро ​​из моего дистрибутива имеет разные адреса для функций системного вызова.
  2. Системный вызов номеров . Это целочисленные значения, которые вы используете перед запуском sysenter (или прерывания), которые говорят «сделать системный вызов». Они всегда одинаковы для данного ABI. ABI - это двоичный интерфейс приложения; возможность переносить скомпилированную программу между компьютерами и запускать ее.

    x86 Linux и x86_64 Linux имеют разные ABI, и поэтому номера системных вызовов различны. Но между двумя разными дистрибутивами под управлением x86 Linux ABI одинаков, поэтому эти системы совместимы с ABI, и теоретически вы должны иметь возможность портировать программы.

    На практике это сложнее (общие библиотеки, пути и т. Д.).

Если вы хотите увидеть адрес функции ядра в вашей системе и у вас есть System.map (вы, вероятно, делаете), попробуйте:

cat /boot/System.map-`uname -r` | grep funcname

Таблица системных вызовов для вашей системы определена в /usr/include/asm/unistd_32.h или /usr/include/asm/unistd_64.h соответственно.

1 голос
/ 14 октября 2011

В Linux системные вызовы не имеют адреса . Конечно, они находятся где-то, по какому-то адресу в памяти, но вызывающие программы обычно их не знают (или даже не имеют доступа к этой памяти). Обычно они вызываются прерыванием (например, Linux использовал 0x80, MS-Dos использовал, например, 0x21). Вызывающий процесс просто запрашивает программное прерывание, а затем обработчик прерываний обрабатывает системный вызов. Тип вызова и параметры заранее заносятся в определенные регистры, поэтому ядро ​​знает, что делать.

В более современном процессоре разработчик изобрел конкретные инструкции (например, у Intel / AMD есть SYSCALL / SYSENTER), поэтому не нужно использовать способ прерывания для вызова системных вызовов, но в основном это то же самое с точки зрения пользователя.

Конечно, есть прерывание, которое отличается от него записями, в зависимости от того, какой у вас x64 или 32.

...