İlk BIOS talimatı neden 0xFFFFFFF0 (RAM'in “üstü”) konumunda?


51

BIOS'un ilk komutunu 0xFFFFFFF0'dan yüklediğini biliyorum, ancak neden bu belirli adres? Bir sürü sorum var ve en azından bazılarında bana yardım edebileceğinizi umuyorum.

Sorularım:

  • İlk BIOS talimatı neden 4 GB RAM'in "en üst kısmında" yer alıyor?
  • Bilgisayarımda yalnızca 1 GB RAM varsa ne olur?
  • 4 GB'tan fazla RAM (örneğin, 8 GB, 16 GB vb.) Olan sistemler?
  • Yığın neden bazı değerlerle başlatıldı (bu durumda, 0xFFFFFFF0'da bulunan bir değer)?

Bunu öğleden sonra okudum ve hala anlamıyorum.


28
Lütfen soru başına bir soru.
Monica ile Hafiflik Yarışları

4
Kabul edilen cevabın bölümlenmiş hafızadan ya da adresleme modlarından bile bahsetmemesini seviyorum ve A20 hattının bile dokunulduğu tek yer yorumlarda.
imallett

Atmel AVR'ler 0 adresinden yürütmeye başlarlar, Freescale HCS08 ise 0xFFFE, iirc'den başlar. Her işlemci ailesinin kendine has özellikleri vardır.
Nick T,

2
@imallett Posterden cevaplarını daha fazla bilgi ile güncellemelerini istemek yerine, burada şikayet etmeye nasıl karar verdiğini seviyorum. Ayrıca, bir soru sormanın amacı, şu anda tam olarak anlayabilecek şeyler hakkında bilgi edinmek olsa bile, OP'nin bu bilgiyi nasıl tespit edebileceğini düşündüğünüzü de seviyorum.
MonkeyZeus,

2
@MonkeyZeus, şu ana kadar 9 yorum yapan daha bunu yaptı ve hala değişmedi. Benim yorumum alaycı iken boş değildi; Gelecekteki netizenlere ve OP'ye bir uyarıdır.
imallett

Yanıtlar:


57

0xFFFFFFF0x86 uyumlu bir CPU açıldığında talimatları çalıştırmaya başlar. İşlemcinin kablolu, değiştirilemez (ekstra donanım olmadan) özelliği ve farklı tipteki CPU'lar farklı davranır.

İlk BIOS talimatı neden 4 GB RAM'in "en üst kısmında" yer alıyor?

4 GB adres alanının "üstünde" bulunur - açılışta BIOS veya UEFI ROM bu adreslerin okumalarına cevap verecek şekilde ayarlanmıştır.

Bunun neden olduğu konusundaki teorim:

Programlamadaki hemen hemen her şey bitişik adreslerle daha iyi çalışır. CPU tasarımcısı, bir sistem kurucunun CPU ile ne yapmak istediğini bilmediğinden, CPU'nun alanın ortasında adreslerin bozulmasını gerektirmesi kötü bir fikir olabilir. Bunu adres yolunun üstünde veya altında "yoldan uzak tutmak" daha iyidir. Tabii ki, 8086 bir yoktu ki, yeni iken bu karar alındı akılda tutmak MMU'yu .

8086'da, kesme vektörleri 0 ve üstü bellek lokasyonlarında vardı. Kesinti vektörlerinin bilinen adreslerde olması ve esneklik için RAM'de olması istenmiştir - ancak CPU tasarımcısının bir sistemde ne kadar RAM olacağını bilmesi mümkün değildi. Bu yüzden 0'dan başlamak ve çalışmak onlar için anlamlıydı (8086'nın icat edildiği 1978'de hiçbir sistem 4 Gbyte RAM'e sahip olamazdı - bu nedenle RAM'in 0xFFFFFFF0'da olmasını beklemek iyi bir fikir değildi) ve ROM'un olması gerekiyordu. üst sınırda.

Tabii ki, en azından 80286'dan başlayarak, kesme vektörleri 0'dan farklı bir başlangıç ​​konumuna taşınabilir, ancak modern 64-bit x86 CPU'lar hala 8086 modunda önyüklenir, bu nedenle her şey hala uyumluluk için eskiden işe yarar (saçma gibi) 2015 yılında göründüğü gibi hala DOS'u çalıştırabilmek için x86 işlemcinize ihtiyaç duyuyor).

