INTEL İŞLEMCİLERİNDE CSD İŞLETİM SİSTEMİNİN BAŞLATILMASI. Selim Nasır



Benzer belgeler
Sistem Programlama. Kesmeler(Interrupts): Kesme mikro işlemcinin üzerinde çalıştığı koda ara vererek başka bir kodu çalıştırması işlemidir.

Adresleme Modları. Mikroişlemciler ve Mikrobilgisayarlar

Bahar Dönemi. Öğr.Gör. Vedat MARTTİN

Mikrobilgisayar Donanımı

Yazılım Kurulumu ve Yönetimi -2010

İşletim Sistemlerine Giriş

Basit Bootstrap Uygulaması

8086 Mikroişlemcisi Komut Seti

Bil101 Bilgisayar Yazılımı I. M. Erdem ÇORAPÇIOĞLU Bilgisayar Yüksek Mühendisi

Assembly Dili Nedir? Assembly dili biliyorum derken hangi işlemci ve hangi işletim sistemi için olduğunu da ifade etmek gerekir.

CUMHURİYET MESLEKİ VE TEKNİK ANADOLU LİSESİ BİLİŞİM TEKNOLOJİLERİNİN TEMELLERİ DERSİ DERS NOTLARI BELLEKLER

MTM 305 MİKROİŞLEMCİLER

Ders 3 ADRESLEME MODLARI ve TEMEL KOMUTLAR

İŞLETİM SİSTEMİ KATMANLARI (Çekirdek, kabuk ve diğer temel kavramlar) Bir işletim sisteminin yazılım tasarımında ele alınması gereken iki önemli konu

İşletim Sistemlerine Giriş

Sanal Bellek (Virtual Memory)

DIGIAC 2000 Deney Seti PAT İŞLEMCİ KARTI :

Mikrobilgisayarlar ve Assembler. Bahar Dönemi. Vedat Marttin

BÖLÜM Mikrodenetleyicisine Giriş

MİKROBİLGİSAYAR SİSTEMLERİ. Teknik Bilimler Meslek Yüksekokulu

MEB YÖK MESLEK YÜKSEKOKULLARI PROGRAM GELİŞTİRME PROJESİ. 1. Tipik bir mikrobilgisayar sistemin yapısı ve çalışması hakkında bilgi sahibi olabilme

Bölüm 3: Adresleme Modları. Chapter 3: Addressing Modes

PROGRAMLAMAYA GİRİŞ. Öğr. Gör. Ayhan KOÇ. Kaynak: Algoritma Geliştirme ve Programlamaya Giriş, Dr. Fahri VATANSEVER, Seçkin Yay.

(Random-Access Memory)

Bilgi ve İletişim Teknolojileri (JFM 102) Ders 7. LINUX OS (Sistem Yapısı) BİLGİ & İLETİŞİM TEKNOLOJİLERİ. LINUX Yapısı

CSD İŞLETİM SİSTEMİNDE SİSTEM FONKSİYONLARININ ÇAĞIRILMASI

Temel Bilgisayar Programlama

Mikroişlemcili Sistemler ve Laboratuvarı

Merkezi İşlem Birimi MİKROİŞLEMCİ SİSTEMLERİ. MİB Yapısı. MİB in İç Yapısı. MİB Altbirimleri. MİB in İç Yapısı

Özyineleme (Recursion)

Linux Assembly Programlamaya Giriş

9. MERKEZİ İŞLEM BİRİM MODÜLÜ TASARIMI

BLM-112 PROGRAMLAMA DİLLERİ II. Ders-8 Dosya İşlemleri-1. Yrd. Doç. Dr. Ümit ATİLA

Windows Eski Sürümleri Bellek Yapısı

8. İŞARETCİLER (POINTERS)

MTM 305 MİKROİŞLEMCİLER

İSTANBUL TİCARET ÜNİVERSİTESİ BİLGİSAYAR MÜHENDİSLİĞİ BÖLÜMÜ MİKROİŞLEMCİLİ SİSTEM LABORATUVARI KESMELİ GİRİŞ/ÇIKIŞ

Programlama Dilleri 1. Ders 12: Belirleyiciler ve Niteleyiciler

Bilgisayarda Programlama. Temel Kavramlar

MTM 305 MĠKROĠġLEMCĠLER

Program Kontrol Komutları. Mikroişlemciler ve Mikrobilgisayarlar 1

Bilgisayar Donanım 2010 BİLGİSAYAR

ELN1002 BİLGİSAYAR PROGRAMLAMA 2

Pointers (İşaretçiler)

VERİ TABANI YÖNETİM SİSTEMLERİ I

BM-311 Bilgisayar Mimarisi

HAFTA 1 KALICI OLMAYAN HAFIZA RAM SRAM DRAM DDRAM KALICI HAFIZA ROM PROM EPROM EEPROM FLASH HARDDISK

KASIRGA 4. GELİŞME RAPORU

Quiz:8086 Mikroişlemcisi Mimarisi ve Emirleri

Bahar Dönemi. Öğr.Gör. Vedat MARTTİN

BİLGİSAYAR KULLANMA KURSU

8086 dan core2 ya yazaç yapısını tanımak. Bayrak yazacının içeriğinde yer alan bayrakların görevlerini tanımlamak. Real mod çalışmada bellek

ALGORİTMA VE PROGRAMLAMA II

BM-311 Bilgisayar Mimarisi. Hazırlayan: M.Ali Akcayol Gazi Üniversitesi Bilgisayar Mühendisliği Bölümü

İŞLEMCİ DURUM KAYDEDİCİSİ (PROCESSOR STATUS REGISTER)

TBİL-405 Mikroişlemci Sistemleri Bölüm 2 1- % %01010 işleminin sonucu hangisidir? % %11000 %10001 %10101 %00011

PROGRAMLAMAYA GİRİŞ DERS 2

ALGORİTMA VE PROGRAMLAMA II

İŞLETİM SİSTEMLERİ. (Operating Systems)

Yrd. Doç. Dr. Caner ÖZCAN

Mikroişlemcili Sistemler ve Laboratuvarı 8.Hafta

Çoktan Seçmeli Değerlendirme Soruları Akış Şemaları İle Algoritma Geliştirme Örnekleri Giriş 39 1.Gündelik Hayattan Algoritma Örnekleri 39 2.Say

MCR02/04/05/08 Serileri Temassız Kart Okuyucular

TEMEL BİLGİ TEKNOLOJİSİ KULLANIMI. Enformatik Bölümü

İşletim Sistemleri Kurulumu

Bil101 Bilgisayar Yazılımı I. M. Erdem ÇORAPÇIOĞLU Bilgisayar Yüksek Mühendisi

İSTANBUL TİCARET ÜNİVERSİTESİ BİLGİSAYAR MÜHENDİSLİĞİ BÖLÜMÜ MİKROİŞLEMCİLİ SİSTEM LABORATUARI MİKROİŞLEMCİLİ A/D DÖNÜŞTÜRÜCÜ

İŞLETİM SİSTEMİ KATMANLARI (Çekirdek, Kabuk ve diğer temel kavramlar) Öğr.Gör. Dr. Dr. Şirin KARADENİZ

HSancak Nesne Tabanlı Programlama I Ders Notları

24 Mart İlgili Modül/ler : Transfer. İlgili Versiyon/lar : ETA:SQL, ETA:V.8-SQL

Setup Yardımcı Programı

ENROUTEPLUS TA YAPILMASI GEREKENLER

BİL 423 Bilgisayar Mimarisi 1. Ara Sınavı

ENF 100 Temel Bilgi Teknolojileri Kullanımı Ders Notları 2. Hafta. Öğr. Gör. Dr. Barış Doğru

Bilgi ve iletişim teknolojileri

Bilgisayar Sistemlerine Genel Bakış

Linux ta komutlar hakkında yardım almak için aşağıdaki komutlar kullanılır : - man - info - whatis - apropos

Bölüm 8: Ana Bellek. Operating System Concepts with Java 8 th Edition

MIKRODENETLEYICILER. Ege Üniversitesi Ege MYO Mekatronik Programı

3/7/2011. ENF-102 Jeoloji 1. Tekrar -- Değişken Tanımlamaları (Definition) ve Veri Türleri (Data Type) Veri Tanımları ve Mantıksal Đşlemler

ELN1002 BİLGİSAYAR PROGRAMLAMA 2

ELN1001 BİLGİSAYAR PROGRAMLAMA I

MİKROİŞLEMCİ MİMARİLERİ

Merkezi İşlem Birimi MİKROİŞLEMCİ SİSTEMLERİ. MİB Yapısı. MİB Altbirimleri. Durum Kütüğü. Yardımcı Kütükler

İSTANBUL TİCARET ÜNİVERSİTESİ BİLGİSAYAR MÜHENDİSLİĞİ BÖLÜMÜ MİKROİŞLEMCİLİ SİSTEM LABORATUARI İKİLİ TABANDA ÇOK BAYTLI ÇARPMA

Bilgisayarların Gelişimi

Yığın MİKROİŞLEMCİ SİSTEMLERİ. Yığın. Örnek MİB için Yığın. Yığma İşlemi. Çekme İşlemi

Hacettepe Robot Topluluğu

Yükleme Emrinde bulunan belge numarası, kamyon plaka numarası ve şoför adının irsaliyeye taşınması,

