'전체'에 해당되는 글 148건

Table of Content
  1. Intro
  2. 쉬운 API
  3. 어려운  API
  4. 어려운 API 와 쉬운 API?
  5. CPU 소모성 API
  6. CPU 소모가 없는 API
  7. msleep()
  8. msleep_interruptible()
  9. ssleep()
  10. schedule_timeout_interrupt()
  11. schedule_timeout_uninterrupt() 
  12. schedule_timeout() 
  13. ndelay(), udelay(), mdelay()  


1. Intro
 커널에서 시간 지연 함수는 여러가지가 있습니다. 
 굳이 분류를 하자면 쉬운 API, 어려운 API, CPU 소모성 API, CPU 소모가 없는 API 정도로 나눌 수 있습니다. 

2. 쉬운 API
 쉬운 API는 크게 보면 아래와 같습니다. 
  #include <linux/delay.h>
  #include <linux/timer.h>

  msleep()
  ssleep()

 이 API들은 함수명대로 micro  second, milli second, 1 second 을 뜻합니다. 
 그냥 사용하시면 됩니다. 

3. 어려운 API
 어려운 API 는 크게 보면 아래와 같습니다. 

 
  #include <linux/delay.h>
   #include <linux/timer.h>
   
   msleep_interruptible()
   schedule_timeout_interruptible();
   schedule_timerout_uninterruptible();
   schedule_timeout();

 이것도 그냥 사용하면 됩니다.

4. 어려운 API 와 쉬운 API ?
  어려운 API 와 쉬운 API 의 차이점은 무엇일까요? 

  가장 기본이 되는 지연 함수는 schedule_timeout() 입니다. 
  관계를 살펴보면

      ssleep()
    -----------------------------------------
      msleep()

    -----------------------------------------
      schedule_timeout_interruptible(), schedule_timeout_uninterruptible
 
    -----------------------------------------
      schedule_timeout()

 입니다. 위에 그림만으로는 잘 설명이 안될 수도 있는데, 커널 소스를 살펴보면 관계를 확실히 확인 할 수 있습니다. 

  ssleep() 는 msleep() 를 호출합니다. 
  msleep() 는 schedule_timeout_uninterrupt() 를 호출합니다. 
  schedule_timeout_uninterrupt() 는 schedule_timeout() 을 호출합니다. 

 결국 최종으로 호출되는 것은 schedule_timeout() 인데 시간 지연이라는게 인터럽트를 허용할 수도, 아닐수도 있고 또한 사용상의 편의상 ssleep() 나 msleep() 같은 front-end 를 만들어 쓴다고 생각하면 됩니다. 

8. CPU 소모성 API
 지정한 지연시간까지 loop 를 돌면서 cpu 시간을 소모하는 형태의 API 입니다. 
 
 ndelay();
 udelay();
 mdelay();

 위와 같이 delay 라는 이름이 붙은 API 들이 CPU 소모성 API 이며 아래와 같이 구현할 경우에도 CPU 소모성 API 입니다. 
 
 while(time_before(jiffies, j1))
 {
   cpu_relax();
 }

9. CPU 소모가 없는 API
 CPU 점유가 없이 시간 지연을 구현하려면 현재 자기자신한테 할당된 프로세스 시간을 반납하고 대기하는 방식을 사용하면 됩니다. 

 schedule_timeout_interruptible()
 schedule_timeout_uninterruptible()

 등이 그런 계통입니다. 

7. msleep()
  header :
asm/delay.h
  void msleep(unsigned int msecs);
  unsigned long msleep_interruptible(unsigned int msecs);

 => 밀리세컨드 동안 지연해 줍니다. 지연시간동안에는 인터럽트를 받을 수 없습니다. 

example
 #include <asm/delay.h>

static void example_msleep(void)
{
  msleep(1000);


 
8. msleep_interruptible()
  header : 
asm/delay.h
  unsigned long msleep_interruptible(unsigned int msecs);

 => 밀리세컨드 동안 지연해 줍니다. 지연시간동안에는 인터럽트를 받을 수 있습니다. 

example)
 #include <asm/delay.h>

static void example_msleep(void)
{
  msleep_interruptible(1000);


 
9. ssleep()
  
  header : asm/delay.h
    void ssleep(unsigned int seconds);

 => 초단위로 지연해 줍니다. 지연시간동안에는 인터럽트를 받을 수 없습니다. 

example)
 #include <linux/sched.h>

static void example_ssleep(void)
{
  ssleep(2);



10. schedule_timeout_interruptible()

  
  header : linux/sched.h
    void schedule_timeout_interruptible(unsigned long timeout);

 => timeout 시간만큼 지연해 줍니다.  

example)
 #include <linux/sched.h>

static void example_ssleep(void)
{
  schedule_timeout_interruptible(1 * HZ); /* 1 초간 지연 */


11. schedule_timeout_uninterruptible()

  
  header : linux/sched.h
    void schedule_timeout_uninterruptible(unsigned long timeout);

 => timeout 시간만큼 지연해 줍니다. 지연시간도중에는 인터럽트를 받을 수 없습니다. 
  
  
example)
 #include <linux/sched.h>

