2 Kasım 2009 Pazartesi

Biraz sinerji katalım

Takip edenler bilir, yaklaşık bir aydır eski nostaljim olan kernelmode dünyasına geri döndüm. Kendisi ile 2 sene önce hazin bir ayrılık yaşamış ve highlvl yollarını aşındırır olmuştum. Sağolsun Emre Tınaztepe ve Kutalmis dostlarım sayesinde tekrar gerçeten severek uğraştığım işe geri döndüm. Bu sebeple yıllar önce şirketteki a4 ve toner kapasitesinin tükenmesine neden olduğum kernelmode dökümanlarımı tekrar gün yüzüne çıkardım ve hararetle okumaya başladım.

Dökümanları karıştırıken günlük gibi tuttuğum ve iyice sararmaya yüz tutmuş olan not defterime denk geldim. Okudukça iyiki yazmışım bunları dedim ve sizlerle paylaşmak için hemen bloguma giriş yaptım. Umarım sizlerinde işine yarar:

== 2004 ==
- User-Mode kodları Objectlere handle'ları kullanarak erişir ancak Kernel-Mode kodları Object'lere doğrudan erişirken pointer'ları kullanır.

- Object'lerde bulunan ReferenceCount hem user-mode dan handle lar vasıtası ile yapılan erişimlerde hem de kernel-mode'dan yapılan erişimlerde 1 artar.

- Bir process zaten çok küçük zaman aralıklarında çalıştığından (quantum slice) hafıza bölgelerinede bitişik olsalar dahi çok küçük erişim boyutlarında erişir.

- İşletim Sistemi, bir processin sadece o an hafızada çalıştığı kümelerini (bknz:working set) saklamaya ihtiyaç duyar

- Her device controller local bir buffer'a sahiptir. CPU bu local bufferdan, ana hafızaya veya ana hafızdan local buffera data taşır

- I/O: Aygıttın kendi device controllerinde bulunan local buffer'a yapılan işlemdir.
Device controller daha sonra bu i/o işleminin bittiğini Cpu'ya interrupt kullanarak bildirir.

- Trap bir kullanıcı hatası veya başka bir problemden dolayı meydana gelen yazılımsal bir interrupt'tır

- I/O Manager, bir IRP oluşturduğunda _IRP yapısının AssociatedIrp.SystemBuffer buffer alanına kullanıcı taraflı buffer alanındaki bilgiyi geçer.

- IofCompleteRequest çağrısı ile bir irp için gerekli işlemlerin tümünün yapıldığı varsayılır. Bu komut sonrasında I/O Manager driver taraflı buffer alanını user taraflı buffer alanına kopyalar.

- IRQL Notları

1.Bir fonksiyona girdiğinizde mutlaka IRQL'ni kontrol edin
2.Her hangi bir fonksiyonu çağırmadan önce IRQL'ı için DDK'ya göz atın
3.Eğer bir thread en düşük IRQL seviyesinde çalışıyorsa onu daha fazla alt seviyeye indiremezsiniz, ancak yükseltebilirsiniz.
4.DISPATCH_LEVEL da PAGE_FAULT yaşamazsınız
5.Paging I/O APC level'da yapılır
6.Kullanıcı her zaman PASSIVE_LEVEL da çalışır
7.Kernel'de PASSIVE_LEVEL da çalışabilir.
8.PASSIVE_LEVEL da iş yükü dağıtımına izin verilir
9.DPC'ler DISPATCH_LEVEL da çalışırlar ve preempt edilemez(etkisizleştirilemez) (ama interrupt edilebilirler tabiki) ve dispatcher olduklarından DISPATCH_LEVEL'da çalışırlar.
10.IRQL'ları manipüle etmek için KeLowerIrql() ve KeRaiseIrql fonksiyonları kullanılır.

- IRP Notları

1.IRP'ler bir uygulamanın veya driver'in davranışları üzerinden IoManager tarafından üretilirler. IRP'in üst kısmı (header) sabit bilgilerden oluşur, alt kısım ise stack location adı verilen bilgi yığınından oluşur.
2.Uygulama driver'a yalnızca kontrolü IRP'lar vasıtası ile devredebilir, ve bilgiler paylaşılan bir hafıza tarafından değiş tokuş edilir.
3.IoManager driver'lar için bir IRP kuyruğu tutmaz, sadece ne zaman alınacaklarını ve gönderileceklerine bakar. IRP'leri kuyruklamaktan driver kendisi sorumludur.
4.IRP sürücü IoCompleteRequest isteği çağrıldığında işlemini sonlandırır.
5.Irp->IoStatus.Information transfer edilen data boyutunu içerir ve bu bilgi usermode tarafındaki DeviceIOController'in en son paramtresi olan bytesreturned'e aktarilir.
6.IoManager geri donen bilgiyi SystemBuffer'dan OutputBuffer'a kopyalar.
7.IoCompleteRequest fonksiyonu IoManager'a bildirilen en son IRP çağrısıdır ve bu IRP'in artık işinin sona erdiğini bildirir. Bu çağrı bir kez yapıldıktan sonra artık o IRP'e erişilemez.
8. Driver'dan Driver'a IRP'ler vasıtası ile haberleşilebilir. Driver'lar aynı adres boşluğunda çalıştıklarından her biri bir diğeri ile paylaşımlı hafıza alanları sayesinde iletişim kurabilir.
9.IRP, sürücü katmanları arasında dolaşabilir. Bu IRP'in bilgilerine IoGetCurrentIrpStackLocation çağrısı ile ulaşılabilir.

İşe yarar temelinizi oluşturacak şeyler buldukça paylaşmaya devam edeceğim... ,

Şimdilik sağlıcakla.

1 yorum:

  1. 1. Hiç bir zaman IoMarkIrpPending ile IRP'yi işaretlemeden Dispatch rutinlerinden STATUS_PENDING döndürmeyin...

    2. Trap hakkında, işletim sistemi çalıştıracağınız Thread'i, kendi thread_fonksiyonu içinde çalıştırdığından her thread'in bir Sturctured Exception Handler'ı bulunmaktadır. Detaylı olarak TRAP FRAME yapısını inceleyebilirsiniz.

    3. IRQL'yi arttırmadıysanız,, hiç bir zaman azaltmayın...

    4. "User-Mode kodları Objectlere handle'ları kullanarak erişir ancak Kernel-Mode kodları Object'lere doğrudan erişirken pointer'ları kullanır. " o zamanlar var mıydı bilmiyorum ama HANDLE da kullanılabilir.

    5. Bir de şimdi aklıma geldi, İbrahim'e teşekkür ediyorum ve bununla ilgili bir döküman için linki aşağıya ekliyorum.

    ÇEKİRDEK SÜRÜCÜ YAZARKEN DİKKAT EDİLMESİ GEREKENLER - (SUYUN KAYNAĞINDAN)

    YanıtlaSil