5. HAFTA KBT104 BİLGİSAYAR DONANIMI. KBUZEM Karabük Üniversitesi Uzaktan Eğitim Uygulama ve Araştırma Merkezi

Uygulama İş Akış Kaydında Koşul Tanımlamaları

Çalışma Açısından Bilgisayarlar

Bilgisayar Mimarisi Nedir?

Mikrobilgisayar Mimarisi ve Programlama

B.Ç. / E.B. MİKROİŞLEMCİLER

İşletim Sistemlerine Giriş

Bilgisayar Donanımı Dersi BİLGİSAYARIN MİMARI YAPISI VE ÇALIŞMA MANTIĞI

Yazılım Çeşitleri. Uygulama Yazılımları. İşletim Sistemleri. Donanım

Bilgi ve iletişim teknolojileri Dersi Ders Notlarıdır?

T E M E L K AV R A M L A R. Öğr.Gör. Günay TEMÜR / Teknoloji F. / Bilgisayar Müh.

Transkript:

INTEL İŞLEMCİLERİNDE CSD İŞLETİM SİSTEMİNİN BAŞLATILMASI Selim Nasır [V:1] Özet: İşletim sisteminin başlatılması (boot edilmesi), işletim sisteminin üzerinde çalışacağı temel ve çevresel donanımların işlevsel duruma getirilmesi, akış çekirdeğe verilmeden önce uygun donanım ve yazılım ortamının oluışturulması ve çekirdeğe ilişkin veri yapılarının başlatılması gibi işlemleri kapsamaktadır. Görüldüğü gibi bu aşama hangi işletim sistemi olursa olsun işletim sisteminin tam olarak çalışır duruma getirilmesinde önemli ve kaçınılmaz bir aşamayı belirtmektedir. Bu makalede CSD işletim sisteminin başlatılmasına ilişkin açıklamalar yapılacaktır. 1. GİRİŞ Çokişlemli işletim sistemlerinde işletim sisteminin bellek yönetimi, çeşitli giriş/çıkış donanımlarının yönetimi, kullanıcı programlarının zaman paylaşımlı olarak çalıştırılması gibi işlemlerden sorumlu olan kısmına çekirdek (kernel) denilmektedir. Dolayısıyla bir işletim sisteminde çekirdeğe ilişkin kodlar işletim sisteminin omurgasını oluşturmaktadır. 80x86 tabanlı bir işlemcide çokişlemliliği destekleyecek ve korumalı modda çalışacak bir işletim sistemi tasarladığımızı düşünelim. Bu durumda düşündüğümüz işletim sisteminin özelliklerini tam olarak sağlayacak bir çekirdek tasarlanmalıdır. Ancak 80x86 tabanlı işlemciler açıldığında gerçek modda çalışmaya başlarlar. Yani işlemci korumalı modda değildir ve çokişlemliliği desteklememektedir. Ayrıca tüm RAM bölgesi rassal verilerle doludur ve donanım aygıtları belirlenemeyen bir konumdadır. Öyleyse tasarlayacağımız çekirdeğin doğru bir biçimde çalışabilmesi ve belirtilen işlevleri yerine getirebilmesi için öncelikle donanım ortamının belli bir biçimde yapılandırılması gerekmektedir. İşte bir işletim sisteminin başlatılması en genel ifadesiyle bu gibi işlemlerin yapılmasını içermektedir. Bu makalede öncelikle 80x86 tabanlı işlemcilerin açılması sırasında yapılan genel işlemler anlatılacaktır. Bu işlemler işletim sisteminden bağımsız olarak donanımın standart fonksiyonları ile gerçekleştirilmektedir. Daha sonra Unix/Linux işletim sistemlerinde akış çekirdeğe bırakılana değin gerçekleştirilen başlatma işlemleri genel olarak ele alınacaktır. Son olarak ise CSD işletim sisteminde akış çekirdeğe bırakılana değin gerçekleştirilen başlatma işlemleri ayrıntılı olarak açıklanacaktır. Bilindiği gibi işletim sistemlerinin başlangıç kodları sabit disk, disket, CDROM gibi ikincil bellek elemanlarında yer almaktadır. Bilgisayar açıldığında sözü edilen başlangıç kodu ikincil bellek elemanından alınarak belleğe getirilmektedir. Bu makalede CSD işletim sisteminin disket sürücü ve MSDOS işletim sistemi ile bilgisayar açıldıktan sonra MSDOS üzerinden başlatılması işlemleri açıklanacaktır. Makalenin yazıldığı tarih gözönüne alındığında CSD işletim sisteminin dosya sistemine ilişkin tasarım çalışmaları henüz sürdüğünden CSD işletim sisteminin sabit disk ya da CDROM üzerinden başlatılması işlemleri bu makalede ele alınmayacaktır. 1

2. 80x86 TABANLI MİKROİŞLEMCİLERİN BAŞLATILMASI 80x86 tabanlı işlemcilerde üç tür çalışma biçimi bulunmaktadır. Bunlar gerçek mod, korumalı mod ve sanal86 modudur. İşlemci ilk açıldığında çalışma biçimi gerçek moddur. CSD işletim sisteminde bir takım hazırlık işlemleri yapıldıktan sonra korumalı moda geçiş yapılmaktadır. Bilgisayara güç verildikten sonra RAM üzerinde rassal bilgiler bulunmaktadır ve hiç bir işletim sistemi çalışmamaktadır. İşlemcinin RESET ucunun etkinleştirilmesi ile işlemcinin bazı yazmaçları belirli değerlerle yüklenirler. Bu yazmaçlardan ikisi o an çalışmakta olan kodun bellek adresini gösteren CS ve EIP yazmaçlarıdır. CS ve EIP yazmaçları başlangıçta belirli değerlerle yüklenerek akışın ilk olarak bellekte belirgin bir yere yönlendirilmesi sağlanmaktadır. 2.1 80x86 Tabanlı İşlemcilerde Gerçek Modda Belleğin Durumu Bilindiği gibi tüm mikroişlemci ailelerinde merkezi işlem birimi (MİB) ve fiziksel bellek arasında aşağıda gösterildiği gibi 3 grup uç bulunmaktadır. Adres Yolu MİB Veri Yolu Kontrol Uçları Fiziksel Bellek (RAM) İşlemci hangi modda çalışıyorsa çalışsın belli bir adres değeri, o moda ilişkin adresleme biçimine göre fiziksel adrese dönüştürüldükten sonra elektriksel olarak işlemcinin adres uçlarına bırakılır. Adres uçları ile belirtilen bellek bölgesine yazılacak bilgi veri yoluna bırakılır ya da adres uçları ile belirtilen bellek bölgesinden okunacak bilgi veri yolundan alınır. İşlemcinin adres uçlarının bitsel genişliği o işlemciye bağlanabilecek fiziksel bellek sığasını belirlemektedir. İşlemcinin veri yolunun bitsel genişliği ise o işlemcinin bir makine komutunda en fazla kaç bitlik veriler üzerinde işlem yapabildiğini, yani kaç bitlik bir işlemci olduğunu belirtmektedir. Örneğin 80x86 ailesindeki, yalnızca gerçek modun tanımlı olduğu 20 8086 işlemcisinin 20 tane adres ucu vardır ve toplam 2 = 1 MB lik belleği adresleyebilmektedir. Yine 80x86 ailesindeki 80386 işlemcinin 32 tane adres ucu 32 vardır ve toplam 2 = 4 GB lik belleği adresleyebilmektedir. Bunlardan 8086 16 bit, 80386 ise 32 bit işlemcilerdir. CSD işletim sistemi 4 GB lik bellek alanını adresleyebilen, korumalı modun tanımlı olduğu 80386 ve yukarısı 80x86 tabanlı 2

mikroişlemciler için tasarlanacaktır. CSD işletim sisteminin diğer mikroişlemci ailelerindeki mikroişlemcilere uyarlanması projenin gelişimi içerisinde ayrıca ele alınacaktır. 80x86 tabanlı mikroişlemcilerde hangi işlemci söz konusu olursa olsun bilgisayar 8086 işlemcisi gibi açılmaktadır. Yani o anki çalışma gerçek moddadır ve ancak 1 MB lik bellek alanı adreslenebilmektedir. İşte işlemcinin korumalı moda geçirilerek 4 GB lik bellek alanını adresleyebilecek duruma getirilmesi CSD işletim sisteminin başlatılması izleği içerisinde gerçekleştirilecektir. Sözü edilen 1 MB lik adres alanı içerisinde bazı adres aralıkları özel anlamlıdır. 1 MB lik adres alanındaki özel anlamlı bölgeler ve bunlara ilişkin adres aralıkları aşağıda gösterilmiştir. 0000:0000 1024 K Kesme Vektörü 256 byte BIOS Haberleşme Alanı 0040:0000 A000:0000 Video Belleği F000:0000 Mikroişlemcinin çalışması 1MB nin son 16 byte ından başlar BIOS Bölgesi F000:FFF0 F000:FFFF 64 K 16 byte 3

