:::: MENU ::::
Browsing posts in: Turkish

SELinux entegrasyonu nasil yapilir?

SELinux çalışan bir Linux sistemini ayaga kaldırmak için gereken çalışmalar anlatılacaktır. 

Kernel seviyesinde SELinux

Kernel’in derleneceği toolchain, 2014-09 linaro arm-linux-gnueabihf’nin SELinux özelinde geliştirilmiş halidir. Repo adresi: https://github.com/eckucukoglu/arm-linux-gnueabihf

Kernel olarak 3.10.80 Linux kernel’i kullanılacaktır. 
omap2plus_defconfig ile konfigüre edilen kernelde, ardindan ethernet için usb, eger pandaboard es chipsee expansion board kullaniliyorsa, ekranı için chipsee dpi, input device için touchscreen ads7846 sürücüleri açılabilir.

CONFIG_USB_EHCI_HCD
CONFIG_USB_PHY
CONFIG_NOP_USB_XCEIV
CONFIG_PANEL_CHIPSEE_DPI
CONFIG_TOUCHSCREEN_ADS7846

Ardından SELinux için gerekli konfigurasyon ayarları açılmalıdır. Bunlar:

CONFIG_AUDIT
CONFIG_SECURITY_NETWORK
CONFIG_SECURITY_SELINUX
DEFAULT_SECURITY_SELINUX

Ayrıca kullanılan filesystem için ‘extended attribute’ desteği açılmalıdır. Bunlar ise (ext2 filesystem için):

CONFIG_EXT2_FS_XATTR
CONFIG_EXT2_FS_SECURITY

Diğer SELinux ayarları da incelenip, ihtiyaca göre kullanılabilinir. Bunlara ek olarak debug amaçlı low-level debugging özelliği de açılabilir.

CONFIG_DEBUG_LL
DEBUG_OMAP4UART3
CONFIG_EARLY_PRINTK

Userspace seviyesinde SELinux

Userspace’de selinux kütüphanelerini derledikten sonra rootfs içerisine koymalıyız. Fakat öncelikle buildroot ile ihtiyaç duyulan temel araçları içeren bir rootfs paketi cikartilabilinir.

Cikan rootfs icerisinde asagidaki degisiklikler, ihtiyaca gore, uygulanabilir:

  • NFS kullanildigi durumda, /etc/network/interfaces dosyasından dhcp servisi kapatılmalı, cihaz nfs kullanıyorsa network bilgileri girilmelidir.
  • auditd kullaniliyor ve baslatilmasinda sikinti varsa: /etc/audit/auditd.conf dosyasının owner’ı değiştirilmeli ve dispatcher adresi güncellenmeli. (audit deamon çalışması için yapılmaktadır. /etc/init.d/S01auditd start yazarak manuel başlatılarak, hata vermesi durumunda /var/log/messages kontrol edilebilinir.)
  • libpcre.so.3 (sistemdeki libpcre’e bağlanacak) symlink oluşturulmalı. (buildroot rootfs’lerinde karsilastigim bir hata, cozumunu bu sekilde sagliyorum.)
  • m4 binary’si /usr/bin içerisine atılacak. (refpolicy-arm için gerekli)

Bu işlemlerin ardından şu repodaki selinux derlenmelidir: https://github.com/eckucukoglu/selinux-arm
Derleme esnasında yine aynı toolchain kullanılacaktır. Çıkan dosyalar olduğu gibi rootfs içerisine kopyalanabilir.

Reference policy yükleme

Sistemimizde SELinux userspace kütüphaneleri ve araçları yer alıyorsa, bir sonraki aşamada SELinux reference policy project derlenerek sisteme yüklenmelidir. Bu policy içerisinde, gömülü bir sistemin ihtiyaçlarından çok fazlası yer almaktadır. Bu nedenle direkt olarak reference policy’nin kullanılması doğru değildir. Gömülü, mobil sistemlerin ihtiyaçları doğrultusunda aşamalı olarak kırpılması gerekmektedir.

Reference policy project için su repo kullanilmistir: https://github.com/eckucukoglu/refpolicy-arm

Burada önemli olan nokta contrib modülü (policy/modules/contrib) bir subproject olduğu için, proje clone’lanırken bu dizin içindeki dosyaların varlığı kontrol edilmelidir.

