sayfa başı

Embedded Linux etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Embedded Linux etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

1 Nisan 2019 Pazartesi

Baştan Sona Embedded Linux Kurulumu -2-

BBB İçin Çapraz Derleyici Kurulumu


Kaynak
Tarih
Versiyon
İşlem
Zafer SATILMIŞ
2019-04-01
0.1
Döküman oluşturuldu













Belli bir süre sonra sadece google sites üzerinden yazılarımı paylaşmayı düşünüyorum. O yüzden buradan da beni takip edebilirsiniz.

1.Amaç
Bu belgede BBB için gerekli çapraz derleyicinin(cross compiler) kurulumu ve kullanımı anlatılacaktır. Uboot, Kernel derlenmesi gibi konularda çapraz derleyicimizden faydalanacağımız için kurulumun doğru ve eksiksiz olması gerekiyor. Kurulum Ubuntu-64bit makine üzerinde gerçekleştirilmiştir.
2.Çapraz Derleyicinin Kurulması
2.1.Çapraz Derleyiciler Hakkında
Kendi işlemci mimarisinden farklı bir işlemci için kod üreten derleyicilere çapraz derleyici(cross compiler) denir. Bizim PC lerimizin mimarisi x86 ve bu yüzden BBB için ARM mimarisinde kod üretmemiz gerekiyor. Özetle çapraz derleyicinin görevi budur.
Çalışabilir bir çıktı alabilmek için derleyicinin yanında linker, debugger ve dump programlarına da ihtiyaç vardır. Bunların hepsini içeren programa ise toolchain denir. Bu sebeple bunları bir takım olarak indirip çalışır hale getirmemiz gerekir.
BBB için (64bit) Linaro GCC toolchain kullanmamız gerekiyor. Güncel sürümünü buradan kendiniz de görebilirsiniz.
2.2. Çapraz Derleyicinin İndirilmesi ve Kurulumu
İlk olarak bu bu sitede belirtilen adresten çapraz  derleyicinin güncel versiyonu indirilir. İndirme işleminden sonra tar dosyası istenilen dizine taşınır ve orada açılır. Ben derleyiciler için /opt/ dizinini kullanıyorum. Yanlışlıkla silinmesi ya da bozulması gibi durumların önüne geçmek için burayı kullanıyorum. /opt/ altında toolchain olarak bir klasör oluşturalım ve kurulumu buranın içinde yapalım. Ayrıca Uçan Linux kitabının yazarı olan Nazım Koç bilgilerini referans aldığım için isterseniz onun yapısı gibi bir yapı da oluşturabilirsiniz. Açıkçası ben o şekilde çalışıyorum.
wget -c https://releases.linaro.org/components/toolchain/binaries/6.4-2018.05/arm-linux-gnueabihf/gcc-linaro-6.4.1-2018.05-x86_64_arm-linux-gnueabihf.tar.xz
Daha sonra tar açmak için aşağıdaki komutu koşalım
tar xf gcc-linaro-6.4.1-2018.05-x86_64_arm-linux-gnueabihf.tar.xz


Oluşacak dosya ismi çok uzun olduğu için arm isimli bir dizin ile link yapalım
ln -s gcc-linaro-arm-linux-gnueabihf-4.8-2014.04_linux arm
Bu adımlar sonrasında toolchain kurulumu tamamlanmış olması lazım. arm/bin dizini altında c ve c++ derleyicilerini görmiş olacaksınız. Bendeki görüntü şu şekilde:
Gerekli kütüphaneleri indirmek için ise aşağıdaki komutları koşmamız yeterli.
            apt-get install gcc-arm-linux-gnueabihf

 
