Системні дзвінки не обробляються як звичайні виклики функцій. Для здійснення переходу від простору користувача до простору ядра потрібен спеціальний код, в основному трохи вбудованого коду складання, введеного у вашу програму на сайті виклику. Код сторони ядра, який "ловить" системний виклик, також є матеріалом низького рівня, який, ймовірно, не потрібно глибоко розуміти, принаймні спочатку.
У include/linux/syscalls.h
підхідному каталозі ядра ви знайдете таке:
asmlinkage long sys_mkdir(const char __user *pathname, int mode);
Потім у /usr/include/asm*/unistd.h
, ви виявите це:
#define __NR_mkdir 83
__SYSCALL(__NR_mkdir, sys_mkdir)
Цей код говорить про mkdir(2)
системний виклик №83. Тобто системні дзвінки дзвоняться за номером, а не за адресою, як звичайний виклик функції у вашій власній програмі або функція в бібліотеці, пов'язаній із вашою програмою. Код клейового вбудованого вкладеного тексту, який я згадав вище, використовує це для здійснення переходу від користувача до простору ядра, приймаючи разом із ним і ваші параметри.
Ще один доказ того, що тут дещо дивно, це те, що не завжди існує суворий список параметрів для системних викликів: open(2)
наприклад, може прийматися 2 або 3 параметра. Це означає open(2)
, що перевантажений , особливість C ++, а не C, але інтерфейс syscall сумісний з C. (Це не те саме, що функція varargs C , яка дозволяє одній функції приймати змінну кількість аргументів.)
Щоб відповісти на ваше перше запитання, там не існує жодного файлу mkdir()
. Linux підтримує безліч різних файлових систем, і кожна з них має власну реалізацію операції "mkdir". Шар абстракції, який дозволяє ядру приховати все, що знаходиться за одним системним викликом, називається VFS . Отже, ви, мабуть, хочете почати копатися fs/namei.c
, з vfs_mkdir()
. Фактичні реалізації коду для модифікації файлової системи низького рівня є в інших місцях. Наприклад, викликається реалізація ext4 ext4_mkdir()
, визначена в fs/ext4/namei.c
.
Що стосується вашого другого запитання, так, є все це, але це не єдине правило. Те, що вам насправді потрібно, - це досить широке розуміння того, як працює ядро, щоб зрозуміти, де слід шукати конкретний системний виклик. Не всі системні дзвінки включають VFS, тому їх ланцюги викликів на стороні ядра починаються не всі fs/namei.c
. mmap(2)
, наприклад, запускається mm/mmap.c
, тому що це частина підсистеми управління пам'яттю ("мм") ядра.
Рекомендую вам отримати копію " Розуміння ядра Linux " Бовета та Чезаті.