:::: MENU ::::

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


Kernel preemption and realtime linux kernel with preempt_rt, part 1

Operating System Design: Scheduling

Only one process per CPU can run at any one time, multitasking operating systems use a concept called multiprogramming to schedule time for each process to run on a CPU. A scheduler is responsible for giving each process time on the CPU. When the current time slice expires, the scheduler puts the current process to sleep and the next process is given CPU time. Some scheduling systems include:

First Come First Served, Shortest Process Next, Shortest Remaining Time, Round Robin Scheduling, Preemption, Priority Scheduling

Preemption

In computing, preemption is the act of temporarily interrupting a task being carried out by a computer system, without requiring its cooperation, and with the intention of resuming the task at a later time. Such a change is known as a context switch. It is normally carried out by a privileged task or part of the system known as a preemptive scheduler, which has the power to preempt, or interrupt, and later resume, other tasks in the system.

In the Linux kernel, the scheduler is called after each timer interrupt (that is, quite a few times per second). It determines what process to run next based on a variety of factors, including priority, time already run, etc.

Pros/Cons: Making a scheduler preemptible has the advantage of better system responsiveness and scalability, but comes with the disadvantage of race conditions (A race occurs when correctness of the program depends on one thread reaching point x before another thread reaches point y.).

Preemptive Multitasking

The term preemptive multitasking is used to distinguish a multitasking operating system, which permits preemption of tasks, from a cooperative multitasking system wherein processes or tasks must be explicitly programmed to yield when they do not need system resources.

Although multitasking techniques were originally developed to allow multiple users to share a single machine, it soon became apparent that multitasking was useful regardless of the number of users. Many operating systems, from mainframes down to single-user personal computers and no-user control systems (like those in robotic spacecraft), have recognized the usefulness of multitasking support for a variety of reasons. Multitasking makes it possible for a single user to run multiple applications at the same time, or to run “background” processes while retaining control of the computer.

Kernel

Kernel is a computer program that manages input/output requests from software, and translates them into data processing instructions for the central processing unit and other electronic components of a computer.

1Monolithic kernels, which have traditionally been used by Unix-like operating systems, contain all the operating system core functions and the device drivers (small programs that allow the operating system to interact with hardware devices, such as disk drives, video cards and printers). This is the traditional design of UNIX systems. A monolithic kernel is one single program that contains all of the code necessary to perform every kernel related task.

The main disadvantages of monolithic kernels are the dependencies between system components – a bug in a device driver might crash the entire system.

2

A microkernel runs most of the operating system’s background processes in user space, to make the operating system more modular and, therefore, easier to maintain.

Main criticisms of monolithic kernels from microkernel advocates, which is that;

  • A device driver can enter an infinite loop or other unrecoverable state, crashing the whole system
  • Some drivers and system calls on monolithic kernels are slow to execute, and can’t return control of the processor to the scheduler or other program until they complete execution.

Kernel preemption

Kernel preemption is a method used mainly in monolithic and hybrid kernels where all or most device drivers are run in kernel space, whereby the scheduler is permitted to forcibly perform a context switch (i.e. preemptively schedule; on behalf of a runnable and higher priority process) on a driver or other part of the kernel during its execution, rather than co-operatively wait for the driver or kernel function (such as a system call) to complete its execution and return control of the processor to the scheduler.

3

Problem in Kernel preemption: Priority Inversion

Lower-priority process effectively blocks a higher-priority one. Lower-priority process’s ownership of lock prevents higher-priority process from running.

4

5

 

Solution to priority inversion is Priority Inheritance: Temporarily increase process’s priority when it acquires a lock.

Linux kernel, preemption in linux kernel

Kernel mode: The Linux kernel System Call Interface, Process scheduling subsystem, IPC subsystem, Memory management subsystem, Virtual files subsystem, Network subsystem, Other components

User mode: System daemons(deamon: In multitasking computer operating systems, a daemon is a computer program that runs as a background process, rather than being under the direct control of an interactive user.), Windowing system, C standard library, Other libraries.