Proje içinde çalışmaya başlamadan önce “make bare” diyerek olası ihtiyaç dışı dosyaları temizlemek gerekebilir.
Öncelikle build.conf dosyası aşağıdaki ayarlar geçerli olacak şekilde güncellenmiştir:

TYPE = standard 
NAME = targeted 
UNK_PERMS = deny 
DIRECT_INITRC = y 
MONOLITHIC = y/n /* monolithic vs modular secimi tercihe gore yapılmalıdır */
UBAC = n 
CUSTOM_BUILDOPT = 
MLS_SENS = 16 
MLS_CATS = 256 
MCS_CATS = 256 
QUIET = n

Ardından derleme işlemine geçmeden önce, sistemin ihtiyaç duyduğu libaudit.so desteği sağlanmalıdır. Eğer sistemde mevcut bir libaudit.so dosyası varsa, ihtiyaç duyulana linklenebilir. Örnek vermek gerekirse sistemde libaudit.so.0 aranıyor fakat libaudit.so.1 mevcut ise, şu şekilde bağlantı oluşturulabilinir:

ln -s libaudit.so.1 libaudit.so.0

modular seçim için:

Bu işlemlerin ardından rootfs içerisine, policy derleme ve yükleme işlemleri esnasında ihtiyaç duyulacak aşağıdaki uygulamalar derlenerek sistem içerisine atılmalıdır:

  • m4 (make conf esnasında kullanılır)
  • gawk (make base esnasında kullanılır)
  • make
  • python

İlerde çağrılacak komutlardan make conf için xml.dom.minidom paketi gerekmektedir. Bu sebeple python’un derlenirken içerisinde bu paketin ve bağlantılı paketlerin yer aldığından emin olmak gerekiyor.

Burada python için libtinfo, libssl, libcrypto kütüphaneleri sistemde hazır bulunmalıdır.

Bu işlemlerin ardından sırasıyla aşağıdaki komutlar çalıştırılacaktır. İşlevlerini öğrenmek için SELinux notebook sayfa 256-257’ye bakılabilir.

make conf
make base
make modules
make install
make load

monolithic seçim için:

Buildroot üzerinden  çıkartılan rootfs üzerine, (bu sistemde gawk, python, auditd, setools, make yüklü olmalidir) şu işlemler yapılmalıdır:

  • m4 sistem içerisine yüklenmelidir.
  • ardından refpolicy-arm içerisinde sırasıyla şu komutlar çalıştırılmalıdır:
make conf
make install

Reference policy işlemlerinin ardından /etc/selinux/config dosyasının aşağıdaki içerik ile oluşturulması gerekmektedir:

SELINUX=enforcing
SELINUXTYPE=targeted

Buildroot kullanimi

Genel hatlarıyla versiyon seçimleri ve konfigürasyon değerleri buildroot ozelinde değişkenlik gösterebilir. Buildroot detaylarina; mimari, toolchain, kernel, target packages secimlerinin detaylarina girilmeyecektir. Fakat bu yazida stabil çalışan pandaboard dagitimi icin yapilacak seçim ve değerleri bulabilirsiniz. Ayrica buildroot uzerinden kernel’e build time’da nasil yama yapilacagi da, preempt_rt yamasiyla orneklenecektir.

İndirme

Buildroot versiyon 2014.11-rc1, http://git.buildroot.net/buildroot/snapshot/buildroot-2014.11-rc1.tar.gz adresinden indirilir.

Buildroot ana konfigürasyonu

buildroot-pandaboard-linux.config indirilip, buildroot dizininde:

make menuconfig

diyerek acilan menuden bu konfigürasyon dosyası yüklenir.

Realtime yaması

Bu konfigürasyon dosyasının realtime ile ilgili ihtiyacı olan diğer dosyalar ve menüdeki ilgili yerleri şu şekildedir:

Realtime preempt_rt yamasını uygulamak istiyorsak:

Derleme ve çıktılar

make diyerek derleme işlemlerinin çalışması sağlanır. Bootloaders -> U-Boot version: ayarına 2011.11.2 girilmesi durumunda buildroot/output/images altindaki

MLO
u-boot.bin
uImage

dosyaları sd-karta atılır. Sd-kartın tek bir partition şeklinde fat-32 kullanarak formatlanmış ve boot etme yeteneği atanmış olması gerekmektedir.

https://github.com/eckucukoglu/linux-tools/tree/master/make-sdcard incelenerek, ihtiyaca uygun hale getirilebilinir.

Bootloaders -> U-Boot version: 2013.01.01 girilmesi durumunda (4460 pandaboard u-boot versiyonu için bu versiyon kullanılmaktadır) sd-kart içerisine /output/images/u-boot.bin yerine output/build/uboot-2013.01.01/u-boot.img  konulmalıdır.

Aynı zamanda sd-kart içerisine konulacak boot.scr dosyası şu şekilde oluşturulur:

setenv bootargs ‘root=/dev/mmcblk0p2 rw rootwait rootfstype=ext3 console=ttyO2,115200n8 vram=16M’
fatload mmc 0 82000000 uImage
bootm start 82000000
bootm loados
bootm go 82000000

içeriği ile oluşturulacak boot_mmc.txt dosyasından,

mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n “Panda SD Boot” -d boot_mmc.txt boot.scr

komutu ile boot.scr oluşturulur ve sd-kart ana dizinine diğer dosyaların yanına atılır.

Pandaboard’a takılacak sd-kart boot edecek ve komut istemini verecektir.

  • Derlenirken izlek oluşturmamak için -jX parametresi girilmemelidir.
  • Adımlar izlenirken öncelikli kaynak olarak [2] kullanılmıştır.
Referanslar

[1]: http://www.linux-magazine.com/Online/Features/Qemu-and-the-Kernel
[2]: http://fooprotected.wordpress.com/2014/03/13/buildroot-linux-on-the-pandaboard-rev-3/
[3]: http://www.rte.se/blog/linux-0/buildroot-basics-building-real-target-pandaboard/1.2
[4]: http://elinux.org/Panda_How_to_buildroot
[5]: http://delog.wordpress.com/2011/09/04/custom-embedded-linux-system-for-pandaboard-with-buildroot/


Pin Muxing (AM335x EVM)

Bu yazida, AM335x EVM board icin external olarak kesme (interrupt) olusturmak icin gerekli pinmuxing ile gpio uzerinden export islemleri anlatilacaktir.

Dokuman uzerinde bahsi gecen islemler https://github.com/eckucukoglu/linux-tools/tree/master/gpio-interrupt uzerinden orneklenecektir.

  • Oncelikle interrupt gonderilmek istenen gpio portlari tespit edilmelidir. Bu nedenle debugfs mount islemi gerceklestirilerek, kullanimda olan gpio pinlerinin durumu (in/out, high/low) incelenmelidir.
    Bunun icin oncelikle mount -t debugfs none /sys/kernel/debug/  ile debugfs mount edilmelidir. Ardindan cat /sys/kernel/debug/gpio ile sistemde kayitli gpio listesine erisilebilinir. gpio-int.c ile user space interrupt islemlerimizde 40. ve 41.pinleri AM335x EVM boardu uzerinde, sirasiyla, interrupt gondermek (signal generator kullanarak) ve yakalanan interrupt sonucunda cikti alabilmek (osiloskop kullanarak) icin kullaniyoruz.
  • Bir sonraki adimda bu gpio pinlerinin board uzerindeki yerini bulmaliyiz. Bu nedenle http://www.ti.com/… adresinden indirdigimiz AM335x processors guide (am3359.pdf) ile ilgili gpio’larin hangi pin’e denk geldigini buluyoruz.
    Ornegin gpio-40 ve gpio-41 icin, dokumanda gpio1_8 ve gpio1_9 degerlerini bakiyoruz. (1*32+8 ve 1*32+9)
    gpio1_8 icin pin isminin UART0_CTSn ve mode’un ise 7 oldugunu gozlemliyoruz.
  • Ardindan http://processors.wiki.ti.com/ind… adresinden indirebileceginiz schematic (am335x_gpevm_zczbaseboard_3h0002_schematic_rev1_5c.pdf) ile expansion connector kismindan UART0_CTSn pininin yerini buluyoruz.
    UART0_CTSn -> Dokumandan gorulecegi gibi J5 21.koluna denk geliyor.
  • Su anda board uzerindeki pinin, kernel’de hangi gpio’a denk gelebilecegini biliyoruz. Bundan sonra 2 adim izlenmesi gerekiyor. Ilki gpio-40 in sisteme kayitlanmasi ve UART0_CTSn uzerinde mode ayarini 7 yaparak gpio1_8 olarak calismasini saglamak.
  • Ilk adimi /sys/class/gpio  icindeyken
    echo 40 > /sys/class/gpio/export

    yaptiktan sonra gpio40’i tanimlamak ve ardindan /gpio40 klasoru icerisindeki direction, edge ve active_low degerlerini istenildigi gibi ayarlayabiliriz.
    Bununla birlikte gpio-int.c icerisinde de gozlemlenebilecegi gibi