Çapraz Derleyicinin Test Edilmesi
Derleyicimizi kurduk bir sorun olduğunu düşünmüyoruz ama yine de test etmek en güzeli. Ubuntu makinenizde daha öncesinden indirip kullandığınız gcc var ise arm için olan gcc ile karışmasını engellemek gerekiyor. Bunun için ilk olarak aşağıdaki komut koşulur:
export PATH=/opt/gomsis/toolchain/arm/bin:$PATH
which arm-linux-gnueabihf-gcc
Bu iki komuttan sonra aşağıdaki çıktıyı almanız gerekiyor. arm kelimesini görüyorsanız içiniz rahat olsun.
/opt/gomsis/toolchain/arm/bin/arm-linux-gnueabihf-gcc
Şimdi hello world uygulamasını derleme zamanı geldi. Eğer bu uygulamayı derleyip cihazda da çalıştığını görürsek o scp hello.out  root@192.168.7.2:/homezaman derleyici işi tamamdır. Çünkü derlenen uygulama sonrasında oluşacak output dosyası BBB bord için uygun olması gerekiyor.
Hızlıca vi ile açtığımız dosyaya hello world uygulamasını yazalım ve aşağıdaki komutları koşarak çapraz derleyici ile derleyelim. Daha sonrasında beaglebone usb kablosu ile pc bağlayalım. Beaglebone usb ile pc bağlandıktan sonra ssh ile scp komutu ile çıktı dosyamızı beaglebone gönderelim.(benim BBB ip: 192.168.7.2)
#include <stdio.h>
int main()
{
     printf("Hello, World!");
     return 0;
}
/opt/gomsis/toolchain/arm/bin/arm-linux-gnueabihf-gcc -C hello.c -o hello.out
scp hello.out  root@192.168.7.2:/home
Bu iki adım sonrasında BBB konsolundan /home dizininde hello.out dosyasını görmüş olacağız. Bu dosya ubuntu tarafında çapraz derleyici ile oluşturduğumuz çalışabilir dosyadır. (chmod 777 hello.out koşmak gerekebilir.)  Dosyayı çalıştırdığımızda Hello World çıktısını görmemiz lazım.
root@beaglebone:/home# ./hello.out
Hello, World!


                                Zafer SATILMIŞ-01.04.2019
                                    İZMİR

Baştan Sona Embedded Linux Kurulumu -1-


Giriş ve U-boot Kavramı



Kaynak
Tarih
Versiyon
İşlem
Zafer SATILMIŞ
2019-03-31
0.1
Döküman oluşturuldu













Belli bir süre sonra sadece google sites üzerinden yazılarımı paylaşmayı düşünüyorum. O yüzden buradan da beni takip edebilirsiniz.

Amaç


Bu belgenin amacı gömülü sistemler üzerinde Linux kurulumunda gerekli ön bilgileri vermektir. Sistem kurulumuna geçmeden önce ne tür sistem kurulumlarının olduğunu görmek ve linux kurulumunun gereksinimlerini aktarmak kurulum yapılırken neyin neden yapıldığını anlamamıza yardımcı olacaktır.   
Ön Bilgiler
Çalışmalar için gerekli donanım olarak BeagleBone Black kullanılmıştır. Linux sisteminin donanımdan bağımsız olduğunu bildiğimiz için sizler de istediğiniz donanım üzerinde bu anlatılanları gerçekleştirebilirsiniz.
Amaç olarak elimizdeki donanımda linux açılması için baştan sona tüm gereksinimleri yerine gerçekleştireceğiz. Gerekli kaynakların nasıl indirileceğini ve nasıl derleneceğini de adım adım yapmış olacağız. Bunun için adım adım aşağıdaki hedefleri tamamlayacağız.
  • Çapraz Derleyicinin Kurulması(cross compiler)
  • U-Boot İndirilmesi ve Derlenmesi
  • Çekirdeğin(Kernel) indirilmesi ve kurulması
  • Kök dosya sisteminin(root file system) kurulması
  • Açılışın gerçekleştirilmesi