Priority inheritance support available since Linux 2.6.18.

Linux kernel is a preemptive operating system. When a task runs in user-space mode and gets interrupted by an interruption, if the interrupt handler wakes up another task, this task can be scheduled as soon as we return from the interrupt handler.

6

However, when the interrupt comes while the task is executing a system call, this system call has to finish before another task can be scheduled. By default, the Linux kernel does not do kernel preemption.

This means that the time before which the scheduler will be called to schedule another task is unbounded.

7

Realtime Linux kernel

Hard real-time systems: required to complete a critical task within a guaranteed amount of time.

Soft real-time systems: requires that critical processes receive priority over less fortunate ones.

Real-time applications have operational deadlines between some triggering event and the application’s response to that event. To meet these operational deadlines, programmers use real-time operating systems (RTOS) on which the maximum response time can be calculated or measured reliably for the given application and environment. A typical RTOS uses priorities. The highest priority task wanting the CPU always gets the CPU within a fixed amount of time after the event waking the task has taken place.

Traditionally, the Linux kernel will only allow one process to preempt another only under certain circumstances:

  • When the CPU is running user-mode code
  • When kernel code returns from a system call or an interrupt back to user space
  • When kernel code code blocks on a mutex, or explicitly yields control to another process

If kernel code is executing when some event takes place that requires a high priority thread to start executing, the high priority thread can not preempt the running kernel code, until the kernel code explicitly yields control. In the worst case, the latency could potentially be hundreds milliseconds or more.

The Linux 2.6 configuration option CONFIG_PREEMPT_VOLUNTARY introduces checks to the most common causes of long latencies, so that the kernel can voluntarily yield control to a higher priority task waiting to execute. This can be helpful, but while it reduces the occurences of long latencies (hundreds of milliseconds to potentially seconds or more), it does not eliminate them. However unlike CONFIG_PREEMPT (discussed below), CONFIG_PREEMPT_VOLUNTARY has a much lower impact on the overall throughput of the system. (As always, there is a classical tradeoff between throughput — the overall efficiency of the system — and latency. With the faster CPU’s of modern-day systems, it often makes sense to trade off throughput for lower latencies, but server class systems that do not need minimum latency guarantees may very well choose to use either CONFIG_PREEMPT_VOLUNTARY, or to stick with the traditional non-preemptible kernel design.)

The 2.6 Linux kernel has an additional configuration option, CONFIG_PREEMPT, which causes all kernel code outside of spinlock-protected regions and interrupt handlers to be eligible for non-voluntary preemption by higher priority kernel threads. With this option, worst case latency drops to (around) single digit milliseconds, although some device drivers can have interrupt handlers that will introduce latency much worse than that. If a real-time Linux application requires latencies smaller than single-digit milliseconds, use of the CONFIG_PREEMPT_RT patch is highly recommended.

The RT-Preempt patch converts Linux into a fully preemptible kernel. The magic is done with:

  • Making in-kernel locking-primitives (using spinlocks) preemptible though reimplementation with rtmutexes.
  • Critical sections protected by i.e. spinlock_t and rwlock_t are now preemptible. The creation of non-preemptible sections (in kernel) is still possible with raw_spinlock_t (same APIs like spinlock_t).
  • Implementing priority inheritance for in-kernel spinlocks and semaphores.
  • Converting interrupt handlers into preemptible kernel threads: The RT-Preempt patch treats soft interrupt handlers in kernel thread context, which is represented by a task_struct like a common user space process. However it is also possible to register an IRQ in kernel context.
  • Converting the old Linux timer API into separate infrastructures for high resolution kernel timers plus one for timeouts, leading to user space POSIX timers with high resolution.

Architectures, CONFIG_PREEMPT_RT patch does the support:

There are systems representing the x86, x86_64, ARM, MIPS, and Power architectures using the CONFIG_PREEMPT_RT patch. However, in many ways this is the wrong question. Support for real-time is not just about the instruction set architecture, but also about supporting the high resolution timer provided by the CPU and/or CPU support chipset, the device drivers for the system being well behaved, etc.