gpio_set_dir(gpio, 0);
gpio_set_edge(gpio, "rising");

seklinde de yapmak mumkundur.

  • Ikinci adim icin ise oncelikle; /sys/kernel/debug/omap_mux/ klasoru altinda iken,
    cat uart0_ctsn

    yaparak, secilebilir mode’lari gormek mumkundur. Burada su sekilde bir cikti almaliyiz:

name: uart0_ctsn.gpio1_8 (0x44e10968/0x968 = 0x0007), b NA, t NA
mode: OMAP_MUX_MODE7 | AM33XX_PIN_OUTPUT
signals: uart0_ctsn | NA | d_can1_tx | i2c1_sda | spi1_d0 | NA | NA | gpio1_8

Belirtilen mode’lardan 7.si yani gpio1_8 isteniyor. Dolayisiyla

echo 7 > uart0_ctsn

yaparak mode degistirmek mumkundur.


Pandaboard ES’de NFS kullanarak root dosya sistemini calistirmak

Pandaboard ES platformları üzerinde kullanilan dosya sistemleri için sd/mmc blok kullanmak yerine NFS kullanarak, geliştirme yapilan bilgisayari kullanmak mümkündür.

Bunun için ana hatlarıyla şu işlemler yapılmalıdır:

  1. NFS ve Pandaboard ES konfigürasyonları düzgün yapılmış bir Linux kernel.
  2. u-boot ayarları ve derlenmesi.
  3. Geliştirme yapılan bilgisayarda network ve NFS ayarları.
  4. otomatize hale getirmek için boot.scr oluşturulması.
  5. udhcpc sisteminin deaktifleştirilmesi.

Kernel konfigürasyonu

Linux kernel omap2plus_defconfig kullanılarak konfigüre edildikten sonra, menuconfig ile girilen menüde aşağıdaki seçenek aktifleştirilmeli:
Device Drivers -> USB support CONFIG_USB_SUPPORT -> EHCI HCD (USB 2.0) support CONFIG_USB_EHCI_HCD

Her ne kadar omap2plus_defconfig aşağıdaki ayarları otomatik açıyor olsa da, kontrol etmekte fayda var:

Networking support
–> [*] TCP/IP networking CONFIG_INET
–> –> [*] IP: kernel level autoconfiguration CONFIG_IP_PNP
–> –> –> [*] IP: DHCP support CONFIG_IP_PNP_DHCP
–> –> –> [*] IP: BOOTP support CONFIG_IP_PNP_BOOTP
–> –> –> [*] IP: RARP support CONFIG_IP_PNP_RARP
Device Drivers
–> [*] Network device support CONFIG_NETDEVICES
–> –> USB Network Adapters
–> –> –> [*] SMSC LAN95XX based USB 2.0 10/100 ethernet devices CONFIG_USB_NET_SMSC95XX
File systems
–> [*] Network File Systems CONFIG_NETWORK_FILESYSTEMS
–> –> NFS client support CONFIG_NFS_FS
–> –> –> [*] NFS client support for NFS version 3 CONFIG_NFS_V3 –> [*] Root file system on NFS CONFIG_ROOT_NFS

Bu ayarlar ile derlenen kernel ve device tree blob (gerekiyorsa) sd-kart içerisine atılmalıdır.

Not: Bazı kernel sürümlerinde aşağıdaki ayarları da açmak gerekebilir:
CONFIG_USB_PHY
CONFIG_NOP_USB_XCEIV

u-boot işlemleri