static void example_ssleep(void)
{
  schedule_timeout_uninterruptible(1 * HZ); /* 1 초간 지연 */


 
12. schedule_timeout()

  
  header : linux/sched.h
    void schedule_timeout(unsigned long timeout);

 => timeout 시간만큼 지연해 줍니다. 가장 기본이 되는 함수입니다. 그렇기 때문에 직접 호출하여 사용하지는 않습니다. 

example)
 #include <linux/sched.h>

static void __sched schedule_timeout_interruptible(void long timeout)
{
  __set_current_state(TASK_INTERRUPTIBLE);
 
return schedule_timeout(timeout); 


13. ndelay, udelay, mdelay
   header : linux/delay.h
   #define ndelay(n);
   #define udelay(n); 
   #define mdelay(n);

  busy wait 방식이어서 cpu 로드가 많은 편입니다. 하지만 간단하게 쓸 수 있는 장점이 있습니다.

example)
#include <linux/delay.h>

void delay_test(void long timeout)
{
  ndelay(1000);
  udelay(1000);
  mdelay(1000); 
 


 

 
   

 

'development' 카테고리의 다른 글

[program] Makefile  (0) 2012.01.04
[kernel] 커널 쓰레드  (0) 2012.01.04
[kernel] 커널 메모리 모델  (0) 2011.12.29
[etc] 빌드 시스템  (0) 2011.12.23
[kernel] Thread 와 Kill  (0) 2011.11.26
블로그 이미지

김유석0

,
 리눅스 커널도 하나의 프로세스이므로 총 4GByte 의 Virtual memory 를 사용하게 됩니다.

 4GByte 의 메모리는 아래와 같이 크게 두 개로 나뉘게 되며 하위 3GByte 는 user space(application) 용이며 상위 1GByte 는 kernel space 로 구분합니다. 



 위와 같이 커널 영역은 Virtual memory 4GByte 영역중에서 하위 1GByte 영역에 위치하게 됩니다.(0xc0000000 ~ 0xffffffff)

 커널 영역의 상위 8Byte 는 아래와 같이 물리 메모리와 1:1 매핑되게 됩니다.


 커널 영역의 하위 128MByte 는 아래와 같이 특수 목적을 위해 커널에서 Reserved 하여 사용하게 됩니다.(물리 메모리와는 상관 없습니다.)


 그러므로 Virtual memory 중에서 커널 영역에서 사용할 수 있는 공간은 1GByte - 128MByte = 896MByte 입니다.  


 위에 설명한 모든 내용은 PAE(Physical Address Extension) 를 사용하지 않는 32Bit CPU 일 경우에 관한 내용입니다.
 64Bit CPU 를 사용하거나 PAE 를 사용하는 경우에는 메모리 매핑하는 방법이 약간 달라집니다.

리눅스메모리모델.pptx




'development' 카테고리의 다른 글

[kernel] 커널 쓰레드  (0) 2012.01.04
[kernel] 시간지연  (1) 2012.01.02
[etc] 빌드 시스템  (0) 2011.12.23
[kernel] Thread 와 Kill  (0) 2011.11.26
[GCC] -S 옵션?  (0) 2011.11.18
블로그 이미지

김유석0

,
조교에게 감사해야 할듯. 


 

'재밌는거' 카테고리의 다른 글

따뜻한 보배드림  (0) 2012.02.03
근본있는 이름  (0) 2011.11.26
이말년의 패기  (0) 2011.11.26
내 손이 도구냐?  (0) 2011.11.26
냥이들  (0) 2011.11.26
블로그 이미지

김유석0

,

[etc] 빌드 시스템

development 2011. 12. 23. 11:02

build_system.tar.bz2


제가 사용중인 빌드시스템입니다.

'development' 카테고리의 다른 글

[kernel] 시간지연  (1) 2012.01.02
[kernel] 커널 메모리 모델  (0) 2011.12.29
[kernel] Thread 와 Kill  (0) 2011.11.26
[GCC] -S 옵션?  (0) 2011.11.18
[kernel] module_init(), module_exit()  (0) 2011.11.17
블로그 이미지

김유석0

,

근본있는 이름

재밌는거 2011. 11. 26. 16:52

멋있다..


친구놈은 딸 낳으면 "마리" 라고 짓고 싶어했는데.

김마리(=김말이)

출처 : 자게

'재밌는거' 카테고리의 다른 글

따뜻한 보배드림  (0) 2012.02.03
수류탄 투척 실패  (0) 2011.12.25
이말년의 패기  (0) 2011.11.26
내 손이 도구냐?  (0) 2011.11.26
냥이들  (0) 2011.11.26
블로그 이미지

김유석0

,

이말년의 패기

재밌는거 2011. 11. 26. 16:49
그래. 남자라면 이정도 패기는 있어야지.

 


출처 : 자게

'재밌는거' 카테고리의 다른 글

수류탄 투척 실패  (0) 2011.12.25
근본있는 이름  (0) 2011.11.26
내 손이 도구냐?  (0) 2011.11.26
냥이들  (0) 2011.11.26
생존왕  (1) 2011.11.19
블로그 이미지

김유석0

,

내 손이 도구냐?

재밌는거 2011. 11. 26. 16:46



출처 : 자게

'재밌는거' 카테고리의 다른 글

근본있는 이름  (0) 2011.11.26
이말년의 패기  (0) 2011.11.26
냥이들  (0) 2011.11.26
생존왕  (1) 2011.11.19
야 사장새끼 오늘 안 나올것 같다.  (0) 2011.11.09
블로그 이미지

김유석0

,

냥이들

재밌는거 2011. 11. 26. 16:45
냥이들입니다.






그냥 그렇다구요.

출처 : 자게

'재밌는거' 카테고리의 다른 글

이말년의 패기  (0) 2011.11.26
내 손이 도구냐?  (0) 2011.11.26
생존왕  (1) 2011.11.19
야 사장새끼 오늘 안 나올것 같다.  (0) 2011.11.09
DC 인사이드의 명언 목록  (0) 2011.11.08
블로그 이미지

김유석0

,

 아래와 같이 쓰레드를 여러개 생성하는 application 이 있습니다.

 1334 root      20   0     0    0    0 S    0  0.0   0:00.00 nfsd                                                                   
 1335 root      20   0     0    0    0 S    0  0.0   0:00.00 nfsd                                                                   
 1336 root      20   0     0    0    0 S    0  0.0   0:00.00 nfsd 


 nfsd 를 kill 하려고 하면 아래와 같이 입력하면 됩니다. 

 poplinux@poplinux: ~$ kill -9 1334 


아마 잘 동작할겁니다.

그런데 이상하지 않나요?

내가 죽이라고 한 것은  PID 1334 번 Process 인데 PID 1335, 1336 번까지 함께 죽어버리니까요.

 kill 명령은 지정한 PID 에 해당되는 프로세스가 죽이는 기능입니다. 





 이유를 살펴보니 이런 역사가 있었습니다. 


 예전에는 "Multi Thread" 라는 개념이 없었습니다.

 그래서 PID == Process 처럼 1:1 매칭이 되었었지요. 그래서 앞에서 언급한 것 같은 논리적인 오류가 없었는데

 이런 세상에, 컴퓨터 공학의 천재들이 그만 "Thread" 라는 녀석을 만들어 버렸네요.

 Thread 라는 녀석이 생겨나면서 PID == Process 라는 가정에 균열이 생기기 시작합니다.

 분명히 쓰레드는 각각 별도의 PID 를 가지고는 있지만 kill 신호로 부모 process 를 죽였는데 자식 쓰레드만 살아서 돌아다닌다면 큰 문제일 겁니다.

 그래서 나온 아이디어가 "부모 프로세스와 자식 쓰레드들을 하나의 그룹으로 묶자" 입니다.

 그게 바로 아래 구조입니다. 

 struct task_struct{
   pid_t pid;
   pid_t tgid;
 }

1개의 쓰레드로 동작하는 프로세스는 pid == tgid 입니다.
N개의 쓰레드로 동작하는 프로세스는 pid != tgid 입니다.

예를 들어 아래와 같은 프로세스가 있을때,

  Process     : pid = 100, 
tgid = 100
  - Thread_1 : pid = 101, tgid = 100
  - Thread_2 : pid = 102,tgid = 100

와 같이 구성되어 있고 getpid()  를 호출하면 pid 를 리턴하는게 아니라 tgid 를 리턴하게 됩니다.

이제 이해가 됩니다.

'development' 카테고리의 다른 글

[kernel] 커널 메모리 모델  (0) 2011.12.29
[etc] 빌드 시스템  (0) 2011.12.23
[GCC] -S 옵션?  (0) 2011.11.18
[kernel] module_init(), module_exit()  (0) 2011.11.17
[kernel] obj-y ? obj-m ? obj-$(CONFIG_TEST) ?  (1) 2011.11.08
블로그 이미지

김유석0

,
참 간단하지요잉?

sudo aptitude install tftpd-hpa 
mkdir /tftpboot
 
설정파일 수정
sudo vi /etc/default/tftpd-hpa

# /etc/default/tftpd-hpa

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/tftpboot"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure"
 
설정 내용 적용
sudo service tftpd-hpa restart
 
테스트는 아래와 같이 하면 됩니다. 

tftp 10.100.4.48
tftp> get test_file
 
끝입니다. 

'linux' 카테고리의 다른 글

리눅스 콘솔내용을 시리얼로 출력해서 보려면  (0) 2012.04.03
iproute2  (0) 2012.02.07
GNOME 설정  (0) 2011.09.27
Iconv 로 인코딩 변경하기  (0) 2011.09.26
LFS(Linux From Scratch)  (0) 2011.09.23
블로그 이미지

김유석0

,