Please refer to platforms tested and in use with CONFIG_PREEMT_RT section in this wiki for a list of platforms that members of the -rt community have used successfully.

Disadvantages of preempt_rt patch

The normal Linux kernel allows preemption of a task by a higher priority task only when the user space code is getting executed.

In order to reduce the latency, the CONFIG_PREEMPT_RT patch forces the kernel to non-voluntarily preempt the task at hand, at the arrival of a higher proiority kernel task. This is bound to cause a reduction in the overall throughput of the system since there will be several context switches and also the lower priority tasks won’t be getting much a chance to get through.
This is the current status of Realtime Linux using the Realtime Preempt patches (aka PREEMPT_RT):

8

1) Since kernel 2.6.24 in mainline Linux
2) Since kernel 2.6.25 in mainline Linux
3) Realtime-Preempt patches 2.6.24.7-rt15 or higher required
4) Since kernel 2.6.30 in mainline Linux
5) Not yet adapted to generic interrupt code
6) Since kernel 2.6.33 in mainline Linux
7) Since kernel 2.6.39 in mainline Linux

Installation of preempt_rt patch to linux kernel and compiling new custom linux kernel

wget https://www.kernel.org/pub/linux/kernel/vx.x/linux-x.x.x.tar.xz

  • or via ketchup: automatically download various kernel patches and update kernels.

ketchup 3.12.6  ketchup -s 2.6-rt #find latest RT revision  

  • After downloading, unpack the kernel tarball and change into the kernel source directory. Patch the kernel with patch level p1:
bzcat ../patch-2.6.23.1-rt11.bz2 | patch -p1
    • Configure kernel, save .config file. Check: ‘Preemption mode’ configurations
make menuconfig

enable CONFIG_PREEMPT_RT

  • activated the High-Resolution-Timer Option (Attention, the amount of supported platforms by the HR timer is still very limited. Right now the option is only supported on x86 systems, PowerPC and ARM Support are however in queue.)
  • disabled all Power Management Options like ACPI or APM
  • Further interesting options can be found under the “Kernel Hacking” menu entry. This menu lists options for system debugging and performance measurement. Keep in mind that the debug options may either increase the kernel size or cause higher latencies. If you do not want to debug the kernel or get some automatically produced histograms, make sure that you don’t activate any unnecessary options here. If you have activated any latency critical options the kernel will warn at boot time.
  • Compile & install
make
make modules
make modules_install
make install
preempt_rt patch, ‘Preemption mode’ configurations
  • No Forced Preemption (Server)  CONFIG_PREEMPT_NONE:

This is the traditional Linux preemption model, geared throughput. It will still provide good latencies most of the time, but there are no guarantees and occasional longer delays are possible. Select this option if you are building a kernel for a server or scientific/computation system, or if you want to maximize the raw processing power of the kernel, irrespective of scheduling latencies.

  • Voluntary Kernel Preemption (Desktop) CONFIG_PREEMPT_VOLUNTARY:

This option reduces the latency of the kernel by adding more”explicit preemption points” to the kernel code. These new preemption points have been selected to reduce the maximum latency of rescheduling, providing faster application reactions, at the cost of slightly lower throughput. This allows reaction to interactive events by allowing a low priority process to voluntarily preempt itself even if it is in kernel mode executing a system call. This allows applications to run more ‘smoothly’ even when the system is under load. Select this if you are building a kernel for a desktop system.

  • Preemptible Kernel (Low-Latency Desktop) CONFIG_PREEMPT__LL:

This option reduces the latency of the kernel by making all kernel code (that is not executing in a critical section) preemptible.  This allows reaction to interactive events by permitting a low priority process to be preempted involuntarily even if it is in kernel mode executing a system call and would otherwise not be about to reach a natural preemption point. This allows applications to run more ‘smoothly’ even when the system is under load, at the cost of slightly lower throughput and a slight runtime overhead to kernel code. Select this if you are building a kernel for a desktop or embedded system with latency requirements in the milliseconds range.

  • Preemptible Kernel (Basic RT) CONFIG_PREEMPT_RTB:  

