Почему для вызова системных вызовов используется int80h вместо sysenter?

Все учебники и интернет-ресурсы говорят мне, что int 80h — это устаревший стиль для вызова системных вызовов, и на платформах x86 он был заменен на SYSENTER.

Но я только что обнаружил, что моя система все еще использует int 80h. Я знаю такие учебники, как VDSO, оболочка libc, которая реализует службу системных вызовов, но не понимаю, почему int 80h все еще используется по умолчанию.

  1. Кто-нибудь может сказать мне причину? Glibc или ядро ​​слишком старое?

  2. В настоящее время при каких условиях «int 80h» все еще используется по умолчанию?

  3. Как я могу применить sysenter без установки нового glibc?


Ниже моя среда:

Я установил виртуальную машину с помощью VMWare на свой macbook air 2011 (процессор Core Duo). 32-разрядная версия Ubuntu 8.04/kernel 2.6.24 (собрана с использованием исходного файла .config)/libc 2.7 в виртуальной машине.


person Infinite    schedule 03.02.2012    source источник
comment
Вот хорошая ссылка о том, как определить, какой механизм int 80h и sysenter используется в системе. Но это не устраняет моего удивления тем, что моя система все еще использует int 80h. Я только что сгенерировал исполняемый файл с помощью gdb и обнаружил, что int 80his на самом деле закодирован в glibc. То есть в моем случае VDSO, предоставляемый ядром, не используется.   -  person Infinite    schedule 04.02.2012
comment
После некоторого расследования я уверен, что ядро ​​предоставляет страницу vsyscall. Просто glibc настроен на прямое использование int 80h. Я предполагаю, что это был выбор людей Ubuntu, которые настроили этот тип libc для выпуска 8.04.   -  person Infinite    schedule 04.02.2012


Ответы (2)


Скорее всего, из соображений совместимости - 32-битная Ubuntu скомпилирована для совместимости с процессором i386 (ну, может быть, не таким старым в наши дни), который не поддерживал sysenter (он появился только на Pentium 2 AFAIK). По-видимому, использование sysenter против int 80h действительно полезно только на некоторых типах процессоров:

http://articles.manugarg.com/systemcallinlinux2_6.html

Поэтому, если в общем случае нет значительного прироста скорости и более широкой совместимости, использование int 80h вместо sysenter все еще имеет смысл, даже сегодня. Если вы используете 64-битную версию Ubuntu, то sysenter/sysexit используются повсюду.

Изменить: на самом деле используемый механизм системных вызовов определяется ядром во время загрузки, а не glibc. Эта страница (раздел 4.6) объясняет, как это работает очень хорошо. В вашем случае просто получается, что аппаратное обеспечение, эмулируемое VMware, считается ядром более эффективным с использованием int 80h, а не sysenter. Вам придется отлаживать ядро, чтобы понять, как оно принимает такое решение.

person Gnurou    schedule 04.02.2012
comment
Это очень разумно! Совместимость, я думаю, является одной из главных проблем выпуска Ubuntu. - person Infinite; 05.02.2012
comment
Но, как указал Питер, ядро ​​решило проблему совместимости с помощью vsyscall, независимо от того, есть ли у процессора инструкция sysenter или нет, тогда почему glibc, настроенный в Ubuntu, просто не использует vsyscall? - person Infinite; 05.02.2012
comment
Отредактировал мой пост с возможными ответами на ваш последний вопрос. - person Gnurou; 07.02.2012
comment
Glibc в моей системе напрямую использует int 80h, игнорируя страницу vsyscall. На самом деле ваш ответ без нового редактирования более разумен. Спасибо, в любом случае. - person Infinite; 11.02.2012
comment
Позже я обнаружил, что в родной среде glibc в Ubuntu 8.04 вызывает *%gs:10h, который затем вызывает sysenter (конечно, процессор не древний, поэтому поддерживает sysenter). Так получилось, что VMware повлияла на установку ubuntu и что glibc использовала int 80h для системных вызовов. - person Infinite; 16.02.2012
comment
Это бы объяснило. Но трудно поверить, что VMWare изменит гостевую ОС таким образом. Является ли ваша родная среда 64-битной установкой? - person Gnurou; 16.02.2012

Какие инструкции (int80 или sysenter) всегда решает сама гостевая ОС, как видно из исходников ядра linux — все зависит от того, какое железо ей представила VMware.

Посмотрите на файл arch/x86/vdso/vdso32-setup.c (исходный код ядра Linux):

   if (vdso32_syscall()) {
            vsyscall = &vdso32_syscall_start;
            vsyscall_len = &vdso32_syscall_end - &vdso32_syscall_start;
    } else if (vdso32_sysenter()){
            vsyscall = &vdso32_sysenter_start;
            vsyscall_len = &vdso32_sysenter_end - &vdso32_sysenter_start;
    } else {
            vsyscall = &vdso32_int80_start;
            vsyscall_len = &vdso32_int80_end - &vdso32_int80_start;
    }

Из приведенного выше вы можете видеть, что решение использовать int80 принимается только тогда, когда обнаружение функции sysenter не удалось. И эта функция, в свою очередь, предоставляется гостю через механизм эмуляции VMWare. Возможно, если бы вы использовали самую последнюю версию VMware вместе с некоторым современным оборудованием, VMware должна была бы предоставить гостю более современную ОС.

person Peter Teoh    schedule 05.02.2012
comment
Это правда. Ядро обнаруживает доступность sysenter/syscall для генерации vsyscall. Например, в моем случае страница vsyscall содержит инструкцию sysenter для обработки системных вызовов. Однако glibc вызывает int 80h напрямую вместо вызова %gs:10h (запись vsyscall), что означает, что glibc игнорирует vsyscall. - person Infinite; 05.02.2012