Birçok gömülü linux kuruluş yöntemi vardır. O yüzden yukarıdaki adımlar seçilen yönteme göre değişiklikler gösterebilir. Fakat ana mantık aynı olduğu için bir yöntemi öğrendikten sonra diğer yöntemi kavramak çok kolay olacaktır.
Kuruluş yöntemlerini birbirinden ayıran fark Kernel ve RootFs bulunduğu yerlerdir. Örneğin Kernel NAND Flash, SD kart gibi bir yerde olabilir. RootFs için de farklı bir yer seçilebilir. Hatta Kernel gömülü bile olabilir.
Bunların yanında cihazın Kernel ve RootFs den önce çalışması gereken açılış yükleyicisi her zaman donanım üzerinde olmalıdır. SD kart, NAND Flash gibi bord üzerindeki alanlar en çok tercih edilenleridir. ARM sistemler için en çok kullanılan açılış yükleyicisi u-boot olduğu için gerekli çalışmaları u-boot kullanılarak yapılacaktır.
RootFs RAM üzerinde oluşturulan sistemlere Initramfs yapılı gömülü sistemler denir. RootFs uzak sunucuda ya da Kernel içinde ise buralardan alınıp RAM üzerinde açılır. 
 Açılış Yükleyicisi (u-boot)
U-boot açılış yükleyici tüm ARM cihazlar için ortak olmuştur. Firmalar kendi borduna göre u-boot için güncellemeler yaparak kullanımı kolaylaşmıştır.
u-boot iki programdan oluşur. MLO ve uboot.bin MLO ufak bir koddur ve sistemi tek başına açamaz. MLO bordun ROM bulunan basit bir program ile kolaylıkla yüklenir. MLO ayağa kalktığında gerekli adresleri atayıp çevre birimlerin ayağa kalkmasını sağlar. Ayrıca MLO tarafından esas açılış yükleyicisi olan uboot.bin yüklenir.
uboot.bin yükleminden sonra açılış yükleyicisi (u-boot) tamamlanmış olur. Ağ üzerinden ya da yerel cihazlardan Kernel, RootFs dtb, yüklenebilir. U-boot kullanılan bord göre farklı özellikler içerebilir. Tüm özellikler borda ait konfigürasyon dosyasında bulunur. O yüzden u-boot derlemeden önce uygun konfigürasyon dosyası bilinmelidir.
MLO ve uboot.bin dışında ayrıca mkimage programı da gereklidir. u-boot derlendiğinde bu üç dosya oluşur. MLO ve uboot cihazın açılış yükleyicisi için gereklidir. mkimage ise uboot.bin uygulamasının gerekli dosyaları tanıması için dosyaların başına 64 byte bilgi yazar. Bu başlık bilgisi olmadan uboot.bin ilgili dosya üzerinde işlem yapamaz. U-boot dan sonra yüklenmesi gereken Kernel imajı için mkimage ile Kernel imajı olan zImage kodunun başına 64 byte bilgi yazılmalıdır. 
Son Söz
U-boot konusu önemli ve derin konudur. Bordun açılışında önem teşkil ettiği için bu kısımda hata yaşamadan ilerlenmelidir.

30 Haziran 2015 Salı

Beagle Bone Konsola Debug Portu ile Erişim




Beagle Bone Konsola Debug Portu ile Erişim


Amaç
BeagleBone Konsolune Erişim
2.1 PUTTY ile IP Üzerinden Erişim
2.2 PUT ile Seri Port Üzerinden Erişim
2.3 Board Üzerinde Bulunan Seri Port Pinleri İle Konsola Erişim


  1. Amaç

Bu dökümanda BeagleBone konsoluna nasıl erişileceği anlatılmaktadır.
  1. BeagleBone Konsolune Erişim

BeagleBone konsoluna erişmek içini üç farklı yöntem bulunmaktadır. PUTY ile IP üzerinden erişim, PUTY ile seri port(USB seri port) üzerinden erişim, board üzerinde olan seri port pinleri ile konsola erişim olara gruplandırabiliriz.

2.1 PUTTY ile IP Üzerinden Erişim

İlk olarak Putty bu linkten indirin. Daha sonra linux makine ile fiziksel teması kurmak için ürünle beraber gelen USB kabloyu bağlayın.
Usb kablo bağlandıktan sonra makine enerjisini buradan aldığı için açılmaya başlayacaktır. Bilgisayarımızın bu USB girişini seri port olarak görmesi için driver kurulması gerekir.


Windows 64 bit için:


Windows 32 bit için:


Linux için:
Bu script  /etc/udev/rules.d/ altında 73-beaglebone.rules isminde yeni bir dosya oluşturacaktır. Bu script koşmak gerekecektir.


