X86 sayfalama nasıl çalışır?


92

Bu soru, konuyla ilgili iyi ücretsiz bilgi boşluğunu doldurmak içindir.

İyi bir cevabın büyük bir SO cevabına veya en azından birkaç cevaba sığacağına inanıyorum.

Temel amaç, yeni başlayanlara, kılavuzu kendi başlarına alabilmeleri ve sayfalandırmayla ilgili temel işletim sistemi kavramlarını anlayabilmeleri için yeterli bilgi vermektir.

Önerilen yönergeler:

  • cevaplar başlangıç ​​dostu olmalıdır:
    • somut, ancak muhtemelen basitleştirilmiş örnekler çok önemlidir
    • gösterilen kavramların uygulamaları kabul edilir
  • yararlı kaynaklardan alıntı yapmak iyidir
  • İşletim Sistemlerinin sayfalama özelliklerini nasıl kullandığına dair küçük bilgiler açığız
  • PAE ve PSE açıklamalarına açığız
  • x86_64 içine küçük alanlar açığız

İlgili sorular ve neden aldatılmadıklarını düşünüyorum:


1
Bu "sss" olarak etiketlenmeli ve "topluluk-wiki" olarak işaretlenmelidir.
Kerrek SB

@KerrekSB Bu tür soruları nasıl yöneteceğimi gerçekten bilmiyorum. Cevaplar topluluk wikileri olmalı, öyle mi? faqEtiket bulamadım .
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

3
Kısa cevabın " Cilt 3, Bölüm 4: Intel Kılavuzunda Sayfalama " olduğunu söyleyebilirim . Oldukça açık, özlü ve iyi yazılmış ve artık otoriterleşmiyor.
Kerrek SB

4
@KerrekSB Kılavuzun açık ve güvenilir olduğuna katılıyorum, ancak benim için ilk okuma kadar biraz zordu, bazı basit ve somut örneklere ve bazı şeyleri daha iyi anlamak için mantığa ihtiyacım vardı.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Yanıtlar:


