
Пока я читал о системных вызовах, я выполнил поиск "syscalls.h", чтобы найти заголовочный файл в LXR. Результаты поиска меня озадачили. Есть дюжина файлов "syscalls.h", поступающих из каталогов в "arch/_arch_name_/include/asm". Это нормально, это определения, специфичные для архитектуры, или что-то еще нужно. Вопрос в том, почему у нас есть два разных заголовка "syscalls.h" в /include/linux и /include/asm-generic?
Также я хочу узнать, для чего нужны заголовки /include/linux и для чего нужны заголовки /include/asm-generic. Как они различаются? В чем логика наличия двух отдельных папок заголовков? Как они связаны друг с другом?
Спасибо
решение1
Заголовки ниже asm/generic
в основном предназначены для временных мер, переносимых версий на C, пока не будет написана версия, специфичная для архитектуры. Вы также обнаружите, что в некоторых случаях /usr/include/foobar.h
включает множество заголовков "внутренней реализации", и, наконец, возвращается к части, которая идет из ядра, часто называемой так же. Примерами являются math.h
и (больше зависят от Linux) syscall.h
.
решение2
Программное обеспечение должно быть переносимым. Если вы компилируете исходники C/C++, то вам не нужно знать, используете ли вы i386/x86_64/arm/mips или что-то еще. Заголовки связаны таким образом, что программное обеспечение компилируется.
Все остальные файлы заголовков существуют, потому что они были реализованы во множестве различных стандартов, есть порты из BSD и так далее. Многие из них исторически основаны. Откуда каждый взялся и почему он там находится, имеет много разных причин и наверняка разнесет ответы.
И ответ для asm-generic:переполнение стека
решение3
arch/x86/entry/
имеет два специальных файла системных вызовов:
syscalls/syscall_32.tbl
и то же самое "64"
Системные вызовы являются особенными, поскольку ядро должно объединить ABI и API.
В общем, каталоги include и другие файлы заголовков (независимые, такие как kernel/sched/sched.h) следуют иерархической логике. Я думаю, что и make, и gcc играют свою роль.
Эти символы систематически используются для того, чтобы гарантировать, что каждый заголовок «единицы» читается только один раз. («защитные оболочки», потому что может быть слишком много перекрестий). Вот из include/linux/mm.h
:
#ifndef _LINUX_MM_H
#define _LINUX_MM_H
#include <linux/errno.h>
#ifdef __KERNEL__
... (#includes)
... (ext. decl. etc., the whole mm.h)
#endif /* __KERNEL__ */
#endif /* _LINUX_MM_H */
Файлы tbl содержат:
# 32-bit system call numbers and entry vectors
Список начинается со слов:
0 i386 restart_syscall sys_restart_syscall __ia32_sys_restart_syscall
1 i386 exit sys_exit __ia32_sys_exit
2 i386 fork sys_fork __ia32_sys_fork
3 i386 read sys_read __ia32_sys_read
#
# 64-bit system call numbers and entry vectors
#
# The format is:
# <number> <abi> <name> <entry point>
#
# The __x64_sys_*() stubs are created on-the-fly for sys_*() system calls
#
# The abi is "common", "64" or "x32" for this file.
Макет сделаю позже...