Nooks: an architecture for reliable device drivers


M. M. Swift, B. N. Bershad, and H. M. Levy, “Improving the Reliability of Commodity Operating Systems,” p. 16.
M. M. Swift, S. Martin, H. M. Levy, and S. J. Eggers, “Nooks: an architecture for reliable device drivers,” in Proceedings of the 10th workshop on ACM SIGOPS European workshop: beyond the PC - EW10, Saint-Emilion, France, 2002, p. 102. doi: 10.1145/1133373.1133393.


개요

디바이스 드라이버를 잘 사용하기 위해서 기존의 방식들을 같이 사용하여 Protection domain과 Light-weight runtime을 만들어서 Isolation을 구현하였다. Fault resistance를 위해서 구현되었다. 즉 Fault tolerance에서는 사용할 수 없다. 즉 kernel data를 오염시키지 않는 잘못 작동하는 디바이스 드라이버가 대상이다.

Problems and importance

디바이스 드라이버는 커널 프로그래밍보다 훨씬 많은 버그가 발생한다. 따라서 커널의 안전을 도모하기 위해서는 디바이스 드라이버를 안전하게 작동시킬 수 있는 방식이 필요하다. 즉 커널은 1. 잘못된 디바이스 드라이버의 오류를 이겨내고 2. 복구하는 두가지의 방식이 필요하다. 이를 통해서 커널을 보다 안전하게 작성할 수 있다.

Main Idea and contribution

기존의 방식은 크게 5가지로 나누어 볼수 있다.

kernel Wrapping
커널 워래핑에서는, 디바이스 드라이버가 사용하는 모든 호출을 감싸서, 디바이스 드라이버가 사용하는 자원을 추적하고 예상되는 Fault를 예방한다. 그러나 이방식으로는 메모리 오류를 막을 수 없다.
Virtual Memory
가상 메모리를 사용하면 메모리 오류를 막을 수 있다. 하지만 이방식은 Logical error을 막을 수 없다 (무한 루프와 같은 오류를 말한다).
Privilege level
사용할 수 있는 Instruction을 Ring을 바꿈으로써 제한할 수도 있다. 그러나 이러한 방식은 Context change에 큰 비용이 들어서 매우 큰 overhead를 발생시킨다.
Software Fault Isolation (SFI)
코드에다가 Dynamic하게 Safety를 체크하는 명령어를 집어넣는 SFI방식은 어느정도 빠르고 안전한 실행을 보장시킬 수 있지만, Raw isntruction보다 느리다는 단점과, Recovery를 위한 방식이 아니라는 단점이 있다.
Safe Language
Safe language를 사용하면 대부분의 Fault를 예방할 수 있지만, High performance를 위한 작업에는 적합하지 않다는 단점이 있다. (그러나 Rust를 사용한다면????) 또한 Recovery를 언어단에서 지원하지 않는 이상 Recovery를 지원하지 않는 단점이 있다.

이 논문에서는 Nook이라는 디자인을 이용해서 Kernel그리고 디바이스 드라이버를 크게 수정하지 않아도, Recovery, High Performance Isolation이 가능하게 만든 Architecture를 제공하였다는 점에서 의의가 있다.

Design

Design Goals: Isolation, Recovery, and Backwards Compatibility

Nook에서는 Device driver를 Fault-isolating 그리고 Recoverable environment에서 실행시킨다. 또한 커널은 디바이스 드라이버를 Nook에서 실행시키거나 아니면 없이 실행시킬 수도 있으며, 여러개의 디바이스 드라이버를 한번에 하나의 Nook runtime에서 실행시킬 수도 있다.

  1. Nook runtime은 하드웨어에서 발생한 인터럽트를 디바이스 드라이버로 전달하며, 하드웨어를 Emulating하여서 검증을 받도록 하였다.
  2. 또한 커널과 디바이스 드라이버 사이의 Call또한 Wrap하여서, 하드웨어 리소스가 추적되도록 하였다.
  3. 모든 디바이스 드라이버들은 하나의 커널 Address space에 있지만, 서로 다른 Protection domain에 있도록 하였다. 따라서 Copy없이도 주어진 Protection domain하에서 안전하게 커널에다가 정보를 작성할 수 있도록 하였다. 이를 위해서, VM, SFI, Priviledge level과 같은 여러 기법들을 통해서 구현할 수 있었다.
  4. 커널의 리소스들을 반드시 공유하여야 하는 자원과 가끔 공유하는 자원으로 구분하였다. 자주 혹은 반드시 공유되는 자원은 Kernel의 intervention이 있도록 하여서 보호받도록 하였다. (약간... 모든 kernel resource를 wrap할수는 없으니 적어둔듯...)

즉 이런식으로 Protection domain, Wrapper등을 통해서 드라이버의 리소스를 분리하면, Kernel state가 분리되기 때문에 안전하게 디바이스 드라이버를 Clean up하고 Recover할 수 있게 된다.

Implementation

리눅스 커널 2.4.0에 구현하였다. 디바이스 드라이버가 이용할 수 있는 Kernel wrapper를 147개 만들었다. insmod가 Kernel wrapper을 link하도록 수정하였다. Nook wrapper는 driver에서 커널사이의 모든 Parameters들을 점검하여, 포인터가 Protection domain에 있는지 검사하고 리소스를 추적함으로써 Synchronization문제들을 회피하였다.

Criticizing

  • Nook은 커널 모듈과 같은 User extensio을 Kernel에서 어떻게 효과적으로 Protection할것이에 대하여 연구한 시발점이 되는 논문으로, Hardware protection과 IDL과 같은 방식으로 사용하여 Protection domain이라는 개념을 제시함.
  • 약간, 이해가 안되서 그런지 기존 있었던 방법들을 혼합한 방법이라는 생각도 듬.

참고

  1. https://courses.cs.vt.edu/~cs5204/fall11-butt/lectures/nooks.pdf