Böylelikle kesme vektörleri 0'dan başlayıp yukarı doğru çalıştığından, ROM üstten başlamalı ve aşağı doğru çalışmalıdır.

Bilgisayarımda yalnızca 1 GB RAM varsa ne olur?

32-bit bir CPU, 0 (0x00000000) ila 4294967295 (0xFFFFFFFF) numaralı 4,294,967,296 adrese sahiptir. ROM bazı adreslerde yaşayabilir ve RAM bazılarında yaşayabilir. CPU'nun MMU'sı ile bu bile anında açılabilir. RAM tüm adreslerde yaşamak zorunda değildir.

Yalnızca 1 GB RAM’le, bazı adreslerin okunduğunda veya yazıldığında yanıt vereceği bir şey olmaz. Bu, bu adreslere erişildiğinde veya bir sistem kilitlendiğinde geçersiz verilerin okunmasına neden olabilir.

Peki ya 4 GB'tan fazla RAM (örneğin: 8 GB, 16 GB vb.) Sistemler?

Biraz basit tutmak: 64-bit CPU'lar daha fazla adrese sahiptir (bu, onları 64-bit yapan şeylerden biridir - örneğin 0x0000000000000000 - 0xFFFFFFFFFFFFFFFFFF), bu yüzden ekstra RAM "uyuyor". CPU'nun uzun modda olduğunu varsayalım . O zamana kadar RAM orada, sadece adreslenebilir değil.

