it-swarm-ko.tech

Linux 커널 시스템 호출 구현을 어떻게 찾을 수 있습니까?

커널 소스를보고 mkdir와 같은 함수의 작동 방식을 이해하려고합니다. 이것은 커널 내부를 이해하고 다양한 기능을 탐색하려는 시도입니다. mkdirsys/stat.h에 정의되어 있음을 알고 있습니다. 프로토 타입을 찾았습니다.

/* Create a new directory named PATH, with permission bits MODE.  */
extern int mkdir (__const char *__path, __mode_t __mode)
     __THROW __nonnull ((1));

이제이 함수가 어느 C 파일에 구현되어 있는지 확인해야합니다. 소스 디렉토리에서 시도했습니다

ack "int mkdir"

어느 표시

security/inode.c
103:static int mkdir(struct inode *dir, struct dentry *dentry, int mode)

tools/perf/util/util.c
4:int mkdir_p(char *path, mode_t mode)

tools/perf/util/util.h
259:int mkdir_p(char *path, mode_t mode);

그러나 이들 중 어느 것도 sys/stat.h의 정의와 일치하지 않습니다.

질문

  1. mkdir 구현이있는 파일은 무엇입니까?
  2. 위와 같은 함수 정의를 사용하여 어떤 파일이 구현되어 있는지 어떻게 알 수 있습니까? 메소드를 정의하고 구현할 때 커널이 따르는 패턴이 있습니까?

참고 : 커널 2.6.36-rc1 을 사용하고 있습니다.

376
Navaneeth K N

시스템 호출은 일반 함수 호출처럼 처리되지 않습니다. 사용자 공간에서 커널 공간으로 전환하기 위해서는 특별한 코드가 필요합니다. 기본적으로 호출 사이트에서 프로그램에 인라인 어셈블리 코드가 약간 주입됩니다. 시스템 호출을 "잡는"커널 사이드 코드는 최소한 처음에는 깊이 이해할 필요가없는 하위 수준의 것입니다.

커널 소스 디렉토리 아래 include/linux/syscalls.h 에서 다음을 찾을 수 있습니다.

asmlinkage long sys_mkdir(const char __user *pathname, int mode);

그런 다음 /usr/include/asm*/unistd.h에서 다음을 찾을 수 있습니다.

#define __NR_mkdir                              83
__SYSCALL(__NR_mkdir, sys_mkdir)

이 코드는 mkdir(2)이 시스템 호출 # 83이라고 말합니다. 즉, 시스템 호출은 사용자 프로그램 내에서 일반적인 함수 호출이나 프로그램에 연결된 라이브러리의 함수와 같이 주소가 아닌 번호로 호출됩니다. 위에서 언급 한 인라인 어셈블리 글루 코드는이를 사용하여 매개 변수와 함께 사용자 공간에서 커널 공간으로 전환합니다.

여기서 약간 이상한 점이 있다는 또 다른 증거는 시스템 호출에 대해 항상 엄격한 매개 변수 목록이있는 것은 아니라는 것입니다. 예를 들어 open(2)은 2 개 또는 3 개의 매개 변수를 사용할 수 있습니다. 이는 open(2)이 C가 아니라 C++의 기능인 overloaded 임을 의미하지만 syscall 인터페이스는 C와 호환됩니다. (이것은 C의 varargs feature 와 동일하지 않으므로 단일 함수가 가변 개수의 인수를 사용할 수 있습니다.)

첫 번째 질문에 답하기 위해 mkdir()이 존재하는 단일 파일은 없습니다. Linux는 여러 가지 파일 시스템을 지원하며 각각의 "mkdir"작업 구현이 있습니다. 커널이 단일 시스템 호출 뒤에있는 모든 것을 숨길 수있는 추상화 계층을 VFS 이라고합니다. 따라서 vfs_mkdir()을 (를) 사용하여 fs/namei.c에서 파기를 시작하고 싶을 것입니다. 저수준 파일 시스템 수정 코드의 실제 구현은 다른 곳입니다. 예를 들어, ext4 구현을 fs/ext4/namei.c 에 정의 된 ext4_mkdir()이라고합니다.

두 번째 질문에 관해서는 그렇습니다.이 모든 것에 패턴이 있지만 단일 규칙은 아닙니다. 실제로 필요한 것은 특정 시스템 호출을 어디에서 찾아야하는지 파악하기 위해 커널 작동 방식을 상당히 광범위하게 이해하는 것입니다. 모든 시스템 호출에 VFS가 포함되는 것은 아니므로 커널 측 호출 체인이 모두 fs/namei.c로 시작되는 것은 아닙니다. 예를 들어, mmap(2)mm/mmap.c 로 시작합니다. 커널의 메모리 관리 ( "mm") 하위 시스템의 일부이기 때문입니다.

Bovet과 Cesati의 " Linux Kernel 이해하기 "의 사본을받는 것이 좋습니다.

388
Warren Young