Cihaz açıldıktan sonra ve Windos tarafında driver kurulumu bittikten sonra PUTTY çalıştıralım. Putty ile SSH üzerinden cihaza bağlanmak için cihazın IP adresi gerekmektedir. BeagleBone fabrika çıkışı olara USB girişine sanal bir static IP adresi vermektedir. Sanal IP diyorum çünkü ethernet kablosu bağlı olmadan makine IP almaz. Bu sanal IP 192.168.7.2. Host Name (or IP address) kısmına bu IP adresini yazalım. Port numarası olarak 22 kalmalı.
Bu ayarlar yapıldıktan sonra “Open” diyerek cihaza bağlanalım. Cihaza ilk bağlandığımızda güvenlik uyarısı verecektir. Yes diyerek devam edelim. Cihaza bağlandımızda ”login as” promp ile hangi kullanıcı olarak devam edeceğimizi soracaktır.”root” deyip cihazın konsoluna erişelim.
Tüm bu adımlardan sonra BeagleBone konsoluna erişmiş oluyoruz.

2.2 PUT ile Seri Port Üzerinden Erişim

Putty çalıştıralım ve “connection type” kısmından “Serial” seçelim. Daha sonra seri port için gerekli ayarları girelim. Doğru Com Port numarasını girdikten sonra baudrate olarak 115200 değerini girelim. Bu adımlardan sonra “Open” dedikten sonra BeagleBone(BB) konsoluna erişmiş olacağız. Enter tuşuna basarak hangi kullanıcı ile bağlandığımızı ve pwd komutu ile bulunduğumuz dizini görebiliriz.

2.3 Board Üzerinde Bulunan Seri Port Pinleri İle Konsola Erişim

Board üzerinde bulunan 6 pinli header konnektor(konsol seri portu) ile BeagleBone konsoluna erişebilinir.(Debug portu) Embedded linux kartlarda genellikle bu yol ile makine konsoluna erişim yapılmaktadır. Bu yüzden BB USB seri portunu değil de bu portu kullanacağız.
Bord üzerindeki debug portunun yerini ve gerekli olan TX, RX ve GND pinlerini gösteren resim incelendikten sonra bağlantılar yapılmalıdır. Burada USB-TTL UART dönnüştürücünüzün 5V ya da 3.3V çıkışlarını bağlanmamasına dikkat ediniz. Sadece TX, RX ve GND pinleri bağlanmalıdır.
USB-TTL UART dönüştürücümüzün TX pini BeableBone RX ile, RX pini BeagleBone TX pini ile bağlanmalıdır.
Bağlantılar yapıldıktan sonra seri port terminal programımız(SecureCRTPortable) açıp konsola erişebiliriz.


USB-TTL RS232 Dönüştürücü









14 Mart 2015 Cumartesi

Adım Adım Linux Driver Yazıyoruz -3-

     Yolu buraya düşen herkse ilk olarak Merhaba. Bugün yazdığımız modülü derleyip çalıştıracağız. Bir önceki yazımda makefile oluşturacağımzı bahsetmiştim. Bu yazımda da Makefile hakkında kısa bir yazı yazmıştım. Bu yazılardan sonra kaldığımız yerden devam edelim.
    İlk olarak modülümüz derlememize yardımcı olacak Makefile kodunu aşağıda bulunmakta. Makefile dosyası ile .c uzantılı modül kodumuzu aynı dizine koyalım ve konsoldan o dizine gidelim. Derleme için tek yapmamız gereken konsola make yazıp entere basmak. Hepsi bu. Belki KERNEL_SOURCE := /usr/src/linux-headers-3.13.0-32-generic bağlı olarak hata alabilirsiniz. Onu da kendi PC bulunan ayara göre düzenleyerek çözebilirsiniz. Zaten /usr/src/ dizinine giderseniz orada linux-...... diye birşey görürsünüz. Gerisi kopyala yapıştır.

# Makefile – makefile of our first driver

