çekirdek yığını ve kullanıcı alanı yığını


111

Çekirdek yığını ile kullanıcı yığını arasındaki fark nedir? Neden çekirdek yığını kullanılır? Bir ISR'de yerel bir değişken bildirilirse, nerede depolanır? Her işlemin kendi çekirdek yığını var mı? O zaman süreç bu iki yığın arasında nasıl koordine olur?

Yanıtlar:


188
  1. Çekirdek yığını ile kullanıcı yığını arasındaki fark nedir?

Kısacası, bellekte farklı bir konum (ve dolayısıyla yığın işaretçisi yazmacı için farklı bir değer) ve genellikle farklı bellek erişim korumaları dışında hiçbir şey yoktur. Örneğin, kullanıcı modunda çalıştırılırken, çekirdek belleğine (bir kısmı çekirdek yığınıdır) eşlenmiş olsa bile erişilemez. Bunun tersi, çekirdek kodu tarafından açıkça talep edilmeden (Linux'ta, benzeri işlevler aracılığıyla copy_from_user()), kullanıcı belleğine (kullanıcı yığını dahil) genellikle doğrudan erişilemez.

  1. Neden [ayrı] bir çekirdek yığını kullanılıyor?

Ayrıcalıklar ve güvenlik ayrımı. Birincisi, kullanıcı alanı programları yığınlarını (işaretçi) istedikleri herhangi bir şeyi yapabilir ve genellikle geçerli bir tane bile mimari gereksinimi yoktur. Bu nedenle çekirdek , kullanıcı alanı yığın işaretleyicisinin geçerli veya kullanılabilir olmasına güvenemez ve bu nedenle kendi denetimi altında bir set gerektirecektir. Farklı CPU mimarileri bunu farklı şekillerde uygular; x86 CPU'lar, ayrıcalık modu anahtarları oluştuğunda ve farklı ayrıcalık seviyeleri için kullanılacak değerler, ayrıcalıklı kodla (yani yalnızca çekirdek) yapılandırılabilir olduğunda yığın işaretleyicilerini otomatik olarak değiştirir.

  1. Bir ISR'de yerel bir değişken bildirilirse, nerede depolanır?

Çekirdek yığınında. Çekirdek (Linux çekirdeğine,) yok değil x86 mimarinin doğrudan ISRS kanca kesme kapıları ancak kayıtlı işleyicisi çağırmadan önce ön kesme sicil durumunu kaydeder giriş / çıkış mekanizması kesme ortak çekirdeğe yerine delegeler kesme gönderme (ler) . Bir kesme gönderirken CPU'nun kendisi bir ayrıcalık ve / veya yığın anahtarı çalıştırabilir ve bu çekirdek tarafından kullanılır / kurulur, böylece ortak kesme giriş kodu zaten mevcut olan bir çekirdek yığınına bağlı olabilir.
Bununla birlikte, çekirdek kodu çalıştırılırken meydana gelen kesintiler, o noktada çekirdek yığınını basitçe (devam edecek) yerinde kullanacaktır. Bu, kesme işleyicileri derinlemesine iç içe geçmiş çağrı yollarına sahipse, yığın taşmalarına yol açabilir (derin bir çekirdek çağrı yolu kesintiye uğrarsa ve işleyici başka bir derin yola neden olursa; Linux'ta, dosya sistemi / yazılım RAID kodu, iptables etkinken ağ koduyla kesilir Bu tür uyumsuz eski çekirdeklerde tetiklediği biliniyor ... çözüm, bu tür iş yükleri için çekirdek yığın boyutlarını artırmaktır).

  1. Her işlemin kendi çekirdek yığını var mı?

Her işlem değil - her iş parçacığının kendi çekirdek yığını (ve aslında kendi kullanıcı yığını) vardır. İşlemler ve iş parçacıkları (Linux'a) arasındaki tek farkın, birden çok iş parçacığının bir adres alanını paylaşabilmesidir (bir süreç oluşturarak).

  1. Süreç bu iki yığın arasında nasıl koordinasyon sağlıyor?

Hiç de değil - buna gerek yok. Zamanlama (farklı iş parçacıklarının nasıl / ne zaman çalıştırıldığı, durumlarının nasıl kaydedildiği ve geri yüklendiği) işletim sisteminin görevidir ve süreçlerin bununla ilgilenmesine gerek yoktur. Parçacığı oluşturulur (ve her işlem en az bir dişe sahip olmalıdır) de, çekirdek kullanıcı alanı yığınları ya da açık bir şekilde oluşturulur ise / (fonksiyonlar gibi bir iplik oluşturmak için kullanılan herhangi bir mekanizma tarafından sağlanan, onlar için çekirdek yığın oluşturur makecontext()ve pthread_create()arayan izin "alt" iş parçacığının yığını için kullanılacak bir bellek bölgesi belirtin veya miras alın (yeni bir işlem oluştururken genellikle "yazarken kopyala" / COW olarak adlandırılan erişime bağlı bellek klonlamasıyla).
Bahsedilen,(durum, bunların arasında iş parçacığının yığın işaretçisi). Orada bunun için birden fazla yolu vardır: UNIX sinyalleri setcontext(), pthread_yield()/ pthread_cancel(), ... - ama bu asıl soruya gelen biraz disgressing edilir.


Mükemmel cevaplar FrankH. Teşekkürler.
kumar

1
@FrankH Mükemmel cevap .. ama bununla ilgili küçük sorularım var ama ARM mimarisinde .. Bu çekirdek yığını farklı işlemci modlarıyla nasıl ilişkilidir?
Rahul

2
@Rahul: "Bir SO yorumunun marjı böyle bir cevap içeremeyecek kadar küçük". Stacks / stackpointer kayıtları, farklı ARM CPU modlarında nasıl çalışır (hangileri bir bankalı SP uygular) iyi bir sorudur, ancak yanıtlamak için bir yorumun verebileceğinden daha fazla alan gerektirir. Aynısı x86 görev geçitleri veya IST'ler gibi şeyler için de geçerlidir - "tek" çekirdek yığını işaretçisi diye bir şey yoktur (tıpkı "tek" bir kullanıcı yığını işaretçisi olmadığı gibi) ve ne için donanım desteği / yetkisi vardır? farklı çalışma modlarında ayrı yığın işaretçileri ... donanıma çok bağlıdır.
FrankH.

@FrankH. Aynı şey için yeni bir soru oluşturdum ... stackoverflow.com/q/22601165/769260 Umarım artık bana yer umursamadan yardım edebilirsiniz :)
Rahul

1
@FrankH. Bir işlemin bellek düzeninde çekirdek yığınının nereye ait olduğunu gösteren bir şema sağlayabilir misiniz?
Jithin Pavithran

19

Cevabım eşyalarımla birlikte diğer SO sorularından alınmıştır.

What's the difference between kernel stack and user stack?

Bir çekirdek programcısı olarak, çekirdeğin hatalı kullanıcı programlarından kısıtlanması gerektiğini biliyorsunuz. Diyelim ki hem çekirdek hem de kullanıcı alanı için aynı yığını tutuyorsunuz, ardından kullanıcı uygulamasındaki basit segfault çekirdeği çöker ve yeniden başlatılması gerekir.

ISR Yığını gibi CPU başına bir "çekirdek yığını" ve İşlem başına bir "çekirdek yığını" vardır. Her işlem için bir "kullanıcı yığını" vardır, ancak her evrenin hem kullanıcı hem de çekirdek evrelerini içeren kendi yığını vardır.

http://linux.derkeiler.com/Mailing-Lists/Kernel/2004-10/3194.html

Why kernel stack is used?

Bu nedenle, çekirdek kipindeyken, kullanıcı alanına benzer yerel değişkenler olan işlev çağrıları ile uğraşmak için yığın türü bir mekanizma gereklidir.

http://www.kernel.org/doc/Documentation/x86/kernel-stacks

If a local variable is declared in an ISR, where it will be stored?

ISR yığınında (IRQSTACKSIZE) depolanacaktır. ISR, yalnızca donanım destekliyorsa ayrı bir kesme yığını üzerinde çalışır. Aksi takdirde, ISR yığın çerçeveleri, kesintiye uğramış ipliğin istifine itilir.

Kullanıcı alanı, kesmenin mevcut sürecin çekirdek yığınında mı yoksa ayrı bir ISR yığınında mı sunulacağını bilmiyor ve açıkçası umursamıyor. Kesintiler cpu başına geldiği için, ISR yığını cpu başına olmalıdır.

 Does each process has its own kernel stack ?

Evet. Her işlemin kendi çekirdek yığını vardır.

 Then how the process coordinates between both these stacks?

@ FrankH'ın cevabı bana harika görünüyor.


4
  1. Çekirdek yığını ile kullanıcı yığını arasındaki fark nedir

Robert Love'ın Linux Kernel Development'tan referans alırsak, temel fark boyuttur:

Kullanıcı alanı, devasa yapılar ve bin öğeli diziler dahil olmak üzere yığın üzerinde birçok değişkeni statik olarak ayırmaktan kurtulabilir.
Bu davranış yasaldır çünkü kullanıcı alanı dinamik olarak büyüyebilen büyük bir yığına sahiptir.
Çekirdek yığını ne büyük ne de dinamiktir; küçük ve sabit boyuttadır.
Çekirdek yığınının tam boyutu mimariye göre değişir.
X86'da yığın boyutu derleme zamanında yapılandırılabilir ve 4KB veya 8KB olabilir.
Tarihsel olarak, çekirdek yığını iki sayfadır ve bu genellikle 32-bit mimarilerde 8KB ve 64-bit mimarilerde 16KB olduğu anlamına gelir — bu boyut sabit ve mutlaktır.
Her işlem kendi yığınını alır.

Ayrıca çekirdek yığını, evre hakkındaki bilgileri tutan evre_info yapısına bir gösterici içerir.

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.