144

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 rside 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 PGbiti cr0ayarlanmış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:

  • PT1ve PT2: RAM üzerindeki tablo 1 ve 2'nin başlangıç ​​konumu.

    Örnek değerler: 0x00000000, 0x12345678vb

    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 = 32erişimi daha hızlı yapmayı seçecek ve sadece kalan bitleri daha sonra kullanmak için ayıracaktır. LX86 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 cr3iç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ü cr3onu 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 0x00000adresindedir 0x00001 * 4K = 0x00001000.

  • nihai fiziksel adresi bulmak için sadece ofseti eklememiz gerekir:

      00001 000
    + 00000 001
      -----------
      00001 001
    

    çünkü 00001tabloda aranan sayfanın fiziksel adresi 001ve 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ü 00001donanımdır, sayfa tablosu girişinin RAM adresinde PT1 + 1 * L( 1sayfa 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 cr32. 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ı 0ve 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, cr2bir Sayfa Hatası oluştuğunda bu adresin değerini ayarlarlar . İstisna işleyici daha sonra sadece cr2adresi 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 -lki 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 = 1Ksayfa 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.
  • PT1ve 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 0x00801004adı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 0x80000000bu 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^9daha 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, PAEbit ü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, PAEbit ü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 cr3ilk 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 00003fiziksel 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ı 00007için 00009o olur:

  valid   linear   physical
  ------  -------  ---------
  1       00003    00005
  1       00007    00009
> 0       00000    00000
  0       00000    00000

Şimdi 00003tekrar çevrilmesi gerekirse , donanım önce TLB'yi arar ve adresini tek bir RAM erişimiyle bulur 00003 --> 00005.

Elbette, 00000hiçbir geçerli giriş 00000anahtar 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 -> 0000Averir:

  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

cr3Değ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, invlpgtek 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.htanımlar CR0ve özellikle PGbit konumunu:

#define X86_CR0_PG_BIT      31 /* Paging */

Kaynakça

Bedava:

  • rutgers-pxk-416 "Hafıza yönetimi: ders notları" bölümü

    Eski işletim sistemi tarafından kullanılan bellek düzenleme tekniklerinin iyi tarihsel incelemesi.

Özgür olmayan:

  • bovet05 "Bellek adresleme" bölümü

    X86 bellek adreslemesine makul giriş. Bazı iyi ve basit örnekler eksik.


Harika cevap, ancak LRU'nun nasıl kararlaştırıldığı konusunda hala emin değilim. MRU dışında bir sayfaya her erişildiğinde işletim sistemini çağırmak pahalı görünüyor. Alternatif olarak, eşzamanlı programlar için tehlikeli olabilecek LRU için sayfa tablosunu yeniden sıralayan donanımı görebiliyordum. Bunlardan herhangi biri doğru mu? Bir sayfa hatası oluştuğunda işletim sistemi LRU'nun hangi sayfa olduğunu nasıl bilir?
Keynan

@Keynan Bence bunu yapan donanım, bu yüzden harcanan zaman bir sorun değil. Eşzamanlılığa gelince, nasıl yönetildiğini bilmiyorum. Bence işlemci başına bir CR3 ve önbellek var ve işletim sistemi sadece bellek sayfalarının çakışmadığından emin olmalı.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

1
real TLBs are not usually fully associativeThe TLB is usually implemented as … CAMBu iki ifade çelişkili değil mi?
a3f

>>> x86_64, 9 | 9 | 9 | 12 şema 9 olmalıdır | 9 | 9 | 9 | 12?
monklof

@monklof Bunun doğru olduğunu düşünüyorum: 9 9 9 12 zaten 512gb RAM'e izin veriyor. 5 seviyeli şema, yalnızca sunuculara yönelik daha yeni bir gelişmedir, bu daha güncel olan web sitemdeki cevapta belirtilmiştir.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

22

İşte çok kısa, üst düzey bir cevap:

Bir x86 işlemci birkaç olası moddan birinde çalışır (kabaca: gerçek, korumalı, 64 bit). Her mod, birkaç olası bellek adresleme modelinden birini kullanabilir (ancak her mod, her modeli kullanamaz), yani: gerçek mod adresleme, bölümlü adresleme ve düz doğrusal adresleme.

Modern dünyada, yalnızca korumalı veya 64-bit kipte düz-doğrusal adresleme önemlidir ve iki kip esasen aynıdır, temel fark makine sözcüğünün boyutu ve dolayısıyla adreslenebilir bellek miktarıdır.

Şimdi, bellek adresleme modu, makine talimatlarının bellek işlenenlerine anlam verir (örneğin mov DWORD PTR [eax], 25, 32 bitlik (aka dword) 25 değerinin tamsayısını, eax32 bitlik kayıtta saklanan belleğe depolar ). Düz doğrusal adreslemede, bu sayının eaxsıfırdan maksimum değere kadar (bizim durumumuzda 2 32  - 1) tek, bitişik bir aralıkta çalışmasına izin verilir .

Ancak, düz doğrusal adresleme sayfalı olabilir veya sayfalanmayabilir . Sayfalama olmadan, adres doğrudan fiziksel belleğe atıfta bulunur. İle çağrı, işlemcinin bellek yönetim birimi (ya da MMU) şeffaf (şimdi bir adlandırılan istediğiniz adresi beslemeleri sanal adres bir arama mekanizması, sözde içine) sayfa tabloları ve fiziksel adres olarak yorumlanır yeni bir değer elde eder. Kullanıcı yalnızca sanal adresi görse bile, orijinal işlem artık fiziksel bellekteki bu yeni, çevrilmiş adres üzerinde çalışır.

Sayfalamanın en önemli yararı, sayfa tablolarının işletim sistemi tarafından yönetilmesidir. Böylece, işletim sistemi sayfa tablolarını keyfi olarak değiştirebilir ve değiştirebilir, örneğin "görevler arasında geçiş yaparken" olduğu gibi. Her bir "işlem" için bir sayfa tablosu koleksiyonunu tutabilir ve belirli bir işlemin belirli bir CPU üzerinde çalışacağına karar verdiğinde, işlemin sayfa tablolarını o CPU'nun MMU'suna yükler (her CPU'nun kendi sayfa tabloları grubu). Sonuç, işletim sistemi bellek ayırmak zorunda kaldığında hangi fiziksel sayfaların boş olduğuna bakılmaksızın her işlemin kendi sanal adres alanını görmesidir . Fiziksel belleğe doğrudan erişemediği için başka bir işlemin belleğini asla bilmez.

Sayfa tabloları, normal bellekte depolanan, işletim sistemi tarafından yazılan ancak doğrudan donanım tarafından okunan iç içe geçmiş ağaç benzeri veri yapılarıdır, bu nedenle format sabittir. Özel bir CPU kontrol kaydı üst düzey tabloyu gösterecek şekilde ayarlanarak MMU'ya "yüklenirler". CPU, aramaları hatırlamak için TLB adı verilen bir önbellek kullanır, bu nedenle aynı birkaç sayfaya tekrarlanan erişim, TLB-miss nedenlerinden ve olağan veri önbelleği nedenlerinden dolayı dağınık erişimlerden çok daha hızlıdır. TLB'de önbelleğe alınmamış olsalar bile sayfa tablosu girişlerine atıfta bulunmak için kullanılan "TLB girişi" terimini görmek yaygındır.

Ve bir işlemin sayfalamayı devre dışı bırakabileceğinden veya sayfa tablolarını değiştirebileceğinden endişelenmeniz durumunda: Buna izin verilmez, çünkü x86 ayrıcalık seviyeleri ("halkalar" olarak adlandırılır) uygular ve kullanıcı kodu izin verilemeyecek kadar düşük bir ayrıcalık seviyesinde çalışır. CPU'nun sayfa tablolarını değiştirmek için.

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.