시스템 호출 및 수 동 으로 시스템 호출 추가
6147 단어 개발 을 추진 하 다
시스템 호출 은 커 널 과 응용 프로그램 간 의 인터페이스 로 응용 프로그램 이 하드웨어 장치 와 다른 운영 체제 자원 에 접근 하려 면 시스템 호출 을 통 해 이 루어 져 야 합 니 다.
Liux 에서 시스템 호출 은 사용자 공간 에서 커 널 을 방문 하 는 유일한 수단 으로 이상 과 중단 을 제외 하고 커 널 의 유일한 > 합 법 적 인 입구 입 니 다.시스템 호출 수량 이 매우 적 고 i386 에 서 는 약 300 개 정도 밖 에 없다.
응용 프로그램 은 시스템 호출 대신 C 라 이브 러 리 의 응용 프로그램 인터페이스 (API) 를 통 해 프로 그래 밍 합 니 다.
C 라 이브 러 리 의 함 수 는 시스템 호출 을 호출 하지 않 을 수도 있 고 하나의 시스템 호출 만 간단하게 봉인 할 수도 있 으 며 여러 시스템 호출 을 통 해 하나의 기능 을 실현 할 수도 있다.
linux > 자체 가 제공 하 는 매크로 는 시스템 호출 에 직접 접근 합 니 다.man 2 syscall。
프로그래머 의 측면 에서 볼 때 시스템 호출 은 중요 하지 않 습 니 다. 그들 은 API 와 만 접촉 하면 됩 니 다.
커 널 의 측면 에서 볼 때 커 널 은 시스템 호출 과 만 접촉 하고 라 이브 러 리 함수 와 응용 프로그램 이 시스템 호출 을 어떻게 사용 하 는 지 는 커 널 이 관심 을 가 지 는 것 이 아니다.
Liux 커 널 의 모든 시스템 호출 함 수 는 sys 를 사용 합 니 다.서두
함수 정의 에 있 는 asmlinkage 매크로 는 컴 파일 러 에 알 리 고 부분 스 택 을 사용 하여 파 라 메 터 를 전달 합 니 다.
함수 정의 의 FASTCALL 매크로 는 컴 파일 러 에 알 리 고 레지스터 를 사용 하여 인 자 를 전달 합 니 다.
위의 두 개의 매크로 가 없 으 면 기본 전송 규칙 을 사용 하고 앞의 4 개의 매개 변 수 는 R0 ~ R3 레지스터 를 통 해 전달 되 며 나머지 더 많은 매개 변 수 는 스 택 을 통 해 전달 된다.
호출 체인: APP -- > LIB -- > 커 널 (syscall) --> module --> hardware
시스템 호출 은 사용자 공간 에서 커 널 공간 으로 들 어가 야 하기 때문에 간단 한 함수 호출 을 통 해 이 루어 질 수 없습니다. 일부 프로세서 가 지원 하 는 특수 메커니즘 (이른바 소프트 인 터 럽 트) 을 통 해 이 루어 져 야 합 니 다.
x86 에서 이 특수 한 메커니즘 은 어 셈 블 리 명령 int $0x 80 이 고 arm 에 서 는 어 셈 블 리 명령 SWI 입 니 다.
이 명령 은 C 라 이브 러 리 의 함수 에 봉 인 됩 니 다. 프로그램 이 이 명령 을 실행 하면 cpu 는 특수 한 이상 모드 (또는 소프트 인 터 럽 트 모드) 에 들 어가 프로그램 지침 을 특징 적 인 위치 로 이동 합 니 다 (예 를 들 어 arm 은 인 터 럽 트 벡터 표 의 0x8 곳).
커 널 에서 많은 시스템 호출 을 실 현 했 습 니 다. 이 시스템 에서 호출 된 주 소 는 시스템 호출 표 에 순서대로 놓 여 있 습 니 다. 이 표 는 sys 라 는 이름 입 니 다.call_table 의 배열, 모두 NRsyscalls 표 항목.
이 표를 통 해 커 널 이 정의 하 는 모든 sys 로 호출 할 수 있 습 니 다.함수
어 셈 블 리 명령 int $0x 80 또는 SWI 를 호출 할 때 시스템 호출 번 호 를 동시에 전달 해 야 합 니 다. 이 시스템 호출 번 호 는 색인 으로 syscall_table 에서 대응 하 는 시스템 호출 을 선택 하 십시오.
int 80 은 시스템 호출 번 호 를 eax 레지스터 에 저장 하고 SWI 는 명령 에 직접 통합 합 니 다 (예 를 들 어 SWI 0x 124).
프로 세 스: swi 시스템 호출 번호 -- > 시스템 호출 표 -- > 시스템 호출
커 널 에서 처리 시스템 호출 함수 정의 arch / x86 / kernel / entry. s 의 systemcall, arm 시스템 은 arch / arm / kernel / entry - common. s 의 vectorswi。
x86 시스템 호출 표 는 arch / x86 / kernel / syscall 로 정의 합 니 다.table. s (또는 entry. s) 에서 직접 정의 되 며, arm 은 arch / arm / kernel / calls. s 에서 정의 합 니 다.
x86 시스템 호출 번 호 는 arch / x86 / include / asm / unistd. h 에 정의 되 어 있 으 며, arm 시스템 호출 번 호 는 arch / arm / include / asm / unistd. h 에 정의 되 어 있 습 니 다.
시스템 호출 은 들 어 오 는 매개 변수의 유효성 을 자세히 검사 해 야 합 니 다. 특히 사용자 가 제공 하 는 지침 은 반드시 확보 해 야 합 니 다. * 포인터 가 가리 키 는 메모리 구역 은 사용자 공간 에 속 하고 프로 세 스 는 커 널 을 속여 커 널 공간의 데 이 터 를 읽 게 해 서 는 안 됩 니 다.* 포인터 가 가리 키 는 메모리 영역 은 프로 세 스 의 주소 공간 에 속 합 니 다. 커 널 을 속여 다른 프로 세 스 의 데 이 터 를 읽 을 수 없습니다.* 프로 세 스 가 메모리 접근 권한 을 돌 릴 수 없습니다.
커 널 은 시스템 호출 을 실행 할 때 프로 세 스 컨 텍스트 에 있 고 휴면 할 수도 있 으 며 선점 할 수도 있 기 때문에 시스템 호출 이 다시 들 어 갈 수 있 도록 해 야 합 니 다.
Liux 커 널 의 arm 구 조 를 추적 하 는 sysgetpid () 시스템 호출
시스템 호출 번 호 는 파일 arch / arm / include / asm / unistd. h 에서 다음 과 같 습 니 다.
설명: 보 이 는 sysgetpid () 의 시스템 호출 번 호 는 20 입 니 다. 이 호출 번 호 는 시스템 호출 표 (배열) 의 아래 표 입 니 다.그래서 시스템 호출 표 중 sysgetpid () 는 20 번 째 항목 에 있 을 것 입 니 다.
특히 주의: 시스템 호출 번호 17 과 같은 시스템 호출 은 이미 폐기 되 었 으 나 호환성 과 향후 혼란 이 없 기 때문에 호출 번 호 를 다시 사용 할 수 없고 비어 있 을 수 밖 에 없습니다 (건 너 뛰 기).
시스템 호출 표 는 파일 arch / arm / kernel / calls. s 에 있 습 니 다. 다음 과 같 습 니 다.
설명: 보 이 는 sysgetpid () 는 시스템 호출 표 에서 20 번 째 항목 으로 시스템 호출 번호 와 일치 합 니 다.
특히 주의: 시스템 호출 번호 17 에 대응 하 는 표 항목 은 버 려 진 시스템 호출 에 대해 Liux 시스템 은 sys 를 통일 적 으로 부여 합 니 다.ni_syscall () 시스템 호출.
시스템 호출 성명 은 파일 에 있 습 니 다. include / linux / syscalls. h, 다음 과 같 습 니 다.
시스템 호출 은 파일 kernel / timer. c 에서 이 루어 집 니 다. 다음 과 같 습 니 다.
설명: 소스 코드 에서 sys 를 직접 찾 을 수 없습니다.getpid () 의 구현 코드 는 64 가 시스템 의 BUG 이기 때문에 소스 코드 의 시스템 호출 sysABC, 모두 SYSCALLDEFINEx (ABC) 는 BUG 를 해결 하기 위해 한 층 포장 했다.
SYSCALL_DEFINE 는 파일 include / linux / syscalls. h 에서 다음 과 같 습 니 다.
자신 이 구현 한 시스템 호출 을 수 동 으로 추가 합 니 다:
먼저, 원래 코드 를 모방 하여 파일 arch / arm / include / asm / unistd. h 에 시스템 호출 번 호 를 추가 합 니 다. 다음 과 같 습 니 다.
특히 자신 이 새로 추가 한 시스템 호출 번 호 는 원래 의 최대 가치 에 만 1 을 추가 할 수 있 기 때문에 나의 시스템 호출 번 호 는 361 이 고 대응 하 는 시스템 호출 은 sys 이다.mysyscall()
그 다음 에 원래 코드 를 모방 하여 파일 arch / arm / kernel / calls. S 에 시스템 호출 표 항목 을 추가 합 니 다. 다음 과 같 습 니 다.
마지막: 시스템 호출 실현 코드 를 작성 합 니 다. 이 코드 는 커 널 에 컴 파일 될 수 있 도록 해 야 합 니 다. 다음 과 같 습 니 다.
파일 init / main. c 가 커 널 에 컴 파일 되 어 있다 는 것 을 알 고 있 기 때문에 구현 코드 는 이 파일 에 추 가 됩 니 다.
특히 주의: 시스템 호출 은 log 값 을 되 돌려 야 합 니 다.
이 시스템 호출 을 사용 하려 면 커 널 을 다시 컴 파일 해 야 하고 개발 판 은 새로운 커 널 을 사용 해 야 합 니 다. 다음 과 같 습 니 다.
1 ,linux , :
2 # make
3 # cp -f arch/arm/boot/zImage /tftpboot/
4 , :
5 $ reboot
프로그램: 테스트 시스템 호출 의 실현 효과
디 렉 터 리 / nfsroot / kern / 2012 - 04 - 16 / 02 / 를 만 듭 니 다.
파일 / nfsroot / kern / 2012 - 04 - 16 / 02 / test. c 를 만 듭 니 다. 내용 은 다음 과 같 습 니 다.
파일 / nfsroot / kern / 2012 - 04 - 16 / 02 / Makefile 을 만 듭 니 다. 내용 은 다음 과 같 습 니 다.
호스트 에서 컴 파일 러 를 만 드 는 과정 은 다음 과 같 습 니 다.
개발 판 에서 테스트 프로그램 을 실행 하 는 과정 은 다음 과 같 습 니 다.
설명: getpid 의 두 가지 결 과 를 볼 수 있 습 니 다. 우리 자신의 시스템 호출 361 도 정확하게 작 동 합 니 다.
특별 설명:
시스템 호출 번 호 는 Liux 커 널 관리자 가 확인 한 것 입 니 다. 자신 이 추가 한 시스템 호출 입 니 다. 다른 사람 이 개발 한 응용 프로그램 은 사용 되 지 않 습 니 다. 자신 만 이 시스템 호출 이 있다 는 것 을 알 고 있 기 때 문 입 니 다.
이러한 시스템 호출 은 커 널 소스 코드 를 직접 수정 해 야 하고 커 널 에 컴 파일 해 야 사용 할 수 있 으 며 시스템 호출 번 호 는 자신 이 설정 한 것 이기 때문에 일반적으로 이렇게 수 동 으로 시스템 호출 을 추가 하지 않 습 니 다.
스스로 sysopen,sys_read 등 시스템 호출 은 모듈 을 통 해 이 루어 지고 시스템 호출 의 재 활용 을 실현 할 수 있 습 니 다.