x86 및 x86_64의 Linux 시스템 호출 번호가 다른 이유는 무엇입니까?


35

시스템 호출 인터페이스는 낮은 수준에서 구현되므로 "일반적인"코드가 아닌 아키텍처 / 플랫폼에 따라 다릅니다.

그러나 Linux 32 비트 x86 커널에서 시스템 호출이 유사한 아키텍처 Linux 64 비트 x86_64에서 동일하게 유지되지 않는 숫자를 갖는 이유를 명확하게 알 수 없습니까? 이 결정의 동기는 무엇입니까?

필자의 첫 번째 추측은 배경 문제가 x86_64 시스템에서 32 비트 응용 프로그램을 실행 가능하게 유지하는 것이므로 시스템 호출 번호에 대한 합리적인 오프셋을 통해 시스템은 사용자 공간이 32 비트 또는 64 비트임을 알 수 있습니다. 각기. 그러나 이것은 사실이 아닙니다. 적어도 x86_64의 시스템 호출 번호 0 인 read ()는이 생각과 일치 할 수없는 것 같습니다.

또 다른 추측은 시스템 호출 번호를 변경하면 보안 / 경화 배경을 가질 수 있다는 것입니다.

아키텍처에 의존하는 코드 부분을 구현하는 데 어려움을 겪지 않아도 필요가 없을 때 시스템 호출 번호를 변경하는 방법이 여전히 궁금 합니다 (16 비트 레지스터조차도 현재 ~ 346 숫자보다 크게 더 많이 저장하기 때문에 호출), 휴식 호환성 이외를 달성하기 위해 도움이 될 , 도서관, libc를 통해 시스템 호출을 사용하지만 (완화시킨다 그것을).


3
나는 당신이 잘못된 질문을하고 있다고 생각합니다. 정답은 왜 동일하게 유지 하는가입니다. 호환성에 대한 답변. 따라서 x86과 x86_64가 호환되지 않으면 변경을 막을 힘이 없습니다. 이제 지난 20 년 동안 변화를 원했던 모든 세력이 지배 할 것입니다 (우리는이를 바꿀 기회를 얻습니다). [이것은 단지 의견 일 뿐이며 새로운 시스템의 설계자들의 내면의 마음에 근거한 것이 아닙니다.]
ctrl-alt-delor

답변:


34

x86_64 아키텍처의 일부인 "x32"를 제외한 다른 아키텍처와 일치하지 않는 특정 번호 매기기에 대한 추론은 다음과 같습니다. Linux 커널에서 x86_64가 지원되는 초기에는 이전 버전과의 호환성 제약 으로 인해 캐시 라인 사용량 수준에서 최적화하기 위해 모든 시스템 호출의 번호가 다시 지정 되었습니다 .

나는 이러한 선택에 대한 구체적인 기준을 알고 커널 개발에 대해 충분히 알고 있지만, 분명히 존재하지 않는 일부 기존 아키텍처에서 번호 다시 매기기이 특정 번호로 모든보다는 단순히 목록을 복사하는 선택의 뒤에 논리와 사용되지 않는를 제거합니다. 읽기 / 쓰기 / 열기 / 닫기가 먼저 시작되는 순서에 따라 순서가 일반적인 것으로 표시 될 수 있습니다. 출구와 포크는 "기본"처럼 보일 수 있지만 각각 프로세스 당 한 번만 호출됩니다.

동일한 캐시 라인 내에서 일반적으로 함께 사용되는 시스템 호출을 유지하는 것에 관한 일이있을 수 있습니다 (이 값은 정수이지만 커널에 각각 함수 포인터가있는 테이블이 있으므로 8 개의 시스템 호출 그룹마다 사용됩니다) 해당 테이블의 64 바이트 캐시 라인)


1
fork may seem "fundamental", but [...] called only once per process.어? 난 당신이 한 번 출구 전화를 기대할 수 이해하지만, 당신은의 부모와 자식의 내부 포크 할 수 있습니다 fork()전화
고양이

5
@cat fork부모 프로세스가 아닌 자식 프로세스에 대한 설명으로 볼 경우 (즉, 프로세스 생성 호출로 볼 경우) Random832의 문장이 정확합니다.
이카루스

