Pazar, Nisan 16, 2006


İŞLETİM SİSTEMİ YAZMAK

Vestel Manisa dan 5 yemekten daha zor olmamakla beraber, işletim sistemi geliştirmek karmaşık bir iş. Uzun süren test süreçlerinden sonra sayısız sürüm ve yamaya ramen bile istenen seviyeye gelemeyen işletim sistemlerine bakınca bunu daha iyi anlıyoruz. Öyle veya böyle kullanmak zorunda olduğumuz bu yazılımlara olan bağımlılığımızı gelecekte aşağı çekebilmemiz için ulusal projelerde çalışacak, bu konuda yetenekli geliştiricilere ihtiyacımız var ülke olarak.

Kendi minik işletim sisteminizi yazıp bilgisayarınızı başlattığınızda koşmasını sağlamanız çok da zor değil. İşin başlangıç kısmı olan boot aşamasını intel mikroişlemcilerde nasıl gerçekleştirebileceğinizi kısaca açıklayacağım. Örnekte floppy disketten boot etmeyi anlatacağım ama CD den veya sabit diskten boot etmek için de bikaç değişiklik yeterli olacaktır.

Windows tabanlı bir sistem kurulu olan bilgisayarı başlattığımızda salt okunur bellekte (ROM) bulunan ve küçük rutinlerden oluşan BIOS, kontrolü ele alır. Linux sistemlerde ise Kernel in içinde bir emülatör olarak sistemin kendi BIOS u bulunur (LinuxBios). LinuxBios diğer ticari BIOS lara oranla çok daha güçlüdür. Başlangıç konumundayken intel işlemcimiz üst düzey bir pentium dahi olsa Real moddadır ve bir 8086 edasıyla çalışır. Ta ki başlayacak olan işletim sistemi protected moda atlayana kadar. Benim anlatacağım kısım protected moda atlamayacak tabiki:) BIOS en başta bir takım kontroller yapar ( tuştakımı bağlımı, aygıtlar uyumlumu) ve bip sesleri eşliğinde bu testler sona erer. Sonra, BIOS ayarlarında seçili olan boot aygıtının (bizde floppy) ilk sektörünü (boot sector veya sector 0) 0x7c00 bellek adresine yükler. Ardından kod akışı 0x7c00 adresinden devam eder. Bizim yapacağımız şey, boot sektörüne çalıştırmak istediğimiz programı yerleştirmek. Bu programı Assembly dilinde yazıp, as86 veya nasm ile derleyeceğiz.
Çalışmalarımızı Linux altında yapacağız. Windows altında çalışınca derlemelerde hata alırız. as86 dokumantasyonu için..

Bizim programımızın boyutu büyüdüğü zaman boot sektörü yetersiz kalacağından ikinci bir yöntem uygulayacağız. Boot sectorune koyacağımız programı kullanarak, sector2 ye koyacağımız ana programımızı bellekte istediğimiz bir adrese yerleştirip, kod akışını o bellek adresine transfer edeceğiz. Böylece ana programımız büyüdüğünde yapacağımız tek şey, boot sector deiki programda değişiklik yaparak, yeterli sayıda sektörü bellek alanına arka arkaya yüklemek olacak.

boot sector ve sector2 programlarını floppy de gereken yerlere yazacak olan C programını yazının sonunda anlatacağım.


Aygıt sürücüleri ancak işletim sisteminin başlamasından sonra belleğe yüklenirler. Biz işletim sistemini devre dışı bıraktığımız için aygıtlara BIOS interrupt ları ile ulaşacağız. Aygıt sürücüsü yazacak duruma geldiğimizde aygıtlarımızı kendimiz yönetmeye başlayabiliriz.


Boot sektör programı
LOC1=0x500

entry start
start:
mov ax,#LOC1
mov es,ax
mov bx,#0
mov dl,#0 ; drive
mov dh,#0 ; head
mov ch,#0 ; track
mov cl,#2 ; sector 2
mov al,#1 ; kaç sektör okunacak
mov ah,#2 ; 2 numaralı function
int 0x13 ; interrupt 13 ü çağır

jmpi 0,#LOC1

Bu programı bsect.s adıyla kaydedip as86 ile aşağıdaki şekilde derleyebilirsiniz.

as86 bsect.s -o bsect.o
ld86 -d bsect.o -o bsect
0x500 segmentinin 0. offsetine denk gelen adres 0x5000 dir. bsect.s programı sector 2 yi 0x5000 adresine yükledikten sonra bu adrese atlama yapar.
Gördüğünüz gibi BIOS interrupt ını çağırmadan önce gerekli parametreleri gereken
register lara atama yapıyoruz. ah registerına da interrupt 13 ün 2 numaralı
fonksiyonunu çağıracağımız için 2 değerini atıyoruz. Interrupt 13 ve diğer
interruptların kullanımlarını interntetten bulabilirsiniz.


Sector 2 deki ana program

entry start
start:
mov cl,#0x00 ; sol üst sütun
mov ch,#0x00 ; sol üst satır
mov dl,#79 ; sağ alt sütun
mov dh,#24 ; sağ alt satır
mov ah,#0x07 ; interrupt 10 un ekran temizleme fonksiyonu
mov al,#0x00 ; özellik
int 0x10 ; interrupt 10 u çağır

mov ah,#0x03 ; int 10 un imleç pozisyonunu alma fonksyonu
xor bh,bh ; video page
int 0x10 ; int 10 u çağır

mov cx,#40 ; string uzunluğu
mov bx,#0x0007 ; özellik
mov bp,#mymsg ; string adresi
mov ax,#0x1301 ; string yazma fonksyonu
int 0x10 ; int 10 u çağır

loop1:
jmp loop1 ; sonsuz döngü

mymsg: ; string etiketi
.byte 13,10
.ascii "Merhaba Dünya, nekadar banelim değilmi?"

Ana programımız ekranı temizledikten sonra ulvi mesajını bastırıyor:)
sect2.s adıyla kaydedip as86 ile derledikten sonra aşağıdaki C programı ile boş bir floppy diskete bsect.s ve sect2.s programlarını yerleştirelim.


Programları diskete yazan C programı

#include /* unistd.h needs this */
#include /* contains read/write */

#include


int main()

{

char boot_buf[512];

int floppy_desc, file_desc;


file_desc = open("./bsect", O_RDONLY);


read(file_desc, boot_buf, 510);

close(file_desc);


boot_buf[510] = 0x55;

boot_buf[511] = 0xaa;


floppy_desc = open("/dev/fd0", O_RDWR);


lseek(floppy_desc, 0, SEEK_SET);

write(floppy_desc, boot_buf, 512);


file_desc = open("./sect2", O_RDONLY);

read(file_desc, boot_buf, 512);

close(file_desc);


lseek(floppy_desc, 512, SEEK_SET);

write(floppy_desc, boot_buf, 512);


close(floppy_desc);

}


programı write.c adıyla kaydedip gcc ile aşağıdaki gibi derleyebilirsiniz.
cc write.c -o write
disketi taktıktan sonra programı çalıştırdığınızda boot sektöre ve sektör 2 ye gerekn makine kodu yazılır.

./write

Bilgisayarı disketten boot ederek nasıl çalıştığını görebilirsiniz artık. Ana programı çeşitli BIOS interruptları kullanarak daha ilginç bir hale getirebilirsiniz.

daha fazla bilgi ve ayrıntılar için

http://linuxgazette.net/issue79/krishnakumar.html
http://www.cs.umbc.edu/courses/undergraduate/CMSC211/fall01/burt/tech_help/BIOSandDOS_Interrupts.html

Hiç yorum yok: