1P by GN⁺ | ★ favorite | 댓글 1개
  • 과거 높은 오버헤드로 실용성이 떨어졌던 마이크로커널은 오늘날 보편화된 IOMMU와 공유 메모리 덕분에 다시 현실적인 선택지가 될 수 있음
  • 드라이버와 서브시스템을 사용자 공간에 격리하면 결함이나 공격의 영향 범위를 제한해 보안·신뢰성·모듈성을 높일 수 있음
  • 1980~90년대에는 사용자 공간 프로세스가 장치에 직접 접근할 수 없어 디스크 읽기 같은 작업마다 시스템 호출과 문맥 전환, 잠금, 메모리 복사가 뒤따랐음
  • IOMMU와 공유 명령 큐를 활용하면 정상 경로에서 문맥 전환과 주소 공간 간 복사, 잠금 없이 비동기 IPC와 장치 접근을 처리할 수 있음
  • Xen, FreeBSD, Linux DRM 같은 기존 구성 요소를 활용할 수 있어 하이퍼바이저와 시스템 서버를 처음부터 새로 만드는 부담도 크지 않음

마이크로커널의 구조와 격리 효과

  • 마이크로커널은 스케줄링, I/O 장치 접근 관리, 프로세스 간 통신(IPC)을 제외한 기능을 사용자 공간에서 실행하는 커널 구조임
  • 서브시스템 격리는 세 가지 이점을 제공함
    • 보안: 드라이버 하나의 취약점이 공격자에게 전체 시스템이 아닌 해당 서브시스템이나 드라이버의 접근 권한만 줄 수 있음
    • 신뢰성: 한 서브시스템의 충돌이 시스템 전체가 아니라 해당 부분에만 영향을 미침
    • 모듈성: Linux 커널 팀이 모든 하드웨어 드라이버를 병합하고 각 칩의 내부 동작까지 검토해야 하는 부담을 덜 수 있음
  • Windows가 마이크로커널 시스템이었다면 CrowdStrike 버그는 일부 IT 보안 담당자의 원격 측정 데이터 수집만 중단시키는 데 그쳤을 수 있음

과거의 성능 한계와 IOMMU의 해법

  • 과거 마이크로커널에서는 사용자 공간 프로세스가 특정 장치에 직접 접근할 수 없어 작업마다 시스템 호출과 문맥 전환이 필요했고, 비싼 잠금과 메모리 복사까지 뒤따랐음
    • Mach는 성능 문제 때문에 사용자 공간 프로세스를 점차 커널 안으로 옮겼고, 결국 일반적인 모놀리식 커널에 가까워짐
  • 오늘날 PC에는 약 10년간 IOMMU가 표준적으로 탑재됐으며, 공유 메모리와 함께 사용하면 코어가 충분한 정상 경로에서 문맥 전환을 완전히 제거할 수 있음
    • 약간의 지연 시간을 받아들이면 전체적으로도 문맥 전환을 거의 없앨 수 있음
    • 가상화 기술 기반 스케줄러는 Xen 하이퍼바이저와 유사한 형태로 구성할 수 있음
    • I/O 장치 접근은 IOMMU 하드웨어가 관리함
  • IPC는 프로세스 사이에 공유 버퍼를 할당하고 정수 원자적 compare-and-swap을 제공하는 방식으로 구현할 수 있음
    • 공유 버퍼를 링 버퍼 형태의 명령 큐로 사용하고 시작·끝 포인터를 원자적으로 갱신함
    • 정상 경로에서는 문맥 전환, 주소 공간 간 복사, 잠금 없이 비동기 메시지를 전달할 수 있으며, GPU 드라이버에서도 널리 쓰이는 방식임

라이브러리 구성과 기존 코드 활용

  • 프로세스가 VM 게스트인 환경에서는 공유 라이브러리를 프로그램 시작 시 링크하고, 다른 프로세스에서 실행할 필요가 없는 기능은 exokernel 방식으로 로컬에서 처리할 수 있음
    • Electron 형태로 애플리케이션마다 자체 운영체제 구성 요소를 함께 배포하는 오늘날에는 메모리의 중복 라이브러리가 30년 전만큼 큰 문제가 아님
  • 구현에 필요한 주요 기반도 이미 존재함
    • Xen은 하이퍼바이저 계층에 필요한 기능 대부분을 갖추고 있음
    • Mach처럼 네트워크와 파일시스템 서버를 구성하되 FreeBSD 코드를 가져와 사용할 수 있음
    • DRM은 이미 비동기 명령 버퍼를 기반으로 하므로 Linux 그래픽 서브시스템을 사용자 공간에서 실행할 수 있음
    • 편의상 디스플레이 서버와 그래픽 서브시스템을 같은 프로세스에서 실행하는 구성도 가능함

댓글과 토론

