X86 Linux'ta fiziksel adres 0 ne içerir?


12

Bu sorunun buraya mı yoksa reverseengineering.stackexchange.com'a mı gitmesi gerektiğinden emin değilim

Vikipedi'den alıntı :

8086 işlemcisinde kesme tablosuna IVT (kesme vektör tablosu) denir. IVT her zaman bellekte 0x0000 ila 0x03ff arasında aynı yerde bulunur ve 256 dört baytlık gerçek mod uzak göstergesinden oluşur (256 × 4 = 1024 bayt bellek).

Qemu monitörde bulduğum şey bu:

(qemu) xp/128xw 0
0000000000000000: 0xf000ff53 0xf000ff53 0xf000e2c3 0xf000ff53
0000000000000010: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000020: 0xf000fea5 0xf000e987 0xf000d62c 0xf000d62c
0000000000000030: 0xf000d62c 0xf000d62c 0xf000ef57 0xf000d62c
0000000000000040: 0xc0005526 0xf000f84d 0xf000f841 0xf000e3fe
0000000000000050: 0xf000e739 0xf000f859 0xf000e82e 0xf000efd2
0000000000000060: 0xf000d648 0xf000e6f2 0xf000fe6e 0xf000ff53
0000000000000070: 0xf000ff53 0xf000ff53 0xf0006aa4 0xc0008930
0000000000000080: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000090: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000a0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000b0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000c0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000d0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000e0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000f0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000100: 0xf000ec59 0xf000ff53 0xf000ff53 0xc0006730
0000000000000110: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000120: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000130: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000140: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000150: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000160: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000170: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000180: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000000190: 0x00000000 0x00000000 0x00000000 0xf000ff53
00000000000001a0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000001b0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000001c0: 0xf000d611 0xf000ec4e 0xf000ec4e 0xf000ec4e
00000000000001d0: 0xf000d61a 0xf000d623 0xf000d608 0xf000ec4e
00000000000001e0: 0xf000ff53 0x00000000 0xf000ff53 0xf000ff53
00000000000001f0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53

Bu değerleri ne yapacağımdan emin değilim. Bir kesme tanımlayıcı tablosu gibi görünmüyor (bu değerlerin silinmesi tüm null değerlerini verir). Peki aslında burada neye bakıyorum?

Yanıtlar:


9

Ürün yazılımınız ne olursa olsun.

İdeal bir modern sistemde, işlemci bu SSS Soru-Cevap bölümünde açıkladığım gibi hiçbir zaman gerçek moda girmez: Modern 64 bit Intel yonga bilgisayarlar önyükleme sektörünü hangi modda çalıştırır? fiziksel belleğin ilk KiB'si, Johan Myréen'in burada başka bir cevapta yer alması kadar önemsizdir. Ancak birçok modern yazılımın (hala) uyumluluk desteği var , yani

  • Onlar (evet, geri bırakabilirsiniz geri önyükleme programlarında AT / böyle eski tarz PC gibi gerçek mod için yazılır sistem yazılımları çalıştırmak için gerçek moda korumalı moddan, onlar korumalı moduna gerçekdışı modundan doğrudan gittiğini verilen) MBR'ler ve VBR'ler; ve
  • eski gerçek mod ürün yazılımı API'lerini sağlarlar ve söz konusu sistem programlarının güvendiği söz konusu API'ler için tüm veri yapılarını ayarlarlar.

Bu veri yapılarından biri gerçek mod IVT'dir. Eski gerçek mod ürün yazılımı API'ları inttalimatlara dayanır ve gerçek mod IVT, bu talimatlar için çeşitli ürün yazılımı işleme rutinlerine işaretçilerle başlatmanın bir parçası olarak ürün yazılımı tarafından doldurulur.