# if KERNELRELEASE is not defined, we've been called directly from the command line.
# Invoke the kernel build system.
ifeq (${KERNELRELEASE},)
 KERNEL_SOURCE := /usr/src/linux-headers-3.13.0-32-generic
 PWD := $(shell pwd)
default:
 ${MAKE} -C ${KERNEL_SOURCE} SUBDIRS=${PWD} modules

clean:
 ${MAKE} -C ${KERNEL_SOURCE} SUBDIRS=${PWD} clean

# Otherwise KERNELRELEASE is defined; we've been invoked from the
# kernel build system and can use its language.
else
 obj-m := zafer.o //derlenecek .c dosyasının ismi verilmeli
endif
    Derleme işleminden sonra elimizde .ko uzantılı bir dosya oluştu. Bundan sonra yapmamız gereken ilk iş ya seriport üzerinden ya da tftp ile bu dosyayı cihaza aktarmamız olacak. Bu adımı da başarılı bir şekilde yaptığımızı varsayarak sıradaki işlemlere geçelim.

    Cihazımıza .ko uzantılı kernel objesini  yükledik. Peki bu dosyayı nasıl çalıştıracağız. Tabiki normal çalıştırılabilir dosyalar gibi ./isim.ko şeklinde çalıştıramayız. Modül dosyalarını çalıştırmak ya da durdurmak için tanımlanmış komutlar vardır. Özetle onlara bir göz atalım.
  • lsmod: yüklenmiş modül dosyalarını listeler
  • insmod: modülü Kernel yükler yani çalışmasını sağlar
  • rmmod: Kernel yüklenen modülü geri alır. Çalışmasını durdurur.
    Şu bilgiyi hatırlayalım: yüklenmiş modüller major numarası ve isimleri ile /proc/devices/ dizini altında görülür. Yazdığımız modülün Kernel yüklenmesi yani çalışır duruma gelmesi için insmod komutunu koşalım $insmod modül_ismi koşalım. Şimdi modülümüz Kernel yüklenmiş oldu. Teyit etmek için cat /proc/devices/ komutunu kullanalım. Verdiğimiz isim ve major numarası ile cihazımız tam karşımızda olması lazım. Major numarasını bir yere not edelim. Kısa bir süre bu numara bizim için önemli olacak.
    Madem insmod ile modülü yükledim, o zaman /dev/ altında normal cihazlar gibi görüp kullanmam gerekir diyenlere bunun şimdilik imkansız olduğunu söylemek gerekir. Cihaz dosyasını /dev/ altında oluşturma işini şimdilik elle yapacağız. 
             sudo mknod /dev/isim c 250 0
   Buradaki isim bağımsız olarak verebileceğimz bir isim, istediğiniz isimi verebilirsiniz. c char device file. 250 hani kaydettiğimiz major numarası vardı ya işte o değer, 0 ise cihaza atayacağımız minor numarası. Bu adımdan sonra ls -l /dev/ yaptığıızda /dev/ altında yeni oluşan dosyayı görebiliriz.


Otomatik Cihaz dosyasını(Device File) Oluşturma

    Bir önceki adımda cihaz dosyasını(Device File) mknod komutu yardımıyla elle oluşturduk. Şimdiki adımımız bu işlemi otomatik olarak yapma.
    2.4 Kernel versiyonna kadar device file oluşturma işi devfs ait uygun API ile Kernel tarafından otomatik olarak yapılırdı. Kernel' ın gelişmesiyle geliştiriciler cihaz dosyasının kullanıcı katmanına ait bir olduğunu düşünerek bunun kullanıcılar tarafından yapılmasına karar verdiler.
    <linux/device.h> altındaki fonksiyonlara bakarak bu işlemi gerçekleştirelim.
struct class *cl;

if (IS_ERR(cl = class_create(THIS_MODULE, MY_DRIVER_CLASS_NAME)))
{
 rv = PTR_ERR(cl);
 goto err_class_create;
}

