Çekirdeği çalıştırırken desteklenen sistem çağrıları


9

Şu anda çalışan Linux Çekirdeği tarafından desteklenen sistem çağrılarının sayısını veya listesini almanın bir yolu var mı? Bu yüzden çalışan bir çekirdeğin sistem çağrı tablosunu 'okumak' için bir yol bulmak istiyorum.

Yanıtlar:


15

Dosya /proc/kallsyms, çalışan çekirdeğin tüm sembollerini listeler. Kural olarak, sistem çağrıları ile başlayan bir adı vardır sys_. 64 bit sistemde, 32 bit programların sistem çağrıları ile başlayan bir adı vardır sys32_. Kesinlikle konuşmak gerekirse, bu sistem çağrısı değil, iç çekirdek işlevlerini listeler, ancak yazışmanın işe yaradığını düşünüyorum (her sistem çağrısı işi yapmak için bir iç çekirdek işlevini çağırır ve adı her zaman önceden sys_eklenen sistem çağrısının adıdır. ).

</proc/kallsyms sed -n 's/.* sys_//p'

Sistem çağrıları çok yavaş değiştiği için bu genellikle yararlı bir bilgi değildir. İsteğe bağlı bileşenler, cihazlar ( kesildiğinde ve kesmediğinde ioctl ile ), dosya sistemleri, soketler vb. Gibi genel özellikleri kullanarak mevcut sistem çağrıları açısından işlevsellik sağlar. sistem destekliyor. Diğer dahili işlev adları da çok hızlı değişmediği için yardımcı olmaz: bir çekirdek sürümde bazı özellikleri uygulayan işlevin adı sonraki sürümde değişebilir.readwrite


+1. "Benden daha fazla deneyime sahip birisinin size cevap vermesine izin vereceğim" dediğimde bunu kastettim . Ayrıca, /proc/kallsymsherhangi bir dosya gibi değiştirilebildiğinden, onu bir programda kullanmak oldukça kolay hale gelir.
John WH Smith

2
@JohnWHSmith “Başka herhangi bir dosya gibi kullanılabilir”… ASLR çekirdeği olan sistemlerde bu dosyanın yalnızca kök tarafından okunabileceği uyarısı ile.
Gilles 'SO- kötü olmayı bırak'

7

TL; DR

Bu yanıtı yazarken yeni alternatifler bulmaya devam ettim, bu yüzden her biri hakkında biraz detay yazdım ve bazı istatistikler yaptım. Temel olarak, aşağıdakilerden birini yapabilirsiniz:

  • Bunu yapmak için temiz ve hızlı bir yol sağlayan Gilles'in cevabını okuyun (dayanır /proc).
  • Belge kaynaklarını kullanın.
  • Sisteminizin C başlık dosyalarını kullanın.
  • Çekirdek kaynak kodunu kullanın.
  • /sysDizini kullanın .

Matematiği yaptıktan sonra /sys, sistem çağrılarının sayısı açısından en iyi sonucu verdiği için (alternatiflerim arasında) dosya sistemini kullanmanızı tavsiye ederim . Diğer püf noktaları hakkında okumak istemiyorsanız, doğrudan o bölüme atlayabilirsiniz.

Belge kaynaklarını kullanma

Bazılarını özleyebilmenize rağmen, aproposbölüm 2'ye (sistem çağrıları) ait tüm sayfaları listelemek için kullanabilirsiniz :

$ apropos -s2 . | awk '{print $1}' | column

columnSüslü sütunlu çıktı istemiyorsanız kaldırın .

Az önce öğrendim, ancak sistem çağrıları hakkında bir Linux man sayfası var ve bunların çoğunu bulabileceksiniz.

$ man syscalls

Ayrıca ilginç olabilecek bu iki web sitesine rastladım:

Üstbilgi dosyalarını kullanma

Düzenleme: Şimdi, hangi sistem çağrılarının kullanılabilir olduğunu belirlemek için programlı (veya en azından, belgelenmiş özelliklere dayanmadan) söz konusu olduğunda, çekirdeğin en azından formu altında değil, sistem çağrıları bir tablo tutmaz korkarım (muhtemelen onları manipüle etmeyi beklediğiniz gibi) bir dize listesi. Bu düzeyde, işlev adları yerine işlev adresleri ve işaretçiler hakkında daha fazla konuşuyoruz.

/usr/includeDizine göz attım ve grepbirkaç şey edindim: Aşağıdaki dizinleri ilginç bulabilirsiniz. Mimarinize ve dağıtımınıza bağlı olarak bazıları makinenizde farklı olabilir, ancak eminim bunları uyarlayabilirsiniz.

  • / Usr / include / Linux
  • / Usr / include / x86_64-Linux-antilop
  • / Usr / include / sys
  • / / Bulunmaktadır usr / asm-jenerik

Bu dosyada işlev tanımları arayarak, orada tam olarak tanımlanmasalar bile birçok sistem çağrısına rastlarsınız. grepBu dizinlerde birkaç s koştum ve bazı sistem çağrılarından bahsedebildim. İşte bir örnek:

$ grep 'sys_exit' /usr/include -R
asm-generic/unistd.h:__SYSCALL(__NR_exit, sys_exit)

Yani, bazılarını bulmak için başka bir yol tahmin ediyorum:

$ egrep '^__SYSCALL' /usr/include -Rh | awk '{print $2}' | tr -d ')'