2.1.1 Kesme Vektörü Kesme vektörü C dilindeki ifadesiyle bir fonksiyon gösterici dizisi olarak düşünülebilir. Bu dizide yer alan her bir fonksiyon göstericisi bir kesme oluştuğunda dallanılacak kod adresine ilişkin segment ve offset çiftini tutmaktadır. Fonksiyon gösterici dizisinin her bir elemanı 4 byte uzunluktadır. Intel işlemcilerinde toplam 256 tane kesme tanımlandığına göre kesme vektörünün toplam uzunluğu 256 x 4 (byte) = 1K dır ve başlangıç adresi belleğin tepesidir. Bu durumda kesme vektörünün görüntüsü aşağıdaki gibi olacaktır: 0000 IP 0 CS 0 0004 0008 000C IP 1 CS 1 IP 2 CS 2 IP 3 CS 3 03F8 03FC IP 254 CS 254 IP 255 CS 255 0400 Korumalı moda geçildikten sonra buradaki kesme vektörünün artık bir anlamı kalmayacaktır. Korumalı modda kesme işlemleri kesme betimleyici tablo ile ele alınmaktadır. 2.1.2 BIOS Haberleşme Alanı BIOS kesmelerinin ve fonksiyonlarının kullandıkları değişkenler ve veriler bu bölgede bulunmaktadır. 2.1.3 Video Belleği PC mimarisinde fiziksel bellekte üzerindeki A000:0000 ile F000:0000 adres aralığı donanımsal olarak doğrudan video kartı ile ilişkilendirilmiştir. 4

2.1.4 BIOS Bölgesi Bilindiği gibi BIOS kodları salt okunabilir bellek (ROM) üzerinde bulunmaktadır. Bilgisayar açıldığında işlemler ilk elden BIOS fonksiyonları ile yürütülmektedir. 1 MB lik bellek alanının son 64K sı donanımsal olarak ROM BIOS ile ilişkilendirilmiştir. 2.2 BIOS İşlemleri ile İşletim Sisteminin Boot Sektörünün Yüklenmesi CS ve EIP yazmaçlarının işlemcinin RESET edilmesinden sonra belli değerlerle yüklendiği daha önce belirtilmişti. İşte bu yazmaçlar 1 MB lik bellek alanının son 16 byte ını (fiziksel F000:FFF0 adresi) gösterecek biçimde yüklenirler. F000:FFF0 adresindeki 5 byte lık jmp makine komutu ile POST (Power On Self Test) fonksiyonuna dallanılır. POST işlemi sırasında PC donanımına (işlemci, bellek, kesme denetleyicisi, DMA, vb.) ilişkin bir dizi sınamalar gerçekleştirilir. Yine bu aşamada BIOS haberleşme alanına ilişkin değişkenlere ve kesme vektörüne ilk değer verme işlemi yapılır. POST işleminden sonra BIOS ayarlarında belirlenen sıraya göre ikincil bellek ortamlarında (sabit disk, CDROM sürücü, disket sürücü) herhangi bir işletim sisteminin boot sektörü aranır. Geçerli bir yükleme ortamı bulunduktan sonra onun ilk sektörü (boot sektörü) fiziksel 07C0:0000 adresine okunur ve akış bu adrese bırakılır. Bu noktada yazmaçların ne durumda olacağı garanti altında değildir. CS:EIP çifti fiziksel olarak 07C0:0000 adresini göstermektedir ama bu yazmaçların hangi bileşimde yüklü olduğu belli değildir. Ancak DL yazmacında yükleme yapılan sürücüye ilişkin bir değer bulunmaktadır. Bu bölümle açıklanan noktalar işletim sisteminden bağımsız, PC mimarisi gereğince standart olarak gerçekleştirilen işlemlerdir. Bu aşamadan sonra yapılacak işlemler işletim sistemi bağımlıdır ve işletim sistemlerinin tasarımsal özelliklerine göre değişiklikler göstermektedir. 3. LINUX SİSTEMLERİNİN BAŞLATILMASI Bu bölümde Linux sistemlerinin yalnızca disket sürücü üzerinden yüklenmesi işlemi ele alınacaktır. Zaten Linux sistemlerinin MSDOS üzerinden yüklenmesi gibi bir kavram yoktur. BIOS tarafından disketin ilk sektörü 07C0:0000 adresine yüklendikten ve akış bu adresten devam edecek biçimde bırakıldıktan sonra boot sektör içerisindeki komutlar ile çekirdek dosyasının geri kalanı fiziksel belleğe aktarılmaktadır. Disketten yükleme söz konusu olduğunda boot yükleyici kodu oldukça yalındır ve arch/i386/boot/bootsect.s sembolik makine dili kaynak dosyası içerisinde bulunmaktadır. 5

3.1 Linux Boot Yükleyicisi Boot yükleyici kodu derlenip çalışabilir kod elde edildikten sonra çekirdek dosyasının başlangıcına yerleştirilir. Böylece çekirdek dosyası bir disketin ilk sektöründen başlayarak aktarıldığında kolaylıkla bir başlatma disketi elde edilebilir. Boot yükleyici koduna disketin ilk sektörü, yani boot yükleyicisi, 07C0:0000 adresine aktarıldıktan sonra BIOS kodu tarafından dallanılır. Boot yükleyicisi işlemlerin girişinde kendini 07C0:0000 adresinden 9000:0000 adresine taşımaktadır. Boot yükleyicisinin yaptığı işlemler CSD işletim sisteminin boot yükleyicinde yapılanlara koşut olduğundan daha geniş açıklama CSD ile ilgili kısımda yapılacaktır. Linux sistemlerinde boot yükleyicisi çekirdek dosyasını yüklerken küçük çekirdek dosyaları için farklı, büyük çekirdek dosyaları için farklı yükleme adresleri kullanmaktadır. Tipik olarak küçük çekirdek dosyaları 64 K dan, büyük çekirdek dosyaları ise 1 MB den başlayarak yüklenmektedir. Boot yükleyicisi işlemlerini tamamladıktan sonra setup() koduna dallanır. 3.2 setup() Fonksiyonu Çekirdek dosyası içerisinde setup() kodu, çekirdek ile tümleştirilmiş boot yükleyicisinin hemen ardına yerleştirilmektedir. setup() fonksiyonu içerisinde varolan bellek miktarı belirlendikten ve bir dizi donanıma ilişkin işlemler yapıldıktan sonra eğer çekirdek düşük adrese yüklenmişse çekirdeği 4K ya taşımakta ancak çekirdek yüksek adrese yüklenmişse her hangi bir taşıma işlemi yapmamaktadır. Çekirdek düşük adrese yüklenmişse ikinci bir taşıma işlemi yapılmasının gerekçesi sıkıştırılmış çekirdek dosyasını açan programın belleğe yüklü durumdaki çekirdeğin ötesinde ek bir geçici tampon bölgeye gereksinim duymasıdır. Bundan sonra setup() fonksiyonunda sırasıyla şu işlemler yapılmaktadır: Geçici bir global betimleyici tablo ve kesme betimleyici tablo oluşturur. Programlanabilir Kesme Denetleyicisini yeniden programlayarak 16 donanım kesmesini [0, 15] aralığından [32, 47] aralığına öteler. İşlemciyi gerçek moddan korumalı moda geçirir. startup_32() sembolik makine dili fonksiyonuna dallanır. 3.3 startup_32 Fonksiyonu Linux sistemlerinde 2 farklı startup_32 fonksiyonu bulunmaktadır. Bunlardan ilki arch/i386/boot/compressed/head.s sembolik makine dili kaynak dosyası içerisinde kodlanmıştır. Çekirdek dosyasının yüksek ya da düşük adrese yüklenmesine göre bu fonksiyon 1 MB ya da 4 KB adresine taşınmaktadır. Sıkıştırılmış çekirdek dosyasının açılması bu fonksiyon tarafından çağrılan decompress_kernel() fonksiyonu ile yapılmaktadır. Eğer sıkıştırılmış çekirdek dosyası düşük adrese aktarılmışsa açılmış çekirdek kodu 1 MB adresine yerleştirilmektedir. Ancak sıkıştırılmış çekirdek dosyası yüksek adrese aktarılmışsa açılmış çekirdek kodu sıkıştırılmış çekirdek dosyasının 6

