Linux Kernel이 아닌, Linux 기능

Linux가 API의 Lingua franca(공용어)가 되어 가면서, Linux가 아닌 POSIX 환경에 대한 여러 노력들은 앞으로도 어려워 계속 것이 아닐까.

물론 대표적인 공영어인 에스페란토처럼 뭔가 중립적인 환경을 정의하고 이것을 사용하자는 아이디어도 있다. CloudABI (https://cloudabi.org/)가 이런 아이디어의 대표적으로 최근 WebAssembly 버전으로 WASI (https://wasi.dev/)가 나온 것을 생각해 보면 좋은 생각이었겠지만 https://github.com/WebAssembly/WASI/issues/294에서 Ed Schouten (CloudABI의 개발자 FreeBSD / LLVM의 기여자이기도하다)가 쓴 것처럼 CloudABI는 큰 관심을 끌지 못했다. .

WSL2 Windows가 Linux 커널을 Windows 구성 요소의 일부로 캡처 버린 것에서도 알 수 있듯이, ** Linux는 OS의 다양성을 구축하고있어 ** 경제적 합리성에서이 흐름을 바꾸기는 어려울 것으로 보인다. 반대로, 앞으로도 시스템 소프트웨어와 소프트웨어 플랫폼 연구를 계속한다면, 실용성으로 본다면 Linux를 의식하지 않을 수 없게 되었다.

커널 / 마이크로 커널 / 라이브러리 OS

어플리케이션이 하드웨어 자원을 이용하기 위해서 OS (operating system)이 제공하는 커널에 각종 system call을 사용한다. UNIX V가 나왔을 때 부터 UNIX 호환 커널의 대표적인 Linux 또한 각종 syscall을 커널에 구현하여 Linux 용 응용 프로그램을 실행하기 때문에 system call 이 같다면 UNIX, Linux 호환 OS와 그 어플리케이션을 만들게된다.

호환성 수준은 ** API 호환 ** (소스 코드를 다시 작성하면 실행할 수)와 ** 바이너리 호환 ** (재 구축 필요없이 그대로 작동)로 구분할 수있다. 이른바 호환 API를 사용한 예로는 Windows의 WSL1 같은 바이너리 호환 전략이라고 할 수 있다.

API 호환

기존 OS에 부록으로 Linux 기능을 구현하는 것이 아니라 Linux 용 응용 프로그램을 동작시키는 것을 목적으로 한 Linux 호환 구현. 일반적인 의미에서의 바이너리 호환성을 실현하고있는 것은 HermiTux만으로 OSv는 중간적인 구현 managarm는 API 호환 구현되고있다.

managarm

managarm는 64bit PC 플랫폼에서 동작하는 마이크로 커널에서 Linux를 의식 syscall의 구현을 제공하고 애플리케이션의 이식성을 배려하고있다.

구현한 것은 syscall은 수십개에 머물러서 완전한 호환과는 거리가 있지만 그래도 Coreutils과 Bash와 같은 응용 프로그램이 이식되어 작동하는 것은 흥미롭다.

이른바 취미 OS의 틀에서 POSIX를 목표로하는 것은 SerenityOS (https://github.com/SerenityOS/serenity) 등 일부 있지만, 명시 적으로 Linux를 목표로하는 것은 드문 것 같다.

HermiTux

소라게가 펭귄을 끼고있는 귀여운 로고가 인상적인 HermiTux는 Linux 바이너리 호환을 목표로 한 Unikernel에서 HermitCore 위에 구축되어있다. 이 HermitCore이 소라게를 캐릭터로하고있다.

같은 Unikernel이다 OSv의 차이로 HermiTux은 바이너리 호환임을 미루어있다. 커널 자체를 일반 사용자 랜드에서 사용되는 하위 측의 주소에 배치하여 응용 프로그램의 메모리 배치를 유지 한 채로 Unikernel 화를 실시하고있다.

논문에서는 전문 커널 컴파일을 언급하고, 따라서 바이너리 분석 도구 syscall-identification도 공개되어있다. 이 도구는 Dyninst (https://www.dyninst.org/)에서 바이너리 실행 영역과 syscall 명령의 위치, RAX 레지스터의 내용을 감지하고 그것을 열거하고있다.

OSv

OSv 부분적으로하라 Linux 바이너리 호환을 목표로 한 Unikernel으로는 초기의 것으로, 실행 파일이 동적 executable임을 전제로 직접 .so를로드하고 실행하는 디자인으로되어있다. 이 디자인을 취하는 것으로, OpenJDK와 같은 큰 이진 작동시키고있다.

OSv의 Linux 호환 상당한 완성도에서 glibc의 syscall 계면 및 if 제어 등을 나름대로 구현하고있다. 그러나 HermiTux 논문에서 언급 된 것처럼 완벽한 바이너리 호환성을 제공하는 것이 아니라 단순히 libc 라이브러리 OS에 대체 할 수있다. 따라서 syscall 테이블은 존재하지 않고, 동적 링커가 직접 .so에서의 API 호출을 OS에 연결된다.

개인적으로 OSv 같은 디자인 (syscall 수준이 아닌 C API 수준의 바이너리 호환) 그 밖에도 나오고 좋다고 생각하는데 아래 같은 응용 프로그램 레벨 구현이 더 가능성이있을 것 일까라는 신경도한다.

Cyanurus

UNIX / Linux 호환 OS를 처음부터 만든 이야기] (https://qiita.com/redcap97/items/20949ad324ca42753e96)에서 소개 된 Cyanurus는 ARM32 용 Linux 호환 커널과 같다.

구현 범위는 매우 제한적인 있지만,이 규모의 구현 Coreutils 움직이는 지와 감동했다.

syscall 에뮬레이션

WSL1의 등장으로 일약 유명해진 커널 레벨에서의 Linux 에뮬레이션은 가장 역사와 전통이있는 Linux 호환 환경의 실현 방법이라고 할 수있다.

FreeBSD

WSL1의 등장 이전에 가장 유명했던 것은 FreeBSD의 Linuxulator이 아닐까 생각하지만, 최신 Linux 커널은 그다지 좋지 추종하지 않은 느낌이있다.

syscall 명령에 의해 처리되는 커널의 서브 루틴을 교체 할에서 Linux 바이너리 호환성을 실현하고있다.

NetBSD

NetBSD에도 Linux 호환 인터페이스가 존재한다. FreeBSD는 독립적 인 구현되고있다.

구현 방법은 FreeBSD와 같이 syscall table의 교환에 의해 구현하고있다.

Solaris / SmartOS

OpenSolaris의 Linux 에뮬레이션 환경이다 Lx는 Joyent (node.js의 개발사로 알려진)가 중심이되어 최근 부활하고있다.

Lx가 독특한 것은 완전한 커널 구현으로 Linux 에뮬레이션을 제공하는 것이 아니라 일부 syscall에 대해서는 사용자 측에 그대로 되돌려 라이브러리 수준에서 에뮬레이션 할 점이라고 할 수있다. inotifyfutex 같은 일부 기능은 해당 기능을 커널 측에 구현하고 그것을 이용하고있다.

Windows (WSL1)

WSL1 (Windows Subsystem for Linux)는 모바일 향 Windows가 한때 Android 호환성을 목표로하고 있던시기의 부산물 결국 MS는 모바일 시장에서 내리는 형태로 포기되는 형태가되었다.

현재는 VM 기반의 일반적인 Linux 커널을 사용하는 WSL2이 권장되고있다. 대해, WSL1는 FreeBSD와 NetBSD의 구현과 같은 전체 Linux syscall 에뮬레이터에서이 커널이 제공하는 syscall table 및 대체 ABI 준수를 PicoProcess라고 부르고있다 추상화 구현하고있다.

응용 프로그램 레벨 구현

OS로 Linux 전체가 아닌 기존의 Linux 응용 프로그램을 단발로 작동시키는 것을 목적으로 한 에뮬레이터 / API 호환 구현이 몇 가지있다.

바이너리 호환

amd64의 Linux 바이너리를 Windows에서 이동하는 것은 너무 자명 한 것이 아니라 단순히 API를 에뮬레이션 할뿐만 아니라 스택의 사용 방법을 맞추는 등 추가 고려 사항이 필요하다 종의 바이너리 변환하거나 WSL1 같은 특수 프로세스의 도입은 불가피하다. 이 점이 Linux에서 Windows 바이너리를 작동 Wine의 차이라고 할 수있다.

Boxedwine

Boxedwine https://t.co/VyW37lx3eT 굉장히 뜨겁다. Wine 전용 Linux 다시 구현 + x86 에뮬레이션에서 @abagames 선생님의 걸작 마사시 군 하이! 이 256 색으로 달린다하고 테네렛차 (벤치)도 달린다. 아직 Emscripten 빌드는 GL이 없지만 이전 만든 https://t.co/yZzYJuaZIc DOOM 전용 WASM 환경에 이식하고 싶은데 . 3DMark! pic.twitter.com/T1jDnqF6rI

— okuoku (@okuoku) May 29, 2020

Boxedwine는 Wine 전용 x86 Linux 에뮬레이터에서 Windows뿐만 아니라 Linux 및 emscripten에 이식되어있다. 특히 emscripten 이식은 최근 상당한 진척을 보지, Web상에서 Windows 게임을 즐길 환경으로 화제가되는 것은 시간 문제 일 것이다.

Wine을 나름대로 사용할 수있는 형태로 동작시키기 위해 오디오와 OpenGL의 직렬화 등도 구현하고있다.

qemu-user

qemu는 유저 랜드 바이너리 에뮬레이션 기능이있어 ARM Linux 바이너리를 x86 Linux에서 동작시키는 것이 가능하게되어있다.

예를 들어, Docker를 사용하여 ARM Linux를 실행시키는 등의 기술로 사용된다. qemu-user는 기본적으로 syscall 프로토콜 변환 기능이므로 Linux 바이너리를 Linux에서 동작시키는 방향으로 밖에 사용할 수 없다. (비교하여 여기에서 언급하는 Usercorn을 제외한 다른 프로젝트는 모든 Linux 응용 프로그램을 Windows에서 작동시키는 것을 목표로하고있다)

Foreign Linux

Foreign Linux는 (CPU 에뮬레이션을 수반하지 않는) 동적 바이너리 변환 Linux 바이너리를 Windows에서 실행시키는 것을 목표 안타깝게도 WSL1의 등장 이후 개발이 멈춰 버린 것 같다.

Usercorn

Usercorn은 qemu을 기반으로 한 CPU 에뮬레이터 프레임 워크이다 Unicorn (https://www.unicorn-engine.org/) 위에 구축 된 커널 에뮬레이터 라이브러리에서 Linux 이외 Darwin이나 MS-DOS (!)까지 구현하고있다.

qemu-user와 같이 전체 CPU 에뮬레이션을 수행하지만, qemu와 달리 Go에서 Linux API를 재 구현하고 있기 때문에, Linux 이외에도 Linux 바이너리를 동작시키는 것이 가능하게되어있다.

구현 범위는 매우 제한적으로 보인다.

Atratus

상세 불명.

LBW

Interix는 Windows에서 POSIX 레이어로 사용하고 있었다. 그런 이유로 더 이상 작동하지 않는다.

환송

Linux는 Docker 나름대로 무엇 나름의 형태로 ABI의 자산 가치가 높아지고 버리고 있기 때문에, ABI가 향후 크게 변화하는 것은 생각하기 어렵다. 따라서 Linux 어떤 안정기를 맞이하고 있다고 생각할 수, Linux를 구현하고자하는 방향에 기회 인 것은 아닐까 생각한다.

무엇보다 앞으로 자신이 공통적 인 I / F를 구현하게된다면 WASI을 선택 일까. . Linux 응용 프로그램을 제대로 움직이기 위해서는/ proc 라든지ioctl 것 같은 것입니다 구현해야, 비교적 귀찮은 것이 아닐까.

Linux 자체를 응용하는 시도로는 [이전 USB / IP를 위해 사용해 본] (https://qiita.com/okuoku/items/c8ca95983c6873d0f872) LKL (https://github.com/lkl/linux) 이 있는데, 여기에는 syscall shim도 기존의 바이너리를 실행하기위한 고려 사항도있다. 그래서 LKL를 Linux 호환 레이어 기반하는 것은 좋은지도 모른다.

이제 와서 커널이나 구현하고 어쩔 것이라는 것은 있을지도 모르지만, 프로세스 체크 포인트와 마이그레이션 다시 최적화 같은 "Linux를 개조하는 것보다 Linux 계열 OS를 만든 것이 빠를"영역 이 있을지도 모른다. Linux 계열 환경의 지식을 연구하여 real world 응용 프로그램과 연구의 거리를 줄일 수있는 것이 아닐까.