2012-08-10 21 views
6

Linux çekirdeği hakkında bir şeyler öğreniyorum ama kullanıcı modundan linux'daki çekirdek moduna geçiş yapmayı anlamıyorum. Nasıl çalışır? Bana bir tavsiyede bulunabilir misiniz, yoksa bana bir link verebilir misiniz? çok teşekkür ederim!Kullanıcı modundan çekirdek moduna nasıl geçilir?

+0

Sorunuzun bağlam nedir aşağıdaki bağlantıdan) bir kod nereye koyduğunuzu S bir dosyadır? Belirli bir CPU üzerinde veya genel olarak belirli CPU mekanizmalarını mı soruyorsunuz? Çözmeye çalıştığın bir problem mi var? –

cevap

11

tek yolu, bir kullanıcı uygulama bu sistem çağrı API'leri aradığında vb bir sistem çağrısı gibi open, read, write

yaparak olduğunu Uygun parametrelerle bir yazılım kesme/istisna (SWI) tetiklenir. Bu SWI'nin bir sonucu olarak, kod yürütme denetimi kullanıcı uygulamasından işletim sistemi tarafından sağlanan Kesinti Vektör Tablosunda [IVT] önceden tanımlanmış bir konuma atlar.

Bu IVT, kullanıcı uygulamasını çekirdek moduna geçirmek ve kullanıcı işlemi adına çekirdek yönergeleri yürütmeye başlamak için gerekli tüm gerekli adımları gerçekleştiren SWI özel durum işleyici yordamı için bir adres içerir.

+2

Oldukça değil. X86'da, kullanıcı modundan kaynaklanan herhangi bir istisna, kontrolü işletim sistemindeki uygun istisna işleyicisine, çekirdek modunda aktarır. –

+0

Doğru. Cevabımı gönderdikten hemen sonra, kullanıcı uygulamasının açıkça kernel moduna geçmek istediğinde durumu yansıtmak istedim. Ancak, ağ sorunları nedeniyle bunu yapmaya çalıştım. Bunu yansıtmak için şimdi düzenlediniz. –

+0

@AmarnathRevanna İşletim sistemi, bir SWI'ye hizmet verirken infact kernel moduna geçtiğini nasıl biliyor? Denetleyici (ring 0)/kullanıcı (ring 3) olmak için modun kaydını tutan ve bir SWI'da güncellenen belirli bir donanım kaydı/bit var mı? Temel olarak, kullanıcıya geçiş seviyesini donanım seviyesinde birleştirir. – Shyam

0

Sadece bunu okudum ve oldukça iyi bir kaynak. Kullanıcı modunu ve çekirdek modunu, neden değişiklik yapıldığını, ne kadar pahalı olduklarını ve bazı ilginç okumaları açıklar.

http://www.codinghorror.com/blog/2008/01/understanding-user-and-kernel-mode.html

Burada kısa bir alıntı:

çekirdek tarz

Çekirdek modunda, yürütme kod temel donanımına tam ve sınırsız erişimi vardır. Herhangi bir CPU komutunu çalıştırabilir ve herhangi bir hafıza adresini referans gösterebilir. Çekirdek modu genellikle işletim sisteminin en düşük düzey, en güvenilir işlevleri için ayrılmıştır. Çekirdek modunda çökmeler felakettir; Tüm bilgisayarı durduracaklar. Kullanıcı modunda

kullanıcı modu

yürütme kodunu doğrudan donanım ya da referans belleğe erişmek için bir yeteneği vardır. Kullanıcı modunda çalışan kod, donanım veya belleğe erişmek için sistem API'lerine yetki vermelidir. Bu tür bir yalıtımın sağladığı koruma nedeniyle, kullanıcı modunda çökmeler her zaman kurtarılabilir. Bilgisayarınızda çalışan kodların çoğu kullanıcı modunda çalışacaktır. Bir kullanıcı uzay uygulama açıkça normal çalışma sırasında modundan çekirdek bir anahtarı başlatabilir

1

Kullanıcı modundan çekirdek moduna geçmek için sistem çağrısı yapmanız gerekir.

Sadece kapağın altında neler olup bittiğini görmek istiyorsanız, TLDP is your new friend'a gidin ve kodu inceleyin (iyi belgelenmiş, montaj kodunu anlamak için ek bilgiye gerek yoktur).

Sen ilgilenen: Gördüğünüz gibi

movl $len,%edx   # third argument: message length 
    movl $msg,%ecx   # second argument: pointer to message to write 
    movl $1,%ebx    # first argument: file handle (stdout) 
    movl $4,%eax    # system call number (sys_write) 
    int  $0x80    # call kernel 

, bir sistem çağrısı bu sistem çağrısı için sadece bir kesintiyi (0x80) gerçekleştirir montaj kodu, etrafında sarıcı ve sonuç olarak bir işleyici olduğunu Aranacak.

Bir hile yapıp burada bir C önişlemcisi kullanarak bir yürütülebilir dosya oluşturun (foo.

gcc -o foo -nostdlib foo.S 

Çalıştır o strace aracılığıyla biz yazdıklarıma alırsınız sağlamak için:

$ strace -t ./foo 
09:38:28 execve("./foo", ["./foo"], 0x7ffeb5b771d8 /* 57 vars */) = 0 
09:38:28 stat(NULL, Hello, world! 
NULL)    = 14 
09:38:28 write(0, NULL, 14)  
İlgili konular