Lobste.rs 의견들
  • Linux가 모든 드라이버를 포함하는 이유는 트리 외부 커널 모듈용 안정적 API가 없기 때문이며, 이런 API를 제공하는 데 마이크로커널이 필수인 것은 아님

    • 마이크로커널도 내부 API의 불안정성을 막아주지는 않으며, 단지 프로세스 간 경계를 넘게 될 뿐임
      모든 Linux 드라이버를 사용자 공간으로 옮긴다는 가정에서도 내부 API 변경이 어려워진다는 LKML의 불만을 본 기억이 있음
  • L4 계열 커널은 빠르다고 알려져 있지 않나 싶음. Redox OS나 Fuchsia는 어떤지도 궁금함

    • L4 커널은 빠를 수 있지만, 실제로는 구성이 매우 고정적인 임베디드 시스템에서나 쓸 만함
      Genode는 여러 커널을 지원하지만 seL4 등에서는 우스울 정도로 성능이 나쁨. 동료들이 Linux VM을 부팅해 봤을 때 32비트만 지원됐고, 절반쯤 부팅하는 데도 수분이 걸렸음
      NOVA microhypervisorGenode 포크가 기본 플랫폼인 데는 실제로 동작하고 성능도 충분하다는 이유가 있음
    • Redox 문서를 보면 요청 메시지를 조립할 때 여전히 문맥 교환을 수행하며, 아마 검증 단계로 보임
      순환 버퍼를 사용하므로 수신자가 다른 코어에서 이미 실행 중이라면 두 번째 문맥 교환은 필요 없을 수도 있음. 문맥 교환 없이 메시지를 해석하면 수신자가 메시지를 검증해야 해서 공격 표면이 지나치게 커질 수 있지만, 커널 제공 동적 라이브러리로 완화할 여지는 있어 보임
      전문가는 아니지만 원문이 몇 가지 중요한 고려 사항을 빠뜨린 느낌
  • QNX는 빠른 마이크로커널로 알려졌는데, 무엇을 제대로 한 것인지 궁금함

    • 직접 써본 QNX는 빠르지 않았음
      예전에 친구와 마이크로커널, 특히 QNX의 우아함에 매료돼 FireWire 기반 영상 처리 문제를 구현했음. 코드는 단순하고 멋졌지만 처참하게 느렸음. 당시 Linux용 1394 드라이버에 DMA 기반 등시성 전송 지원을 약 12시간 만에 추가하자 성능이 크게 개선됐고, 이 일을 계기로 회사의 광학 선별 장비에 Linux를 쓰는 데 대한 회의론도 사라졌음
      QNX와 마이크로커널, 메시지 전달의 이상은 여전히 훌륭하지만 널리 자리 잡으려면 프로세스 간 데이터 전달 비용을 훨씬 낮춰야 함
      지금은 Elixir로 웹 애플리케이션을 만들며 QNX가 내세운 것과 같은 프로세스 격리를 누리고 있음. 광학 처리처럼 성능이 중요한 작업이 아니어서 괜찮지만, Elixir/BEAM도 데이터 복사 문제는 동일함
  • Mach가 원래 구상만큼 구성 요소를 완전히 독립시키지는 못했더라도 평범한 모놀리식 커널이 된 것은 아니며, 그 아키텍처가 여전히 주는 이점이 있다고 들었음
    고전적인 POSIX 파일 목록 벤치마크처럼 모든 항목에 readdir()stat()을 호출하면 마이크로커널이 불리할 수밖에 없음. 하지만 io_uring 같은 일괄 처리 API를 사용해 시스템 호출 빈도를 낮추면 높은 지연 시간이 큰 약점이 아닐 수도 있음

    • Liedtke의 “on μ-Kernel Construction”, 1995는 Mach가 느린 원인을 큰 캐시 사용량, 즉 충분히 작지 않았던 설계에서 찾았음
      Linux도 네트워크 패킷마다 시스템 호출을 한 번씩 하면 회선 속도를 따라갈 수 없음. 일괄 처리는 Linux와 마이크로커널 모두에서 중요함
  • 이 분야의 흥미로운 최신 진입자로 HongMeng이 있지만, 아쉽게도 독점 소프트웨어

  • 데이터 이동 비용이 한 자릿수 이상 크게 줄지 않는 한 마이크로커널이 충분한 경쟁력을 갖추기는 어려워 보임
    이론적으로는 우아하고 깔끔하지만 현실은 복잡하므로, 그 복잡성을 다루려면 커널도 어느 정도 복잡해야 할지 모름

  • 올바른 아키텍처를 좋아하지만 Linux가 지배적인 위치에 오른 데는 순수한 기술 외의 부차적 요인도 컸다고 봄. 이를 여러 차원에서 분석한 글을 읽고 싶음