ötesindeki geçici bir tampona yerleştirilmekte ve dosya açma işleminin sonunda 1 MB ye taşınmaktadır. Görüldüğü gibi her iki durumda da Linux sistemlerinde çekirdeğin en son konumu fiziksel bellekteki 1 MB adresidir. Açılan çekirdek kodu arch/i386/kernel/head.s sembolik makine dili kaynak dosyası içerisinde kodlanmış diğer startup_32() fonksiyonu ile çalışmasına başlamaktadır. Bu fonksiyon ilk Linux prosesi için (proses 0) çalışma ortamını hazırlamakta ve start_kernel() fonksiyonuna dallanmaktadır. start_kernel() fonksiyonu sayfa tablolarının başlatılması, kesme mekanizmasının kurulması gibi bir takım kritik işlemleri yaptıktan sonra işletim sistemini en temel halde kullanılabilir duruma getirmektedir. 4. CSD İşletim Sisteminin Çekirdek Dosyasının Oluşturulması CSD işletim sisteminin çekirdek dosyası tek bir tümleşik dosya olarak oluşturulmaktadır. CSD işletim sistemi projesinde sembolik makine dili derleyicisi olarak NASM derleyici sistemi kullanılmaktadır. Microsoft ve Borland tabanlı sembolik makine dili ve C derleyicilerinde düz çalışabilir dosya biçiminde çıkış alınamamaktadır. Bu nedenle sembolik makine dili kaynak dosyaları için NASM ve C kaynak dosyaları için Unix/Linux sistemlerinin yerleşik C/C++ derleyici sistemi olan gcc derleyicisi kullanılacaktır. Bilindiği gibi Linux sistemlerinde çekirdek kodu en son yükleme adresine taşındıktan sonra startup_32() ve start_kernel() fonksiyonları çağrılmaktadır. CSD işletim sisteminde ise çekirdek en son konumuna taşındıktan sonra çalışma Linux sistemlerindeki startup_32() ve start_kernel() fonksiyonlarının işlevsel eş değerleri olan startup() ve KernelMain() fonksiyonları ile devam edecektir. Buna göre sistemin açılmasından KernelMain() fonksiyonu çağrılana değin kullanılan kaynak dosyalar ve bunların dizin ağacındaki yerleri aşağıdaki tabloda gösterilmiştir. Kaynak Dosyanın İsmi boot.asm setup.asm startup.asm main.c Dosyanın Dizin Ağacındaki Yeri arch/i386/boot arch/i386/boot arch/i386/init init Yukarıdaki tabloda belirtilen kaynak dosyaların derlenmesinden sonra elde edilen düz çalışabilir dosyaların birleştirilerek tek bir çekirdek dosyasının oluşturulması ise CSD işletim sistemi projesi içerisinde yazılmış olan fmerge yardımcı programı ile yapılacaktır. Bu durumda k.bin isimli tümleşik çekirdek dosyasının oluşturulması aşağıdaki adımlardan geçilerek gerçekleştirilmektedir. 7

boot.asm ve setup.asm sembolik makine dili kaynak dosyaları aşağıdaki tabloda gösterilen toplu işlem dosyaları kullanılarak derlenir. Toplu İşlem Dosyasının Yol İfadesi arch/i386/boot/dos/b.bat arch/i386/boot/dos/s.bat Toplu İşlem Dosyasının Açılımı nasm f bin o boot.bin -i \ \boot.asm nasm f bin o setup.bin -i \ \setup.asm startup.asm sembolik makine dili kaynak dosyası NASM derleyicisi ile düz çalışabilir dosya elde edecek biçimde derlenir. KernelMain() fonksiyonu çekirdeğin giriş noktasıdır ve C dilinde yazılmıştır. KernelMain() fonksiyonunun tanımlamasının bulunduğu init/main.c C kaynak dosyası Linux altında gcc derleyicisi ile derlenerek amaç dosya elde edilir. start.asm ve main.c kaynak dosyalarının derlenmesinden elde edilen amaç dosyalar Linux komut satırında ld bağlayıcısı ile aşağıdaki biçimde bağlanarak k.bin isimli çıkış dosyası elde edilmektedir. ld startup.o kernel.o format binary TTEXT=0x100000 o kernel.bin CSD işletim sisteminde çekirdeğin en son konumu fiziksel bellekteki 1 MB adresidir. Bu nedenle yukarıdaki bağlama ifadesinde T anahtarı ile programın bellekteki yerleşim adresi TTEXT=0x100000 biçiminde 1 MB olarak verilmiştir. Tüm derleme işlemleri sonucunda boot.bin, setup.bin ve k.bin isimli üç tane düz çalışabilir dosya elde edilmektedir. İşte bu üç dosya birleştirilerek tümleşik çekirdek dosyası artık elde edilebilecektir. Bu işlem için CSD işletim sistemi projesi içerisinde yazılmış olan fmerge yardımcı programı kullanılacaktır. Birleştirme işlemini kolaylaştırmak için arch/i386/boot/dos dizini altındaki m.bat isimli toplu işlem dosyası kullanılmaktadır. Bu dosya aşağıdaki gibi düzenlenmiştir: \osdev\boot\fmerge -o k.bin boot.bin setup.bin kernel.bin Görüldüğü gibi o anahtarı ile tümleşik çekirdek dosyasının ismi k.bin olarak belirlenebilmektedir. Artık elde edilen çekirdek dosyası disket sürücüye aktarılabilir. Bu işlem için CSD işletim sistemi projesi içerisinde yazılmış olan rawrite isimli yardımcı program kullanılacaktır. Program komut satırı argümanı olarak aldığı tümleşik çekirdek dosyasını disketin ilk sektöründen başlayarak aktarmaktadır. 8

K.BIN boot.bin setup.bin startup.bin kernel.bin KernelMain() { } Yukarıdaki şekilde oluşum sürecine katılan düz çalışabilir dosyaların tümleşik çekirdek dosyası içerisindeki konumları gösterilmiştir. Ok imi ile CSD işletim sisteminin gelişim sürecinde çekirdek dosyasının büyüyeceği vurgulanmak istenmiştir. Tabii çekirdek dosyasını belleğe yükleyen programlar da çekirdeğin sektör uzunluğunu göz önünde bulundurarak işlemlerini yapacaktır. Bu amaçla include/arch/i386/boot/bootdef.inc sembolik makine dili başlık dosyası içerisinde NKERNEL_SECTS isimli bir sembolik sabit bildirilmiştir. Bu sembolik sabit çekirdek dosyasının sektör uzunluğunu belirtmektedir. Çekirdek dosyasına bir ekleme yapıldığında NKERNEL_SECTS isimli sembolik sabit de güncellenecektir. 5. CSD İŞLETİM SİSTEMİNİN BAŞLATILMASI Bu bölümde CSD işletim sisteminin disket sürücü ya da bilgisayarın MSDOS işletim sistemi ile açıldıktan sonra MSDOS komut satırı üzerinden başlatılması işlemleri ele alınacaktır. 5.1 CSD İşletim Sisteminin Disket Sürücüden Yüklenmesi Tümleşik çekirdek dosyası disketin boot sektöründen başlayarak diskete yüklenmektedir. Bilindiği gibi BIOS yüklenebilir bir ikincil bellek ortamı bulduktan sonra onun boot sektörünü fiziksel belleğe 07C0:0000 adresinden başlayarak kopyalamakta ve akışı bu adresten devam edecek biçimde bırakmaktadır. Yani bu noktada disket üzerindeki tümleşik çekirdek dosyasının yalnızca ilk sektörü fiziksel belleğe aktarılmış durumdadır. Öyleyse yükleme işleminin bundan sonraki aşamalarında, genel olarak, çekirdeğin geri kalan kısmı fiziksel belleğe aktarılacak, 9

donanıma ilişkin bir takım özel işlemler yapılacak, korumalı moda geçilecek ve sonunda akış belirlenen bir noktaya bırakılacaktır. CSD işletim sisteminin disket sürücüden yüklenmesi süreci sembolik makine dili kaynak dosyalarındaki akış göz önüne alınarak açıklanacaktır. Bu nedenle ilgili kaynak dosyalar eşliğinde makalenin okunması salık verilmektedir. 5.1.1 boot.asm Sembolik Makine Dili Kaynak Dosyası Linux sistemlerinde olduğu gibi çekirdek dosyasının ilk sektörü boot sektör olacak biçimde bir düzenleme yapılmıştır. CSD işletim sisteminin boot kodu arch/i386/boot dizini içerisindeki boot.asm dosyası içerisinde bulunmaktadır. Hatırlanacağı gibi boot.asm dosyası derlenerek boot.bin dosyası elde edilmekte ve bu dosya çekirdek dosyasının ilk sektöründe yer alacak biçimde birleştirme işlemi yapılmaktadır. Gerek disketten yükleme gerekse de MSDOS üzerinden yükleme sırasında aynı boot.bin dosyası kullanılacaktır. boot.asm içerisinde öncellikle boot kodu 9000:0000 adresine taşınmaktadır. Bu adres bootdef.inc başlık dosyası içerisinde aşağıdaki biçimde bildirilmiştir. %define BOOT_SEG 0x9000 ; (576K) 07C0:0000 adresinden 9000:0000 adresine 1 sektörlük aktarma yapıldıktan sonra akış artık BOOT_SEG:.BOOT_MOVE_CONTINUE ile belirtilen adresten devam edecektir. Bundan sonra SS ve SP yazmaçlarına ilk değerleri verilmiştir. SS yazmacı BOOT_SEG değeri ile yüklenmiştir. Yığın 64K uzunluğundadır ancak yığının ilk 12 byte ı disket parametre tablosu için ayrılmıştır. Bu durumda SP yazmacı aşağıdaki sembolik sabit ile yüklenmektedir. %define INITIAL_SP 0xFFFE-12 Çekirdeğin geri kalan kısmının fiziksel belleğe yüklenmesi boot.asm içerisinde tanımlanan AbsRead() fonksiyonu ile yapılmaktadır. Ancak MSDOS üzerinden çekirdek yüklenirken MSDOS un disk fonksiyonları kullanıldığından böyle bir fonksiyona gereksinim yoktur. Bir başka anlatımla, MSDOS üzerinden yükleme yapılırken boot kodunun disket işlemlerine ilişkin bölümü gözardı edilmektedir. boot.bin hem disketten hem de MSDOS üzerinden yükleme sırasında ortak olarak kullanıldığından şöyle bir strateji izlenmiştir: Bilindiği gibi BIOS sistemin açıldığı sürücü numarasını DL yazmacında bırakmaktadır. MSDOS üzerinden yükleme yapan lcsd.com isimli yardımcı program da DL yazmacına 0xFF değerini yerleştirmektedir. Bu noktadan hareketle boot.asm içerisinde DL yazmacı drive isimli bir değişkene alınmakta ve aşağıdaki biçimde bir karşılaştırma işlemi yapılmaktadır: 10

