Hawkboard

hawkboard

Hawkboard, TI (Texas Instruments) firmasının geliştirdiği, OMAP ARM9 (OMAP-L138) işlemcisini kullanan açık bir donanımdır.

Temel olarak aşağıdaki bileşenlere sahiptir.

İşlemci ARMV5/ARM926
DSP C674x Floating Point
RAM 128 MB DDR
NAND 128 MB
MMC/SD Var
Ethernet Var
VGA Var
Konsol Var

Not: Hawkboard projesi, kartın bazı donanım problemleri nedeniyle sonlandırılmış durumdadır. Fakat kartın NAND, Ethernet ve VGA gibi bileşenlere sahip olması, bu tür sistemleri tanıma sürecinde bizim için kullanışlı bir çalışma ortamı oluşturacaktır.

Bu bölümde, cihaz için önyükleyici ve işletim sistemi çekirdeğinin nasıl derlendiğinden, sonrasında cihazı kendi bilgisayarımız üzerinden (Host) nasıl açabileceğimize (Recovery) ve temel bazı kullanım senaryolarına bakacağız.

İlk olarak, önyükleyici ve çekirdeği nasıl edinip derleyebileceğimize bakalım.

Not: Derleme sürecinde CodeSourcery geliştirme araçlarını kullanacağız. Bu aşamada çapraz derleyicinizin yol ifadesinin PATH çevre değişkeninde tanımlı olduğundan emin olunuz.

Ayrıca başka bir derleyici kullanıyorsanız, önyükleyici ve çekirdek derleme aşamalarında, derleyicinize ait öneki (prefix) kullanmalısınız. CodeSourcery için derleyici öneki arm-none-linux-gnueabi- şeklindedir.

Önyükleyici (Bootloader)

Hawkboard, U-Boot önyükleyicisini kullanmaktadır.

wget -c http://hawkboard.googlecode.com/files/u-boot-omapl1_v1.tar.bz2
tar xf u-boot-omapl1_v1.tar.bz2
cd u-boot-omapl1
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- distclean
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- omapl_hawkboard_config 
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-

Bu aşamada ana dizinde u-boot dosyası oluşmuş olmalıdır.

Çekirdek (Kernel)

wget -c http://hawkboard.googlecode.com/files/linux-omapl1_ver1.tar.bz2
tar xf linux-omapl1_ver1.tar.bz2
cd linux-omapl1
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- distclean
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- omapl138_hawkboard_defconfig
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- uImage

Bu aşamada ana dizinden itibaren arch/arm/boot dizininde, U-Boot tarafından yüklenebilecek, çekirdek imajı uImage oluşmuş olmalıdır.

Şimdi kartı sıfırdan nasıl açabileceğimize bakalım.

Kartın Kurtarılması (Board Recovery)

Kart üzerinde, açılış sürecine ilişkin alt seviye bir yazılım olmaması, bu yazılımın bozulmuş olması durumununda veya bu süreç bypass edilmek istendiğinde, kartın dışarıdan açılması tek veya alternatif bir seçenek olarak karşımıza çıkmaktadır.

Kart kurtarma senaryolarında genel olarak cihaza SD kart, USB veya seri port üzerinden ilk olarak önyükleyicinin atılarak çalıştırılması hedeflenmektedir. Cihaz üzerinde önyükleyici çalıştırıldıktan sonra seri terminal üzerinden cihazla alt seviye bir iletişim kurulabilir ve sonraki adımlara buradan devam edilebilir.

Hawkboard seri port üzerinden (UART Recovery) açılabilmektedir. Öncesinde, daha önce derlediğimiz önyükleyici dosyasını (u-boot) seri port için uygun şekilde imzalamalıyız. Bu imzalama ve önyükleyiciyi cihaza atma işlemleri için TI tarafından hazırlanan AIS Generator / UART Host Tool araçlarını kullanacağız. Gerekli araçları sisteminize kurmak için ilk olarak aşağıdaki zip dosyasını indirebilirsiniz.

Not: TI tarafından sağlanan bu araçlar, maalesef Linux karşılıkları olmayan, .NET Framework bağımlılığı olan pencereli uygulamalardır. Linux altında bu programları kullanabilmek için sisteminizde mono, mono-vbnc ve wine paketleri bulunmalıdır.