This option is basically the same as (Low-Latency Desktop) but enables changes which are preliminary for the full preemptible RT kernel.

  • Fully Preemptible Kernel (RT) CONFIG_PREEMPT_RT_FULL:

All and everything.

There have been two approaches to bring realtime capability to linux kernel:
  1. Mentioned PREEMPT_RT and other one is
  2. Linux (realtime) extensions: Add extra layer between hardware and the Linux kernel to manage real-time tasks separately. Below the normal kernel, there have been three generations: RTLinux, RTAI, and Xenomai.
References

The content of this text is mainly compiled from various resources.

http://lwn.net/Articles/146861/
https://rt.wiki.kernel.org/index.php/Main_Page
http://www.linux.com/news/featured-blogs/200-libby-clark/710319-intro-to-real-time-linux-for-embedded-developers
http://taste.tuxfamily.org/wiki/index.php?title=Tricks_and_tools_for_PREEMPT-RT_kernel
http://www.spinics.net/lists/linux-rt-users/



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.

Display panel and touchscreen driver support for Pandaboard ES

Chipsee pandaboard expansion set comes with ubuntu-precise kernel. Even though, modified files are already indicated by readme files, as far as i know there isn’t any vanilla kernel integration of expansion set drivers.

To achieve that, I analyzed some linux kernel patches* from version 3.2 through version 3.10.80. And then, modified both chipsee provided files and kernel files.

These are the changed files:

+ drivers/video/omap2/displays/panel-chipsee-dpi.c
M drivers/video/omap2/displays/Kconfig
M drivers/video/omap2/displays/Makefile
M drivers/input/touchscreen/ads7846.c
M arch/arm/mach-omap2/board-omap4panda.c
M arch/arm/mach-omap2/dss-common.c

And this is the related commit:
https://github.com/eckucukoglu/sober-kernel/commit/f6820c3a926b6ffd685b47f5ac9d4aac7b78dc26

Although, it is not proper to implement platform spesifics in dss-common.c, since it is an experimental work, i didn’t hesitate to do that.

After patching kernel, one should calibrate the touchscreen. Tslib (http://processors.wiki.ti.com/index.php/Tslib) is the hardware handling utility and it has ts_calibrate tool to do that. However, before executing ts_calibrate, some environment variables should be set:

export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_FBDEVICE=/dev/fb0
export TSLIB_TSDEVICE=/dev/input/event0
export TSLIB_PLUGINDIR=/usr/lib/ts
export TSLIB_CALIBFILE=/etc/pointercal

Moreover, in TSLIB_CONFFILE, module_raw input line has to be commented out.

After all of them, to run a qt application in linux frame buffer, these arguments should be passed:

-platform linuxfb -plugin evdevkeyboard:/dev/input/eventX -plugin evdevmouse:/dev/input/eventY -plugin tslib:/dev/input/eventZ

X, Y, Z numbers can be checked from /sys/class/input.

*: Here are the kernel patches that I analyzed:
http://permalink.gmane.org/gmane.linux.kernel.commits.head/335192
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=a8d5e41cef43bd740ca7c56ff316bdee30040a91
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=a9105cb5c25aa335b11088549927a8aa9eaa7ef2
http://www.spinics.net/lists/linux-omap/msg86741.html
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=54b956b903607
http://permalink.gmane.org/gmane.linux.ports.arm.omap/87206
http://permalink.gmane.org/gmane.linux.ports.arm.omap/73541
http://lists.infradead.org/pipermail/linux-arm-kernel/2011-December/076194.html
http://lists.infradead.org/pipermail/linux-arm-kernel/2012-October/128063.html
http://lkml.iu.edu/hypermail/linux/kernel/1007.3/02904.html
http://lists.infradead.org/pipermail/linux-arm-kernel/2011-February/040712.html


Pages:12