
İŞ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=0x5000x500 segmentinin 0. offsetine denk gelen adres 0x5000 dir. bsect.s programı sector 2 yi 0x5000 adresine yükledikten sonra bu adrese atlama yapar.
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
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 startAna programımız ekranı temizledikten sonra ulvi mesajını bastırıyor:)
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?"
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
#include
#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 writedisketi 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:
Yorum Gönder