Korumalı mod sistem yazılımları eski gerçek mod ürün yazılımı API'larına ihtiyaç duymaz ve işlemciyi asla gerçek modda çalıştırmaz, bu nedenle ilk 1KiB fiziksel belleğin gerçek mod IVT'si kullanılmaz. (v8086 korumalı mod, 00000000 ve üzeri fiziksel adreslere yönelik değildir , unutmayın. Sayfa tabloları tarafından çevrilen 00000000 ve üzeri mantıksal adreslere yöneliktir.) Modern EFI sistemlerinde, bellenim fiziksel belleğin bellek haritasını işletim sistemine verir. bootstrap, hangi bölümlerin kendi korumalı mod API amaçları için bellenime ayrıldığını ve işletim sisteminin hangi bölümleri sadece fiziksel bellek havuzu için kullanmakta özgür olduğunu söyler. Teorik olarak, fiziksel belleğin ilk sayfası ikinci kategoride olabilir.

Uygulamada, öncelikle yazılımlar genellikle işletim sistemi, yani "önyükleme hizmetleri kod" olarak fiziksel bellek ilk sayfasını işaretlemek için , iddia ve sadece devam edin ve fiziksel bellek havuzunun bir parçası olarak kullanmak ancak sonra BOOT- EFI ürün yazılımının zaman hizmetleri işletim sistemi tarafından kapatılmıştır ve ürün yazılımı yalnızca çalışma zamanı hizmetlerini sağlamak üzere azaltılmıştır. Bunun bir örneği add_efi_memmapFinnbarr P. Murphy tarafından gösterilen Linux çekirdek günlüğünde ( isteğe bağlı olarak) görülebilir:

[0.000000] efi: mem00: tür = 3, attr = 0xf, aralık = [0x0000000000000000-0x0000000000001000) (0MB)
ki bu xe başka bir programla daha insan tarafından okunabilir bir biçimde çözülür:

