GNU/Linux >> Znalost Linux >  >> Linux

Linux – Jak najít implementace systémových volání jádra Linuxu?

Snažím se pochopit, jak funguje funkce, řekněme mkdir , funguje tak, že se podívá na zdrojový kód jádra. Toto je pokus porozumět vnitřnostem jádra a navigovat mezi různými funkcemi. Znám mkdir je definován v sys/stat.h . Našel jsem prototyp:

/* Create a new directory named PATH, with permission bits MODE.  */
extern int mkdir (__const char *__path, __mode_t __mode)
     __THROW __nonnull ((1));

Nyní se musím podívat, ve kterém souboru C je tato funkce implementována. Ze zdrojového adresáře jsem zkusil

ack "int mkdir"

který se zobrazil

security/inode.c
103:static int mkdir(struct inode *dir, struct dentry *dentry, int mode)

tools/perf/util/util.c
4:int mkdir_p(char *path, mode_t mode)

tools/perf/util/util.h
259:int mkdir_p(char *path, mode_t mode);

Ale žádný z nich neodpovídá definici v sys/stat.h .

Otázky

  1. Který soubor má mkdir implementace?
  2. Jak mohu s definicí funkce, jako je výše uvedená, zjistit, který soubor má implementaci? Existuje nějaký vzorec, kterým se jádro řídí při definování a implementaci metod?

POZNÁMKA:Používám jádro 2.6.36-rc1.

Přijatá odpověď:

Systémová volání nejsou zpracovávána jako běžná volání funkcí. K provedení přechodu z uživatelského prostoru do prostoru jádra je zapotřebí speciální kód, v podstatě trochu inline kódu sestavení vloženého do vašeho programu na místě volání. Kód na straně jádra, který „zachytí“ systémové volání, je také věc nízké úrovně, které pravděpodobně nemusíte hlouběji rozumět, alespoň zpočátku.

V include/linux/syscalls.h ve zdrojovém adresáři jádra najdete toto:

asmlinkage long sys_mkdir(const char __user *pathname, int mode);

Poté v /usr/include/asm*/unistd.h , najdete toto:

#define __NR_mkdir                              83
__SYSCALL(__NR_mkdir, sys_mkdir)

Tento kód říká mkdir(2) je systémové volání #83. To znamená, že systémová volání jsou volána podle čísla, nikoli podle adresy, jako u normálního volání funkce ve vašem vlastním programu nebo funkci v knihovně propojené s vaším programem. Kód lepidla vložené sestavy, který jsem zmínil výše, to používá k přechodu z uživatelského do prostoru jádra, přičemž s sebou bere i vaše parametry.

Dalším důkazem toho, že věci jsou trochu divné, je to, že pro systémová volání vždy neexistuje přesný seznam parametrů:open(2) , například může mít 2 nebo 3 parametry. To znamená open(2) je přetížený, což je vlastnost C++, nikoli C, přesto je rozhraní syscall kompatibilní s C. (To není totéž jako funkce varargs jazyka C, která umožňuje jedné funkci přijmout proměnný počet argumentů.)

Abych odpověděl na vaši první otázku, neexistuje jediný soubor, kde by bylo mkdir() existuje. Linux podporuje mnoho různých souborových systémů a každý z nich má svou vlastní implementaci operace „mkdir“. Abstraktní vrstva, která umožňuje jádru skrýt vše za jediné systémové volání, se nazývá VFS. Takže pravděpodobně budete chtít začít kopat v fs/namei.c , pomocí vfs_mkdir() . Skutečné implementace kódu pro úpravu nízkoúrovňového souborového systému jsou jinde. Například implementace ext4 se nazývá ext4_mkdir() , definovaný v fs/ext4/namei.c .

Pokud jde o vaši druhou otázku, ano, na to všechno existují vzory, ale ne jediné pravidlo. Ve skutečnosti potřebujete poměrně široké znalosti o tom, jak jádro funguje, abyste zjistili, kde byste měli hledat konkrétní systémové volání. Ne všechna systémová volání zahrnují VFS, takže jejich řetězce volání na straně jádra nezačínají v fs/namei.c . mmap(2) , například začíná v mm/mmap.c , protože je součástí podsystému správy paměti („mm“) jádra.

Související:Linux – Co znamenají příznaky v /proc/cpuinfo?

Doporučuji vám získat kopii „Understanding the Linux Kernel“ od Bovet a Cesati.


Linux
  1. Jak zvládnout paniku linuxového jádra

  2. Jak změnit identitu systému Linux

  3. Jak přenést výsledky 'najít' do mv v Linuxu

  1. Jak zkontrolovat verzi OS a Linuxu

  2. Jak zjistit, zda je disk SSD nebo HDD v Linuxu

  3. Jak zkontrolovat verzi jádra v Linuxu

  1. Jak linuxové jádro zpracovává přerušení

  2. Linux – Jak zjistit, jaké pevné disky jsou v systému?

  3. Jak linuxové jádro určuje pořadí volání __init?