'리눅스/커널'에 해당되는 글 43건

  1. 2011.04.20 커널 초기화
  2. 2011.04.18 시스템콜 (미완성)
  3. 2011.04.15 asmlinkage 에 대한 설명
리눅스/커널2011. 4. 20. 08:53



다음은 커널 이미지를 만드는 과정이다.


부트로더와 부트스트랩은 다르다. 부트가 첫단계 스테이지라고 생각한다면 부트스트랩은 두번째단계로 리눅스커널 이미지를 올려준다.

'리눅스 > 커널' 카테고리의 다른 글

Linux 3.0 Kernel  (0) 2011.07.31
커널선점  (0) 2011.05.01
커널 스레드  (0) 2011.05.01
시스템콜 (미완성)  (0) 2011.04.18
asmlinkage 에 대한 설명  (0) 2011.04.15
Posted by code cat
리눅스/커널2011. 4. 18. 08:54
시스템콜(종종 시스콜이라 불림)

asmlinkage long sys_getpid (void)
{
return current->tgid
}




프로세스 컨텍스트 내에선 커널은 휴면이 가능하며 선점될 수 있다.

휴면이 가능하다는 것은 인터럽트에 비해 훨씬 편리한 커널 프로그래밍을 가능하게 한다.(인터럽트는 휴면이 불가능 하므로 프로세스 컨텍스트에서 도는 시스콜보다 제한이 많다). 
선점이 가능하다는 것은 지금 테스크 역시 선점 가능하다는 소리이므로 다른 테스크에서 같은 시스콜을 호출 할 수 있기에 시스콜이 재진입 여부를 체크해야 한다.(이것은 SMP에서 고려해야 하는 상황과 같다)

시스콜이 리턴하면 컨트롤은 system_call() 계속되며 결국 유저 프로세스로 돌아간다

시스콜 추가 하는법
1. 시스템콜 테이블 끝에 새로운 엔트리를 추가한다. 지원할려는 아키텍쳐마다 추가해야 하며, 테이블에서의 위치-1이 시스템콜 넘버이다. 
Entry.S

ENTRY(sys_call_table)
.long sys_open
.long sys_read 


....


2. 각 지원되는 아키텍쳐마다 시스콜 넘버를에 정의한다. 

#define __NR_restart_sys_call
#define __NR_exit




3. 시스콜을 커널이미지에 컴파일 한다.(kernel/ 에 관련된 파일에 시스콜을 추가한다. 예)sys.c)

asmlinkage sys_foo (void)
{
...
}



'리눅스 > 커널' 카테고리의 다른 글

Linux 3.0 Kernel  (0) 2011.07.31
커널선점  (0) 2011.05.01
커널 스레드  (0) 2011.05.01
커널 초기화  (0) 2011.04.20
asmlinkage 에 대한 설명  (0) 2011.04.15
Posted by code cat
리눅스/커널2011. 4. 15. 23:25

출처: http://studyfoss.egloos.com/4951809


커널 소스를 보다보면 asmlinkage로 선언된 함수들을 볼 수 있다.
asmlinkage는 어셈블리 코드에서 직접 호출(링크)할 수 있다는 의미이며
커널 소스의 <include/linux/linkage.h>에 다음과 같이 정의되어 있다.

#include <linux/config.h>
#include <asm/linkage.h>

#ifdef __cplusplus
#define CPP_ASMLINKAGE extern "C"
#else
#define CPP_ASMLINKAGE
#endif

#ifndef asmlinkage
#define asmlinkage CPP_ASMLINKAGE
#endif

...

그렇다면 어셈블리 코드에서 직접 호출할 수 있다는 것은 무엇을 의미할까?
일반적으로 C 함수는 어셈블리 코드에서 별 어려움없이 호출할 수 있지만
함수의 인자를 넘기거나 리턴값을 받는 부분 등의 호출 규약이 필요하다.

레지스터에 여유가 있는 ARM이나 MIPS 등의 아키텍처에서는
함수의 인자를 넘길 때 특정 레지스터를 사용하도록 호출 규약이 정의되어 있지만,
그렇지 못한 x86 아키텍처에서는 때에 따라 레지스터, 스택 혹은 별도의 메모리 영역에
함수의 인자를 저장하여 넘길 수 있도록 지원한다.

당연히 인자를 레지스터에 저장하여 넘기는 방식이 빠르기 때문에 (fastcall)
최적화 옵션을 켜고 컴파일하는 경우 인자를 레지스터를 통해 전달하도록
함수의 호출부와 구현부를 변경해 버릴 수 있다. (일반적인 최적화 방법)
이 경우 GCC를 통해 자동 생성되는 코드는 적절히 변환되므로 문제가 없을테지만
직접 작성한 어셈블리 코드에서 함수를 호출하는 경우 문제가 발생하게 된다.

이 경우를 방지하기 위해 어셈블리 코드와 링크되는 함수는
인자를 (레지스터를 이용하지 않고) 스택을 이용해서 전달하도록
선언하는 데, 이 때 asmlinkage가 사용된다.

위의 코드에서 <asm/linkage.h> 파일을 #include 하고 있는 것에 주의하자.
대부분의 아키텍처에서 이 파일은 asmlinkage를 정의하지 않지만
i386에서는 다음과 같이 정의한다.

#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
#define FASTCALL(x) x __attribute__((regparm(3)))
#define fastcall __attribute__((regparm(3)))

regparm 속성은 레지스터를 이용하여 전달한 인자의 수를 지정한다.
asmlinkage로 선언된 경우 모두 스택을 이용하고 (레지스터로 0개의 인자 전달)
fastcall로 선언된 경우 최대 3개의 인자를 레지스터로 전달한다.
(이 경우 EAX, EDX, ECX 레지스터를 이용하며, 인자는 정수형이어야 한다.)

'리눅스 > 커널' 카테고리의 다른 글

Linux 3.0 Kernel  (0) 2011.07.31
커널선점  (0) 2011.05.01
커널 스레드  (0) 2011.05.01
커널 초기화  (0) 2011.04.20
시스템콜 (미완성)  (0) 2011.04.18
Posted by code cat