Çekirdeğin Yüklemesi Sırasında İlk 1 MB lik Bellek Haritası KERNEL_LOW_SEG 0000:000 0 0100:0000 // 4K KERNEL_LOAD_SEG Boot Kodu 0xAA55 7C00:0000 // 31K boot.bin Boot kodu kendini 576K ya taşıyor 2000:0000 // 128K MSDOS üzerinden çalıştırılan lcsd.com çekirdek kodunu yüklerken kendini ezmemek için kendini yüksek bir adrese taşımaktadır Taşınan Boot Kodu 0xAA55 Setup Kodu 9000:0000 // 576K boot.bin 9020:0000 setup.bin LCSD.COM lcsd.com un Kullandığı Yığın 9A00:0000 // 616K SP Disket Parametre Tablosu A000:0000 // 640K Video Belleği 1 MB 64K KernelMain() { } EPROM 11 F000:0000 KERNEL_FINAL_POS OS startup.asm kernel.bin = + main.c

cmp byte [drive], 0xFF ; is booting from DOS? jz.set_int80_vector Böylece eğer drive değişkeninde 0xFF değeri varsa doğrudan 80h kesmesinin kesme vektörüne yerleştirildiği fonksiyona gidilmekte ya da akış disket işlemlerinin yapılması ile devam etmektedir. Tabii disket işlemleri yapıldıktan sonra akış sonunda 80h kesmesine ilişkin işlemlerin yapıldığı fonksiyona gelecektir. 5.1.1.1 Disket Parametre Tablosu Boot işleminde gelinen bu noktada gerçek moddaki tüm segment yazmaçları 0x9000 (576K) değeri ile yüklenmiş durumdadır. Bilindiği gibi oluşturulan yığın alanının son 12 byte ı disket parametre tablosu için ayrılmıştır. Bundan sonraki işlemler bu tabloya ilk değer verilmesi işlemi ile devam edecektir. Bölüm 2.1 de gerçek modda 1 MB lik bellek alanının durumu incelenmişti. Buna göre 0 nolu adresten başlayarak ilk 1024 byte kesme vektörü için ayrılmıştır. Kesme vektörünün 1Eh numaralı elemanı (fiziksel bellekte [78h, 7Bh] adres aralığı) disket parametre tablosunun segment ve offset adresini içermektedir. Yani bu eleman her hangi bir kesme fonksiyonun adresini gösteren bir fonksiyon göstericisi biçiminde değildir. Bilindiği gibi 13h numaralı BIOS kesmesi disk işlemlerini gerçekleştirmektedir. İşte BIOS un disket sürücüye ilişkin işlemlerde kullandığı parametre tablosuna disket parametre tablosu denilmektedir. Öyleyse gerçek modda 13h kesmesinin fonksiyonlarının kullanılabilmesi için disket parametre tablosunun oluşturulması gerekmektedir. Ayrıca kesme vektöründeki 1Eh numaralı eleman da oluşturulan disket parametre tablosunun adresini göstermelidir. Hatırlanacağı gibi disket parametre tablosu yığın bölgesinin ilk 12 byte ında yer alacaktır. Buna göre kesme vektörünün 1Eh numaralı elemanına aşağıdaki biçimde değer verilmektedir: ; fs = 0 bx = 0x78 mov [fs:bx], di mov [fs:bx + 2], es ; di = INITIAL_SP ; es = 0x9000 5.1.1.2 İz Başına Sektör Sayısının Belirlenmesi Bundan sonra yüklenebilir disketin iz (track) başına düşen sektör sayısı (sector per track) bilgisi elde edilmektedir. Bugünkü PC mimarisinde farklı bellek sığalarında disketler kullanılmaktadır. Aşağıdaki tabloda çeşitli disket türlerine ilişkin yapısal veriler ve bellek sığaları verilmiştir. 12

3.5-inç Disket Formatları Bellek Sığası İz İz Başına Sektör 720K 80 9 1.2 MB 80 15 1.44 MB 80 18 2.88 MB 80 36 13h numaralı BIOS kesmesinin okuma fonksiyonu bir seferde, aynı iz üzerindeki ardışıl sektörleri okuyabilmektedir. Yani bir iz üzerinden okunacak sektör sayısı o iz üzerindeki tüm sektörlerin sayısını aşıyorsa 13h kesmesinin okuma fonksiyonu o izin sonuna kadar belirli sayıda sektörü okumakta ve okuma işlemini bitirmektedir. Bir başka anlatımla okunamayan sektörler için bir sonraki ize geçilerek okuma işlemi devam ettirilmeyecektir. Yukarıdaki tabloda belirtilen disket türlerinin iz başına sektör sayılarını temsil eden nsects isimli bir dizi alınmıştır. nsects db 36, 18, 15, 9 Bir döngü içerisinde disketten 13h kesmesinin okuma fonksiyonu ile okuma yapılmıştır. Döngünün her ilerleyişinde disketin 0 numaralı izi üzerindeki, nsects dizisinin bir elemanı ile belirtilen sektör numarasından başlayarak 1 sektör okunmaya çalışılmıştır. Okuma işlemi döngünün hangi adımında başarılı olmuşsa disketin bir izinde nsects dizisinin ilgili elemanında belirtilen sayıda sektör bulunduğuna karar verilmiştir. Örneğin iz başına 18 sektör bulunan bir disket için döngünün 2. adımında 0 numaralı iz üzerindeki son sektör olan 18. sektör başarılı bir biçimde okunabilecektir. Belirlenen iz başına sektör sayısı sectorpertrack isimli bir değişkende saklanmaktadır. 5.1.1.3 80h Kesmesinin Kesme Vektörüne Yerleştirilmesi Bilindiği gibi Linux sistemlerinin sistem fonksiyonları 80h kesmesinin fonksiyonları biçiminde yazılmışlardır. CSD işletim sisteminde de benzer yaklaşımla sistem fonksiyonları yine 80h kesmesinin fonksiyonları biçiminde bulundurulacaktır. Sistemin başlatılması sırasında gereksinim duyulan 2 temel sistem fonksiyonu 80h kesmesinin fonksiyonları olarak yazılmış ve 80h kesmesi de kesme vektörüne yerleştirilmiştir. 80h kesmesinin kesme vektörüne yerleştirilmesi aşağıdaki biçimde yapılmaktadır: 13

xor ax, ax mov es, ax mov word [es:0x80 * 4], Int80Handler mov word [es:0x80 * 4], BOOT_SEG Burada Int80Handler 80h kesmesi çağrıldığında dallanılacak fonksiyonun offsetini belirtmektedir. Görüldüğü gibi kesme vektörüne yerleştirilen segment adresi boot sektörünün taşındıktan sonraki segment adresidir. Akış Int80Handler ile belirtilen fonksiyona geldiğinde öncelikle AH yazmacındaki fonksiyon numarasına bakılarak ona göre ilgili fonksiyona dallanılmıştır. 80h kesmesinin fonksiyonu olarak yazılan iki temel fonksiyondan birisi Puts() diğeri ise AbsRead() fonksiyonlarıdır. Puts fonksiyonu 10h numaralı BIOS kesmesini kullanarak ekrana bir stringi yazdırmaktadır. AbsRead() fonksiyonu ile ilgili açıklama Bölüm 5.1.1.5 de yapılmıştır. 5.1.1.4 Çekirdek Dosyasının Geri Kalan Kısmının Disketten Yüklenmesi Boot kodu 9000:0000 adresine taşındıktan sonra hala çekirdeğin yalnızca 1 sektörü fiziksel bellektedir. Bu nedenle boot kodu setup programını SETUP_SEG ile belirtilen segment adresine, gerçek çekirdek kodunu (kernel image) ise KERNEL_LOAD_SEG ile belirtilen segment adresine kopyalayacaktır. Tabii MSDOS üzerinden yükleme sırasında setup programının ve gerçek çekirdek kodunun disketten yüklenmesine ilişkin kısımlar göz ardı edilecektir. Sözü geçen sembolik sabitler bootdef.inc sembolik makine dili başlık dosyası içerisinde aşağıdaki gibi bildirilmişlerdir: %define SETUP_SEG 0x9020 ; (576K + 512) %define KERNEL_LOAD_SEG 0x2000 ; (128K) Çekirdek kodunun belleğe yüklenmesi 64K lık parçalar halinde yapılmaktadır. Bir sektörün 512 byte olduğu düşünülürse her seferinde 128 sektörlük (128 x 512 byte = 64K) parça belleğe aktarılmaktadır. Bu işlem bir döngü içerisinde yapılmıştır. Döngünün her adımında bellek aktarım adresinin segmenti 64K ve AbsRead() fonksiyonuna geçirilen mantıksal sektör numarası 128 arttırılmıştır. Bu işlemler aşağıdaki gibi yapılmaktadır: mov ax, es add ah, 0x10 ; ES:BX Next 64K : 0 add dx, 128 14