wget -c http://www-s.ti.com/sc/techlit/sprab41.zip

zip dosyasından AISgen_d800k008_Install_v1.13.exe kurulum dosyası çıkacaktır. Kurulum sonrasında, sırasıyla imzalama ve cihaza önyükleyici atmak için AISgen_d800k008.exe ve UartHost.exe uygulamalarını kullanacağız.

İlk olarak, imzalama işlemini nasıl yaptığımıza bakalım.

Not: İşlemci yongasındaki ROM önyükleyici dışarıdan okuyacağı bir sonraki önyükleyiciyi, TI tarafından geliştirilen, Application Image Script (AIS) formatında beklemektedir. Formatın detaylarına TI dokümanlarında mevcuttur.

Seri Port Hedefli İmzalama

AISgen imzalama uygulamasında General ve DDR sekmelerine aşağıdaki değerleri vermeliyiz. DDR sekmesinin görünür olması için General sekmesinde, Configure DDR seçeneği işaretlenmelidir.

General:

Özellik Değer
Device Type d800k002 - ARM
Boot Mode UART2

DDR:

Özellik Değer
Memory Type DDR2
DRPYC1R 0x43
SDCR 0x00134632
SDCR2 -
SDTIMR1 0x26492a09
SDTIMR2 0x7d13c722
SDRCR 0x249

Not: Bu aşamada yukarıdaki bu değerlerin ne anlama geldiğini bilmek zorunda değiliz.

Linux altında aldığımız örnek ekran görüntüleri aşağıdaki gibidir.

recovery

recovery

Sonrasında, ARM Application File bölümüne daha önce derlediğiniz u-boot dosyasını, AIS Output File bölümünü de oluşturulacak olan dosya ismini vererek imzalama işlemini gerçekleştirebilirsiniz. Biz imzalı dosyamıza u-boot_uart.bin ismini verdik.

Şimdi imzalanmış önyükleyici dosyasını Hawkboard'a nasıl atacağımıza bakalım.

Seri Port Üzerinden Önyükleyicinin Atılması

Bu amaçla UartHost.exe uygulamasını kullanacağız. Fakat öncesinde cihaz üzerindeki açılış sürecini kontrol eden anahtarları (Boot Switches) uygun şekilde ayarlamalıyız. Üretim aşamasında işlemci içindeki dahili bir hafızaya kodlanan önyükleyici (ROM Bootloader) bu anahtarların durumuna göre sonraki önyükleyiciyi NAND veya seri port üzerinden okumaya çalışmaktadır. Cihazı seri port üzerinden açabilmek için boot anahtarları aşağıdaki gibi ayarlanmalıdır.

Not: Boot anahtarları, kart üzerinde DIP switch şeklinde bulunmaktadır. Reset butonunun yakınında bulunan bu anahtarlar SW1 olarak isimlendirilmiştir.

1 2 3 4
OFF ON OFF ON

Bu durumda, cihaza enerji verildiğinde veya resetlendiğinde, seri terminale BOOTME mesajını gönderecektir. Cihaza önyükleyiciyi atmadan önce bu mesajın geldiğinden emin olunuz ve seri terminal bağlantınızı sonlandırınız.

Şimdi UartHost.exe uygulamasını kullanabiliriz. Uygulamaya daha önce imzaladığımız u-boot dosyasını ve seri portu göstermeliyiz, ayrıca Wait for BOOTME seçeneğinin seçili olduğundan emin olunuz. Bu durumda uygulamada Start butonuna bastığımızda Linux altında aldığımız örnek ekran görüntüsü aşağıdaki gibidir.

Bu aşamada uygulama cihaza enerji vermemizi veya resetlememizi beklemektedir. Cihaz yeniden başlatıldığında, imzalanmış u-boot cihaza atılacaktır. Örnek ekran görüntüsü aşağıdaki gibidir.

Sonrasında seri terminal üzerinden cihaza bağlanıp enter tuşuna bastığınızda u-boot komut satırını görmelisiniz. printenv ile önyükleyicinin kullandığı çevre değişkenlerini görebilirsiniz.

