Linux 커널 시스템 호출 구현을 찾는 방법은 무엇입니까?

Linux 커널 시스템 호출 구현을 찾는 방법은 무엇입니까?

mkdir커널 소스 코드를 보면서 함수가 어떻게 작동하는지 이해 하려고 합니다 . 이는 커널 내부를 이해하고 다양한 기능을 탐색하려는 시도입니다. mkdir에 정의되어 있는 것으로 알고 있습니다 sys/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.

답변1

시스템 호출은 일반 함수 호출과 다르게 처리됩니다. 사용자 공간에서 커널 공간으로의 변환을 구현하려면 특수 코드가 필요합니다. 기본적으로 일부 인라인 어셈블리 코드는 호출 사이트에서 프로그램에 삽입됩니다. 시스템 호출을 "잡는" 커널측 코드도 최소한 처음에는 깊이 이해할 필요가 없는 낮은 수준의 코드입니다.

존재하다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++ 기능이지만 시스템 호출 인터페이스가 C와 호환됩니다. (이것은 C와는 다르다.가변 매개변수 기능, 단일 함수가 다양한 수의 인수를 취할 수 있도록 합니다. )

첫 번째 질문에 답하자면 단일 파일이 존재하지 않습니다 mkdir(). Linux는 각각 자체적으로 "mkdir" 작업을 구현하는 다양한 파일 시스템을 지원합니다. 커널이 단일 시스템 호출 뒤에 모든 것을 숨길 수 있도록 하는 추상화 계층을 호출합니다.가상 FS. 따라서 더 깊이 파고들고 싶을 수도 fs/namei.c있으며 vfs_mkdir()저수준 파일 시스템 수정 코드의 실제 구현은 다른 곳에 있습니다. 예를 들어, ext4 구현은 다음 ext4_mkdir()과 같이 정의됩니다.fs/ext4/namei.c.

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

"라는 사본을 구하는 것이 좋습니다.Linux 커널에 대해 알아보기” 보베와 체사티.

답변2

strace이것은 귀하의 질문에 직접적으로 대답하지 못할 수도 있지만 기본 시스템 호출, 심지어 가장 간단한 쉘 명령을 이해하려고 할 때 매우 멋지다고 생각합니다 . 예를 들어

strace -o trace.txt mkdir mynewdir

이 명령에 대한 시스템 호출은 mkdir mynewdir사용자가 검토할 수 있도록 Trace.txt에 덤프됩니다.

답변3

Linux 커널 소스 코드를 읽기에 좋은 곳은 다음과 같습니다.Linux 상호 참조(LXR)1. 자유 텍스트 검색 결과 외에도 검색에서는 유형 일치(함수 프로토타입, 변수 선언 등)도 반환하므로 일반 grep보다 더 편리하고 빠릅니다.

LXR은 전처리기 정의를 확장하지 않습니다. 시스템 호출 이름은 전처리기에 의해 모든 곳에서 손상됩니다. 그러나 대부분의 (모두?) 시스템 호출은 다음 중 하나로 정의됩니다.SYSCALL_DEFINEx매크로 시리즈. mkdir두 개의 매개변수가 필요하므로 다음을 검색하세요 .SYSCALL_DEFINE2(mkdir~로 이어지다mkdir시스템 호출 선언:

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

좋아, 시스템 호출 sys_mkdirat이라는 뜻 mkdirat이므로 클릭하면 의 선언만 볼 수 있지만 include/linux/syscalls.h정의는 바로 위에 있습니다.

mkdirat전화하는 것이 주된 업무 이다.vfs_mkdir(VFS는 범용 파일 시스템 계층입니다). 이를 클릭하면 두 가지 검색 결과가 표시됩니다. 즉, 선언 include/linux/fs.h과 몇 줄 위의 정의입니다. 주요 작업은 vfs_mkdir파일 시스템별 구현을 호출하는 것입니다 dir->i_op->mkdir. 방법을 찾고이것일단 구현되면 단일 파일 시스템 구현으로 이동해야 하며 엄격하고 빠른 규칙은 없습니다. 커널 트리 외부의 모듈일 수도 있습니다.

1 LXR은 인덱싱 프로그램입니다. 알려진 버전과 웹 인터페이스 세트가 약간 다른 LXR 인터페이스를 제공하는 여러 웹사이트가 있습니다. 그것들은 오고 가는 경향이 있으므로, 익숙한 것을 사용할 수 없다면 웹에서 "linux 상호 참조"를 검색하여 다른 것을 찾으십시오.

답변4

참고: .h 파일에는정의기능. 그것은발표하다해당 .h 파일에 있고 다른 곳에서 정의(구현)되었습니다. 이를 통해 컴파일러는 함수 시그니처(프로토타입)에 대한 정보를 포함하여 매개변수의 유형을 검사하고 반환 유형을 코드의 호출 컨텍스트와 일치시킬 수 있습니다.

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

mkdir특히 시스템 호출. GNU가 있을 수 있습니다.도서관해당 시스템 호출을 둘러싼 래퍼입니다(사실 거의 확실합니다). 실제 커널 구현은 mkdir특히 커널 소스 코드와 시스템 호출을 검색하여 찾을 수 있습니다.

각 파일 시스템은 일종의 디렉터리 생성 코드도 구현합니다. VFS(Virtual File System) 계층은 시스템 호출 계층에서 호출할 수 있는 공통 API를 제공합니다. 각 파일 시스템은 VFS 계층이 호출할 함수를 등록해야 합니다. 이를 통해 다양한 파일 시스템이 고유한 디렉터리 구조 의미를 구현할 수 있습니다(예: 특정 항목을 보다 효율적으로 검색하기 위해 일부 해싱 체계를 사용하여 저장하는 경우). Linux 커널 소스 트리를 검색하는 경우 이러한 파일 시스템별 디렉터리 생성 기능을 발견할 수 있기 때문에 이것을 언급합니다.

관련 정보