5.1.1.5 AbsRead() Fonksiyonu Aşağıdaki tabloda görüldüğü gibi 13h kesmesinin okuma fonksiyonu işleme ilişkin oldukça fazla parametreye gereksinim duyan aşağı seviyeli bir fonksiyondur. 13h Kesmesinin Okuma Fonksiyonu 16-bit Yazmaç 8-bit Yazmaç İşlev AX AL Okunacak Sektör Sayısı AH Fonksiyon Numarası (F:2) CX CL Başlangıç Sektör Numarası* CH İz Numarası* DX DL Okuma Yapılacak Sürücünün Numarası DH Okuma Yapılacak Yüz ES:BX Verinin kopyalanacağı bellek tamponunun adresi * İz numarası gerçekte 10 bitlik bir bilgidir ([0, 1023]). Bu bilginin düşük anlamlı 8 biti zaten CH yazmacındadır, yüksek anlamlı 2 biti olarak ise CL yazmacının 6 ve 7 numaralı bitleri kullanılmaktadır. Bu durumda başlangıç sektör numarası olarak CH yazmacının düşük anlamlı 6 biti kullanılacaktır. Bu fonksiyon standart bir C fonksiyonu olmayan biosdisk() fonksiyonu gibi çalışmaktadır. Yani fonksiyon fiziksel koordinatlar ile okuma yapmaktadır. Bu durum ise her disket okumasında aynı işlemlerin sıkıcı bir biçimde yinelenmesi ve okunabilirliğin bozulması anlamına gelmektedir. Bu nedenle mantıksal koordinatlar ile çalışan bir fonksiyonun tasarımına gereksinim duyulmuştur. Linux sistemlerinde disketten okuma işlemleri için AbsRead() gibi bir fonksiyon bulunmamaktadır. Onun yerine disketten her okuma işleminde bir takım dönüşümler yapılmış ve gerçek okuma işlemini yapan bir fonksiyon çağrılmıştır. Bu da disket işleminin her yapıldığı noktada bir sürü kodun yer almasına ve okunabilirliğin bozulmasına yol açmaktadır. İşte CSD sisteminde mantıksal koordinatlarla çalışan bir okuma fonksiyonu 80h kesmesinin bir fonksiyonu olarak yazılmıştır. Öyleyse disketten okuma yapmak isteyen programcının yapacağı işlem okunacak ilk sektörün mantıksal koordinatını ve bu sektörden başlayarak okunacak sektör sayısını belirleyip 80h kesmesi aracılığıyla AbsRead() fonksiyonunu çağırmaktır. AbsRead() fonksiyonu kendi içerisinde LBAToCHS() fonksiyonu ile mantıksal koordinatı fiziksel koordinatlara dönüştürmektedir. LBAToCHS() fonksiyonunun çağırma ifadesi aşağıdaki gibidir. 15

mov ax, dx ; AX Logical Sector Number push ax push bx push cx call LBAToCHS LBAToCHS() fonksiyonu aşağıda gösterilen bölme işlemleri ile mantıksal koordinattan fiziksel koordinatları elde etmektedir. Mantıksal Sektör No İz Başına Sektör Sayısı sectorpertrack Bölüm Yüz Sayısı trackperhead Bölüm - - İz No Fiziksel Sektör Yüz No (I) (II) (I) ile belirtilen bölme işleminde kalan iz üzerindeki fiziksel sektör numarasını vermektedir. Bilindiği gibi bir iz üzerindeki sektör numaralandırması 0 dan değil 1 den başlayarak yapılmaktadır. Bu nedenle elde edilen kalan daha sonra 1 arttırılmaktadır. Disketin iz başına sektör sayısının 18 olduğunu düşünelim. Bu durumda (I) ile belirtilen bölme işleminde bölüm mantıksal sektör numarasının 18 in kaç katı olduğunu vermektedir. (II) ile belirtilen bölme işleminde ise bu değer disketteki yüz sayısına bölünmektedir. Disketteki yüz sayısına ilişkin değişken aşağıdaki gibi tanımlanmıştır. trackperhead dw 2 2 ile bölme sonucunda kalan 0 ya da 1 olacağından 18 in çift katlarında yüz numarası 0, tek katlarında 1 olacaktır. Böylece bir iz bitirildikten sonra arka yüzdeki izden devam edilecektir. (II) ile belirtilen bölme işleminde bölüm ise kalan ile belirlenen yüz üzerindeki iz sayısını belirtmektedir. Fiziksel koordinatlara ilişkin yüz, iz ve sektör parametreleri sırasıyla headnumber, tracknumber ve sectornumber isimli değişkenlerde tutulmaktadır. Koordinat dönüşümü yapıldıktan sonra AbsRead() fonksiyonu 13h kesmesinin okuma fonksiyonunu kullanarak sektör okuma işlemini yapmaktadır. AbsRead() fonksiyonunun sektör sayısı parametresi, bir iz üzerindeki sektör sayısından daha fazla olabilir. Bu durumda fonksiyon gerekirse kendi içerisinde bir çok kez 13h kesmesinin okuma fonksiyonunu çağırarak işlemlerini yapmaktadır. 16

Boot kodu tüm işlemlerin sonunda aşağıdaki gibi setup programına dallanmaktadır: jmp SETUP_SEG:0 5.1.2 setup.asm Sembolik Makine Dili Kaynak Dosyası Setup programı bellek haritasında da görüldüğü gibi boot sektörünün hemen ardındaki sektöre yüklenmektedir. Setup programında genel olarak aşağıdaki işlemler yapılmaktadır. Çalışmakta Olan İşlemcinin Belirlenmesi Çekirdek Kodunun KERNEL_LOW_SEG Adresine Taşınması A20 Hattının Açılması Donanım Kesmelerine İlişkin Kesme Numaralarının Ötelenmesi Korumalı Moda Geçiş Çekirdeğin Başlangıç Koduna Dallanılması 5.1.2.1 Çalışmakta Olan İşlemcinin Belirlenmesi CSD işletim sistemi en az 80386 ve yukarısı Intel işlemcilerinde çalıştırılmak üzere tasarlanmaktadır. Bu nedenle akış çekirdeğe verilmeden önce tipik olarak o an çalışmakta olan işlemcinin belirlenmesi gerekmektedir. Ne var ki o an çalışmakta olan işlemcinin belirlenmesine ilişkin ne bir BIOS fonksiyonu ne de bir makine komutu bulunmaktadır. Ancak Intel işlemcileri arasındaki makine kodu düzeyindeki bazı küçük ayrımların bulunmasından yararlanarak o an çalışmakta olan işlemcinin türü belirlenebilmektedir. TestCPU() fonksiyonu geri dönüş değeri olarak bayrak yazmacının elde (carry) bitinin değerini değiştirmektedir. Eğer elde biti set edilmişse işlemci testi başarısız olmuş demektir. Buna göre TestCPU() fonksiyonunun çağırma ifadesi ve geri dönüş değerinin sınanması aşağıdaki gibi yapılmaktadır: call TestCPU jc.cpufail TestCPU() fonksiyonunda yapılan test işlemi farklı işlemci türlerinde bayrak yazmacının değişen işlevine dayandırılmıştır. Tüm işlemcilerde bayrak yazmacının 0 ile 15 arasındaki bitleri ortaktır. Ancak 80286 işlemcisine değin yüksek anlamlı 4 bitin bir anlamı yoktu. Bu nedenle 80286 işlemcisinin aşağısındaki işlemcilerde bayrak yazmacı yığına atılıp POPF makine komutu ile yığından alındığında yüksek anlamlı dört bit set edilmektedir. Bunun için test fonksiyonunda AX yazmacının yüksek anlamlı kısmı 0 lanarak yığına atılmış ve bu değer POPF komutu ile bayrak yazmacına alınmıştır. 17

