LCTT 번역: 어제 AlmaLinux는 RHEL과의 1:1 호환성을 포기하지만 RHEL에서 실행되는 소프트웨어가 AlmaLinux에서 원활하게 실행될 수 있도록 RHEL과의 ABI 호환성을 유지할 것이라고 말했습니다. 일부 학생들은 ABI의 개념을 잘 이해하지 못할 수도 있으므로 모든 사람이 이해할 수 있도록 이 글을 번역했습니다.
많은 Linux 애호가들은 Linus Torvalds의 유명한 훈계: "우리는 사용자 공간을 파괴하지 않습니다"에 익숙하지만, 그 의미는 듣는 모든 사람에게 명확하지 않을 수 있습니다.
이 "첫 번째 규칙"은 개발자에게 애플리케이션과 커널 간의 통신 및 구성에 사용되는 ABI(Application Binary Interface)의 안정성을 상기시킵니다. 다음 내용은 독자에게 ABI 개념을 익히고, ABI 안정성이 중요한 이유를 설명하고, Linux 안정 ABI에 무엇이 포함되어 있는지 논의하기 위한 것입니다. Linux의 지속적인 성장과 발전으로 인해 ABI에 대한 변경이 필요했으며 그 중 일부는 논란의 여지가 있었습니다.
ABI는 애플리케이션 바이너리 인터페이스를 의미합니다. ABI의 개념을 이해하는 한 가지 방법은 ABI가 다른 개념과 어떻게 다른지 고려하는 것입니다. 많은 개발자에게는 API(애플리케이션 프로그래밍 인터페이스)가 더 친숙합니다. 일반적으로 라이브러리의 헤더 파일과 문서는 HTML5과 같은 표준 문서와 함께 API로 간주됩니다. 라이브러리를 호출하거나 문자열 형식으로 데이터를 교환하는 프로그램은 API에 설명된 규칙을 준수해야 합니다. 그렇지 않으면 예기치 않은 결과가 발생할 수 있습니다.
ABI는 명령이 해석되고 바이너리 데이터가 교환되는 방식을 지정한다는 점에서 API와 유사합니다. C 프로그램의 경우 ABI에는 일반적으로 함수의 반환 유형 및 인수 목록, 구조의 레이아웃, 열거된 유형의 의미, 순서 및 범위가 포함됩니다. 2022년 현재 Linux 커널은 여전히 거의 전적으로 C 프로그램이므로 이러한 사양을 준수해야 합니다.
"커널 시스템 호출 인터페이스"에 대한 설명은 "Linux 매뉴얼 섹션 2"에서 찾을 수 있으며 미들웨어 응용 프로그램에서 호출할 수 있는 "mount
和 sync
的 C 版本函数。这些函数的二进制布局是 Linux ABI 的第一个重要组成部分。对于问题 “Linux 的稳定 ABI 包括哪些内容?”,许多用户和开发人员的回答是 “sysfs(/sys
)和 procfs(/proc
)과 같은 내용이 포함되어 있습니다. 실제로 공식 The Linux ABI 문서 는 주로 이러한 가상 파일 시스템에 중점을 둡니다.
이전 섹션에서는 Linux ABI가 프로그램에서 사용되는 방법에 중점을 두지만 ABI의 기능 요구 사항인 C와 같은 중요한 인적 요소는 다루지 않습니다. 컴파일러(예: GCC 또는 clang), 사용자 공간 C 라이브러리(일반적으로 glibc)를 생성하는 개발자, ELF(Executable and Linking Format)에 배치된 바이너리 애플리케이션
개발 내의 공동 노력 커뮤니티
.Torvalds가 직접 제공하는 Linux ABI의 안정성 보장으로 Linux 배포판과 개별 사용자는 운영 체제의 영향을 받지 않고 독립적으로 커널을 업데이트할 수 있습니다.
Linux에 안정적인 ABI가 없으면 보안 문제를 해결하기 위해 커널을 패치해야 할 때마다 운영 체제 대부분 또는 전체를 다시 설치해야 합니다. 분명히 바이너리 인터페이스의 안정성은 Linux의 유용성과 광범위한 채택에 있어 중요한 요소 중 하나입니다.
터미널 출력
위 그림과 같이 커널(in linux-libc-dev
) 및 Glibc( libc6-dev
) 비트 마스크. 분명히, 이 두 가지 정의 세트는 반드시 일치해야 합니다! apt
패키지 관리자는 패키지에서 제공하는 각 파일을 식별합니다. Glibc ABI의 잠재적으로 불안정한 부분은 bits/
디렉터리. linux-libc-dev
中)和 Glibc(在 libc6-dev
中)都提供了定义文件权限的位掩码。显然,这两个定义集必须一致!apt
软件包管理器会识别软件包提供每个文件。Glibc ABI 的潜在不稳定部分位于 bits/
目录中。
在大部分情况下,Linux ABI 的稳定性保证运作良好。按照 康韦定律Conway's Law,在开发过程中出现的烦人技术问题往往是由于不同软件开发社区之间的误解或分歧所致,而这些社区都为 Linux 做出了贡献。不同社区之间的接口可以通过 Linux 包管理器的元数据轻松地进行想象,如上图所示。
通过考虑当前正在进行的、缓慢发生 的 “Y2038” ABI 破坏的例子,可以更好地理解 Linux ABI。在 2038 年 1 月,32 位时间计数器将回滚到全零,就像较旧车辆的里程表一样。2038 年 1 月听起来还很遥远,但可以肯定的是,如今销售的许多物联网设备仍将处于运行状态。像今年安装的 智能电表 和 智能停车系统 这样的普通产品可能采用的是 32 位处理器架构,而且也可能不支持软件更新。
Linux 内核已经在内部转向使用 64 位的 time_t
不透明数据类型来表示更晚的时间点。这意味着像 time()
这样的系统调用在 64 位系统上已经变更了它们的函数签名。这些努力的艰难程度可以在内核头文件中(例如 time_types.h)清楚地看到,在那里放着新的和 _old
Y2038: Linux ABI를 더 잘 이해하기 위해 현재 진행되고 느리게 발생하는 "Y2038" ABI 중단 사례를 고려하여 ABI 중단
의 예입니다. 2038년 1월에는 32비트 시간 카운터가 구형 차량의 주행 거리계와 마찬가지로 모두 0으로 롤백됩니다. 2038년 1월은 아직 멀게 들릴지 모르지만 현재 판매되는 많은 IoT 장치가 여전히 작동할 것이라는 확신이 듭니다. 스마트 미터와 스마트 주차 시스템 이러한 일반 제품은 32비트 프로세서 아키텍처를 사용할 수 있으며 소프트웨어 업데이트를 지원하지 않을 수 있습니다. Linux 커널은 이후 시점을 나타내기 위해 내부적으로 64비트 -indent: 0px; display: inline-block;">time_t 불투명 데이터 유형을 사용하도록 전환했습니다. 이는 time()
과 같은 시스템 호출의 함수 서명이 64비트 시스템에서 변경되었습니다. 이러한 노력의 규모는 time_types.h와 같은 커널 헤더 파일에서 명확하게 볼 수 있습니다. 코드 스타일="배경 색상: rgb(231, 243, 237); 패딩: 1px 3px; 테두리 반경: 4px; 오버플로 랩: break-word; 텍스트 들여쓰기: 0px; 디스플레이: 인라인 블록;"> _이전 버전의 데이터 구조입니다.
안정적인 ABI를 이해하는 것은 약간 까다롭습니다. 고려해야 할 점은 대부분의 sysfs가 안정적인 ABI인 반면 디버그 인터페이스는 커널 내부를 사용자 공간에 노출시키기 때문에 확실히 불안정하다는 것입니다. Linus Torvalds는 한때 "사용자 공간을 손상시키지 마십시오"라고 말했는데, 이는 일반적으로 커널 문서와 소스 코드를 읽어 볼 수 있어야 하는 시스템 프로그래머와 커널 엔지니어보다는 "그냥 작동하기를 원하는" 일반 사용자를 보호하는 것을 의미했습니다. 버전 간에 변경된 사항. 아래 이미지는 이러한 차이점을 보여줍니다.
안정성 보장
일반 사용자가 Linux ABI의 불안정한 부분과 상호 작용할 가능성은 거의 없지만 시스템 프로그래머는 의도치 않게 그렇게 할 수 있습니다. 제외 /sys/kernel/debug
제외, sysfs(/sys
) 및 procfs(/proc
)는 안정적입니다. /sys/kernel/debug
以外,sysfs(/sys
)和 procfs(/proc
)的所有部分都是稳定的。
那么其他对用户空间可见的二进制接口如何呢,包括 /dev
中的设备文件、内核日志文件(可通过 dmesg
/dev에 있는 장치 파일 및 커널 로그 파일
( dmesg
명령), 파일 시스템 메타데이터 커널의 "명령줄"에 제공된 "부팅 매개변수"(GRUB 또는 u-boot와 같은 부트 로더에서 볼 수 있음)? 물론, "상황에 따라 다릅니다." 오래된 파일 시스템 마운트Linux 시스템이 부팅 중에 중단된다는 사실 외에도 파일 시스템을 마운트할 수 없다는 점이 가장 실망스럽습니다. 파일 시스템이 유료 고객의 SSD에 있다면 문제는 정말 심각합니다. 이전 커널 버전에서 마운트할 수 있었던 Linux 파일 시스템은 커널을 업그레이드해도 여전히 마운트할 수 있어야 합니다. 그렇죠? 사실, “상황에 따라 다릅니다.” 2020년에 불만을 품은 한 Linux 개발자가 커널 메일링 리스트에 불평
을 올렸습니다.커널은 이를 버그나 어떤 종류의 문제도 없이 유효한 마운트 가능한 파일 시스템 형식으로 수락했으며, 오랫동안 이와 같이 안정적으로 작동해 왔습니다. 년... 나는 일반적으로 기존 루트 파일 시스템을 마운트하는 것이 커널사용자 공간 또는 커널 기존 시스템 경계의 범위 내에 속한다고 가정했습니다. 커널 업그레이드는 기존 사용자 공간 및 시스템과 호환되어야 합니다. , 커널에서 허용되고 기존 사용자 공간에서 성공적으로 사용되는 항목에 따라 정의됩니다.
하지만 문제가 있습니다. 이러한 마운트할 수 없는 파일 시스템은 커널에서 정의했지만 커널에서 사용하지 않는 플래그에 의존하는 독점 도구를 사용하여 생성됩니다. 이 플래그는 Linux의 API 헤더나 procfs/sysfs에 표시되지 않지만 구현 세부정보입니다. 따라서 사용자 공간 코드에서 이 플래그를 해석한다는 것은 거의 모든 소프트웨어 개발자를 떨게 만드는 문구인 "정의되지 않은 동작"에 의존한다는 것을 의미합니다. 커널 커뮤니티가 내부 테스트를 개선하고 새로운 일관성 검사 작업을 시작했을 때 "man 2 mount
" 시스템 호출이 갑자기 독점 형식의 파일 시스템을 거부하기 시작했습니다. 형식 작성자는 분명히 소프트웨어 개발자였기 때문에 커널 파일 시스템 관리자로부터 동정을 얻지 못했습니다.공사 표지판에는 직원들이 나무 작업을 하고 있다고 적혀 있습니다
🎜/dev
디렉터리의 파일 형식은 안정적인지, 불안정한지 보장됩니까? dmesg 명령 /dev
目录中的文件格式是否保证稳定或不稳定?dmesg 命令 会从文件 /dev/kmsg
中读取内容。2018 年,一位开发人员 为 dmesg 输出实现了线程化,使内核能够“在打印一系列 printk()
消息到控制台时,不会被中断和/或被其他线程的并发 printk()
干扰”。听起来很棒!通过在 /dev/kmsg
输出的每一行添加线程 ID,实现了线程化。密切关注的读者将意识到这个改动改变了 /dev/kmsg
的 ABI,这意味着解析该文件的应用程序也需要进行相应的修改。由于许多发行版没有编译启用新功能的内核,大多数使用 /bin/dmesg
的用户可能没有注意到这件事,但这个改动破坏了 GDB 调试器 读取内核日志的能力。
确实,敏锐的读者会认为 GDB 的用户运气不佳,因为调试器是开发人员工具。实际上并非如此,因为需要更新以支持新的 /dev/kmsg
은 파일 /dev/kmsg 2018년에 개발자는 dmesg 출력을 위한 스레딩 <a target="_blank" href="https://www.php.cn/link/50d2e70cdf7dd05be85e1b8df3f8ced4">을 구현하여 커널이 " printk()</a>
메시지가 콘솔로 전송되면 다른 스레드에 의해 중단되거나 동의되지 않습니다. 코드 스타일="배경 색상: rgb(231, 243, 237); 패딩: 1px 3px; 테두리 반경: 4px; 오버플로 랩: break-word; 텍스트 들여쓰기: 0px; 디스플레이: 인라인 블록;"> printk() 간섭". 좋은 것 같아요! /dev/kmsg
스레딩을 달성하기 위해 각 출력 줄에 스레드 ID를 추가합니다. 세심한 주의를 기울이는 독자라면 이 변경 사항이 /dev/kmsg
의 ABI는 파일을 구문 분석하는 애플리케이션도 그에 따라 수정해야 함을 의미합니다. 많은 배포판은 새로운 기능이 활성화된 커널을 컴파일하지 않기 때문에 대부분은 /bin/dmesg
사용자는 이를 눈치채지 못할 수도 있지만 이 변경 사항으로 인해 GDB 디버거 커널 로그를 읽는 기능.
/dev/kmsg
형식의 코드는 커널 자체 Git 소스 코드 저장소의 "트리 내" 부분에 있습니다. 일반 프로젝트의 경우 단일 코드 기반 내의 프로그램이 함께 작동하지 않는 것은 명백한 실수이므로 GDB가 스레드 /dev/kmsg패치가 병합되었습니다. BPF 프로그램은 어떻습니까? BPF는 실행 중인 커널에서 모니터링하고 실시간으로 구성할 수도 있는 강력한 도구입니다. BPF는 원래 시스템 관리자가 명령줄에서 즉시 패킷 필터를 수정할 수 있도록 하여 실시간 네트워크 구성을 지원하도록 설계되었습니다. Alexei Starovoitov와 다른 사람들은 임의의 커널 기능을 추적할 수 있도록 BPF를 크게 확장했습니다. 추적은 확실히 일반 사용자가 아닌 개발자의 영역이므로 ABI가 보장되지 않습니다(비록
bpf() 시스템 호출은 다른 시스템 호출과 동일한 안정성 보장을 제공하지만). 반면에 새로운 기능을 갖춘 BPF 프로그램을 만들면 "커널 확장의 사실상 표준 수단으로 커널 모듈을 교체"할 가능성이 열립니다. 커널 모듈은 장치, 파일 시스템, 암호화, 네트워킹 등이 제대로 작동하도록 하므로 "그냥 작동하기를 원하는" 일반 사용자가 의존하는 시설이기도 합니다. 문제는 대부분의 오픈 소스 커널 모듈과 달리 BPF 프로그램이 전통적으로 커널 소스 코드에 없다는 것입니다.
2022년 봄, 장치 드라이버 패치 대신 미니 BPF 프로그램을 사용하여 광범위한 휴먼 인터페이스 장치(예: 마우스 및 키보드)에 대한 지원을 제공하겠다는 제안이 주목을 받았습니다.
🎜열린 토론이 이어졌지만 Open Source Summit에서 🎜Torvalds의 의견 🎜을 통해 문제가 분명히 해결되었습니다. 🎜그는 "일반(비커널 개발자) 사용자가 사용하는 실제 사용자 공간 도구"를 깨뜨리면 eBPF 사용 여부에 관계없이 이를 수정해야 한다고 지적합니다.
커널 업데이트 후에도 BPF 프로그램이 계속 작동하기를 원하는 개발자는 커널 소스 코드 저장소의 아직 지정되지 않은 위치에 커밋해야 한다는 합의가 나타나고 있는 것 같습니다. 커널 커뮤니티가 BPF 및 ABI 안정성과 관련하여 어떤 정책을 채택하는지 계속 지켜봐 주시기 바랍니다.
커널의 ABI 안정성 보장은 procfs, sysfs 및 시스템 호출 인터페이스에 적용되지만 중요한 예외가 있습니다. 커널 변경으로 인해 "트리 내" 코드나 사용자 공간 응용 프로그램이 중단되면 문제가 되는 패치가 빠르게 롤백되는 경우가 많습니다. 커널 구현 세부 사항에 의존하는 독점 코드의 경우 이러한 세부 사항은 사용자 공간에서 액세스할 수 있지만 문제가 발생하면 보호되지 않으며 제한적인 동정을 받습니다. Y2038과 같은 문제가 ABI 위반을 피할 수 없는 경우 가능한 가장 신중하고 체계적인 방식으로 전환이 이루어집니다. 그리고 BPF 프로그램과 같은 새로운 기능은 ABI 안정성의 경계에 대해 답이 없는 질문을 제기합니다.
이전 버전의 자료에 유용한 의견을 주신 Akkana Peck, Sarah R. Newman 및 Luke S. Crawford에게 감사드립니다.
위 내용은 10분 만에 Linux ABI에 대해 알아보세요의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!