"Booting" kelimesi ile
bilgisayarın başlatılması için kullanılan alışılmış bir terim.
"Bootstrapping" kelimesinin kısa formu. "Bootstrap" sözlükte
başkalarının yardımı olmadan kendi kendini idame ettirmek gibi bir kaç anlamı
var ama buraya en uygun olanı şu olabilir: En az kaynakla bir şey yaratma,
oluşturma, başlatma yaklaşımı. Bilgisayar terimi olarak, bir programı
çalıştırmak için(genelde bir işletim sistemini veya mini bir çekirdeği) önce
daha küçük bir program yükleyeme süreci.
Boot süreci sonunda, kernel hafızaya yüklenir ve çalışmaya
hazır hale gelir, önceliği yüksek programlar, başlangıç betikleri
çalıştırılır ve sistem kullanıcılar için hazır hale getirilir. Aşağıdaki
şemada bunun genel bir özetini görebilirsiniz:
Bir bilgisayar en kaba tabirle; üzerindeki işlemcinin,
hafızadaki(RAM) adreslerin içindeki ikili kodu, sırayla anlamlandırıp
çalıştıran bir cihaz. Tanım basit olsada burda bir kaç problem var. İşlemci
sağına soluna takılmış donanımları nasıl tanıyacak, hafızasında(RAM) henüz hiç
birşey yok; çalıştıracağı programı nerde arayacak; bu bilgisayarın ekranı
varmı; ekranı varsa ne tür bir ekran; klavye fare varmı, varsa ne tür;
sabit disk varmı ve ne tür vs şeklinde bir sürü farklı türde kombinasyonla
tasarlanmış bir bilgisayar olabilir. Aynı işlemciyi kullanan binlerce farklı
bilgisayar üreticisi var ve bir okadar bilgisayar modeli. Üstelik bunların
üzreinde çalışacak işletim sistemi türleride bir tane değil. Burdaki temel
problemi biraz fark etmiş olmamız gerek. Bir bilgisayarda üreticisinin yazdığı
bir firmware(firm-software) bulunduran
BIOS(Basic Input/Output System) çipine neden ihtiyaç duymuşlar işte bu
yüzden. Yani üretici benim yazdığım kodu(öncelikle bir işletim sistemi)
bilgisayarın hafızasına yükleyebilmem için bana bir yol vermeli ve ilk aşamada
hakkında hiçbirşey bilmediğim bu sistem hakkında bazı bilgiler sunabilmeli.
(bios olmadan çalışan sistemler şu an için ilgi alanımıza girmiyor. bios yoksa
yine bu işi yapabilmem için bir yol sunulur belki sonraki yazılarda bir seri
ekleyebiliriz bu serinin ardına.)
İlk olarak şunu bilmeliyiz: Bir 80386 işlemcisi çalışmaya başladığında 0xFFFF_FFF0 adresine gider. Yani
doğal fiziksel hafızanın nerdeyse sonuna ama tam sonuna değil
16 byte (veya 16 tane adres) gerisine. (farklı işlemciler için ilk komut için
işlemcinin hangi adreslere gittiğini merak ederseniz şuraya bakabilirsiniz:
https://en.wikipedia.org/wiki/Reset_vector) Burada işlemcinin üreticisi, ilk çalışma anında hafızanın başına gidecek
şekilde de tasarım yapmış olabilir, sonunada ortasınada. ARM işlemcileri için
başına yani 0x0 veya 0xFFFF0000 adresine gidiyor olduğu gibi. Önemli olan
bunun üreticinin insiyatifinde olduğunu bilmemiz.
8086/88 işlemcileri, 16 bit veri
yolu(data width), 20 bit adres yolu genişliği (adress width)
80286 işlemcileri,
16 bit veri yolu genişliği, 24 bit adres yolu
genişliği
80386
32 bit veri yolu genişliği, 32 bit adres
yolu genişliği
8086/88: CS:IP = FFFF:0000 first instruction at FFFF0
80186/188: CS:IP = FFFF:0000 first instruction at FFFF0
80286: CS:IP = F000:FFF0 first instruction at
FFFF0
80386: CS:IP = 0000:0000FFF0 or F000:0000FFF0[1], first
instruction at FFFFFFF0
80486+: CS:IP = F000:0000FFF0(?) first instruction at FFFFFFF0
Yukarıdaki şema bilgisayar mimarileri ile
ilgilenenler için yabancı gelmeyecektir. Kısaca açıklayacak olursak; (A1 ve
A0) adres yolu, (D0,D1,D2,D3) ise data yolu. Kontrol yolu ise OKU ve YAZ
oluyor.
İki tane adres yolu hattı (A0,A1) ile olarak 2^2=4 adet bellek gözünü
seçebiliriz. Yukarıdaki resim temsili olanın da temsili gibi. Gerçekten nasıl
bir yapı olduğu anlamak için mimarilere bakmanız gerek. (İşlemcinin mimarisi,
bus mimarisi; çipsetler, northbridge, southbridge, dma vs....)
Dolayısıyla fiziksel sınırımız kabaca(!) şöyle eğer bir işlemcinin
adress yolu genişliği 32 bit ise, 2^32 adet bellek gözünü seçebiliriz.
(1 bellek gözü :8 bit , günümüzde böyle... en küçük hafıza birimi 1 byte
yani 8 bit oluyor, bir adrese ulaştığımızda 8 bit birden muhatabımız oluyor
yani. Tek bir bit-e doğrudan bir adres yardımıyla ulaşamıyoruz bu yüzden.) Haliyle 2^32 byte (4GB) veri tutabilen bir hafızayı kontrol
edebiliyor işlemcimiz.
Yine en basit haliyle, adress bus, data bus, control bus ve işlemci
arasında aşağıdaki gibi bir ilişki vardır. Mimarilerin detaylarını atlıyoruz.
Yani işlemci ana belleğe, biosa, giriş çıkış birimlerine vs bu üç temel hattı
kullanarak ulaşır. İşlemci adresleme kapasitesi bu birimlere paylaştırılır.
Burada işlemcinin ilk çalışma anında üretici tarafından belirlenmiş bir adrese
gittiğini biliyoruz.
Bu adres RAM üzerinde olmamalı çünkü ilk çalışma anında RAM bomboş
olacak. Bu adres bios ROM üzerine yönlendirilir veya map edilir. Bu işi en basit
haliyle şöyle yapabiliriz:
Yukarıdaki resimde 8bitlik data hattı(D0-D7) , 20 bitlik adres
hattı(A0-A19) görüyoruz. Hafıza çipinin etkinleşmesi için A16-A19 adres hattı
pinleri 0 olmalı A15 pinide 1 olmalı. Yani diğer bir değişle adres aralığı
0x0800H ile 0xFFFFH aralığında ki adresler bu çipe uğruyor demek oluyor.
Eğer bu çip bir bios un hafıza çipi ise (üzerine yazılabilen türden çünkü
yazma kontrol hattı da bağlı) demekki bu adres aralığı RAM çipine değilde
bios çipine gidiyor denebilir. Bu bir adres aralığının bilgisayarın üreticisi tarafından, ilgili çip için
donanımsal olarak tanımlandığını gösterir. Tasarıma göre bu programlanabilen
bir kontrol çipide olabilir. Bu durumda ilk çalışma anında bios çipine gitmesi
sonra RAM çipine gitmesi programlanabilir. (
kaynaklar kısmından, 80x86 IBM PC
and Compatible ... kitabına bakabilirsiniz detay için: ch10- ch11). Bu yönteme
memory adress decoding, benzer şekilde I/O için I/O adress decoding deniyor.
Bu sayfada
bir kendi 8086 bilgisayarını yap kiti var. Şemasını incelerseniz I/O ve
Memory decoding işini GAL22V10 pld çipi ile yaptığını görebilirsiniz.
Yukarıdaki gibi veya basit bir 74 serisi decoder kullanarak
tasarlanabilir.
Intel 8088/8086 referans dökümanından aşağıdaki tasarım
örneğini inceleyebilirsiniz.
Yakın dönem tasarımların şemalarına
bakarsanız, Memory Controller Hub(MCH) ve I/O Controller Hub(ICH), veya Nort
Bridge ve South Bridge gibi isimler görürsünüz. İşlemci ve adresteki hedef
arasında neler var, hangi yol izlenir, çeşitli yapılar için hangi birimler
farklı aşağıdaki bir kaç farklı şemadan inceleyebilirsiniz.
Yani yukardaki 3 temel hat aradaki bu yapılar yardımıyla biosu, klavye,
fare, ram gibi bileşenlere nasıl map ediliyor, nasıl yönlendiriliyor görmek
isterseniz:
Veya şöyle bir tasarım olabilir...
veya
veya
Ayrıca "
The Indispensable PC Hardware Book" kitabını
inceleyebilirsiniz, bütün bir x86 referans dökümanlarını incelemektense daha
hızlı fikir verebilecek bir kitap. Real mode,
wrap-around,
protected mode,
memory segment,
memory map-shadow-paging,
I/O map vs birçok konuyu donanımla iç
içe şekilde anlatır.
Şimdi Intel işlemcilerin referans dökümanlarına biraz göz
atabiliriz. 8086, 80286 ve tabiki 80386 öncelikle incelememiz gereken
işlemciler. Çünkü birbirine oldukça yakın ve real mode ile protected mode
arasındaki değişimi ilk göreceğiniz örnek.
80286 öncesi işlemcilerde real mode haricinde bir mod yok, işlemci bir
adresle ilgileniyorsa bu ram üzerinde fiziksel bir alana karşılık geliyor
yani.
Protected mode ilk defa 80286 ile beraber bahis konusu oluyor. Sonraki
işlemcilerde de başka modlar ekleniyor. Bu yüzden sadece bu iki işlemcinin referans dökümanında ilgili yerlere
bakarak ilk çalışma anında gittikleri adresleri ve register durumlarını
görmemiz önemli.
8086 işlemcinin ilk çalışma anında register durumu burda CS:IP = FFFF:0000
adresi (FFFF<<4)+(0000 )=FFFF0 oluyor, dolayısıyla ilk çalışma anında
bu adrese gidiyor. Bu adresin neden böyle hesaplandığına 80286 ve 80386
içinde ilk çalışma anında register durumlarını gösteren tabloyu ekleyelim
sonra detaylarına bakalım.
80286 için register durumları şöyle:
bu iki parçayı olduğu gibi kopyaladım bizim için önemli
Son Olarak
80386 için (aslında 386DX, bu be sonrası işlemcileri referans
dökümanları daha yakın)
Biraz uzattık ama yukardaki bilgiler
işlemcilerin modlarını ve adreslerle ilgili konuları incelerken işimizi
kolaylaştıracak. Sonuç olarak mimari nasıl olursa olsun, üreticisi bize ilk
çalışma anında işlemcinin nereye gittiğini veya oraya gitmesi için ne yapmamız
gerektiğini söylemek zorunda.
Aşağıdaki tasarım için, BIOS a giden yolda: northbridge
sponsorluğunda, DMI, southbridge, LPC nin iş yaptığını görebilirsiniz:
x86 uyumlu
bütün işlemciler
real mode
denen bir modda çalışmaya başlarlar. Real Mode x86-uyumlu,
8086 işlemcilerinden bu günün modern intel 64-bit işlemcilerine kadar
desteklenir. Bu modun bazı sınırları ve özelikleri var onları anlamaya
çalışalım. Öncelikle bu modda bir adres hafızada doğrudan fiziksel bir yere
erişir.
8086
işlemcisi 20-bit genişliğinde bir adres yoluna sahiptir. Dolayısıyla bu
işlemci 0x0 ile 0xF_FFFF arasında
1 megabyte adres alanıyla çalışır.
Ama yukarda da bahsettiğimiz gibi
16-bit register-ları vardır ve bu
yüzden bir register-ın tutabileceği maximum adres değeri 2^16-1 yada
hexadecimal olarak 0xFFFF(1111 1111 1111 1111) dir; ve 16 bit adres aralığı 64
kilobyte hafıza segmentini işaret edebilir. Bu 16 bit register-larla 1MB lık
potansiyel hafızayı yönetebilmek için
memory segmentation denilen bir
yöntem kullanılmış.
Memory segmentation yönteminde adres iki parçadan oluşur:
Segment Selector ve
Offset. Örneğin 0X
F_
FFFF adresinin ilk 16 bitlik kısmı
bir
Offset, geriye kalan kısmı ise
Segment Selector olur. Şöyle iki
parça arasına iki nokta konarak gösterilir: 000F:FFF . Bu adresi bulmak çin
[(segment<<4) + offset] şeklinde hesaplanarak bulunur. 4 bit sola
kaydırmak la decimal 16( 10h) ile çarpmak aynı şey dolayısıyla (segment*16
+offset) şeklinde de hesaplanabilir. Teorik olarak bu yöntemde 1 MB
hafızadan daha büyük hafıza alanına da erişilebilir. Örneğin FFFF:FFFF =>
0x10FFEF ama bu adres 8086 işlemcileri için 21. adres hattının olmasını
gerektirir ki 20 adettir. Dolayısıyla adresin en başındaki (1) yok sayılır.
Bu durumda adres 0x0FFEF haline gelir. Bu şu demektir 0x10FFEF=0xFFEF (!).
Bu durum wrap-around olarak literatüre geçirilimiş, inceleyebilirsiniz. 80286 işlemcinin 24
bit adres hattı olduğunu biliyoruz dolayısıyla Real modda 1 MB adres
alanından daha fazlasına ulaşabileceğimiz anlamına gelir. Tam da burayla
ilgili A20 etkinleştirmesi meselesi ortaya çıkar. Protected Mode
meselesine geldiğimizde detayları anlatalım merak edenler için(wrap-around)
Segmentasyon meselesini geçtiğimize göre 8086 developer's
reference dökümanına bakarsak işlemci reset durumundaki register durumları gereği: CS:IP = FFFF:0000 adresine gitmesi gerektiğini görürüz. Bu adres yukardaki gibi hesaplandığında 0XF_FFF0 adresini verir. Ve bu adres yukarda bahsettiğimiz decode yöntemi gibi gibi bir yöntemle bios çipine ulaşacak şekilde decode edilir.
80286 için CS:IP =F000:FFF0 => 0xF_FFF0 adresini verir. CS ve IP registerlarının değerleri farklı olsa da yine aynı adrese ulaştık. Burada dikkat etmemiz gereken bir konu var. Yukarda referans dökümanlarından aldığım ve altını çizdiğim yerleri okursanız aslında bu adresin gizli bir base adress kısmı var. Yani bu adres aslında 0xF_FFF0 değil 0xFF_FFFF adresi(24 bitlik bir adres). Burada descriptor table denen bir konudan bahsetmemiz gerekecek ama şimdilik sadece bahsedip geçelim. Protected mode konusunu uygulamalı anlatırken buraya tekrar döneceğiz.
80386 için CS:IP=F000:FFF0 => 0xF_FFF0 yine aynı adrese ulaştık. Ama bu adreste aslında 286 da olduğu gibi gizli bir base adress le geliyor. Yani bu adres aslında 0xFFFF_FFFF(32 bitlik bir adres). Ve bu base adreslerin ilk CS register ile işlem yapıldığında(örneğin bir far jump) 286 için en önemli 4 biti, 386 için en önemli 12 biti temizleniyor yani sıfırlanıyor. Burayıda uygulama kısmında canlı olarak qemu üzerinde göreceğiz. Şimdilik sadece bahsetmeden geçemeyeceğimiz için değinmiş olalım.
Peki şimdilik detayları atlayarak bile zorda olsa biosdaki bu adrese
ulaştık. Peki bu adreste ne var? Bunu uygulamalı olarak birazda tersine mühendislikle inceleyelim.
Kaynaklar
1.Jim Ledin - Modern Computer Architecture and Organization
2.BIOS DISASSEMBLY NINJUTSU UNCOVERED, Darmawan Salihun
3.The Bios Companion, Phil Croucher
7.80X86 IBM PC and Compatible Computers: Assembly Language, Design
and Interfacing Vol. I and II: Volumes I & II (80x86 IBM PC &
Compatible Computers) [Hardcover] Mazidi, Muhammad Ali
and Mazidi, Janice G.
8.The x86 PC: Assembly Language, Design, and
Interfacing, Muhammad Ali Mazidi Janice G. Mazidi
Danny Causey
12. The Intel Mıcroprocessors ... Architecture, Programming and
Interfacing, Barry B. Brey
19. i386/i486 Advanced Programming: Real Mode Protected Mode Virtual
8086 Mode,Sen-Cuo Ro, Sheau-Chuen Her (auth.), Rajvir Singh
Yorumlar
Yorum Gönder