Bu cevabın güzel bir TOC ve daha fazla içerikle versiyonu .
Bildirilen herhangi bir hatayı düzelteceğim. Büyük değişiklikler yapmak veya eksik bir yön eklemek istiyorsanız, hak edilmiş bir temsilci almak için bunları kendi cevaplarınızda yapın. Küçük düzenlemeler doğrudan içinde birleştirilebilir.
Basit kod
Minimum örnek: https://github.com/cirosantilli/x86-bare-metal-examples/blob/5c672f73884a487414b3e21bd9e579c67cd77621/paging.S
Programlamadaki diğer her şey gibi, bunu gerçekten anlamanın tek yolu minimal örneklerle oynamaktır.
Bunu "zor" bir konu yapan şey, minimum örneğin büyük olmasıdır, çünkü kendi küçük işletim sisteminizi yapmanız gerekir.
Intel kılavuzu
Akılda örnekler olmadan anlamak imkansız olsa da, kılavuzları mümkün olan en kısa sürede öğrenmeye çalışın.
Intel sayfalamayı, Intel Kılavuzu Cilt 3 Sistem Programlama Kılavuzu - 325384-056TR Eylül 2015 Bölüm 4 "Çağrı" 'da açıklar .
Özellikle ilginç olan Şekil 4-4 "CR3 Formatları ve 32-Bit Sayfalı Sayfalama Yapısı Girişleri", anahtar veri yapılarını verir.
MMU
Sayfalama, CPU'nun Bellek Yönetim Birimi (MMU) kısmı tarafından yapılır . Diğerleri gibi (örn. X87 yardımcı işlemci , APIC ), bu da ilk günlerde ayrı bir yonga ile yapılıyordu ve daha sonra CPU'ya entegre edildi. Ancak terim hala kullanılmaktadır.
Genel gerçekler
Mantıksal adresler "normal" kullanıcı kara kodunda kullanılan bellek adresleri (ör içerikleri rsi
de mov eax, [rsi]
).
İlk bölümleme bunları doğrusal adreslere çevirir ve ardından sayfalama, doğrusal adresleri fiziksel adreslere çevirir.
(logical) ------------------> (linear) ------------> (physical)
segmentation paging
Çoğu zaman, fiziksel adresleri gerçek RAM donanım bellek hücrelerini indeksliyor olarak düşünebiliriz, ancak bu% 100 doğru değildir çünkü:
Çağrı yalnızca korumalı modda kullanılabilir. Korumalı modda sayfalama kullanımı isteğe bağlıdır. Kayıt PG
biti cr0
ayarlanmışsa sayfalama açıktır .
Sayfalama ve segmentasyon
Sayfalama ve segmentasyon arasındaki en büyük farklardan biri şudur:
- sayfalama, RAM'i sayfalar adı verilen eşit büyüklükteki parçalara böler
- segmentasyon hafızayı rastgele boyutlarda parçalara böler
Bu, sayfalamanın ana avantajıdır, çünkü eşit büyüklükteki parçalar işleri daha yönetilebilir hale getirir.
Sayfalandırma o kadar popüler hale geldi ki, segmentasyon desteği, yeni yazılım için ana çalışma modu olan 64-bit modunda, yalnızca IA32'yi taklit eden uyumluluk modunda var olan x86-64'te düştü.
Uygulama
Sayfalama, modern işletim sistemindeki sanal adres alanlarını uygulamak için kullanılır. Sanal adreslerle işletim sistemi, iki veya daha fazla eşzamanlı işlemi tek bir RAM'e şu şekilde sığdırabilir:
- her iki programın da diğeri hakkında hiçbir şey bilmesine gerek yoktur
- her iki programın belleği gerektiği gibi büyüyebilir ve küçülebilir
- programlar arasında geçiş çok hızlı
- bir program başka bir işlemin belleğine asla erişemez
Sayfalandırma tarihsel olarak bölümlemeden sonra geldi ve büyük ölçüde Linux gibi modern işletim sistemlerinde sanal belleğin uygulanması için yerini aldı, çünkü değişken uzunluktaki bölümler yerine sabit boyutlu bellek parçalarını yönetmek daha kolay.
Donanım uygulaması
Korumalı moddaki segmentasyon gibi (bir segment kaydını değiştirmenin GDT veya LDT'den bir yükü tetiklediği), sayfalama donanımı işini yapmak için bellekteki veri yapılarını kullanır (sayfa tabloları, sayfa dizinleri, vb.).
Bu veri yapılarının formatı donanım tarafından belirlenir , ancak bu veri yapılarını RAM üzerinde doğru bir şekilde kurmak ve yönetmek ve donanıma onları nerede bulacağını (aracılığıyla cr3
) söylemek işletim sistemine bağlıdır .
Diğer bazı mimariler sayfalamayı neredeyse tamamen yazılımın eline bırakır, bu nedenle bir TLB, sayfa tablolarında gezinmek ve yeni eşlemeyi TLB'ye eklemek için işletim sistemi tarafından sağlanan bir işlevi çalıştırır. Bu, işletim sistemi tarafından seçilecek sayfa tablosu formatlarını bırakır, ancak donanımın, x86'nın yapabildiği gibi, diğer talimatların sıra dışı yürütülmesiyle sayfa gezintilerini üst üste getirme olasılığını ortadan kaldırır .
Örnek: basitleştirilmiş tek seviyeli sayfalama şeması
Bu, sanal bellek alanını uygulamak için x86 mimarisinin basitleştirilmiş bir sürümünde sayfalamanın nasıl çalıştığının bir örneğidir .
Sayfa tabloları
İşletim sistemi onlara aşağıdaki sayfa tablolarını verebilir:
İşletim sistemi tarafından 1. işleme verilen sayfa tablosu:
RAM location physical address present
----------------- ----------------- --------
PT1 + 0 * L 0x00001 1
PT1 + 1 * L 0x00000 1
PT1 + 2 * L 0x00003 1
PT1 + 3 * L 0
... ...
PT1 + 0xFFFFF * L 0x00005 1
İşletim sistemi tarafından işlem 2'ye verilen sayfa tablosu:
RAM location physical address present
----------------- ----------------- --------
PT2 + 0 * L 0x0000A 1
PT2 + 1 * L 0x0000B 1
PT2 + 2 * L 0
PT2 + 3 * L 0x00003 1
... ... ...
PT2 + 0xFFFFF * L 0x00004 1
Nerede:
PT1
ve PT2
: RAM üzerindeki tablo 1 ve 2'nin başlangıç konumu.
Örnek değerler: 0x00000000
, 0x12345678
vb
Bu değerleri belirleyen işletim sistemidir.
L
: bir sayfa tablosu girişinin uzunluğu.
present
: sayfanın bellekte olduğunu gösterir.
Sayfa tabloları RAM'de bulunur. Örneğin şu şekilde konumlandırılabilirler:
--------------> 0xFFFFFFFF
--------------> PT1 + 0xFFFFF * L
Page Table 1
--------------> PT1
--------------> PT2 + 0xFFFFF * L
Page Table 2
--------------> PT2
--------------> 0x0
Her iki sayfa tablosu için RAM üzerindeki başlangıç konumları keyfidir ve işletim sistemi tarafından kontrol edilir. Çakışmamalarını sağlamak işletim sistemine bağlıdır!
Her işlem herhangi bir sayfa tablosuna doğrudan dokunamaz, ancak işletim sistemine sayfa tablolarının değiştirilmesine neden olan taleplerde bulunabilir, örneğin daha büyük yığın veya yığın segmentleri istenebilir.
Bir sayfa, 4KB'lik (12 bit) bir yığın ve adresler 32 bit içerdiğinden, her sayfayı tanımlamak için yalnızca 20 bit (20 + 12 = 32, dolayısıyla onaltılık gösterimde 5 karakter) gerekir. Bu değer, donanım tarafından sabitlenir.
Sayfa tablosu girişleri
Bir sayfa tablosu ... sayfa tablosu girdilerinin bir tablosudur!
Tablo girişlerinin tam biçimi donanım tarafından belirlenir .
Bu basitleştirilmiş örnekte, sayfa tablosu girişleri yalnızca iki alan içerir:
bits function
----- -----------------------------------------
20 physical address of the start of the page
1 present flag
bu yüzden bu örnekte donanım tasarımcıları seçebilirdi L = 21
.
Çoğu gerçek sayfa tablosu girişinin başka alanları vardır.
Bellek bitlerle değil baytlarla adreslenebildiğinden, nesneleri 21 bitte hizalamak pratik olmaz. Bu nedenle, bu durumda sadece 21 bitte ihtiyaç duyulsa bile, donanım tasarımcıları muhtemelen L = 32
erişimi daha hızlı yapmayı seçecek ve sadece kalan bitleri daha sonra kullanmak için ayıracaktır. L
X86 için gerçek değer 32 bittir.
Tek seviyeli düzende adres çevirisi
Sayfa tabloları işletim sistemi tarafından kurulduktan sonra, doğrusal ve fiziksel adresler arasındaki adres çevirisi donanım tarafından yapılır .
OS etkinleştirmek süreç 1 istediğinde, o setleri cr3
için PT1
, süreç biri için tablonun başlangıcını.
İşlem 1 doğrusal adrese erişmek isterse 0x00000001
, sayfalama donanım devresi işletim sistemi için aşağıdakileri otomatik olarak yapar:
doğrusal adresi iki bölüme ayırın:
| page (20 bits) | offset (12 bits) |
Yani bu durumda elimizde:
- page = 0x00000
- ofset = 0x001
Sayfa tablosu 1'e bakın çünkü cr3
onu gösteriyor.
girişe bakın 0x00000
çünkü bu sayfa kısmıdır.
Donanım, bu girişin RAM adresinde bulunduğunu bilir PT1 + 0 * L = PT1
.
mevcut olduğu için erişim geçerlidir
sayfa tablosuna göre, sayfa numarasının konumu 0x00000
adresindedir 0x00001 * 4K = 0x00001000
.
nihai fiziksel adresi bulmak için sadece ofseti eklememiz gerekir:
00001 000
+ 00000 001
-----------
00001 001
çünkü 00001
tabloda aranan sayfanın fiziksel adresi 001
ve ofsettir.
Adından da anlaşılacağı gibi, ofset her zaman basitçe sayfanın fiziksel adresine eklenir.
donanım daha sonra belleği o fiziksel konumda alır.
Aynı şekilde, 1. süreç için aşağıdaki çeviriler gerçekleşecektir:
linear physical
--------- ---------
00000 002 00001 002
00000 003 00001 003
00000 FFF 00001 FFF
00001 000 00000 000
00001 001 00000 001
00001 FFF 00000 FFF
00002 000 00002 000
FFFFF 000 00005 000
Örneğin, adrese erişirken 00001000
, sayfa bölümü 00001
donanımdır, sayfa tablosu girişinin RAM adresinde PT1 + 1 * L
( 1
sayfa bölümü nedeniyle) bulunduğunu bilir ve onu arayacağı yer orasıdır.
İşletim sistemi işlem 2'ye geçmek istediğinde, tüm yapması gereken cr3
2. sayfaya işaret etmektir. Bu kadar basit!
Şimdi 2. işlem için aşağıdaki çeviriler gerçekleşecektir:
linear physical
--------- ---------
00000 002 00001 002
00000 003 00001 003
00000 FFF 00001 FFF
00001 000 00000 000
00001 001 00000 001
00001 FFF 00000 FFF
00003 000 00003 000
FFFFF 000 00004 000
Aynı doğrusal adres , yalnızca içindeki değere bağlı olarak farklı işlemler için farklı fiziksel adreslere dönüşür cr3
.
Bu şekilde her program, kesin fiziksel adresler konusunda endişelenmeden verilerinin başlaması 0
ve bitmesini bekleyebilir FFFFFFFF
.
Sayfa hatası
İşlem 1, mevcut olmayan bir sayfadaki bir adrese erişmeye çalışırsa ne olur?
Donanım, yazılımı bir Sayfa Hatası İstisnası aracılığıyla bilgilendirir.
Bu durumda, ne yapılması gerektiğine karar vermek için bir istisna işleyicisi kaydettirmek genellikle işletim sistemine bağlıdır.
Tabloda olmayan bir sayfaya erişmenin bir programlama hatası olması mümkündür:
int is[1];
is[2] = 1;
ancak kabul edilebilir olduğu durumlar olabilir, örneğin Linux'ta şu durumlarda:
program yığınını artırmak istiyor.
Sadece belirli bir olası aralıkta belirli bir bayta erişmeye çalışır ve eğer işletim sistemi mutluysa, bu sayfayı işlem adres alanına ekler.
sayfa diske değiştirildi.
İşletim sisteminin sayfayı RAM'e geri almak için işlemlerin arkasında bazı çalışmalar yapması gerekecektir.
İşletim sistemi, sayfa tablosu girişinin geri kalanının içeriğine bağlı olarak durumun böyle olduğunu keşfedebilir, çünkü mevcut bayrak açıksa, sayfa tablosu girişinin diğer girdileri, işletim sisteminin istediği şeye tamamen bırakılır.
Örneğin Linux'ta, mevcut olduğunda = 0:
sayfa tablosu girişinin tüm alanları 0 ise, geçersiz adres.
aksi takdirde, sayfa diske değiştirilmiştir ve bu alanların gerçek değerleri sayfanın diskteki konumunu kodlar.
Her durumda, işletim sisteminin sorunla başa çıkabilmek için hangi adresin Sayfa Hatasını oluşturduğunu bilmesi gerekir. Bu nedenle güzel IA32 geliştiricileri, cr2
bir Sayfa Hatası oluştuğunda bu adresin değerini ayarlarlar . İstisna işleyici daha sonra sadece cr2
adresi almak için araştırabilir .
Basitleştirmeler
Bu örneğin anlaşılmasını kolaylaştıran gerçekliğe basitleştirmeler:
tüm gerçek sayfalama devreleri yerden tasarruf etmek için çok seviyeli sayfalama kullanır, ancak bu basit bir tek seviyeli şema gösterdi.
sayfa tabloları yalnızca iki alan içeriyordu: 20 bitlik bir adres ve 1 bitlik mevcut bayrak.
Gerçek sayfa tabloları toplam 12 alan ve dolayısıyla atlanan diğer özellikleri içerir.
Örnek: çok seviyeli sayfalama şeması
Tek seviyeli bir sayfalama şemasındaki sorun, çok fazla RAM kullanmasıdır: 4G / 4K = işlem başına 1M giriş . Her giriş 4 bayt uzunluğundaysa, bu işlem başına 4M yapar ps -A | wc -l
ki bu bir masaüstü bilgisayar için bile çok fazladır: şu anda 244 işlem çalıştırdığımı söylüyor, bu nedenle RAM'imin yaklaşık 1 GB'ı alacaktır!
Bu nedenle x86 geliştiricileri, RAM kullanımını azaltan çok seviyeli bir şema kullanmaya karar verdiler.
Bu sistemin dezavantajı, biraz daha yüksek erişim süresine sahip olmasıdır.
PAE'siz 32 bit işlemciler için kullanılan basit 3 seviyeli sayfalama düzeninde, 32 adres biti aşağıdaki gibi bölünmüştür:
| directory (10 bits) | table (10 bits) | offset (12 bits) |
Her işlemin kendisiyle ilişkilendirilmiş bir ve yalnızca bir sayfa dizini olmalıdır, bu nedenle en azından 2^10 = 1K
tek seviyeli bir şemada gereken minimum 1M'den çok daha iyi olan sayfa dizini girişlerini .
Sayfa tabloları yalnızca işletim sistemi tarafından ihtiyaç duyulduğunda tahsis edilir. Her sayfa tablosunun 2^10 = 1K
sayfa dizini girişleri vardır
Sayfa dizinleri şunları içerir ... sayfa dizini girişleri! Sayfa dizini girişleri, tabloların fiziksel adresleri yerine sayfa tablolarının RAM adreslerine işaret etmeleri dışında sayfa tablosu girişleriyle aynıdır . Bu adresler yalnızca 20 bit genişliğinde olduğundan, sayfa tabloları 4KB sayfaların başında yer almalıdır.
cr3
şimdi sayfa tabloları yerine geçerli işlemin sayfa dizininin RAM üzerindeki konumunu işaret ediyor.
Sayfa tablo girişleri, tek seviyeli bir şemadan hiç değişmez.
Sayfa tabloları tek seviyeli bir düzenden değişiyor çünkü:
- her işlem, sayfa dizini girişi başına bir tane olmak üzere en fazla 1K sayfa tablosuna sahip olabilir.
- her sayfa tablosu 1 milyon giriş yerine tam olarak 1K giriş içerir.
İlk iki seviyede (örneğin değil 12 | 8 | 12
) 10 bit kullanmanın nedeni , her bir Sayfa Tablosu girişinin 4 bayt uzunluğunda olmasıdır. Ardından Sayfa dizinlerinin ve Sayfa Tablolarının 2 ^ 10 girişi 4Kb sayfalara güzelce sığar. Bu, bu amaç için sayfaları ayırmanın ve ayırmanın daha hızlı ve daha kolay olduğu anlamına gelir.
Çok seviyeli düzende adres çevirisi
İşletim sistemi tarafından 1. işleme verilen sayfa dizini:
RAM location physical address present
--------------- ----------------- --------
PD1 + 0 * L 0x10000 1
PD1 + 1 * L 0
PD1 + 2 * L 0x80000 1
PD1 + 3 * L 0
... ...
PD1 + 0x3FF * L 0
PT1 = 0x10000000
( 0x10000
* 4K) ' da OS tarafından işlem 1 için verilen sayfa tabloları :
RAM location physical address present
--------------- ----------------- --------
PT1 + 0 * L 0x00001 1
PT1 + 1 * L 0
PT1 + 2 * L 0x0000D 1
... ...
PT1 + 0x3FF * L 0x00005 1
PT2 = 0x80000000
( 0x80000
* 4K) ' da OS tarafından işlem 1 için verilen sayfa tabloları :
RAM location physical address present
--------------- ----------------- --------
PT2 + 0 * L 0x0000A 1
PT2 + 1 * L 0x0000C 1
PT2 + 2 * L 0
... ...
PT2 + 0x3FF * L 0x00003 1
nerede:
PD1
: RAM'deki işlem 1'in sayfa dizininin başlangıç konumu.
PT1
ve PT2
: RAM üzerindeki işlem 1 için sayfa tablosu 1 ve sayfa tablosu 2'nin başlangıç konumu.
Dolayısıyla bu örnekte sayfa dizini ve sayfa tablosu RAM'de şu şekilde saklanabilir:
----------------> 0xFFFFFFFF
----------------> PT2 + 0x3FF * L
Page Table 1
----------------> PT2
----------------> PD1 + 0x3FF * L
Page Directory 1
----------------> PD1
----------------> PT1 + 0x3FF * L
Page Table 2
----------------> PT1
----------------> 0x0
Doğrusal adresi 0x00801004
adım adım çevirelim.
Bunun cr3 = PD1
, az önce açıklanan sayfa dizinine işaret ettiğini varsayıyoruz .
İkili olarak doğrusal adres:
0 0 8 0 1 0 0 4
0000 0000 1000 0000 0001 0000 0000 0100
Verildiği gibi gruplama 10 | 10 | 12
:
0000000010 0000000001 000000000100
0x2 0x1 0x4
hangi verir:
- sayfa dizini girişi = 0x2
- sayfa tablosu girişi = 0x1
- ofset = 0x4
Böylece donanım, sayfa dizininin 2. girişini arar.
Sayfa dizini tablosu, sayfa tablosunun konumunda olduğunu söylüyor 0x80000 * 4K = 0x80000000
. Bu, işlemin ilk RAM erişimidir.
Sayfa tablosu girişi olduğundan 0x1
, donanım, sayfa tablosunun 1. girişine bakar ve 0x80000000
bu ona fiziksel sayfanın adreste bulunduğunu söyler 0x0000C * 4K = 0x0000C000
. Bu, sürecin ikinci RAM erişimidir.
Son olarak, sayfalama donanımı ofseti ekler ve son adres 0x0000C004
.
Çevrilen adreslerin diğer örnekleri şunlardır:
linear 10 10 12 split physical
-------- --------------- ----------
00000001 000 000 001 00001001
00001001 000 001 001 page fault
003FF001 000 3FF 001 00005001
00400000 001 000 000 page fault
00800001 002 000 001 0000A001
00801008 002 001 008 0000C008
00802008 002 002 008 page fault
00B00001 003 000 000 page fault
Sayfa dizini girişi veya sayfa tablosu girişi yoksa sayfa hataları meydana gelir.
İşletim sistemi başka bir işlemi aynı anda çalıştırmak isterse, ikinci işleme ayrı bir sayfa dizini verir ve bu dizini ayrı sayfa tablolarına bağlar.
64 bit mimariler
64 bit, mevcut RAM boyutları için hala çok fazla adrestir, bu nedenle çoğu mimari daha az bit kullanır.
x86_64, 48 bit (256 TiB) kullanır ve eski modun PAE'si zaten 52 bit adreslere (4 PiB) izin verir.
Bu 48 bitin 12'si, 36 bit bırakan ofset için zaten ayrılmıştır.
2 seviyeli bir yaklaşım benimsenirse, en iyi bölme iki 18 bitlik seviye olacaktır.
Ancak bu, sayfa dizininin 2^18 = 256K
çok fazla RAM gerektiren girdilere : 32 bit mimariler için tek seviyeli bir sayfalamaya yakın!
Bu nedenle 64 bit mimariler, genellikle 3 veya 4 olmak üzere daha da ileri sayfa seviyeleri oluşturur.
x86_64, bir 9 | 9 | 9 | 12
şemada 4 seviye kullanır , böylece üst seviye yalnızca 2^9
daha yüksek seviyeli girişleri alır.
PAE
Fiziksel adres uzantısı.
32 bit ile sadece 4GB RAM adreslenebilir.
Bu, büyük sunucular için bir sınırlama haline geldi, bu nedenle Intel PAE mekanizmasını Pentium Pro'ya tanıttı.
Sorunu gidermek için Intel 4 yeni adres satırı ekledi, böylece 64GB adreslenebilir.
PAE açıksa, sayfa tablosu yapısı da değişir. Değiştirilme şekli, PSE'nin açık veya kapalı olmasına bağlıdır.
PAE, PAE
bit üzerinden açılır ve kapanır cr4
.
Toplam adreslenebilir bellek 64 GB olsa bile, bireysel işlemler yine de yalnızca 4 GB'a kadar kullanabilir. Ancak işletim sistemi, farklı 4GB'lık yığınlara farklı işlemler koyabilir.
PSE
Sayfa boyutu uzantısı.
Sayfaların 4K yerine 4M (veya PAE açıksa 2M) uzunluğunda olmasına izin verir.
PSE, PAE
bit üzerinden açılır ve kapatılır cr4
.
PAE ve PSE sayfa tablosu şemaları
PAE ve PSE'den herhangi biri etkinse, farklı sayfalama düzeyi şemaları kullanılır:
PAE yok ve PSE yok: 10 | 10 | 12
Hiçbir PAE ve PSE: 10 | 22
.
22, 4Mb sayfasındaki ofsettir, çünkü 22 bit 4Mb'yi adresler.
PAE ve PSE yok: 2 | 9 | 9 | 12
9'un 10 yerine iki kez kullanılmasının tasarım nedeni, artık girişlerin artık 32 bite sığamayacak olmasıdır, bunların tümü 20 adres biti ve 12 anlamlı veya ayrılmış bayrak bitiyle doldurulmuştur.
Bunun nedeni, 20 bitin artık sayfa tablolarının adresini temsil etmek için yeterli olmamasıdır: İşlemciye eklenen 4 ekstra kablo nedeniyle artık 24 bit gereklidir.
Bu nedenle, tasarımcılar giriş boyutunu 64 bite çıkarmaya karar verdiler ve bunları tek bir sayfa tablosuna sığdırmak için giriş sayısını 2 ^ 10 yerine 2 ^ 9'a düşürmek gerekiyor.
Başlangıç 2, sayfa dizinlerini işaret ettiği ve 32 bit doğrusal adresi doldurduğu için Sayfa Dizini İşaretçi Tablosu (PDPT) olarak adlandırılan yeni bir Sayfa seviyesidir . PDPT'ler ayrıca 64 bit genişliğindedir.
cr3
şimdi ilk dört 4GB bellek üzerinde olması ve verimliliği adreslemek için 32 bit katları üzerinde hizalanmış olması gereken PDPT'leri işaret ediyor. Bu, artık cr3
ilk 4 GB'ın 2 ^ 32'sini tamamlamak için 32 kat * 2 ^ 27 için 20: 2 ^ 5 yerine 27 anlamlı bit olduğu anlamına gelir .
PAE ve PSE: 2 | 9 | 21
Tasarımcılar, tek bir sayfaya sığdırmak için 9 bit genişliğinde bir alan tutmaya karar verdiler.
Bu 23 bit bırakır. PSE'siz PAE kasasıyla işleri tekdüze tutmak için PDPT için 2'yi bırakmak, ofset için 21 bırakır, bu da sayfaların 4M yerine 2M genişliğinde olduğu anlamına gelir.
TLB
Translation Lookahead Buffer (TLB), sayfalama adresleri için bir önbellektir.
Bir önbellek olduğu için, ilişkilendirilebilirlik seviyesi gibi CPU önbelleğinin tasarım sorunlarının çoğunu paylaşır.
Bu bölüm, 4 tek adres girişine sahip basitleştirilmiş, tamamen ilişkilendirilmiş bir TLB'yi açıklayacaktır. Diğer önbellekler gibi, gerçek TLB'lerin genellikle tam olarak ilişkilendirilmediğini unutmayın.
Temel operasyon
Doğrusal ve fiziksel adres arasında bir çeviri gerçekleştikten sonra, TLB'de saklanır. Örneğin, 4 girişli bir TLB aşağıdaki durumda başlar:
valid linear physical
------ ------- ---------
> 0 00000 00000
0 00000 00000
0 00000 00000
0 00000 00000
, Değiştirilecek >
geçerli girişi gösterir.
ve doğrusal bir sayfa adresi 00003
fiziksel bir adrese çevrildikten sonra 00005
, TLB şu hale gelir:
valid linear physical
------ ------- ---------
1 00003 00005
> 0 00000 00000
0 00000 00000
0 00000 00000
ve ikinci bir çeviri sonrası 00007
için 00009
o olur:
valid linear physical
------ ------- ---------
1 00003 00005
1 00007 00009
> 0 00000 00000
0 00000 00000
Şimdi 00003
tekrar çevrilmesi gerekirse , donanım önce TLB'yi arar ve adresini tek bir RAM erişimiyle bulur 00003 --> 00005
.
Elbette, 00000
hiçbir geçerli giriş 00000
anahtar olarak içermediği için TLB'de değildir .
Değiştirme politikası
TLB doldurulduğunda, eski adreslerin üzerine yazılır. Tıpkı CPU önbelleğinde olduğu gibi, değiştirme ilkesi potansiyel olarak karmaşık bir işlemdir, ancak basit ve makul bir buluşsal yöntem, en az kullanılan girdiyi (LRU) kaldırmaktır.
LRU ile, durumdan başlayarak:
valid linear physical
------ ------- ---------
> 1 00003 00005
1 00007 00009
1 00009 00001
1 0000B 00003
eklemek şunu 0000D -> 0000A
verir:
valid linear physical
------ ------- ---------
1 0000D 0000A
> 1 00007 00009
1 00009 00001
1 0000B 00003
KAM
TLB'yi kullanmak, çeviriyi hızlandırır, çünkü ilk çeviri TLB seviyesi başına bir erişim alır , bu da basit bir 32 bit şemada 2, 64 bit mimarilerde 3 veya 4 anlamına gelir.
TLB genellikle içerik adreslenebilir bellek (CAM) adı verilen pahalı bir RAM türü olarak uygulanır. CAM, donanım üzerinde ilişkisel bir harita uygular, yani bir anahtar (doğrusal adres) verilen bir yapı, bir değer alır.
Eşlemeler ayrıca RAM adreslerine de uygulanabilir, ancak CAM eşlemeleri bir RAM eşlemesinden çok daha az giriş gerektirebilir.
Örneğin, içinde:
- hem anahtarların hem de değerlerin 20 bit'i vardır (basit bir sayfalama şemaları durumunda)
- her seferinde en fazla 4 değerin saklanması gerekir
4 girişli bir TLB'de saklanabilir:
linear physical
------- ---------
00000 00001
00001 00010
00010 00011
FFFFF 00000
Bununla birlikte, bunu RAM ile uygulamak için 2 ^ 20 adrese sahip olmak gerekir :
linear physical
------- ---------
00000 00001
00001 00010
00010 00011
... (from 00011 to FFFFE)
FFFFF 00000
bu bir TLB kullanmaktan daha pahalı olacaktır.
Geçersiz kılma girişleri
cr3
Değişiklik yapıldığında , tüm TLB girişleri geçersiz kılınır, çünkü yeni bir işlem için yeni bir sayfa tablosu kullanılacağından, eski girişlerden herhangi birinin herhangi bir anlamı olması olası değildir.
X86 ayrıca, invlpg
tek bir TLB girişini açıkça geçersiz kılan talimatı da sunar . Diğer mimariler, belirli bir aralıktaki tüm girişlerin geçersiz kılınması gibi, geçersiz kılınmış TLB girişleri için daha da fazla talimat sunar.
Bazı x86 CPU'lar, x86 spesifikasyonunun gereksinimlerinin ötesine geçer ve bir sayfa tablosu girişini değiştirmek ve TLB'de önceden önbelleğe alınmamışken onu kullanmak arasında garanti ettiğinden daha fazla tutarlılık sağlar . Görünüşe göre Windows 9x, doğruluk için buna güveniyordu, ancak modern AMD CPU'lar tutarlı sayfa yürüyüşleri sağlamıyor. Yanlış spekülasyonları tespit etmeleri gerekse bile Intel CPU'lar bunu yapar. Bundan yararlanmak muhtemelen kötü bir fikirdir, çünkü muhtemelen kazanılacak çok şey yoktur ve hata ayıklaması zor olacak ince zamanlamaya duyarlı sorunlara neden olma riski büyüktür.
Linux çekirdeği kullanımı
Linux çekirdeği, küçük veri parçalamalı hızlı işlem anahtarlarına izin vermek için x86'nın sayfalama özelliklerini kapsamlı şekilde kullanır.
İçinde v4.2
, altına bakın arch/x86/
:
include/asm/pgtable*
include/asm/page*
mm/pgtable*
mm/page*
Sayfaları temsil etmek için tanımlanmış hiçbir yapı yok gibi görünüyor, sadece makrolar: include/asm/page_types.h
özellikle ilginç. Alıntı:
#define _PAGE_BIT_PRESENT 0 /* is present */
#define _PAGE_BIT_RW 1 /* writeable */
#define _PAGE_BIT_USER 2 /* userspace addressable */
#define _PAGE_BIT_PWT 3 /* page write through */
arch/x86/include/uapi/asm/processor-flags.h
tanımlar CR0
ve özellikle PG
bit konumunu:
#define X86_CR0_PG_BIT 31 /* Paging */
Kaynakça
Bedava:
Özgür olmayan: