Sistem çağrıları normal işlev çağrıları gibi gerçekleştirilmez. Kullanıcı alanından çekirdek alana geçiş yapmak için özel bir kod gerekir, temel olarak çağrı sitesinde programınıza enjekte edilen bir satır içi montaj kodu. Sistem çağrısını "yakalayan" yan kod, aynı zamanda en azından ilk başta derinlemesine anlamanız gerekmeyen düşük seviyeli şeylerdir.
Gelen include/linux/syscalls.h
Çekirdek kaynak dizin altında, bu bulmak:
asmlinkage long sys_mkdir(const char __user *pathname, int mode);
Sonra /usr/include/asm*/unistd.h
, şunu bulursun:
#define __NR_mkdir 83
__SYSCALL(__NR_mkdir, sys_mkdir)
Bu kod diyor mkdir(2)
ki sistem çağrısı # 83. Diğer bir deyişle, sistem çağrıları, kendi programınızdaki normal bir işlev çağrısındaki adrese göre değil, programınızla bağlantılı bir kitaplıktaki bir işleve göre numara olarak adlandırılır. Yukarıda bahsettiğim satır içi montaj tutkal kodu, parametrelerinizi beraberinde alarak, kullanıcıdan çekirdek alanına geçiş yapmak için bunu kullanır.
Burada işlerin biraz garip olduğuna dair bir başka kanıt da, sistem çağrıları için her zaman katı bir parametre listesi bulunmadığıdır: open(2)
örneğin, 2 veya 3 parametre alabilir. Bu demektir ki open(2)
bir aşırı , C ++, C bir özelliği, henüz syscall arayüzü Cı-uyumludur. (Bu, tek bir fonksiyonun değişken sayıda argüman almasına izin veren C'nin varargs özelliği ile aynı şey değildir .)
İlk sorunuza cevap vermek için, var olan tek bir dosya mkdir()
yok. Linux birçok farklı dosya sistemini desteklemektedir ve her biri "mkdir" işlemi için kendi uygulamasına sahiptir. Çekirdeğin hepsini tek bir sistem çağrısının arkasına gizlemesini sağlayan soyutlama katmanına VFS denir . Yani, muhtemelen fs/namei.c
, içinde kazmaya başlamak istersiniz vfs_mkdir()
. Düşük seviyeli dosya sistemi değiştirme kodunun gerçek uygulamaları başka yerdedir. Örneğin, ext4 uygulaması ext4_mkdir()
, içinde tanımlandığı şekilde adlandırılır fs/ext4/namei.c
.
İkinci sorunuza gelince, evet, tüm bunların kalıpları var, ancak tek bir kural yok. Gerçekte ihtiyacınız olan şey, belirli bir sistem çağrısını nerede aramanız gerektiğini bulmak için çekirdeğin nasıl çalıştığını anlamak için oldukça geniş bir anlayış. Tüm sistem çağrıları VFS'yi kapsamaz, bu nedenle çekirdek tarafındaki çağrı zincirleri tümüyle başlamaz fs/namei.c
. mmap(2)
örneğin, mm/mmap.c
çekirdeğin bellek yönetimi ("mm") alt sisteminin bir parçası olduğu için başlar .
Bovet ve Cesati'nin " Linux çekirdeğini anlama " nın bir kopyasını almanızı tavsiye ederim .