pushf ; Bayrak yazmacı ile yapılacak işlemlerden önce bayrak yazmacı yığında saklanıyor xor ah, ah push ax popf Bayrak yazmacı ile doğrudan işlem yapılamadığından bayrak yazmacı yığına atılmış ve sonra AX yazmacına çekilmiştir. pushf pop ax Artık AX yazmacındaki değerin yüksek anlamlı 4 bitinin hepsi set edilmişse işlemci 80286 işlemcisinden daha düşük bir işlemcidir. Öyleyse elde biti set edilerek fonksiyondan geri dönülmektedir. İkinci bir test ile bu sefer işlemcinin 80286 olup olmadığına bakılmaktadır. Buradaki test işleminde 80286 işlemcisinde POPF komutu uygulandığında bayrak yazmacının 12., 13. ve 14. bitlerinin 0 lanmasından yararlanılmaktadır. Eğer test sonucunda işlemcinin 80286 olduğu belirlenirse fonksiyon başarısızlıkla geri dönmektedir. Görüldüğü gibi test işlemi sonucunda çalışılan işlemcinin 80386 ve yukarısı bir işlemci olması garanti altına alınmaktadır. 5.1.2.2 Çekirdek Kodunun KERNEL_LOW_SEG Adresine Taşınması Çekirdek kodu bu aşamada KERNEL_LOAD_SEG ile belirtilen adresten KERNEL_LOW_SEG ile belirtilen adrese taşınmaktadır. Bilindiği gibi KERNEL_LOAD_SEG ile belirtilen adres 128K dır. Bu adres görüldüğü gibi 64K nın katı biçimindedir. 13h kesmesinin fonksiyonları kullanılarak disketten belleğe okuma işlemleri sırasında DMA mekanizması araya girmektedir. Yani disketteki bilgi önce DMA ya oradan da belleğe aktarılmaktadır. Ancak DMA dan belleğe aktarılacak bilgi bellekte 64K sınırları içerisinde kalmalıdır. Bellekteki 64K sınırları 1000:0000 (64K), 2000:0000 (128K), 3000:0000 (192K), biçimindedir. Öyleyse belleğe tek bir hamlede 64K aktarabilmek için aktarma adresinin 64K sınırından başlaması gerekmektedir. Böylece 64K sınırından başlayarak bir sonraki 64K sınırına değin 64K lık aktarma işlemi sorunsuz bir biçimde yapılabilecektir. İşte disketten belleğe aktarma sırasında tek hamlede 64K lık aktarma sırasında DMA sorunu ile karşılaşmamak için çekirdek kodunun disketten ilk yükleme adresi 128K biçiminde alınmıştır. CSD işletim sisteminin boot kodu çekirdek dosyasının boot kodu dışında geri kalan kısmını boot kodu BIOS tarafından belleğe aktarılmaktadır çekirdek kodu 128K dan başlayacak biçimde fiziksel belleğe aktarmaktadır. Setup programının bu aşamasında çekirdek kodu KERNEL_LOW_SEG sembolik sabiti ile belirtilen 4K adresine çekilmektedir. Bu aktarma sırasında artık DMA sorununun önemsenmesine bir gereksinim kalmamıştır çünkü burada string komutları kullanılarak bellekten belleğe kopyalama işlemi yapılmaktadır. Aşağıda DMA sorunu ile ilişkili şekil görülmektedir. 18

0000:0000 Disketten 13h kesmesi ile okuma yapıldığında DMA devreye girer. Belleğe okuma işlemi 64K sınırlarını aşmayacak biçimde yapılmalıdır. Bu durumda buradaki okuma işlemi başarısız olacaktır! Disketten 64K okuyarak belleğe yazma işlemi 64K sınırını aşacak biçimde bir hamlede yapılamaz!... 1000:0000 2000:0000 64K Şimdi bir hamlede disketten 64K okuma yapılabilir! 3000:0000 1 MB 5.1.2.3 A20 Hattının Açılması Bilindiği gibi belli bir adres değeri işlemcinin adres uçlarına elektriksel olarak bırakılmaktadır. İşlemci korumalı moda geçirildikten sonra artık 4 GB lik adres alanı kullanılabilecektir. 4 GB lik adresler işlemcinin 32 adres ucu kullanılarak oluşturulmaktadır. Bu nedenle işlemcinin tüm adres uçlarının etkin durumda olması gerekmektedir. Ancak kullanılan işlemci ne olursa olsun işlemci gerçek modda açıldığında yalnızca ilk 20 adres ucu kullanılabilmektedir ve işlemcinin 21. adres ucu 19

geriye doğru uyumun korunması için edilgin (pasif) konumdadır. Öyleyse korumalı moda geçilmeden önce mutlaka 21. adres ucunun etkinleştirilmesi gerekmektedir. PC mimarisinde A20 hattı klavye denetleyicisi ile ilişkilendirilmiştir. 8042 klavye denetleyicisinin çıktı portunun (output port) 2. biti A20 hattını kontrol etmek için kullanılmaktadır. Eğer bu bit 1 ise A20 hattı etkinleştirilir, 0 ise A20 hattı edilginleştirilir. Klavye denetleyicisine ilişkin yazmaçların durumu aşağıda gösterilmiştir: Port Mod Açıklama 64h Okuma 8042 durum yazmacı 64h Yazma 8042 komut yazmacı 60h Okuma 8042 çıktı yazmacı 60h Yazma 8042 veri yazmacı A20 hattının etkinleştirilmesi şu biçimde yapılmaktadır: Öncelikle klavye denetleyicisinin çıktı yazmacı 0x64 yazmacına 0xD1 değeri yazılarak set edilmektedir. 0xD1 komutu çıktı yazmacına yazma yapılacağı anlamına gelmektedir. Böylece bir sonraki adımda 0x60 yazmacına yazılacak değer doğrudan çıktı yazmacına alınacaktır. Bu nedenle 0x64 yazmacına yazma komutu gönderildikten sonra 0x60 portuna istenilen değer yazılacaktır. A20 etkinleştirilmesi ve edilginleştirilmesi için sırasıyla 0xDF ve 0xDD değerleri kullanılmaktadır. mov al, 0xD1 out 0x64, al ; Porta yazma komutu mov al, 0xDF out 0x60, al ; A20 hattı etkinleştiriliyor Her işlem bloğundan önce klavye tamponunun boşaltılması aşağıdaki biçimde beklenmektedir: xor cx, cx.bufclr1: in al, 0x64 loopnz.bufclr1 Tüm bu işlem blokları donanım kesmeleri edilginleştirildikten sonra uygulanmaktadır. 20

5.1.2.4 Donanım Kesmelerine İlişkin Kesme Numaralarının Ötelenmesi Intel mimarisinde gerçek modda donanım kesmelerine ilişkin kesme numaraları 0 ile 15 arasındadır. Ancak korumalı moda geçildikten sonra bu kesme numaraları işlemcinin korumalı moda ilişkin içsel kesmeleri (exceptions) ile çakışmaktadır. İşlemcinin içsel kesmeleri 0 ile 31 aralığındadır. İşte bu nedenle donanım kesmelerine ilişkin kesme numaraları programlanabilir kesme denetleyicisi programlanarak [32, 47] aralığına ötelenmektedir. 5.1.2.5 Korumalı Moda Geçiş Bilindiği gibi korumalı moda geçiş yapılmadan önce bir takım hazırlık işlemlerinin yapılmalıdır. Örneğin global betimleyici ve kesme betimleyici tabloların oluşturulması gerekmektedir. Bu nedenle korumalı moda geçmeden önce global ve kesme betimleyici tablolar geçici olarak oluşturulmakta ve bu tablolara ilişkin yazmaçlar yüklenmektedir. lidt [idtload] lgdt [gdtload] Daha sonra CR0 yazmacının en düşük anlamlı biti set edilerek korumalı moda geçiş yapılmaktadır. 5.1.2.6 Çekirdeğin Başlangıç Koduna Dallanılması KERNEL_LOW_SEG sembolik sabiti gerçek modda çekirdeğin taşındığı düşük bellek adresinin segmentini belirtmektedir. Bu değer korumalı moda geçildiğinde artık offset değeri olarak kullanılacaktır. Bu nedenle gerçek moddaki aynı fiziksel adresin elde edilebilmesi için bu değer 16 ile çarpıldıktan sonra offset olarak kullanılmaktadır. Buna göre çekirdeğin başlangıç koduna aşağıdaki gibi dallanılmaktadır: jmp KERNEL_PROVISIONAL_CODE_SEL : (KERNEL_LOW_SEG * 16) 5.2 CSD İşletim Sisteminin MSDOS Üzerinden Yüklenmesi Çekirdek dosyası oluşturulduktan tipik olarak disketten ya da sabit diskten başlatma işlemi yapılabilmektedir. Ancak dosya sistemine ilişkin çalışmalar tamamlanmadığından CSD işletim sisteminin kendi dosya sistemi kullanılarak başlatılması henüz olanaklı değildir. Bu durumda disketten sistemin başlatılması tek seçenekmiş gibi durmaktadır. Ancak disketten sistemin başlatılmasının test işlemleri sırasında bir takım sorunları vardır. Bilindiği gibi disket işlemleri sabit disk işlemlerine göre daha yavaştır. Bundan da önemlisi test işlemi sırasında bir hata 21