Neden yığın bir değerle başlatılıyor (bu durumda, 0xFFFFFFF0'da bulunan bir değer)?

X86'nın açılışta yığın işaretçisini atadığı şey hakkında hemen bir şey bulamıyorum, ancak sonuçta sistemde ne kadar RAM olduğunu öğrendiğinde, bir başlatma rutini tarafından atanması gerekir. (Aşağıdaki yorumlarda bulunan @Eric Towers, açılışta sıfıra ayarlandığını bildirmektedir.)


7
Adres alanını, şeylerin donanım tarafından atanabileceği büyük bir alan olarak düşünmek en iyisidir. CPU belleği okuduğunda / yazdığında, aslında bir veri yolu üzerinden iletişim kurar ve donanım RAM veya ROM gibi şeylerin belirli adres aralıklarında yanıt verdiğinden emin olabilir. Bu yüzden böyle bir donanım CPU sıfırlandığında bir ROM'un 0xFFFFFFF0'da yanıt verdiğinden emin olmak zorundadır. ROM'un RAM'den hemen sonra ortaya çıkması gibi bir zorunluluk yoktur. Bu donanımın özelliklerine bağlı olarak, donanımın söylediği her yerde görünebilir.
LawrenceC

4
ROM, RAM veya başka herhangi bir şey tarafından kullanılmayan "delikler" veya atanmamış alanlara sahip olmak mümkündür - genellikle bunlara erişmek sistemin kilitlenmesine neden olur.
LawrenceC

16
Bu cevap CPU'nun 16 bit modunda 32 adres bitini kullanabileceğini varsayar. Ancak 16 bit modunda yalnızca 20 adres bitini kullanabilir. 0xFFFFFFF0CPU 32 bit moda geçinceye kadar adrese erişilemiyor. BIOS koduna en son baktığımda giriş noktası idi 0xFFFF0.
kasperd

6
@ MichaelKjörling hesaplamanız yanlış. Değişen segment ve ofset ORed değildir, eklenirler. Bu nedenle, mantıksal FFFF: FFF0 fizikseldir (1) 0FFE0 (A20 etkinse, öncü 1'in olduğu yerde).
Ruslan

9
@ kasperd Burada bir kesmek var - bellek yöneticisi ilk uzun atlama gerçekleşene kadar 1 olarak ayarlanmış en yüksek 12 bit'e sahip. Yani evet, mantıksal olarak çalışıyorsunuz 0xFFFF0, ama gerçekte, bununla eşleşiyor 0xFFFFFFF0. Bunun 8086 ile uyumluluk için yapılmasını bekliyorum - hem onun hem de daha modern CPU'ların kullandığı görülüyor0xFFFF0 , ancak 32-bit CPU'lar gerçekten erişiyor 0xFFFFFFF0(BIOS ROM ile eşleştirildi).
Luaan

26

RAM'in tepesinde bulunmuyor; Ethernet denetleyicileri gibi, genişletme kartlarındaki tüm belleklerle birlikte, adresleri bellek adres alanının en üstünde bulunan ROM'da bulunur. En azından 4 GB kurulu olana kadar RAM ile çakışmayacak şekilde oradadır. 4 GB veya daha fazla RAM'e sahip sistemler, çatışmayı çözmek için iki şey yapabilir. Ucuz anakartlar RAM'in ROM'un bulunduğu yerle çatışan kısımlarını görmezden geliyor. Terbiyeli olanlar, RAM’in 4 GB’ın üzerindeki bir adres gibi göründüğünü gösteriyor.

Yığın hakkında ne istediğinden emin değilim. ROM'da olduğu için kesinlikle başlatılmadı. CPU sıfırlandığında, başlangıçta "gerçek modda" olduğu gibi, orijinal 8086 gibi davranır ve yalnızca 1 MB belleğe erişmesine izin vererek, 16 bit segmentli adresleme kullanır. BIOS kodu bu 1 MB’ın üst kısmında bulunur. BIOS, yığını ayarlamak için RAM'de bir yere alır ve ilk önyüklenebilir sürücünün ilk kesimini yükler ve yürütür. Devraldıktan ve kendi yığınlarını (görev / iş başına bir tane) ayarladıktan sonra 32 veya 64 bit moduna geçmek OS'ye bağlıdır.


1
Cevap için çok teşekkür ederim, ama @LawrenceC cevabı hakkında daha fazla ayrıntı verdi ve her şeyin nasıl çalıştığı konusunda bana yardımcı oldu. Neyse, teşekkür ederim! Sana bir oy verdim: 3
Fernando Paladini

13

İlk olarak, bunun RAM ile ilgisi yok, gerçekten. Burada adres alanından bahsediyoruz - yalnızca 16 MiB belleğiniz olsa bile, 32 bitlik bir CPU'da hala 32 bit adres alanına sahipsin.

Bu zaten ilk sorunuzu yanıtlıyor, gerçekten - bu tasarlandığında, gerçek dünya bilgisayarlarının tam 4 GiB belleğe yakın hiçbir yeri yoktu; daha çok 1-16 MiB bellek aralığındaydı. Adres alanı, tüm amaç ve amaçlar için serbest kaldı.

Şimdi, neden tam olarak 0xFFFFFFF0? CPU ne kadar BIOS olduğunu bilmiyor. Bazı BIOS'lar yalnızca birkaç kilobayt sürebilirken, diğerleri tam megabayt bellek alabilir - ve isteğe bağlı olarak çeşitli RAM'lere bile giremiyorum. İşlemcinin başlayabilmesi için bir adrese bağlanmış olması gerekir - işlemciyi yapılandıracak bir yer yoktur. Ancak bu yalnızca adres alanının eşleşmesidir - adres doğrudan BIOS ROM yongasına eşlenir (evet, bu sayede 4 GiB RAM'in tamamına erişemezsiniz.) bu özel bir şey değil, birçok cihaz adres alanında kendi aralığını gerektiriyor). 32-bit bir işlemcide, bu adres size çok temel başlatma işlemini yapmak için tam 16 bayt verir - bu da segmentlerinizi ve gerekirse adres modunu ayarlamak için yeterlidir (unutmayın,Gerçek önyükleme "yordam". Bu noktada, hiç RAM kullanmazsınız - hepsi sadece eşlenmiş ROM'dur. Aslında, RAM bu noktada kullanıma hazır bile değil - bu BIOS POST'un işlerinden biri! Şimdi, düşünüyor olabilirsiniz - 16 bitlik bir gerçek mod 0xFFFFFFF0 adresine nasıl erişir? Elbette, segmentler var, yani 20 bitlik adres alanınız var, ama bu hala yeterince iyi değil. Eh, bir hile var - adresin 12 yüksek biti ilk uzun atlayışınızı gerçekleştirene kadar ayarlanır, yüksek adres alanına erişmenize izin verir (0xFFF00000'den daha düşük herhangi bir şeye erişimi reddederken - uzun bir atlayış yapana kadar) .

Bütün bunlar, modern işletim sistemlerinde çoğunlukla programcılardan (kullanıcılardan bahsetmiyorum bile) gizlenen şeylerdir. Genelde bu kadar düşük seviyeli hiçbir şeye erişiminiz yoktur - bazı şeyler zaten kurtarılmayacak kadar yüksektir (CPU modlarını değiştiremezsiniz), bazıları sadece işletim sistemi çekirdeği tarafından yönetilir.

Bu yüzden daha eski bir görünüm MS DOS üzerindeki eski okul kodlamasından geliyor. Doğrudan adres alanına eşlenen cihaz belleğinin başka bir tipik örneği video belleğine doğrudan erişimdir. Örneğin, ekrana hızlı bir şekilde metin yazmak istiyorsanız, doğrudan adrese B800:0000yazdınız (artı ofset - 80x25 metin modunda, bu, (y * 80 + x) * 2hafızamın bana doğru hizmet etmesi durumunda - her karakter için iki bayt, satır satır). Piksel piksel çizmek istiyorsanız, bir grafik modu ve başlangıç ​​adresini A000:0000(tipik olarak piksel başına 8 bit olarak 320x200) kullandınız. Yüksek performanslı herhangi bir şey yapmak, doğrudan nasıl erişileceğini bulmak için genellikle cihaz kılavuzlarına dalmak anlamına gelir.

Bu, bu güne kadar hayatta kalır - sadece gizlidir. Windows'ta, Aygıt yöneticisindeki aygıtlarla eşlenen bellek adreslerini görebilirsiniz - yalnızca ağ kartınız gibi bir şeyin özelliklerini açın, Kaynaklar sekmesine gidin - tüm Bellek Aralığı öğeleri aygıt belleğinden ana adres alanınıza eşleme yapar. Ve 32-bit'de, bu cihazların çoğunun, kullanıcının kullanabileceği hafıza ile olan çatışmaları en aza indirgemek için 2 GiB (daha sonra 3 GiB) işaretinin üzerinde eşlendiğini göreceksiniz, ancak bu gerçekten sanal hafıza ile ilgili bir sorun değil ( uygulamalar gerçek, donanım adres alanının yakınında hiçbir yere ulaşamazlar - örneğin RAM, ROM, aygıtlar veya sayfa dosyasına eşlenebilecek kendi sanallaştırılmış bellek yığınlarına sahiptirler).

Yığın gelince, varsayılan olarak, yığının üstten büyüdüğünü anlamak için yardımcı olmalıdır. Yani, eğer yaparsanız push, yeni yığın işaretçisi olacaktır 0xFFFFFEC- başka bir deyişle, BIOS init adresine yazmaya çalışmazsınız :) Tabii ki, BIOS init yordamları, yeniden göndermeden önce yığını güvenle kullanabileceği anlamına gelir. daha kullanışlı bir yer. Eski okul programlarında, disk belleği fiili varsayılan hale gelmeden önce, yığın genellikle RAM'in sonunda başladı ve uygulama belleğinizin üzerine yazmaya başladığınızda "yığın taşması" gerçekleşti. Bellek koruması bundan çok değişti, ancak genel olarak mümkün olduğunca geriye dönük uyumluluğu koruyor - en modern x86-64 işlemcinin bile MS DOS 5'i nasıl önyükleyebileceğini unutmayın - Windows nasıl disk belleği hakkında hiçbir fikri olmayan birçok DOS uygulamasını çalıştırabilir.


3
Mükemmel yanıt, sadece genişletmek ve modern işlemcilerin A20 hattı maskeleme gibi saldırıları düşürmeye başladığını söylemek için, bu nedenle daha eski kenar durumlarda destek ölüyor.
Temel

2
Son paragrafa göre: BIOS "serbestçe" yığınını kullanamaz: ROM'a yazamaz ( 0xFFFFFFECharitalanacak). Bu sadece hayır demek değil push, örneğin hayır demek call. Bunlar RAM hazır olana kadar beklemeliler.
Vee

7

Bahsedilen diğer noktalara ek olarak, bir adres anlamaya yardımcı olabilir olduğunu . Yeni mimariler işleri karmaşıklaştırırken, tarihsel olarak bir makine her bir hafıza döngüsünde 20 ila 32 kabloya istenen adresi verir (mimariye bağlı olarak, aynı anda bir çift ya da dörtlü bayta ihtiyaç duyulup duyulmadığını not etmek için bazı özel numaralar); bellek sisteminin çeşitli kısımları, bu kabloların durumunu inceler ve yüksek ve düşük değerlerin belirli kombinasyonlarını gördüklerinde kendilerini aktive ederler.

32 adresli bir makinenin yalnızca 1MB RAM ve 64KB ROM [bazı yerleşik denetleyiciler için oldukça uygun] kullanması gerekiyorsa, üst adres kablosunun düşük olduğu tüm adresler için RAM'i ve bulunduğu adreslerin tümü için ROM'u etkinleştirebilir. yüksek. Alttaki 20 adres teli 1.048.576 bayttan birini seçmek için RAM'e bağlanır ve alt 16, 65.536 bayttan birini seçmek için ROM'a da bağlanır. Kalan 11 adres teli hiçbir şeye bağlanmayacaktır.

Böyle bir makinede, 0x00100000-0x001FFFFF adreslerine erişen RAM adreslerine erişen 0x00000000-0x000FFFFF ile aynı olacaktır. Aynı şekilde, 0x000200000-0x0002FFFFF veya 0x7FF00000-0x7FFFFFFFF adresleriyle. 0x80000000 üzerindeki adresler ROM'u okuyacak ve alan boyunca yinelenen 64K deseniyle ROM'u okuyacaktır.

İşlemcinin 4.294.967.296 baytlık bir adres alanına sahip olmasına rağmen, donanımın birçok farklı adresleri tanımasına gerek yoktur. Sıfırlama vektörünü adres alanının üstüne koymak, sistemin ne kadar az RAM ve ROM'a sahip olduğuna ve adres alanının tamamen kodunu çözme ihtiyacından kaçınılmasına bakmaksızın çalışacak bir tasarımdır.


İyi nokta - Adreslenebilir 64 bit bellek alanına yakın olan herhangi bir şeyi (veya hatta 1x10 ^ -12) destekleyecek herhangi bir 64 bit donanım bulamazsınız.
Temel

3

Teorim, çünkü negatif bir mantık kullanıyoruz; dijital olan (1) hiç gergin değil (O volt) Başlangıçtaki son 4 bit üzerine gerginlik koymamız gerekiyor, böylelikle program sayacı (veya Talimat göstericisi) 1111 1111’de 1111 1111 1111 1111 1111 0000. En üstteki 28 bit ile uğraşmak zorunda değiliz çünkü çoğu (eski) cpu'nun) 16 bit idi ve alt çentikler eski günlerde tek bir adres çipiyle ele alınabiliyordu. Şimdi 32 bit ile 32 bit ve 16 bit ile 16 bit arasında uyumlu 64 bitimiz olduğundan, donanım desteği geliştirilmiştir, ancak yöntem devam eder. Ayrıca biyolojik sistemler her zaman 64 bit veya 32 bit programlanmış değildir. Benim düşünceme göre, hatıralar her zaman aynı olmadığı için, biyografilerin aynı ilk segmentte bulunması gerekir. Biyografileri ele aldığımız yol her zaman gerçek adres değil. Sadece bana öğretti ...


2

RESET üzerine 8088/8086 uyumlu bir cpu, 1 megabayt sınırının 16 bayt altında olan 0FFFF0'da talimatları yürütür. normalde bu konumdaki ROM (PC uygulamalarında) BIOS olacaktır, bu nedenle BIOS ROM'un sonunda, BIOS rom'unun başlangıcına bir sıçrama olur.

burada gösterilir: vektörü başlat ve arkasındaki 'tarih' imzası, IBM 5150 PC 8KB eprom döküm bios tarihi: 10/19/1981

00001FEE  FF                db 0xff
00001FEF  FF                db 0xff
00001FF0  EA5BE000F0        jmp word 0xf000:0xe05b
00001FF5  3130              xor [bx+si],si
00001FF7  2F                das
00001FF8  3139              xor [bx+di],di

adreslemenin 8KB $ 2000 rom olduğunu unutmayın; başlangıç ​​adresini (JMP için mutlak uzak olan JMP, hangisi olursa olsun, bu durumda bu durumda 8KB rom içerisinde, bu rom içinde mümkün olan en düşük adres olmasa da) $ FFFF: $ 0 bölümlenmiş veya $ FFFF0 linear.

Uyumluluk gelince: eğer bir 'gelecek' ya da mevcut işlemci 'adresin önünde çok daha fazla F'ye sahip olmasını beklerse, önemli değil. Daha yeni cpus'ların eski sistemlerde uyumluluğu için, ek adres satırları bağlantısız kalır ve bu nedenle veri tabanındaki veriler tamamen aynıdır. En az önemli bit FFFF0 kaldığı sürece.

(sadece 1mb ram ve rom bu ramın sonuna yerleştirilmiş olan bir sistemde ve başka hiçbir şey olmadan, mutlu bir şekilde daha yüksek bir adresle konuştuğunu düşünecek, ancak aynı verileri aldıklarını çünkü bu uygulamaların hiç duymadığı adres satırları A19'dan yüksek olan)

Dünyanın sadece 'adet' olmadığını unutmayın ... IBM PC bir 'kazaydı', bu işlemciler hiçbir zaman 'adet' için özel olarak tasarlanmamıştır ve sadece adetlerden (uydu gibi silah sistemleri vb. 32 ve 64bit korumalı mod genellikle istenmez. (sanal 8086 modu, örneğin daha yeni bir sürüm (386+) seçmek için bir neden olarak çok daha ilginç). bu nedenle “geriye dönük uyumluluk” ile ilgili olarak “sadece dos çalıştırır” dan çok daha fazlası var.


1

Anakart, sıfırlama vektöründeki komutun BIOS giriş noktasına eşlenmiş olan hafıza konumuna bir atlayış olmasını sağlar. Bu sıçrama, açılışta bulunan gizli ana adresi dolaylı olarak temizler. Bu bellek konumlarının tümü, yonga kümesi tarafından tutulan bellek haritası sayesinde CPU tarafından ihtiyaç duyulan doğru içeriğe sahiptir. Hepsi RAM içeren modüller ile eşleştirilir, çünkü bu noktada RAM modülleri rasgele zırvalara sahiptir.

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.