Aşağıdaki adresten güncel u-boot versiyonu indirilebilinir:
ftp://ftp.denx.de/pub/u-boot/u-boot-latest.tar.bz2

Ardından u-boot ana dizini içerisinde

make omap4_panda_defconfig
make all

komutları kullanılarak u-boot.img dosyası oluşturulmalı ve sd-kart içerisine atılmalıdır.

Geliştirme yapılan bilgisayar ayarları

/etc/exports dosyası içerisine

<rootfs dizini> <ip aralığı>(rw,sync,no_root_squash,no_subtree_check)

satırı eklenmelidir.
Ardından
sudo /etc/init.d/nfs-kernel-server restart
ile NFS server restart edilmelidir.

Daha sonra network ayarlarından yaratılacak bir ağ bağlantısı ile verilen <ip aralığı> içerisinden bir ip adresi atanmalı ve netmask <netmask adresi>, gateway <gateway adresi> olarak ayarlanmalıdır.

Boot scripti oluşturmak

Pandaboard içine atılan u-boot üzerinde saveenv komutunun yer almadığını göreceksiniz. Benzer sekilde, kernel ve bootloader’u da tftp ile transfer etmeyi pandaboard es rev3 platformlar icin basaramadim. Bu nedenle u-boot’un argümanlarını boot.scr dosyasından almasını sağlamamız gerekiyor. Bu nedenle aşağıdaki satırları içeren boot.script dosyasını oluşturmak gerekiyor, lütfen ilgili değişkenleri kendi ayarlarınıza göre değiştirin:

mmc rescan
fatload mmc 0:1 0x80000000 uImage
fatload mmc 0:1 0x82000000 omap4-panda-es.dtb
setenv bootargs vram=32M console=ttyO2,115200 mem=456M@0x80000000 mem=512M@0xA0000000 root=/dev/nfs rw nfsroot=<host ip adresi>:<rootfs dizini>,nolock,wsize=1024,rsize=1024 ip=<panda ip adresi> init=/linuxrc
bootm 0x80000000 - 0x82000000

Ardından oluşturulan boot.script dosyası aşağıdaki komutla derlenerek boot.scr dosyası oluşturulmalıdır:

mkimage -A arm -T script -C none -n "mmis:panda boot script" -d boot.script boot.scr

Oluşturulan boot.scr dosyası sd-kart içerisine atılmalıdır.

Platform network ayarları

Şu anda sd-kart panda üzerinde çalıştırıldığında başarılı bir şekilde istenen remote dizinden dosya sistemini kullanacaktır. Fakat eğer dhcp servisi aktifleştirilmiş ise komut istemi kullanıcıya verilmeden önce u-boot ile kernele atanan ip adresi değiştirilmeye çalışılacak ve bu nedenle de NFS ile olan bağlantı kopacaktır. Bunun önüne geçmek için platform dosya sistemi içerisindeki /etc/network/interfaces dosyasındaki
iface eth0 inet dhcp
satırı çıkartılmalıdır.
Manual olarak aşağıdaki ayarlar kullanılabilinir:

iface eth0 inet static
address <panda ip adresi>
netmask <netmask adresi>
gateway <gateway adresi>

Örnek değişken değerleri:

<rootfs dizini>: /home/eckucukoglu/nfsroot
<ip aralığı>: 192.168.1.0/24
<host ip adresi>: 192.168.1.1
<panda ip adresi>: 192.168.1.2
<netmask adresi>: 255.255.255.0
<gateway adresi>: 0.0.0.0

preempt_rt yamasinin dogrulanmasi

Burada preempt_rt patchinin internal olarak, varlığının gösterilmesi için gereken adımlar anlatılacaktır.

  • Kernel versiyon stringine bakarak: (-rtx, x o kernel surumunun yama versiyonudur)
# uname -a 
Linux krachkiste 2.6.18-rt5 #3 PREEMPT Thu Oct 06 14:28:47 CEST 2006 i686 GNU/Linux
  • dmesg çıktısına bakarak:
Real-Time Preemption Support (C) 2004-2006 Ingo Molnar
  • Interrupt requestleri yamalanmış kernelde thread olarak islenecegi için IRQ handler’ları task struct ile kontrol edilecektir. Bu sebeple:
ps ax

