나는 시스템 호출 인터페이스가 낮은 수준에서 구현되므로 "일반" 코드가 아닌 아키텍처/플랫폼에 따라 다르다는 것을 이해합니다.
그러나 Linux 32비트 x86 커널의 시스템 호출 번호 지정이 유사한 아키텍처의 Linux 64비트 x86_64의 번호 지정과 왜 다른지 명확하게 알 수 없습니다. 이 결정을 내린 동기/이유는 무엇이었나요?
내 첫 번째 추측은 배경 이유가 x86_64 시스템에서 32비트 응용 프로그램을 계속 실행하여 시스템 호출 번호의 합리적인 오프셋을 사용하여 시스템이 사용자 공간이 각각 32비트인지 64비트인지 알 수 있도록 하는 것입니다. 그러나 그렇지 않습니다. 적어도 내 생각에는 x86_64의 시스템 호출 번호 0인 read()는 이 아이디어와 맞지 않습니다.
또 다른 추측은 syscall 번호를 변경하면 보안/강화 배경이 있을 수 있다는 것입니다. 그러나 이를 직접 확인할 수는 없습니다.
코드의 아키텍처 종속 부분을 구현하는 데 따른 어려움을 이해하지 못하더라도 여전히 알고 싶습니다.시스템 호출 번호를 변경하는 방법, 불필요해 보일 때(16비트 레지스터라도 모든 호출을 나타내기 위해 현재 ~346개 숫자보다 더 많은 숫자를 저장하므로),호환성을 깨는 것 이외의 목표를 달성하는 데 도움이 될 것입니다.(이는 libc 라이브러리를 통한 시스템 호출을 사용하여 완화될 수 있습니다.)
답변1
특정 숫자 뒤에 있는 추론은 다른 아키텍처와 일치하지 않습니다[실제로 x86_64 아키텍처의 일부인 "x32" 제외]. Linux 커널에서 x86_64 지원 초기, 지원이 없었습니다. 심각한 이전 버전과의 호환성 제한으로 인해 모든 시스템 호출의 번호가 다시 매겨집니다.캐시 라인 사용량 수준에서 최적화.
나는 이러한 선택에 대한 구체적인 근거를 알 만큼 커널 개발에 대해 충분히 알지 못하지만 분명히 다음과 같은 것들이 있습니다.일부단순히 기존 스키마에서 목록을 복사하고 사용되지 않는 목록을 삭제하는 대신 이러한 특정 숫자를 사용하여 모든 항목의 번호를 다시 매기도록 선택하는 논리입니다. 순서는 호출 빈도에 따라 달라질 수 있는 것 같습니다. 예를 들어 읽기/쓰기/열기/닫기가 앞에 있습니다. 종료 및 포크는 "기본"처럼 보일 수 있지만 프로세스당 한 번만 호출됩니다.
일반적으로 사용되는 시스템 호출을 동일한 캐시 라인에 유지하면 문제가 발생할 수도 있습니다(값은 단지 정수이지만 커널에는 각 시스템 호출에 대한 함수 포인터가 있는 테이블이 있으므로 8개의 시스템 호출로 구성된 각 그룹이 이를 차지합니다) 테이블용 64바이트 캐시 라인)
답변2
바라보다그 대답질문 "스택 오버플로에서 amd64 Linux에서 시스템 호출 번호가 다른 이유는 무엇입니까?"
요약하자면, 호환성을 위해 시스템 호출 목록은 안정적이며 증가할 수만 있습니다. x86 64 아키텍처가 나왔을 때 ABI(매개변수 전달, 반환 값)가 달라서 커널 개발자들은 오랫동안 기다려온 변화를 가져올 기회를 잡았습니다.
답변3
간단히 말해서, 일부 사람들은 " 방법보다 N+1
불필요한 비호환성 N
이 더 낫다"고 믿기 때문입니다. 역사적 아키텍처의 경우 시스템 호출 번호는 일부 레거시 독점 UNIX와 일치하도록 선택되는 경우가 많습니다. 그러나 x86_64에서는 커널 개발자가 원하는 번호를 자유롭게 선택할 수 있습니다. 단순한 선택을 하고 기존 번호를 재사용하는 대신 새로운 표준을 고안하기로 결정했습니다. 그런 다음 그들은 aarch64와 다른 몇 가지에 대해 동일한 작업을 수행했습니다. 이는 Linux 커널 개발에서 자주 반복되는 패턴입니다.