oluştuğunda, hata ortadan kaldırıldıktan sonra her seferinde çekirdek dosyasının yeniden derlenerek diskete aktarılması gerekmektedir. Tabii hatanın düzeltilebilmesi için yeniden bir işletim sistemi ile bilgisayarın açılması zorunludur. Bu işlem için de CSD işletim sisteminin başlatılması gibi için kullanılan disketin disket sürücüden çıkartılması gerekmektedir. İşte tüm bu nedenlerden dolayı sistemin hızlı ve pratik bir biçimde başlatılabilmesi için MSDOS işletim sistemi ile bilgisayarın başlatılıp çekirdek dosyasının MSDOS komut satırı üzerinden yüklenmesi öngörülmüştür. Sistemi MSDOS üzerinden yüklemek için CSD işletim sistemi projesi içerisinde yazılmış lcsd isimli yardımcı program kullanılmaktadır. Program çekirdek dosyasının bölümlerini uygun adreslere yükleyerek akışı CSD işletim sistemine bırakmaktadır. lcsd bir COM programı olarak yazılmıştır. Programın komut satırından çalıştırılması aşağıdaki gibidir: lcsd [çekirdek dosya ismi] Eğer komut satırında çekirdek dosyasının ismi açıkça belirtilmezse program buluduğu dizinde k.bin isimli bir çekirdek dosyasını aramaktadır. Böylece eğer çekirdek dosyasının ismi k.bin olarak alınırsa komut satırında çekirdek dosyasının ayrıca belirtilmesine gerek kalmamaktadır. Program komut satırından çalıştırıldıktan sonra MSDOS tarafından belirlenen bir adrese yüklenmektedir. Ancak çekirdek kodunun belleğe yüklenmesi sırasında lcsd nin program kodu yüklendiği adres nedeniyle ezilebilmektedir. Bu nedenle program kendini 1 MB içerisinde daha yüksek bir adrese taşımaktadır. lcsd.asm içerisinde programın gerçek yüklenme adresine ilişkin değer aşağıdaki gibi alınmıştır. %define SELF_COPY_SEG 0x9A00 ; 616K Programın yığın uzunluğu olarak 640K sınırının aşılmaması için 4K gibi küçük bir değer alınmıştır. Çekirdek dosyasının bölümlerinin yüklendiği segment adreslerine ilişkin sembolik sabitler ise aşağıdaki gibidir. %define BOOT_SEG 0x07C0 %define SETUP_SEG 0x9020 %define KERNEL_SEG 0x4000 ; 256K Bilindiği gibi hem disketten hem de MSDOS üzerinden yükleme sırasında aynı boot kodu kullanılmaktadır. Yani boot işlemine ilişkin farklı boot.bin dosyaları oluşturulmamaktadır. İşte MSDOS üzerinden yükleme sırasında boot kodunda disket işlemlerine ilişkin kodların göz ardı edilebilmesi için DX yazmacına aşağıdaki biçimde 0xFF (-1) değeri yerleştirilmektedir. mov dx, -1 22

Artık boot kodu içerisinde bu yazmaç kontrol edilerek disketten mi yoksa MSDOS üzerinden mi sistemin başlatıldığı belirlenebilecektir. lcsd programı MSDOS un disk işlemlerine ilişkin fonksiyonlarını kullanarak çekirdek dosyasını bir bütün olarak belleğe yükledikten sonra akışı aşağıdaki gibi 07C0:0000 adresine bırakmaktadır: mov ax, BOOT_SEG push ax xor ax, ax push ax retf 6. ÇEKİRDEK BAŞLANGIÇ KODU (STARTUP.ASM) Çekirdek başlangıç kodu akış KernelMain() fonksiyonuna verilmeden önce sistemin çalışacağı donanım ortamına ilişkin son işlemleri gerçekleştirmektedir. Çekirdek başlangıç kodu içerisinde genel olarak aşağıdaki işlemler yapılmaktadır: A20 Hattının Sınanması Çekirdeğin KERNEL_FINAL_POS Adresine Taşınması Sayfalama Mekanizmasının Etkinleştirilmesi Kesme Betimleyici Tablonun Oluşturulması Akışın KernelMain() Fonksiyonuna Bırakılması 6.1 Çekirdeğin KERNEL_FINAL_POS Adresine Taşınması KernelMain() fonksiyonu bağlanırken fonksiyon kodu 1 MB ye yerleştirilecek biçimde offset üretilmektedir. Bu nedenle akış KernelMain() fonksiyonuna bırakıldığı zaman fonksiyon kodunun 1 MB adresinde bulunması gerekmektedir. Bu nedenle çekirdek kodu son olarak KERNEL_FINAL_POS sembolik sabiti ile belirtilen 1 MB adresine taşınmaktadır. 6.2 Sayfalama Mekanizmasının Etkinleştirilmesi Sayfalama mekanizması etkinleştirildikten sonra artık doğrusal adres sayfa tablosuna sokularak fiziksel adres elde edilmektedir. Öyleyse sayfalama mekanizması etkinleştirilmeden önce sayfalamaya ilişkin olan dizin ve sayfa tabloları 23

oluşturulmalıdır. Dizin ve sayfa tabloları doğrusal adresler fiziksel adreslere eşit olacak biçimde oluşturulmaktadır. Dizin tablosunda yalnızca 1 dizin elemanı alınmış ve bu dizin elemanın gösterdiği sayfa tablosunun tüm elemanları kullanılmıştır. Böylece 4 MB lik (1 x 1K x 4K) bir adres alanının doğrusal adresler fiziksel adreslere eşit olacak biçimde adreslenebilmesi sağlanmıştır. Dizin ve sayfa tabloları aşağıdaki gibi oluşturulmaktadır: pagedir: dd (page0 + 111B) ; P=1, R/W=1, U/S=1 times (4096 4) db 0 page0: %assign adr 7 %rep (4096 / 4) dd adr %assign adr (adr + 0x1000) %endrep Görüldüğü gibi sayfa düzeyinde koruma yöntemi henüz kullanılmadığından sayfalar kullanıcı modunda, hem okunabilir hem yazılabilir olacak biçimde alınmışlardır. Doğrusal adreslerin fiziksel adreslere eşit olabilmesi için doğrusal adreslere ilişkin sayfa tablosu indeksleri sayfa elemanının fiziksel sayfa numarasına eşit olarak alınmıştır. 0 numaralı sayfa tablosu oluşturulduktan sonra görüntüsü aşağıdaki gibi olacaktır: Dizin Tablosu Sayfa Tablosu Page0 0 0 0 0 0 0... 0 0 İndeks Sayfa tablosunda, sayfa elemanının yüksek anlamlı 10 bitinin, yani sayfanın fiziksel bellekteki numarasının, sayfa tablosundaki indekse eşit alındığına dikkat edilmelidir. 0 1 2 3 4 5 6 7 8 1022 1023 24 Sayfa Elemanı 0000 0000 0000 0000 0000 0000 0000 0111 0000 0000 0100 0000 0000 0000 0000 0111 0000 0000 1000 0000 0000 0000 0000 0111 0000 0000 1100 0000 0000 0000 0000 0111 0000 0001 0000 0000 0000 0000 0000 0111 0000 0001 0100 0000 0000 0000 0000 0111 0000 0001 1000 0000 0000 0000 0000 0111 0000 0001 1100 0000 0000 0000 0000 0111 0000 0010 0000 0000 0000 0000 0000 0111 1111 1111 1000 0000 0000 0000 0000 0111 1111 1111 1100 0000 0000 0000 0000 0111

Örneğin 0x000B8000 doğrusal adresinin yukarıdaki sayfa tablosuna göre fiziksel adrese dönüştürüleceğini düşünelim. Bu durumda belirtilen doğrusal adres aşağıdaki gibi üç kısma ayrıştırılacaktır: Dizin İndeksi Tablo İndeksi Sayfa Offseti 0000 0000 00 00 1011 1000 0000 0000 0000 Görüldüğü gibi belirtilen adrese ilişkin dizin indeksi 0 dır. Bu durumda dizin tablosunda Page0 ile belirtilen sayfa tablosuna erişilecektir. Sayfa tablosundaki indeks değeri ise 184 tür. Yani 0x000B8000 adresi fiziksel bellekte 184 numaralı sayfaya ilişkindir. Bu sayfanın fiziksel bellekteki adresi 753 664 (184 x 4K) biçimindedir. Sayfa offseti 0 olduğuna göre belirtilen adres sayfanın başında yer almaktadır. Sonuç olarak sayfa tablosunda doğrusal adres fiziksel adrese eşit olarak alındığından sayfalama mekanizması altında gerçek moddaki fiziksel adresler elde edilmektedir. 6.3 Kesme Betimleyici Tablonun Oluşturulması Intel işlemcilerinde 256 kesme tanımlıdır. Korumalı moda geçildiğinde sözü edilen 256 kesmeye ilişkin betimleyicilerin oluşturulması ve kesme betimleyici tabloya yerleştirilmesi gerekmektedir. Her bir kesme betimleyicisi aşağıdaki gibi oluşturulmaktadır: 31 16 15 0 KERNEL_CODE_SEL DefIntrHandler[0, 15] DefIntrHandler[16, 31] 1 00 0 1110 000 Ayrılmış 63 48 47 32 Burada tüm kesmelerin giriş noktası aynıdır. Kesme betimleyicileri 64 bit uzunluğunda olduğundan betimleyiciler EAX ve EDX yazmaçları üzerinde oluşturulmaktadır. Betimleyicilerin 32 ile 47. bitlerine aşağıdaki gibi değer verilmektedir. mov dx, 0x8E00 ; 1000 1110 0000 0000 0x8E00 değeri ile betimleyiciye ilişkin segmentin bellekte ve 0 öncelik seviyesine sahip olduğu ve betimleyicinin sisteme ilişkin bir kesme betimleyicisi olduğu gibi belirlemeler yapılmıştır. 25

Kaynaklar 1. CSD İşletim Sistemi Projesi Yükleyici Grubu Çalışma Notları 2. PC Intern, Michael Tischer, Bruno Jennrich, Abacus, 1996 3. Understanding The Linux Kernel, Daniel P. Bovet, Marco Cesati, O Reilly, 2001 4. Intel İşlemcileri Korumalı Mod Yazılım Mimarisi, Kaan Aslan, Pusula Yayıncılık, 1997 5. 80x86 Sembolik Makine Dili Programlama Kurs Notları, Kaan Aslan, C ve Sistem Programcıları Derneği, 2002-2003 6. http://www.mega-tokyo.com/os/os-faq-memory.html 7. http://members.tripod.com/~oldboard/assembly/keyboard_commands.html 8. http://osdev.neopages.net/downloads/enablea20.s 26