hawkboard.org > printenv
bootargs=mem=128M console=ttyS2,115200n8 root=/dev/ram0 rw initrd=0xc1180000,4M ip=dhcp
bootcmd=
bootdelay=3
baudrate=115200
bootfile="uImage"
stdin=serial
stdout=serial
stderr=serial
ethaddr=0a:c1:a8:12:fa:c0
ver=U-Boot 2009.01 (Oca 21 2015 - 14:11:03)

Environment size: 254/131068 bytes

Bu aşamadan sonra sistemi açmak için bir çok seçeneğe sahibiz. Sırayla bunlardan bazılarını kısaca inceleyim.

Cihazın TFTP ve NFS Üzerinden Açılması

Bu yöntemi kullanarak, ağ üzerindeki başka bir sistemden veya geliştirme yaptığınız bilgisayardan, çekirdeği cihaza çekmek ve uzaktaki bir dosya sistemini mount etmek mümkündür. Öncesinde geliştirme yaptığınız bilgisayarınızda TFTP ve NFS sunucuları kurulu olmalıdır.

Uzaktaki bir makinadan çekirdeği cihaz üzerine aşağıdaki gibi çekebilirsiniz.

setenv autoload no
dhcp
setenv serverip <TFTP sunucu adresi>
tftp c0700000 uImage

Açılış sırasında root dosya sistemi olarak NFS'i kullanmak için ise bootargs değişkenine aşağıdaki formda değerler geçirilmelidir.

setenv nfsroot ${serverip}:<Uzak makinadaki NFS dizini>

setenv bootargs "root=/dev/nfs nfsroot=${nfsroot} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:eth0"

dhcp özelliğinin olmaması durumunda, cihaz IP, gateway ve netmask değerlerini aşağıdaki gibi verebilirsiniz.

setenv ipaddr <Cihaz IP adresi>
setenv gatewayip <Gateway adresi>
setenv netmask <Netmask>

Sonrasında daha önce çekirdeği çektiğiniz adresteki kodu çalıştırarak cihazı açabilirsiniz.

bootm <Çekirdeğin belleğe çekildiği adres>

Kendi sistemimiz için örnek bir kullanım aşağıdaki gibidir.

setenv autoload no
dhcp
setenv serverip 172.16.2.136
tftp c0700000 uImage
setenv nfsroot ${serverip}:/nfsroot
setenv bootargs "console=ttyS2,115200 init=/bin/sh root=/dev/nfs nfsroot=${nfsroot} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:eth0"
bootm c0700000

Şimdi, bir diğer alternatif olarak, cihazı NAND üzerinden nasıl açabileceğimize bakalım.

Cihazın NAND Üzerinden Açılması

Cihazı NAND üzerinden açabilmek için ilk olarak gerekli dosyaları bir şekilde NAND üzerine yazmalıyız. Bu işlemi, dosya sistemini NFS üzerinden mount edip, Linux üzerinden yapabildiğimiz gibi, U-Boot üzerinden de yapabiliriz. Fakat öncesinde, daha önce seri port için yaptığımıza benzer şekilde, NAND üzerine yazacağımız u-boot dosyasını imzalamalıyız.

Şimdi sırasıyla, imzalama işlemine ve gerekli dosyaları NAND üzerine nasıl yazabileceğimize bakalım.

NAND Hedefli İmzalama

İmzalama işlemi için yine AISgen_d800k008.exe uygulamasını kullanacağız, seri port için imzalama yaparken kullandığımız aynı değerleri kullanacağız yalnız Boot Mode tipini NAND Flash olarak seçmeliyiz.

General:

Özellik Değer
Device Type d800k002 - ARM
Boot Mode NAND Flash

NAND Bölümlendirmesi

Çekirdek, NAND üzerinde sanki bir bölümlendirme (Partition) yapısı varmış gibi işlem yapabilir. Bu bölümlendirme, Linux kaynak kodu içerisinden sabit olarak ayarlanabileceği gibi çekirdeğe önyükleyici tarafından geçirilen argümanlar vasıtasıyla dinamik olarak da yapılabilir.

