
Während ich etwas über Systemaufrufe las, suchte ich nach „syscalls.h“, um die Header-Datei in LXR zu finden. Die Suchergebnisse verwirrten mich. Es gibt ein Dutzend „syscalls.h“-Dateien aus Verzeichnissen unter „arch/_arch_name_/include/asm“. Diese sind in Ordnung, es sind architekturspezifische Definitionen oder etwas anderes, das benötigt wird. Die Frage ist, warum wir unter /include/linux und /include/asm-generic zwei verschiedene „syscalls.h“-Header haben?
Außerdem möchte ich herausfinden, wofür die Header /include/linux und /include/asm-generic sind. Wie unterscheiden sie sich voneinander? Welche Logik steckt hinter den zwei separaten Header-Ordnern? In welcher Beziehung stehen sie zueinander?
Danke
Antwort1
Die Header unter asm/generic
sind hauptsächlich als Übergangslösungen gedacht, portable Versionen in C, bis eine architekturspezifische Version geschrieben wird. Sie werden auch feststellen, dass in einigen Fällen /usr/include/foobar.h
eine Menge „interner Implementierungs“-Header enthalten sind und schließlich auf einen Teil zurückgegriffen wird, der vom Kernel stammt und oft gleich genannt wird. Beispiele sind math.h
und (eher Linux-abhängig) syscall.h
.
Antwort2
Die Software muss portierbar sein. Wenn Sie Ihre C/C++-Quellen kompilieren, müssen Sie nicht wissen, ob Sie i386/x86_64/arm/mips oder was auch immer verwenden. Die Header sind so verknüpft, dass die Software kompiliert wird.
Alle anderen Header-Dateien existieren, weil sie in vielen verschiedenen Standards implementiert wurden, es gibt Ports von BSD und so weiter. Viele von ihnen haben also eine historische Basis. Woher jede einzelne kommt und warum sie da ist, hat viele verschiedene Gründe und wird sicherlich Antworten auf diese Fragen sprengen.
Und eine Antwort für asm-generic:Paketüberfluss
Antwort3
arch/x86/entry/
hat zwei spezielle Syscall-Dateien:
syscalls/syscall_32.tbl
und dito "64"
Systemaufrufe sind etwas Besonderes, da der Kernel ABI und API zusammenbringen muss.
Im Allgemeinen folgen die Include-Verzeichnisse und die anderen Header-Dateien (unabhängige wie kernel/sched/sched.h) einer hierarchischen Logik. Ich denke, sowohl make als auch gcc spielen eine Rolle.
Diese Symbole werden systematisch verwendet, um sicherzustellen, dass jede Header-"Einheit" nur einmal gelesen wird. ("Schutzhüllen", da es zu viele Überschneidungen geben kann). Hier von 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 */
Die TBL-Dateien haben:
# 32-bit system call numbers and entry vectors
Die Liste beginnt mit:
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.
Das Layout mache ich später...