[# 00] Tür: EfiBootServicesCode Attr: 0xF
      Fiz: 0000000000000000-0000000000001000
      Fazlası: 0000000000000000-0000000000001000

Uygulamada, ikincisi, ürün yazılımı devam edebileceğini ve kullanabileceğini söylese bile Linux bu fiziksel bellek aralığını açıkça görmezden gelir . Hem EFI hem de EFI olmayan yazılımlarda, Linux fiziksel bellek haritasına sahip olduktan sonra (yama adlı bir işlevdetrim_bios_range ) aşağıdaki gibi çekirdek günlük mesajlarına neden olur:

[0.000000] e820: güncelleme [mem 0x00000000-0x00000fff] kullanılabilir ==> saklıdır

Bu, gerçek mod IVT'nin bellenim API'sinin bir parçası olmadığı modern EFI bellenimleri ile başa çıkmak için çok fazla değildir, çünkü bellenim API'sının bir parçası olduğu eski PC98 bellenimleri ile başa çıkmaktır, ancak bellenimler bunu rapor eder (üzerinden aynı kendi kendine aynı API) işletim sistemi tarafından üzerine yazılması mümkün fiziksel bellek olarak kullanılabilir.

Yani iken fiziksel bellek aralığı o teoride olabilir rasgele kod veya çekirdek bellek allocators ve istenen sayfa sanal belleğin anlık ihtiyaçları sarkan verileri içerir; pratikte Linux, bellenim ilk kurulduğu anda ona dokunulmaz.

Ve sisteminizde bellenim gerçek mod IVT girişleriyle doldurmuştu. Gerçek mod IVT girişleri elbette sadece 16:16 uzak işaretçilerdir ve 2 baytlık bir hexdump kullanarak belleğinize bakarsanız, bunu oldukça net bir şekilde görebilirsiniz. Bazı örnekler:

  • IVT girişlerinizin çoğu, gerçek mod ürün yazılımı ROM alanındaki bir adres olan F000: FF53'ü gösterir. Muhtemelen bir şeyden daha fazlasını yapmayan kukla bir rutindir iret.
  • IVT girişi 1E , aynı ROM alanındaki bir tablo olan F000: 6AA4'ü gösterir.
  • IVT girişi 1F , gerçek mod video ROM ürün yazılımı alanındaki bir tablo olan C000: 8930'u gösterir.
  • IVT girişi 43 , gerçek mod video ROM ürün yazılımı alanındaki başka bir tablo olan C000: 6730'a işaret eder.

daha fazla okuma


Hayır, ne yazdığımı kastediyorum. Intel Mimari Yazılım Geliştiricileri El Kitabı cilt 3 bölüm 20 § 2.
JdeBP

Peki şimdi var, çünkü o; bu bölümün ilk cümlesinin açıkladığı gibi. Bundan "v8086" ortak kısaltmasının tanınmamasının bir tür shibboleth olduğundan şüpheleniyorum. (-:
JdeBP

İlişkili isimlerin nasıl okunacağını öğrenmeniz gerekir. Ya da mantar çorbası olmadan yaşamayı öğrenin.
JdeBP

7

Orijinal 8086 işlemci mimarisi (80286+ işlemcilerde Gerçek Mod olarak uygulanır), Korumalı Mod'da çalışan Linux için hiçbir ilgisi yoktur. Fiziksel adres 0'da kesinti vektör tablosu yoktur, bunun yerine Kesme Tanımlayıcıları içeren bir Kesme Tanımlayıcı Tablosu kullanılır. IDT bellekte herhangi bir yerde bulunabilir.

Linux çekirdeği, bellenimden (BIOS veya EFI) hangi fiziksel bellek sayfası çerçevelerinin kullanılabilir olduğunu ve hangilerinin ayrılmış veya mevcut olmadığını söyleyen bir fiziksel bellek haritası alır. Kullanılabilir sayfa çerçeveleri aralığı bitişik değildir, ancak genellikle içinde büyük delikler vardır. Geleneksel olarak, x86 Linux çekirdeği, kullanılabilir olarak işaretlenmiş olsa bile fiziksel belleğin başlangıcını atlamıştır. Bu nedenle, fiziksel adres 0 Linux çekirdeği tarafından kullanılmaz.


Bu mantıklı. Kullanılmayan sayfada kalan içeriğin ne olduğuna dair bir fikrin var mı?
rhodeo

Google için 53 ffbunun, büyük olasılıkla bellenim veya bir önyükleyici tarafından kurulan bir 8086 Gerçek Mod kesinti vektör tablosu olduğunu ortaya çıkarır.
Johan Myréen

4

Boşaltma hafızası

Sistemin içindeki bellek içeriğini boşaltmak yerine harici olarak yapmak zorunda kalmanın alternatif bir yolu:

$ head /dev/mem | hexdump -C
00000000  53 ff 00 f0 53 ff 00 f0  53 ff 00 f0 53 ff 00 f0  |S...S...S...S...|
00000010  53 ff 00 f0 53 ff 00 f0  cc e9 00 f0 53 ff 00 f0  |S...S.......S...|
00000020  a5 fe 00 f0 87 e9 00 f0  53 ff 00 f0 46 e7 00 f0  |........S...F...|
00000030  46 e7 00 f0 46 e7 00 f0  57 ef 00 f0 53 ff 00 f0  |F...F...W...S...|
00000040  22 00 00 c0 4d f8 00 f0  41 f8 00 f0 fe e3 00 f0  |"...M...A.......|
00000050  39 e7 00 f0 59 f8 00 f0  2e e8 00 f0 d4 ef 00 f0  |9...Y...........|
00000060  a4 f0 00 f0 f2 e6 00 f0  6e fe 00 f0 53 ff 00 f0  |........n...S...|
00000070  ed ef 00 f0 53 ff 00 f0  c7 ef 00 f0 ed 57 00 c0  |....S........W..|
00000080  53 ff 00 f0 53 ff 00 f0  53 ff 00 f0 53 ff 00 f0  |S...S...S...S...|
...
...
000afea0  00 00 00 00 00 00 00 00  aa aa aa 00 aa aa aa 00  |................|
000afeb0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000b0000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
000c0000  55 aa 40 e9 62 0a 00 00  00 00 00 00 00 00 00 00  |U.@.b...........|
000c0010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 49 42  |..............IB|

analiz

000c0000 üzerindeki üst kısım, önyükleyici ile ilgili olabilir. Neden bundan şüpheleneyim ki? Konumdaki 55aah kodu 000c0000, BIOS'un ikincil önyükleyiciyi çalıştırması için tetikleyici gibi şeyler için genellikle bellekte bir işaret olabilir.

Referans: Önyükleme İmzası - BIOS

  ss 1.

Bununla birlikte, bu 55aah'ın c0000h-effffh aralığında olduğu düşünüldüğünde, bu bölümün PNP Genişletme Başlığı olması daha olasıdır:

Referans: BIOS Önyükleme Özellikleri

3.3 PnP Genişletme Başlıklarına Sahip Cihazlar

Seçenek ROM'lu tüm IPL aygıtları, 2k sınırında C0000h ve EFFFFh sistem belleği adresleri arasında bulunan ve 55AAh ile başlayan geçerli bir seçenek ROM başlığı içermelidir. Bir aygıtın önyüklemesi yalnızca bir PnP Genişletme Başlığı varsa kontrol edilebilir. Adresi ofset + 1Ah'daki standart seçenek ROM başlığı içinde bulunan Genişletme Başlığı, cihazı yapılandırmak için kullanılan önemli bilgileri içerir. Ayrıca, BIOS'un aygıttan önyükleme yapmak için çağıracağı aygıtın seçenek ROM'unda (BCV veya BEV) kodlamak için işaretçiler içerir. PnP Genişletme Başlığının yapısı için Ek A'ya bakın. PnP Genişletme Başlığına sahip bir IPL aygıtının önyüklenmesinin iki yolu vardır. Bir BCV veya bir BEV içermelidir.

53ff ...

Başlangıçta 53ffh verilere gelince. Bunun gerçekte ne olduğu bana açık değil. Daha fazla araştırma, BIOS'un MBR'nin önyüklemesi, önyükleme için Linux çekirdeğine teslim edildikten sonra Linux çekirdeğinin yazdığı bir şeydir.

Genellikle, önyükleyici çekirdeği belleğe yükler ve sonra çekirdeğe atlar. Çekirdek daha sonra önyükleyici tarafından kullanılan belleği geri alabilir (zaten işini yapmış olduğundan). Ancak, işletim sistemi kodunu önyükleme sektörüne dahil etmek ve işletim sistemi başladıktan sonra da yerleşik tutmak mümkündür

Daha fazla kazmak Bu paragraf / dev / mem üzerinden Kötü Amaçlı Kod Enjeksiyonu başlıklı bir araştırma makalesinden bu paragrafı bulabildim :

1 mem Cihazı

/ dev / mem, fiziksel olarak adreslenebilir belleğe sürücü arabirimidir. Hem mem hem de kmem'in asıl amacı, çekirdeğin hata ayıklamasına yardımcı olmaktı. Bir adres ofseti seçmek için lseek () kullanarak cihazı normal karakter cihazı gibi kullanabiliriz. Kmem cihazı benzerdir ancak sanal adresleme bağlamında bir çekirdek belleği görüntüsü sağlar. Xorg sunucusu VESA video belleğine erişmek için mem cihazını ve VM86 modunda video modlarını değiştirmek için fiziksel adres 0x00000000'de bulunan BIOS ROM Kesinti Vektör Tablosunu (IVT) kullanır. DOSEMU bunu, çeşitli görevler (disk okumaları, konsola yazdırma, vb.) İçin BIOS Kesmeleri yapabilmek amacıyla BIOS IVT'ye erişmek için de kullanır.

Referanslar

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.