Sabit bölümlendirme bilgileri arch/arm/mach-davinci/board-omapl138-hawk.c dosyasında mtd_partition türündeki omapl138_hawk_nandflash_partition isimli bir dizi ile temsil edilmektedir.

Dinamik bölümlendirme için ise çekirdek kodu command line partition table parsing seçeneği seçilerek derlenmeli ve çekirdeğe mtdparts komut satırı seçeneği geçirilmelidir. Örnek olarak aşağıdaki gibi bir bölümlendirme oluşturalım.

Bölüm Uzunluk
U-Boot_Env 128K
U-Boot 512K
Kernel 4M
Recovery 40M
FileSystem Kalan Boş Alan

Bu bölümlendirmeyi oluşturabilmek için çekirdeğe, diğer komut satırı parametreleriyle beraber, aşağıdaki mtdparts değerini geçirmeliyiz.

mtdparts=davinci_nand.1:128K(U-Boot_Env),512K(U-Boot),4M(Kernel),40M(Recovery),-(FileSystem)

Not: Yukarıdaki ifadede davinci_nand, mtd id değerini, noktadan sonra eklenen 1 değeri ise aygıt numarasını göstermektedir. mtd id değerine, Linux üzerinden, aşağıdaki gibi ulaşabilirsiniz.

ls /sys/bus/platform/drivers | grep nand

Linux üzerinden NAND bölümlendirmesini cat /proc/mtd şeklinde görebilirsiniz. Örneğimiz için çıktı aşağıdaki gibidir.

# cat /proc/mtd 
dev:    size   erasesize  name
mtd0: 00020000 00020000 "U-Boot_Env"
mtd1: 00080000 00020000 "U-Boot"
mtd2: 00400000 00020000 "Kernel"
mtd3: 02800000 00020000 "Recovery"
mtd4: 05360000 00020000 "FileSystem"

Her bir bölüm üzerinde, bir blok aygıt (block device) olarak işlem yapılabilir. İlgili dosya düğümlerini aşağıdaki gibi listeleyebilirsiniz.

# ls /dev/mtdblock*
/dev/mtdblock0  /dev/mtdblock1  /dev/mtdblock2  /dev/mtdblock3  /dev/mtdblock4

Şimdi sırasıyla önyükleyici, çekirdek imajı ve dosya sistemini nasıl yazabileceğimize bakalım. Ayrıca, FileSystem olarak isimlendirdiğimiz son bölümden önce Recover isimli başka bir bölüm daha oluşturduğumuza dikkat ediniz. Bu bölüm üzerinde, güvenlik amaçlı, yalnız okunabilen bir dosya sistemi oluşturacağız.

Gerekli Dosyaların Linux Üzerinden Yazılması

İlk olarak, NAND üzerine yazacağımız önyükleyici, çekirdek ve dosya sistemi imajlarını NFS üzerinden açtığımız cihazımızın dosya sistemine kopyalamalıyız. Gerekli dosyaları /opt altına attığımızı kabul edelim.

/opt # ls
rootfs.jffs2     uImage
rootfs.sqsh      u-boot_nand.bin
Dosya Türü
u-boot_nand.bin NAND için imzalanmış önyükleyici
uImage Çekirdek imajı
rootfs.sqsh squashfs dosya sistemi imajı
rootfs.jffs2 jffs2 dosya sistemi imajı

Gerekli dosyaları dd aracı ile aşağıdaki gibi sırasıyla NAND üzerine yazabiliriz.

Uyarı: Bu işlemler öncesinde, U-Boot komut satırından nand erase ile tüm NAND'i silmeyi unutmayınız. Diğer bir alternatif mtd-utils araçlarını cihaz hedefli derleyerek aynı işlemi Linux üzerinden yapmak olabilir.

dd if=u-boot_nand.bin of=/dev/mtdblock0 bs=128k
dd if=uImage of=/dev/mtdblock2 bs=128k
dd if=rootfs.sqsh of=/dev/mtdblock3 bs=128k
dd if=rootfs.jffs2  of=/dev/mtdblock4 bs=128k

