İşletim Sistemleri hakkındaki temel bilgileri buradan ve daha başka bir çok kaynaktan edinebilirsiniz. Bu yüzden üniversitenin Ders 0 olarak hazırladığı kısmı geçiyorum. Assembly ile ilgili kısa bilgileri de buradan kısaca öğrenebilirsiniz.
Ders 1
Bu derste Raspberry Pi üzerindeki OK lambasının nasıl yakılacağını öğreneceğiz.
Yandaki resimde OK LED’inin yeri gösterilmiştir.
Başlamak için öncelikle daha önceki bir yazıda bahsettiğim gereklilikleri yerine getirmelisiniz. GNU araçlarını indirmelisiniz. Daha sonra template‘i indirip bir klasöre atın.
Template klasörü içine girin orda birkaç dosya göreceksiniz. Bunların yanına source şeklinde bir klasör oluşturun ve içine “main” isimli “s” uzantılı(main.s) bir dosya açın. Bu dosya içine assembly kodlarımızı yazacağız. Bunun için herhangi text editörü kullanabilirsiniz(nano,vi,notepad vs).
İlk komutlarımız:
[code]
.section .init
.globl _start
_start:
[/code]
şeklinde olacak. Bunlar aslında hiçbir şey yapmazlar başlangıç komutlarıdır. Assembler için talimatlardır. Assembler bizim anladığımız assembler kodlarını, RPi’nin anlayabileceği makine kodlarına çeviren programdır. “.section” ve “.init” Rpi’ye bu kodun ilk çalışması gerektiğini söyler. Sonuçta hangi kodun daha önce çalışacağından emin olmalıyız. Eğer bunu yapmazsak kodlar alfabetik olarak çağrılacaklar. İkinci satırda ise _start’ı globl olarak tanımlıyoruz ve bu etiketle bir sonraki satırda başlangıç yapıyoruz.
Assembly’de her talimat yeni bir satırda başlar. Biz de yeni satıra:
[code]
ldr r0,=0x20200000
[/code]
yazıyoruz. Burada ldr load register’ın mnemonic halidir. Mnemonic özel bir kısa yazım şeklidir. Assembly de hep bu şekilde bir kullanım söz konusudur. r0 isimli register’a 0x20200000 sayısını yüklemektedir. Bu sayı üretici tarafından belirlenmiş 16’lık tabanda GPIO kontrolcüsünün adresidir. Diğer adreslerle ilgili bilgileri üretici dökümanında bulabilirsiniz.
Çıkışa Yetki Vermek
Kullanıcı kitabından, GPIO’ya iki mesaj göndermem gerektiğini öğreniyoruz. Onun dilinden konuşmalıyız ancak böyle yaparsak ne istiyorsak yaptırabilir ve OK led’ini açtırabiliriz.
[code]
mov r1,#1
lsl r1,#18
str r1,[r0,#4]
[/code]
Bu kodlar 16. GPIO pinine yetki verir. İlk olarak, üreticinin kitabı bize GPIO controller’ının 24 bytelık bir grup olduğunu söyler. İlk 4’ü birinci 10’da bulunan GPIO pinleriyle ilgilidir, ikinci 4 sıradaki 10 ile ilgilidir ve böyle devam eder. 54 GPIO pini vardır. Bu yüzden 6 tane 4 byte’lık sete ihtiyacımız var. Her 4 byte’lık bölge içerisinde, 3 bit bir özel GPIO piniyle ilgilidir. Biz 16 GPIO pinini istediğimizden dolayı, ikinci 4 byte’lık sete ihtiyacımız var. İlk 4 byte’lık set daha önce söylediğimiz gibi ilk 10 pin ile ilgilidir. Biz 16’yı istiyoruz. Bu yüzden 3’erli gruplardan 6. bize uygun 6×3=18 buradan geliyor.
str komutu store register’in kısaltılmış şeklidir. Adres atama işlemi gerçekleştirir. Yukarıdaki ifadede r0’a daha önce hafızanın başlangıç adresini atamıştık. [r0,#4] diyerek ikinci byte’ının adresini r1 register’ına atamış oluyoruz. Şimdi 16. pin çıkış için hazır durumda.
Hayat Belirtisi
Şimdi sıra geldi led’i yakmaya. Çip üreticileri led’i yakmak için pini kapatmayı akla uygun bulmuşlar.
[code]
mov r1,#1
lsl r1,#16
str r1,[r0,#40]
[/code]
burada r1’e decimal 1 değeri taşınıyor. 16 defa sola öteleme yapılıyor ve r1’in adresine r0+40 adresi yazılıyor.
Mutlu Son
[code]
loop$:
b loop$
[/code]
b branch yani dallan komutunun kısaltılmış halidir. Koşulsuz olarak loop etiketine dallanır, sonsuz döngüye girer. Aslında her işletim sistemi koşullu olarak sonsuz döngü içinde çalışır.
RPi’de Çalıştırmak
Bu komutların hepsini Raspberry Pi dışında bir bilgisayarda yazdık. Main.s içinde yazdığımız bu kodları kaydedip kapatıyoruz. İçinde bulunduğumuz klasörün source klasörü olduğunu hatırlayalım. Buradan bir üst klasöre çıkıyoruz ve make komutu ile çekirdeğimizi derliyoruz. Derleme sonucunda üç dosya oluşacaktır. Bizim için önemli olan kernel.img dosyası. Öncelikle SD kartı bilgisayarımızda açtık ve içinde kernel.img şeklinde bir dosya zaten bulunmaktadır. Bu dosyanın adını linux_kernel.img şekline getirip kendi işletim sistemimizi SD karta atalım ve sonucu görelim.
Hatalar
[code]
arm-none-eabi-as -I source/ source/main.s -o build/main.o
/home/pi/arm-2008q3/bin/arm-none-eabi-as: 1: /home/pi/arm-2008q3/bin/arm-none-eabi-as: Syntax error: “(” unexpected
make: *** [build/main.o] Error 2
[/code]
şeklinde bir hata alırsanız bunun nedeni GNU ARMv6 araçlarını hazırlarken belirttiğiniz yolun yanlış olması. Orada export PATH=$PATH:$HOME/arm-2008q3/bin şeklinde örneklenmiş fakat eğer sizin indirdiğiniz dosya başka bir klasör içindeyse örneğin downloads gibi bir klasör içindeyse o zaman export PATH=$PATH:$HOME/downloads/arm-2008q3/bin şeklinde yazarak sorunu çözebilirsiniz.
[code]
arm-none-eabi-ld –no-undefined -Map kernel.map -o build/output.elf -T kernel.ld
arm-none-eabi-ld: no input files
make: *** [build/output.elf] Error 1
[/code]
şeklinde bir hata alırsanız bu, main.s dosyanızı source isimli bir klasör içine almadan derlediğinizden dolayıdır.
make: *** No rule to make target `kernel.ld’, needed by `build/output.elf’. Stop
böyle bir hata alıyorum yardımcı olabilir misiniz?