Çekirdeğin kaynak kodunu ve sistem çağrı tablosunu kullanma

Başka bir çözüm, çekirdek kaynak kodunun kendisini (ve sadece üstbilgileri değil!) Kullanmak ve verimli bir şekilde aramak için bir yol bulmaktır. Çekirdek 303395ac3bf3e2cb488435537d416bc840438fcb işlediğinden , bunu öncekinden biraz daha kolay bulabilirsiniz. İşte 3.13 için bir örnek (ki bu benim çekirdeğim):

$ wget https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/plain/arch/x86/syscalls/syscall_64.tbl?id=refs/tags/v3.13 -O syscall_64.tbl

Şimdi gerçek syscalls tablosuna sahip olduğunuza göre, sadece göz atın:

$ while read line; do awk '! /#/ {print $3}'; done < syscall_64.tbl

Çalışan çekirdek sürümünüze ve mimariye bağlı olarak dosyayı doğrudan git.kernel.org adresinden indirmek için unameve öğesini kullanarak bir yol bulabilirsiniz .archtbl

/sysDosya sistemini kullanma

Gilles'in cevabı bana biraz ilham verdi ve bu sistem çağrılarını içeride bulabilirsiniz /sys/kernel/debug/tracing/events/syscalls. Bu dizin, sistemdeki her bir sistem çağrısının kullanımını izlemek için kullanılır. Her sistem aramasında iki dizin vardır:

  • sys_enter_ [syscall]
  • sys_exit_ [syscall]

Bu nedenle, kullanarak ls, grepve cut...

$ ls /sys/kernel/debug/tracing/events/syscalls | grep 'sys_enter' | cut -d'_' -f3

İstatistikleri

Sistemimde:

  • Man sayfalarında 440 sistem çağrısı ortaya çıktı.
  • grep-ing __SYSCALLbaşlık dosyalarında 212 sistem çağrısı ortaya çıktı.
  • Çekirdek kaynaklarından sistem çağrıları tablosunun okunması 346 sistem çağrısını ortaya çıkardı.
  • /sysAçıklanan 290 sistem çağrısı kullanma .

Şimdi, eğer her şeyi bir araya getirirsem ...

$ apropos -s2 . | awk '{print $1}' > system_calls.txt
$ egrep '^__SYSCALL' /usr/include -Rh | awk '{print $2}' | tr -d ')' >> system_calls.txt
$ while read line; do awk '! /#/ {print $3}'; done < syscall_64.tbl >> system_calls.txt
$ ls /sys/kernel/debug/tracing/events/syscalls | grep 'sys_enter' | cut -d'_' -f3 >> system_calls.txt

$ sort < system_calls.txt | uniq | wc -l
707

İşte başlıyoruz, 707 sistem çağırıyor! Tabii ki, bu sayı bir "sistem çağrısı" nın çok esnek bir tanımını yansıtmaktadır, çünkü 3.13'ün sadece 274 sistem çağrısı sağlaması beklenmektedir (okuma /sysen yakın çözüm gibi görünmektedir).


Sistem çağrı tablosunu 'sayfalar' açısından man sayfalarında hangi sistem çağrılarının belgelendiğini bulmak yerine daha çok bir yol
arıyorum

Çekirdeğin en azından dizelerin bir listesi olarak değil, sistem çağrılarının bir listesini tuttuğunu sanmıyorum. Cevabımı düzenledim. Bunu yapmanın gerçek bir yolu varsa, benden daha fazla deneyime sahip birisinin size cevap vermesine izin vereceğim;)
John WH Smith

Bu yüzden çekirdeğe bir sistem çağrısı ekledikten ve kullanmaya çalıştığımda "fonksiyon uygulanmadı" diye merak ediyordum ve mevcut çekirdek için syscall tablosunu almanın bir yolu olup olmadığını merak ettim. '#make install' yaptığımda, grub güncelleme ve yeni bir çekirdek başlatma, yeni çekirdek ilgili adımda yeni sistem çağrısını içeren dosyaları içerir?
Swair

1
Sistem çağrısı bulunmazsa, doğru şekilde uygulamadınız. Cevabım Linux'un sistem çağrılarını nasıl bulacağınızı anlatıyor, ancak kendiniz nasıl hata ayıklayacağınızı anlatıyor (çünkü istediğiniz şey bu değil). Bunu geliştirmekte sorun yaşıyorsanız, özellikle bu konuda bir soru sormalı ve XY probleminden kaçınmalısınız .
John WH Smith

@swair Bir sistem çağrısı ekleyerek işlevsellik eklemek son derece alışılmadık bir durumdur. Herhangi bir kod sağlamadığınız için neyin yanlış olduğunu kesin olarak söyleyemeyiz (ve sorunuz C kodu gerektiriyorsa, konu dışıdır, ancak evde Stack Overflow'da ). Bir sistem çağrısı yaptığınızdan (doğru ya da değil) ve bir C programından kullanmaya çalıştığınızdan ve sistem çağrısı yapan bir C işlevi yazma adımını kaçırdığınızdan şüpheleniyorum. Sistem çağrısı normal bir işlev çağrısı değildir.
Gilles 'SO- kötü olmayı bırak'

1

Tüm cevaplar iyi.

Belirli bir Sistem Çağrısı adı arıyorsanız:

$ cat /proc/kallsyms | grep <sys_call_name>

Tüm Sistem Çağrılarının bir listesini arıyorsanız:

$ cat /proc/kallsyms
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.