Şimdi aynı işlemi u-boot üzerinden nasıl yapabileceğimize bakalım.

Gerekli Dosyaların U-Boot Üzerinden Yazılması

nand erase 0x20000 0x80000
tftpboot 0xc0700000 u-boot_nand.bin
nand write.e 0xc0700000 0x20000 0x80000

nand erase 0xA0000 0x400000
tftpboot 0xc0700000 uImage
nand write.e 0xc0700000 0xA0000 0x400000

nand erase 0x2CA0000 0x1000000
tftpboot 0xc0700000 rootfs.sqsh
nand write.e 0xc0700000 0x2CA0000 0x1000000

nand erase 0x4A0000 0x1000000
tftpboot 0xc0700000 rootfs.jffs2
nand write.e 0xc0700000 0x4A0000 0x1000000

nand write.e komutunun genel şekli aşağıdaki gibidir.

nand write.e <memory address> <offset> <size>

Çekirdeğe geçireceğininiz NAND bölümlendirmesini değiştirmeniz durumunda, kullandığımız ofset değerleri de değişecektir. Ayrıca yukarıdaki örnek kullanımda dosya sistemlerinin 16M sınırında olduğu kabul edilmiştir, boyut olarak 0x1000000 değerinin kullanıldığına dikkat ediniz.

Root dosya sisteminin uygun parametlerle jffs2 imajının oluşturuluması ve sonrasında, U-Boot veya Linux üzerinden, NAND üzerine yazıldıktan sonra tekrar okunmasında bazı problemler ortaya çıkabilmektedir. Bu yüzden önyükleyici ve çekirdeği u-boot üzeriden yazmanızı, dosya sistemini ise Linux üzerinden ilgili bölümü mount edip dosya sistemini kopyalamanızı öneririz.

Önerilen Yöntem

U-Boot:

nand erase

tftpboot 0xc0700000 u-boot_nand.bin
nand write.e 0xc0700000 0x20000 0x80000

tftpboot 0xc0700000 uImage
nand write.e 0xc0700000 0xA0000 0x400000

setenv nfsroot ${serverip}:/nfsroot

setenv bootargs "console=ttyS2,115200 init=/bin/sh root=/dev/nfs nfsroot=${nfsroot} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:eth0"

bootm c0700000

Linux:

mount -t jffs2 /dev/mtdblock4 nand/
tar xf rootfs.tgz -C nand/
umount nand

Bu aşamada ROM yükleyicinin, bir sonraki açılışta, u-boot yükleyicisini NAND üzerinden araması için boot anahtarları aşağıdaki gibi ayarlanmalıyız.

1 2 3 4
ON OFF OFF OFF

Gerekli dosyaları NAND üzerine yazdıktan sonra cihazın kendiliğinden NAND üzerinden açılabilmesi için önyükleyici üzerinde bazı değişiklikler yapmalıyız. Cihazı resetleyerek tekrar u-boot komut satırına düşelim.

Çekirdeğe, root dosya sisteminin yerini ve tipini geçirmeliyiz. Aşağıdaki kullanımda root=/dev/mtdblock4 dosya sisteminin aranacağı NAND bölümünü, rootfstype=jffs2 ise dosya sisteminin tipini göstermektedir. Sonrasında NAND üzerindeki çekirdek kodu, güvenli bir adrese çekilip başlatılmalıdır. nand read ve bootm komutları bu işleri yapmaktadır. bootcmd ile gösterilen komutlar, açılışta önyükleyici tarafından otomatik olarak çalıştırılarak, bu komutların icra edilmesi sağlanır.

setenv bootargs "console=ttyS2,115200 init=/bin/sh root=/dev/mtdblock4 rootwait rootfstype=jffs2 mtdparts=davinci_nand.1:128K(U-Boot_Env),512K(U-Boot),4M(Kernel),40M(Recovery),-(FileSystem)"

setenv bootcmd 'nand read c0700000 A0000 200000; bootm c0700000'

saveenv

Bu aşamadan sonra cihaz resetlendiğinde, dışarıdan herhangi bir müdahale olmaksızın, dahili NAND hafızası üzerinden açılacaktır.

results matching ""

    No results matching ""