gibi işlemler listesinde, yamasız kernel’den farklı olarak kernel thread’i şeklinde gösterileceklerdir. “[]” kare parantez içinde gösterilir.

  • Asagidaki kod gcc -o test_rt test_rt.c -lrt derlenip, çalıştırılarak kontrol sağlanabilir.
#include <string.h>
#include <stdio.h>
#include <sys/utsname.h>

int main(int argc, char **argv)
{
    struct utsname u;
    int crit1, crit2 = 0;
    FILE *fd;

    uname(&u);
    crit1 = strcasestr (u.version, "PREEMPT RT");
    if ((fd = fopen("/sys/kernel/realtime","r")) != NULL) {
        int flag;
        crit2 = ((fscanf(fd, "%d", &flag) == 1) && (flag == 1));
        fclose(fd);
    }
    fprintf(stderr, "this is a %s kernel\n",
            (crit1 && crit2)  ? "PREEMPT RT" : "vanilla");
}

 

 


Priority gozlemleme ve degistirme

chrt

chrt kullanarak realtime sistemlerde, pid degeri bilinen bir process’in scheduling policy’sini ve priority degerini degistirmek mumkundur.

chrt -p $PID_OF_THE_KTHREAD

Yukaridaki komut ile verilen pid’li process’in priority degerini ve policy bilgilerini almak mumkundur.

chrt -f -p $PRIO $PID_OF_THE_KTHREAD

-f ile FIFO policy’si kullanarak verilen pid’li processin priority degeri verilen degere cekilecektir.

htop

htop, top komutunun ozellestirilebilir ve daha fonksiyonel bir varyasyonudur.
htop ile processlerin priority degerleri gozlemlenebilir, processler parent-child iliskisiyle birlikte gozlemlenebilir, userspace ve kernelspace thread’ler detaylica incelenebilir.
Ayni zamanda htop kullanarak processlerin ve threadlerin nice degerleri degistirilebilinir, bu sayede priority degerlerinde de farklilasma gozlemlenecektir.
Platform boardlar uzerinde calisirken rootfs ile kisitli ozellikleri sunan ps alternatifi olarak kullandigimiz top, priority gosterme ve thread/process islemlerinde yetersiz kalmaktadir. Bu nedenle bir cok fonksiyonellik sunan htop kullanilabilinir.

nice degerinin priority uzerine etkisi

nice degeri kullanici tarafindan -20 ile 19 arasinda, process basina ayarlanan bir priority talebi olarak dusunulebilinir.
htop uzerinden de gozlemlenebilecegi gibi
nice(-20) -> prio(0)
nice(-10) -> prio(10)
nice(0) -> prio(20)
nice(10) -> prio(30)
nice(19) -> prio(39)
seklinde lineer bir eslesme mevcuttur. Burada priority degerinin dusuk olmasi (htop uzerinden gozlemlenen degerler icin) daha yuksek oncelikli oldugunu gostermektedir. Dolayisiyla nice value’da meydana gelen dusme, prioritynin anlamsal olarak artmasi, sayisal olarak azalmasi anlamina gelmektedir.

chrt ve htop priority degerlerinin karsilastirilmasi

bu sonuclar beaglebone black uzerinde kosturulan vanilla kernel’in varsayilan degerleridir.

  • IRQ’lar icin htop, priority degeri olarak (-51) vermektedir.
    chrt ise SCHED_FIFO policy ile birlikte 50 degerini donmektedir.
  • userspace process’ler icin htop, 20 default priority degerini gostermektedir. chrt’de ise SCHED_OTHER policy ile birlikte 0 degerini donmektedir.
  • sched_setscheduler ile policy degeri SCHED_FIFO olarak 80 priority ile ayarlanan processler, htop ile, (-81) priority degerini donmektedir. chrt ise SCHED_FIFO policy ile birlikte 80 degerini donmektedir.
  • cyclictest’in ./cyclictest -p 80 -t5 -n -q &  seklinde calistirilmasiyla, htop cyclictest icin priority 20 gosterirken, 5 adet thread icin bu deger (-81) olarak ayarlanmistir.
    chrt ise cyclictest’in kendisi icin (SCHED_OTHER, 0) seklinde cikti verirken, threadler icin (SCHED_FIFO, 80) ciktisini vermektedir.