이것은 아마도 귀하의 질문에 직접 대답하지는 않지만 strace는 가장 간단한 쉘 명령을 위해 만들어진 기본 시스템 호출을 이해하려고 할 때 정말 멋지다는 것을 알았습니다. 예 :.

strace -o trace.txt mkdir mynewdir

시스템은 mkdir mynewdir는 시청의 즐거움을 위해 trace.txt에 덤프됩니다.

86
Banjer

리눅스 커널 소스를 읽는 좋은 곳은 Linux 상호 참조 (LXR) ¹입니다. 검색은 자유 텍스트 검색 결과와 함께 유형이 일치하는 항목 (함수 프로토 타입, 변수 선언 등)을 반환하므로 단순한 grep보다 빠릅니다 (더 빠름).

LXR은 전 처리기 정의를 확장하지 않습니다. 시스템 호출의 이름은 모든 곳에서 전처리기에 의해 엉망이됩니다. 그러나 대부분의 시스템 호출은 SYSCALL_DEFINEx 매크로 패밀리 중 하나로 정의됩니다. mkdir은 두 개의 인수를 취하므로 SYSCALL_DEFINE2(mkdir를 검색하면 mkdir syscall 선언 이됩니다.

SYSCALL_DEFINE2(mkdir, const char __user *, pathname, int, mode)
{
    return sys_mkdirat(AT_FDCWD, pathname, mode);
}

좋아, sys_mkdiratmkdirat syscall임을 의미하므로이를 클릭하면 include/linux/syscalls.h의 선언으로 만 이어지지 만 정의는 바로 위에 있습니다.

mkdirat의 주요 작업은 vfs_mkdir (VFS는 일반 파일 시스템 레이어)를 호출하는 것입니다. 클릭하면 두 가지 검색 결과가 나타납니다. include/linux/fs.h의 선언과 위의 몇 줄의 정의입니다. vfs_mkdir의 주요 작업은 파일 시스템 별 구현 인 dir->i_op->mkdir를 호출하는 것입니다. this 구현 방법을 찾으려면 개별 파일 시스템의 구현으로 전환해야하며, 규칙이 빠르지 않으며 심지어 커널 트리 외부의 모듈 일 수도 있습니다.

¹ LXR은 인덱싱 프로그램입니다. LXR에 인터페이스를 제공하는 여러 웹 사이트가 있으며, 약간 다른 버전의 알려진 버전과 약간 다른 웹 인터페이스가 있습니다. 그것들은왔다 갔다하는 경향이 있으므로, 익숙한 것이 없다면, "linux cross-reference"를 웹 검색하여 다른 것을 찾으십시오.

시스템 호출은 일반적으로 SYSCALL_DEFINEx() 매크로에 래핑되므로 간단한 grep에서 찾지 못합니다.

fs/namei.c:SYSCALL_DEFINE2(mkdir, const char __user *, pathname, int, mode)

매크로가 확장 된 후 최종 함수 이름은 sys_mkdir가됩니다. SYSCALL_DEFINEx() 매크로는 각 syscall 정의에 필요한 추적 코드와 같은 상용구를 추가합니다.

22
stefanha

참고 : .h 파일은 define 함수가 아닙니다. 해당 .h 파일에서 선언이며 다른 곳에서 정의 (구현)됩니다. 이를 통해 컴파일러는 함수의 서명 (프로토 타입)에 대한 정보를 포함하여 인수의 유형 검사를 허용하고 리턴 유형을 코드의 호출 컨텍스트와 일치시킬 수 있습니다.

일반적으로 C의 .h (헤더) 파일은 함수를 선언하고 매크로를 정의하는 데 사용됩니다.

mkdir는 특히 시스템 호출입니다. 해당 시스템 호출 주위에 GNU libc 래퍼가있을 수 있습니다 (실제로 사실임). mkdir의 실제 커널 구현을 찾을 수 있습니다. 커널 소스와 시스템 호출을 검색하여.

또한 각 파일 시스템마다 일종의 디렉토리 작성 코드가 구현됩니다. VFS (가상 파일 시스템) 계층은 시스템 호출 계층이 호출 할 수있는 공통 API를 제공합니다. 모든 파일 시스템은 VFS 계층이 호출 할 기능을 등록해야합니다. 이를 통해 다른 파일 시스템은 디렉토리가 어떻게 구조화되는지에 대한 고유 한 의미를 구현할 수 있습니다 (예 : 특정 항목을보다 효율적으로 검색하기 위해 일종의 해싱 구성표를 사용하여 저장 한 경우). Linux 커널 소스 트리를 검색하는 경우 이러한 파일 시스템 특정 디렉토리 작성 기능을 넘어갈 가능성이 있기 때문에 이것을 언급합니다.

17
Jim Dennis

찾은 구현 중 어느 것도 sys/stat.h의 프로토 타입과 일치하지 않습니다.이 헤더 파일을 사용하여 include 문을 검색하면 더 성공적 일 수 있습니다.

8
greg0ire

다음은 저수준 커널 소스 코드를 사냥하는 다양한 기술을 설명하는 몇 가지 훌륭한 블로그 게시물입니다.

6
An̲̳̳drew