Dlaczego aplikacje przestrzeni użytkownika potrzebują nagłówków jądra?

10

Buduję busy-box i iptables dla urządzenia osadzonego, a jedną z zależności dla nich są nagłówki jądra.

Przeszukałem cały system plików w poszukiwaniu plików * .ko i nie znalazłem żadnego. Doszedłem więc do wniosku, że aplikacje nie tworzą żadnych ładowalnych sterowników (modułów jądra).

W jakich innych przypadkach aplikacja przestrzeni użytkownika wymaga nagłówków jądra?

TheMeaningfulEngineer
źródło
Łatwym przykładem jest wymyślenie, gdy coś w przestrzeni użytkownika wywołuje wywołanie systemowe.
Sami Laine,
@SamiLaine Domyślam się, że biblioteka c zapewnia interfejs do wywołań systemowych. Jeśli to, co mówisz, było prawdą, czy nie musiałbyś na przykład importować nagłówków jądra, aby otworzyć gniazdo?
TheMeaningfulEngineer
Socket (2) to wywołanie systemowe, a nie funkcja biblioteczna, więc tak.
Sami Laine,
@SamiLaine Czy możesz podać przykład, w którym musisz include <linux/*.h>otworzyć gniazdo? (Celowałem w sys / socket.h)
TheMeaningfulEngineer

Odpowiedzi:

8

Ponieważ te programy są budowane do korzystania z rzeczy zdefiniowanych w nagłówkach jądra:

busybox-1.22.1]$ egrep -RHn '^#include <linux'
modutils/modutils-24.c:194:#include <linux/elf-em.h>
include/fix_u32.h:17:#include <linux/types.h>
libbb/loop.c:11:#include <linux/version.h>
console-tools/openvt.c:23:#include <linux/vt.h>
console-tools/kbd_mode.c:23:#include <linux/kd.h>
console-tools/showkey.c:19:#include <linux/kd.h>
util-linux/blockdev.c:36:#include <linux/fs.h>
util-linux/mkfs_ext2.c:50:#include <linux/fs.h>
util-linux/mkfs_vfat.c:28:#include <linux/hdreg.h> /* HDIO_GETGEO */
util-linux/mkfs_vfat.c:29:#include <linux/fd.h>    /* FDGETPRM */
....

Dla każdego konkretnego narzędzia musisz przeczytać jego źródło i odpowiedni nagłówek jądra, aby dokładnie dowiedzieć się, co.

Aby ułatwić, możesz zobaczyć kilka komentarzy.

Na przykład mkfs_vfatobejmuje, linux/fd.haby uzyskać FDGETPRM:

$ egrep -RHn FDGETPRM util-linux/mkfs_vfat.c
util-linux/mkfs_vfat.c:29:#include <linux/fd.h>    /* FDGETPRM */
util-linux/mkfs_vfat.c:351:         int not_floppy = ioctl(dev, FDGETPRM, &param);

Prawdopodobnie możesz usunąć odpowiedni #includei uważać na błędy kompilatora, aby ułatwić, otrzymasz ostrzeżenia, że ​​niektóre rzeczy nie są zdefiniowane. Te rzeczy prawdopodobnie pochodzą z nagłówków jądra.

suprjami
źródło
2
1. Busybox jest przeznaczony do wbudowanych i innych lekkich systemów, w których chcesz załadować jak najmniej bibliotek do pamięci. Nie przeczytałem źródła, ale prawdopodobnie BB zasadniczo omija biblioteki i łączy bezpośrednio z jądrem. 2. Nie. Łączy plik binarny przestrzeni użytkownika z wersją API jądra , która jest kompatybilna wstecz: dzisiejszy plik binarny może nie działać na starszym jądrze (w zależności od zawartych symboli ... przeczytaj kod źródłowy), ale będzie praca z przyszłymi jądrami.
ignis
1
@suprjami ABI przestrzega standardu SysV ABI, co do którego można zasadnie założyć, że się nie zmienia; między innymi SysV ABI jest powodem, dla którego możesz łączyć się z jądrem z wybranym kompilatorem (i wersją), niekoniecznie tym samym, który emitował plik binarny jądra.
ignis
1
... umożliwia także chroot / LXC w dystrybucji, która jest dostarczana z innym jądrem. itd.
ignis
1
(Dla jasności: zauważ, że jądro ma zewnętrzny ABI , o którym tutaj dyskutujemy, oraz wewnętrzny ABI między modułami jądra, który podlega częstym i prawdopodobnie niekompatybilnym zmianom, ale nie jest widoczny w przestrzeni użytkownika i nie ma znaczenia przy kompilacji przestrzeni użytkownika kod.)
ignis
1
(Należy również zauważyć, że ABI = / = API. Interfejs API jądra (zewnętrzny) zawiera symbole przywoływane w kodzie źródłowym, a twórcy jądra zobowiązali się do zachowania zgodności; chyba że symbole są bardzo rzadko używane w prawdziwym oprogramowaniu, byłoby to nierozsądnym posunięciem w celu wprowadzenia niezgodnych zmian, chociaż żaden standard innej firmy nie nakazuje całego Linux API, a zatem nic nie przeszkadza technicznie.)
ignis