4
@cat 좋아, fork ()를 두세 번 호출 할 수도있다. 그러나 read ()를 수백만 또는 수십억 번 호출 할 수 있습니다.
Michael Hampton

1
그렇습니다. init, clone [프로세스 또는 스레드를 생성 할 수 있음] 등과 같은 세부 사항을 무시하고 포크 호출 횟수와 시스템 수명 동안 프로세스 수는 동일합니다.
Random832

15

"AMD64 Linux에서 시스템 호출 번호가 다른 이유는 무엇입니까?"라는 질문에 대한 답변 을 참조하십시오. 스택 오버플로.

요약하면 호환성을 위해 시스템 호출 목록은 안정적이며 계속 커질 수 있습니다. x86 64 아키텍처가 나타 났을 때 ABI (인수 전달, 반환 값)가 다르기 때문에 커널 개발자는 오랫동안 기다려온 변경 사항을 가져올 수있었습니다.


내 추측이 맞았 어
ctrl-alt-delor

2
당신이 링크하는 다른 대답은 추측입니다. "Linux 사람들이 가장 많이 결정 했을 것입니다 ..."라고 강조했습니다. 나는 당신의 대답이 증거가 아닌 추측에 근거한 것으로 보인다는 것을 알려 주면 도움이 될 것이라고 생각합니다. 덧붙여서, 링크 된 답변 아래에 게시 된 최신 의견은 진정한 이유가 부스러기의 일반적인 정리가 아니라 (답변이 추측하는 것처럼) 구체적으로 "캐시 라인 사용"에 관한 증거를 제공합니다 . 여기의 다른 답변에서 설명 합니다 .
DW

-3

요컨대, 누군가가 " N+1무의식적으로 양립 할 수없는 방법이 N방법 보다 낫다 "고 생각했기 때문 입니다. 역사적 아치의 경우 syscall 번호는 일반적으로 일부 독점 독점 유닉스와 일치하도록 선택되었습니다. 그러나 x86_64의 경우 커널 개발자는 마음에 드는 번호를 자유롭게 선택할 수있었습니다. 간단한 선택을하고 기존 번호를 재사용하는 대신 새로운 표준을 고안하기로 결정했습니다. 그런 다음 그들은 aarch64와 다른 많은 사람들을 위해 다시했습니다. 이것은 Linux 커널 개발에서 자주 반복되는 패턴입니다.


3
변화는 무례 하지 않았다 . 확실한 기술적 이유가 있습니다. 이전 버전과의 호환성 요구 사항이 아니라면 기존 아키텍처에도 비슷한 변경 사항이 적용되었을 것입니다.
Jörg W Mittag

번호 매기기의 차이는 100 % 무의미합니다. 특정 번호 매기기에는 기술적 이점이 없습니다.
R ..

2
이 다른 답변에서 설명하는 것처럼 syscall은 일반적으로 함께 사용되는 syscall이 syscall 테이블에서 동일한 캐시 라인을 공유하도록 그룹화됩니다. 그리고 시스템 콜 번호 는 해당 테이블에 대한 간단한 색인이되도록 선택됩니다. 이론적으로, 우리는 간접 호출 계층을 사용하여 syscall 테이블에서 syscall 테이블의 syscall 위치를 syscall 번호에서 분리 할 수 ​​있지만 핫 캐시 호출을 동일한 캐시 라인에 넣음으로써 얻을 수있는 성능 향상의 일부를 차지할 수 있습니다.
Jörg W Mittag

@ JörgWMittag : 그리고 그것은 분명히 조기 최적화이며 측정 가능한 개선이 아닙니다. syscall이 얼마나 많은 사이클을 수행하고 얼마나 많은 캐시 라인을 제거하는지 살펴보십시오. 테이블 순서에서 캐시 라인을 하나만 저장해도 차이가 없습니다.
R ..

2
@R .. "일부 네트워크 및 데스크탑 응용 프로그램의 인기있는 DBMS 및 strace 출력으로 tpcc 커널 프로파일 링 정보의 기능으로 번호 매기기를 선택했습니다." 측정이 있었던 것처럼 확실히 소리가납니다. 그러나 저자는 숫자를 제공하지 않았거나 방법론을 적절하게 설명했습니다.
user45891
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.