728x90
0

I have written kernel module to measure the correctness of ndelay() kernel function.

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/time.h>
#include <linux/delay.h>
static int __init initialize(void)
{
    ktime_t start, end;
    s64 actual_time;
    int i;
    for(i=0;i<10;i++)
    {
        start = ktime_get();
            ndelay(100);            
        end = ktime_get();
        actual_time = ktime_to_ns(ktime_sub(end, start));
        printk("%lld\n",(long long)actual_time);    
    }
    return 0;
}

static void __exit final(void)
{
     printk(KERN_INFO "Unload module\n");
}

module_init(initialize);
module_exit(final);

MODULE_AUTHOR("Bhaskar");
MODULE_DESCRIPTION("delay of 100ns");
MODULE_LICENSE("GPL");

the dmesg output is like this:

[16603.805783] 514
[16603.805787] 350
[16603.805789] 373
[16603.805791] 323
[16603.805793] 362
[16603.805794] 320
[16603.805796] 331
[16603.805797] 312
[16603.805799] 304
[16603.805801] 350

I have gone through one of the posts in stackoverflow: Why udelay and ndelay is not accurate in linux kernel?

But I want a fine tuned nanosecond delay (probably in the range of 100-250ns) in kernel space. Can anyone please suggest me any alternative for doing this?

0

You can use

High resolution timers (or hrtimers)

    hrtimer_init
    hrtimer_start
    hrtimer_cancel

functions. An example is available here

0

If you are targeting x86 only system, you can use rdtsc() call to get the CPU clock counts. The rdtsc() api has very little overhead. But you do need to convert from CPU clock to the ns, it is dependent on how fast your CPU clock is running.

static unsigned long long rdtsc(void)
{
    unsigned int low, high;
    asm volatile("rdtsc" : "=a" (low), "=d" (high));
    return low | ((unsigned long long)high) << 32;
}

Otherwise you can use the kernel high resolution timers API.

  • The above code snippet returns the number of cycles or the time gap itself? – Bhaskar Jupudi Mar 31 '16 at 22:10
  • rdtsc return clock cycles only. It is fast, low overhead, but you do need to convert it base on how fast is your CPU and it is x86 only. – Jbobo Lee Apr 1 '16 at 0:35
  • Thanks for your comment. But I'm quite confused here. My CPU has 12 cores. Can you provide an example to convert the number of cycles that are obtained from rdtsc to actual time in nanoseconds? – Bhaskar JupudiApr 1 '16 at 1:18


728x90



Kernel 단위에서 System Call 과 함께 이용하면 좀 더 정밀한 ns 단위로 결과 측정이 가능하다. 물론 이 부분에서 insmod 와 rmmod 를 해줘야 한다는 단점이 있지만, 원하는 시간대에 ns 단위로 측정이 가능하다는 소리 자체가 엄청난 이득이기 때문이다.


#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/time.h>
#include <linux/delay.h>
static int __init initialize(void)
{
    ktime_t start, end;
    s64 actual_time;
    int i;
    for(i=0;i<10;i++)
    {
        start = ktime_get();
            ndelay(100);            
        end = ktime_get();
        actual_time = ktime_to_ns(ktime_sub(end, start));
        printk("%lld\n",(long long)actual_time);    
    }
    return 0;
}

static void __exit final(void)
{
     printk(KERN_INFO "Unload module\n");
}

module_init(initialize);
module_exit(final);

MODULE_AUTHOR("Remoted");
MODULE_DESCRIPTION("delay of 100ns");
MODULE_LICENSE("GPL");


조금더 복잡한 이유는 일부 모듈이 환경변수 Path 에 존재하지 않는다는 점이다. Kernel 단계에서 컴파일 되는 영역이기 때문에, 여기서 필요한 라이브러리들을 불러다 쓰려면 Makefile 을 작성해야 하는 점이 있다.


You need to build the module within the Context of the Linux tree. By default, the compiler will look for user-space headers in /usr/include. There ARE some linux headers there (/usr/include/linux), but module.h is not one of them, as it deals with kernel constructs directly.

In short, you need a Makefile. Also, get rid of the #define MODULE. save the following to a file called Makefile and run make:

Code:
obj-m += foo.o
all:
		make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
		make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

This triggers the kernel build system.

Given that you are using Ubuntu, you probably already have the kernel headers installed at /usr/src/linux-headers-$(uname -r). module.h lives here:

Code:
jameson@aqua:~$ ls /usr/src/linux-headers-$(uname -r)/include/linux/module.h
/usr/src/linux-headers-3.0.0-12-generic/include/linux/module.h


728x90



파일은 요아래에..

nano_sleep.c



#include <stdio.h>
#include <time.h>   /* Needed for struct timespec */


int nsleep(long miliseconds)
{
   struct timespec req, rem;

   if(miliseconds > 999)
   {   
        req.tv_sec = (int)(miliseconds / 1000);                            /* Must be Non-Negative */
        req.tv_nsec = (miliseconds - ((long)req.tv_sec * 1000)) * 1000000; /* Must be in range of 0 to 999999999 */
   }   
   else
   {   
        req.tv_sec = 0;                         /* Must be Non-Negative */
        req.tv_nsec = miliseconds * 1000000;    /* Must be in range of 0 to 999999999 */
   }   

   return nanosleep(&req , &rem);
}
 
