То, что вы ищете не в ядре. это находится в библиотеке C. К сожалению, историческая библиотека C не является частью linux-0.11.tar.gz
, поэтому мы можем только предполагать, как она написана.
Библиотека C использует этот макрос из <unistd.h>
:
#define _syscall0(type,name) \
type name(void) \
{ \
long __res; \
__asm__ volatile ("int $0x80" \
: "=a" (__res) \
: "0" (__NR_##name)); \
if (__res >= 0) \
return (type) __res; \
errno = -__res; \
return -1; \
}
с аргументами int, fork
(да, похоже, он не использует pid_t
в качестве возвращаемого значения, даже если этот тип существует), который расширится до
int fork(void) {
long __res;
__asm__ volatile ("int $0x80" :
"=a" (__res) :
"0" (__NR_fork));
if (__res >= 0)
return (int) __res; e
errno = -__res;
return -1;
}
Это определение функции скомпилировано в одной единице перевода библиотеки C. Кроме того, unistd.h
файл ядра - это файл, доступный для пространства пользователя.
Встроенный ассемблер просто помещает значение __NR_fork
в eax
, вызывает прерывание 0x80 и получает __res
возвращаемое значение от eax
.
Прерывание 0x80 входит в _system_call
из system_call.s
, которое имеет следующий код:
.align 2
_system_call:
cmpl $nr_system_calls-1,%eax
ja bad_sys_call
[...]
call _sys_call_table(,%eax,4)
[...]
iret
т.е. eax
сначала сравнивается с максимальным номером системного вызова, и, если указано выше, возникает ошибка; затем eax
th 4-байтовый указатель вызывается из таблицы системных вызовов, и, наконец, iret
возвращается из прерывания, возвращаемое значение вызываемой функции сохраняется в eax
.