- 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에서 실행시킬 수도 있다.
- Nook runtime은 하드웨어에서 발생한 인터럽트를 디바이스 드라이버로 전달하며, 하드웨어를 Emulating하여서 검증을 받도록 하였다.
- 또한 커널과 디바이스 드라이버 사이의 Call또한 Wrap하여서, 하드웨어 리소스가 추적되도록 하였다.
- 모든 디바이스 드라이버들은 하나의 커널 Address space에 있지만, 서로 다른 Protection domain에 있도록 하였다. 따라서 Copy없이도 주어진 Protection domain하에서 안전하게 커널에다가 정보를 작성할 수 있도록 하였다. 이를 위해서, VM, SFI, Priviledge level과 같은 여러 기법들을 통해서 구현할 수 있었다.
- 커널의 리소스들을 반드시 공유하여야 하는 자원과 가끔 공유하는 자원으로 구분하였다. 자주 혹은 반드시 공유되는 자원은 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문제들을 회피하였다.