int main(int argc, char **argv, char **arge) {
  struct timespec tps, tpe;
  //int ret = nsleep(1000);

	while(1){
 		if ((clock_gettime(CLOCK_REALTIME, &tps) != 0) || (clock_gettime(CLOCK_REALTIME, &tpe) != 0)) {
    	perror("clock_gettime");
    	return -1;
		}
	  //printf("sleep result %d\n",ret);
	  printf("[%lu.%lu] %lu ns\n", tps.tv_sec, tps.tv_nsec, tpe.tv_nsec-tps.tv_nsec);
  }
  return 0;
}


자 코드를 분석해보자. 사실상 clock_gettime 으로 접근가능한 실행시간 (Elapsed Time) 으로 접근하면 위의 스크린샷처럼 CPU에 의존성을 띄며 정확한 Nano Second 단위로 접근하여 Command 를 날리는 것이 불가능하다.


만약 핵융합과 핵분열 같이 정확한 타이밍을 필요로하는 문제가 있다면 어떻게 해야할까? 바로 고전시대의 라이브러리가 우리를 반겨준다. 다음 포스팅에서 살펴보자.




728x90

New to Linux and in need of a good painting tool? Check out Krita! It’s completely free, open source and has dozens of features to satisfy artists of all types.

Krita is part of the KDE project and has support for pretty much every Linux distribution out there. To install Krita, open up a terminal and follow the instructions that correspond to your Linux distribution.

Ubuntu

Krita is in the official software repositories on Ubuntu, and users can quickly install it with the following command in a terminal.

sudo apt install krita

The version of Krita in the Ubuntu software sources is relatively recent, but it’s not the absolute latest. If you’re looking for a more recent version, you’ll need to update it with the official Krita PPA. To do this, use the following command.

sudo add-apt-repository ppa:kritalime/ppa

After adding the new Krita software PPA, run the update command.

sudo apt update

Running the update command will see the new Krita PPA and detect that a newer version of the software is available. To switch over to the latest version of the software on Ubuntu, run the upgrade command.

sudo apt upgrade -y

Debian

Debian has the Krita graphic design tool ready for installation on nearly every version. To install it, open up a terminal and use the Apt-get package management tool to get it working.

sudo apt-get install krita

Installing the Krita tool on Debian will get you out of a pinch. However, due to the nature of how Debian works, you’ll likely be using an older version of the software. To get around this, consider following this tutorial to enable Debian Backports. Using Backports will let you get a newer version of Krita on your Debian setup.

Don’t want to go through the trouble of enabling Debian Backports? Consider continuing through the tutorial and following either the Flatpak or AppImage instructions to get a more recent version of Krita.

Arch Linux

Arch Linux users can easily install Krita, though before doing so you’ll need to enable the “Extra” software repository. To enable it, launch a terminal and open up your Pacman configuration file in the Nano text editor.

sudo nano /etc/pacman.conf

In the Pacman editor, scroll through the file until you see “[Extra],” and remove all “#” symbols in front of it.

After enabling the Extra software repository, re-sync Pacman, and install any updates.

sudo pacman -Syyu

With Extra set up, install Krita to your Arch Linux PC.

sudo pacman -S krita

Fedora

Using a reasonably new version of Krita on Fedora Linux requires no extra setup. To install it, open up a terminal and use the DNF package tool.

sudo dnf install krita -y

OpenSUSE

Like Fedora, OpenSUSE users looking to install the Krita painting/sketch program don’t need to follow any steps to enable third-party software repos. Open up a terminal and use the Zypper packaging tool to get the app working.

sudo zypper install krita

Flatpak

The Krita application is available on Flathub, which means that users who don’t have access to the program through traditional means still can install it.

Getting Krita working with Flatpak is quite straightforward. First, learn how to set up Flatpak on your Linux PC. When that’s taken care of, open up a terminal and use the command-line to install Krita.

flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo

flatpak install flathub org.kde.krita

Generic Linux Instructions Via AppImage

Many Linux distributions offer support for Flatpak and Snap packages to make up for lack of software in their official software sources. However, not all distros have support for these packaging formats.

If your Linux distribution doesn’t have support for Flatpak, you’ll have to go the AppImage route instead.

To install Krita via AppImage, open up a terminal window and use the wget tool to download it.

mkdir -p ~/AppImages

cd ~/AppImages
wget https://download.kde.org/stable/krita/4.1.1/krita-4.1.1-x86_64.appimage

Now that the Krita AppImage is done downloading, it’s time to update its system permissions. Changing the permissions will allow the AppImage to run as a program on your Linux PC.

sudo chmod +x krita-4.1.1-x86_64.appimage

Run Krita from the terminal with:

./krita-4.1.1-x86_64.appimage

Updating Krita AppImage

The Krita AppImage doesn’t update automatically. Instead, if you want to upgrade to a newer version of Krita, follow the steps below.

Step 1: Open up a terminal and delete the Krita app image on your Linux PC.

cd ~/AppImages

rm krita-4.1.1-x86_64.appimage

Step 2: Go to the official website, click on “AppImage” and download the new release.

Step 3: Move the terminal into the ~/Downloads folder with CD.

cd ~/Downloads

Step 4: Change the new file’s permissions, move it into the ~/AppImages folder and launch it.

sudo chmod +x krita-*-x86_64.appimage

mv krita-*-x86_64.appimage ~/AppImages

./krita-*-x86_64.appimage


+ Recent posts