if (IS_ERR(dev_ret = device_create(cl, NULL, dev, NULL, MY_DRIVER_DEVICE_FILE_NAME)))
{
 rv = PTR_ERR(dev_ret);
 goto err_device_create;
}
    Bu kod parçasını init fonksiyomuz içine koyarak cihaz dosyasını otomatik olarak oluşturmuş oluruz. IS_ERR makrosu ile fonksiyonların geri dönüş değerleri test edildi. Her ne kadar C kullananlar goto kullanmayı sevmese de burada goto iyi bir tercih. “Linux Device Drivers” kitabinda sayfa 33' de goto için yazılanlar aynen size aktarıyorum. "We normally hate to use goto, but in our opinion, this is one situation where it is useful."  Bu cümlenin ardından verdikleri örnek de şu şekilde:
int __init my_init_function(void)
{
   int err;

   /* registration takes a pointer and a name */
   err = register_this(ptr1, "skull");
   if (err) goto fail_this;
   err = register_that(ptr2, "skull");
   if (err) goto fail_that;
   err = register_those(ptr3, "skull");
   if (err) goto fail_those;
   return 0; /* success */
   fail_those: unregister_that(ptr2, "skull");
   fail_that: unregister_this(ptr1, "skull");
   fail_this: return err; /* propagate the error */
}
    Peki IS_ERR hata olduğunu bildirir ve goto nun gösterdiği yere gidersek burada ne yapacağız. 
err_device_create:
 class_destroy(cl);
err_class_create:
 cdev_del(&c_dev);
    Burada bir şeye dikkat çekmek isterim. İlk sorguya ait hata işleme yeri ikinci sorguya ait hata işleme yerinden daha sonra yazılmış yani en son adım hata oluşursa kendinden önceki tüm adımlarda yapılan işlemler hatalıymış gibi onlar da geri alınmalı. Hataları ele alma yeri init fonksiyonun sonunda return hemen önce olmalı. Ayrıca exit fonksiyonumuzda da bu durumları ele almalıyız. Bu kadar sözel açıklamadan sonra kodun son halini görerek anlatılanların resmine bakalım.
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/cdev.h>

static dev_t dev;          //dev device number
static struct cdev c_dev;   //character device structure
static struct class *cl;   //device class


static int __init myModule_init(void) /* Constructor */
{
 int retVal = -EACCES;
 struct device *dev_ret;

 if ((retVal = alloc_chrdev_region(&dev, 0, 1, "zafer")) < 0)
 {
  goto err_alloc_dev_region;
 }

 if (IS_ERR(cl = class_create(THIS_MODULE, "chardriver")))
 {
  retVal = PTR_ERR(cl);
  goto err_class_create;
 }

        /*Burada verdigimiz isim /dev/ altinda gorulur "myDevice"*/
 if (IS_ERR(dev_ret = device_create(cl, NULL, dev, NULL, "myDevice"))) 
 {
  retVal = PTR_ERR(dev_ret);
  goto err_device_create;
 }
 return 0;

err_device_create:
 class_destroy(cl);
err_class_create:
 cdev_del(&c_dev);
err_cdev_add:
 unregister_chrdev_region(dev, 1);
err_alloc_dev_region:
 return retVal;
}

static void __exit myModule_exit(void) /* Destructor */
{
 cdev_del(&c_dev);
 device_destroy(cl, dev);
 class_destroy(cl);
 unregister_chrdev_region(dev, 1);
 printk(KERN_INFO "myModule unregistered");
}

module_init(myModule_init);
module_exit(myModule_exit);

MODULE_AUTHOR("Zafer Satilmis");
MODULE_DESCRIPTION("First Character Driver");
    Artık modülümüz hazır. /dev/ altında da cihaz dosyamızı görür durumdayız. Bundan sonraki adım kullanıcı katmanında bu cihaz dosyası ile cihazı kontrol etmek. Bunun için son adım olan dosya operasyonları kodunu yazacağız. Dosya operasyonları ile cihazımız üzerinde okuma, yazma işlemleri yapacağız. ioctl(input/output control) ile cihaza kendimizin tanımladığı komutları vereceğiz. Bu işlemler sonucunda tam kullanışlı bir iş yapmış olacağız. 

Faydalanacağını düşündüğünüz kişilere iletin, eksik ya da yanlış olduğunu düşündüğünüz yerleri belirtin.


Şimdi Yazmaya Devam ....