TL;DR

  • smolBSD로 NetBSD 마이크로VM을 구성하면 Ubuntu 호스트에서 C 개발 도구 모음과 Emacs를 갖춘 개발 환경을 실행할 수 있음.
  • NetBSD는 서버부터 임베디드·빈티지 기기와 일부 게임 콘솔까지 폭넓은 하드웨어를 지원하며, 이식성을 중시하는 선택지이자 4.3BSD의 향수를 담은 운영체제임.
  • SMOLerfile에서 base, etc, comp를 바탕으로 개발 셸, 패키지, Emacs 설정을 지정하고 512MB 추가 공간을 확보한 마이크로VM 이미지를 구성함.
  • QEMU가 Ctrl-A를 이스케이프 키로 가로채는 문제를 피해 Emacs에 M-a와 M-e 키 바인딩을 추가함.
  • Dell Latitude 7400에서 NetBSD 커널 부팅은 26ms, VM의 초기 호스트 메모리 사용량은 180MB임.

요구 사항

  • C 네트워킹 라이브러리와 C 빌드 도구 모음의 전체 빌드를 NetBSD에서 시험할 필요가 있음. Ubuntu와 macOS에서는 정상 작동하므로 NetBSD에서도 작동하는지 확인하려는 목적임.
  • NetBSD는 뛰어난 이식성으로 유명한 오픈소스 유닉스 계열 운영체제임. 최신 x86-64·aarch64 서버와 데스크톱부터 임베디드 시스템, 휴대 기기, VAX·m68k 같은 구형 기기, 일부 게임 콘솔까지 폭넓은 하드웨어에서 실행됨.
  • NetBSD의 오래된 표어는 “물론 NetBSD가 실행됨”이며, 최대한의 이식성을 원하는 경우에 어울리는 선택임. 4.3BSD의 전통을 이어받아 향수를 더하는 측면도 있음.
  • 홈 데이터 센터에는 전용 NetBSD 기기가 없어 가상 머신을 선택함. 구체적으로는 부팅 후 몇 밀리초 만에 서비스를 시작하는 최소 NetBSD 기반 BSD 유닉스 가상 머신인 smolBSD 마이크로VM을 사용함.
  • 필요한 항목은 NetBSD 기본 셸인 ksh에 접속할 수 있는 대화형 셸, 마이크로VM 안에서 소프트웨어를 컴파일하기 위한 컴파일러와 헤더·라이브러리·빌드 도구(gcc, make, ld 등), 그리고 편집·디렉터리 탐색·컴파일·디버깅에 사용할 Emacs임.
  • NetBSD에는 vi 1.81.6-2013-11-20nb4가 사전 설치되어 있지만, 필요한 편집기는 Emacs임.

Ubuntu에서 NetBSD 마이크로VM 만들기

smolBSD 설치

  • Debian 기반 시스템과 macOS에서 smolBSD를 설치하는 자세한 절차는 smolBSD GitHub 페이지에 안내되어 있음.

원시 마이크로VM 이미지(.img) 빌드

  • 최소 NetBSD 기반 마이크로VM 서비스를 정의하는 smolBSD 설정 파일인 SMOLerfile로 원시 NetBSD 이미지를 빌드함. FROM, RUN, CMD 등 익숙한 Dockerfile 명령을 지원하지만 Dockerfile 전체 참조 사양을 구현하지는 않으며, 여기서 필요한 기능에는 충분함.
  • Dockerfile.devsh라는 SMOLerfile을 호스트의 $NETBSD_ROOT/smolerfiles 디렉터리에 저장함. 호스트의 NETBSD_ROOT 환경 변수는 smolBSD 설치 디렉터리를 가리킴.
  • FROM base,etc,comp로 기본 시스템, 시스템 설정 파일, 컴파일러·도구 모음을 이미지 구성에 포함함. base에는 최소 NetBSD 시스템에 필요한 핵심 실행 파일·공유 라이브러리·유틸리티가 들어가며 필수 항목임. etc는 처음부터 완전한 설치를 구성하는 데 필요한 기본 설정 뼈대를 제공함. comp에는 C·C++ 컴파일러, /usr/include 헤더, 정적 라이브러리, 링커, make와 관련 개발 도구가 포함됨.
  • 서비스 이름은 devsh로 지정하고, 필요한 콘텐츠만 남기도록 이미지를 최소화하면서 추가 512MB를 확보함. pkgin, pkg_tarup, pkg_install, sqlite3, rsync, curl을 추가 패키지로 지정하고, 콘솔에는 pty를 사용하며 초기 디스크 크기는 2GB로 설정함. 이미지 크기는 최소 구성에 추가 공간을 더한 크기로 줄어듦.
  • 호스트 이름 기본값은 bsd, 사용자 셸은 /bin/ksh, 사용자 이름은 magnolia로 설정함. 대화형 셸은 smolBSD 배포판이 제공하는 smolerfiles/usershell.inc를 INCLUDE로 불러옴. INCLUDE는 SMOLerfile 확장 기능임.
  • 사용자 홈 디렉터리에 최소 Emacs 설정 파일을 만들고 소유자를 magnolia로 설정한 뒤 권한을 600으로 제한함. 설정에는 열 번호 표시, 괄호 강조, 현재 줄 강조, 데스크톱 상태와 명령 기록 저장, 선택 영역 교체, 들여쓰기·줄바꿈·마우스 휠 동작 등이 포함됨. 줄 번호는 기본적으로 끄고 C-c l로 전환하도록 설정함.
  • C 편집 기본 스타일은 stroustrup으로, 들여쓰기 폭과 기본 오프셋은 4칸으로 설정하며 네임스페이스와 외부 언어 블록의 오프셋은 0으로 지정함. 메뉴 막대와 백업 파일, 자동 저장은 끔.
  • 셸에서 Emacs 키를 사용하도록 /etc/shrc에 set -o emacs를 추가하고, ll을 ls -la 별칭으로 지정함.
  • pkgin을 갱신한 뒤 X 윈도우 시스템이 없는 emacs-nox11을 설치함. 기본 bsdmake 대신 사용할 GNU make 패키지 gmake도 설치함.
  • 기본 셸인 ksh에 사용자로 로그인하도록 CMD를 설정함.
  • Emacs에 M-a를 줄 처음으로, M-e를 줄 끝으로 이동하는 키 바인딩으로 추가함. QEMU는 문자 백엔드 멀티플렉서의 특수 이스케이프 키로 Ctrl-A를 사용하며, Linux·macOS·Windows·BSD와 주요 CPU 아키텍처에서 사용할 수 있는 오픈소스 머신 에뮬레이터이자 가상화 도구임.
  • 따라서 Ctrl-A를 누르면 키 입력이 Emacs로 전달되지 않고 VM 동작을 중단하거나 방해함. Ctrl-A를 두 번 누르면 첫 입력은 QEMU가 소비하고 두 번째 입력은 게스트로 전달되어 실제 C-a를 보낼 수 있음. 두 번 누르는 방식이 손에 익지 않아 M-a를 추가했으며, 기억하기 쉽지는 않지만 M-e도 일관성을 위해 함께 추가함.
  • 빌드 스크립트는 NETBSD_ROOT가 설정되지 않았거나 서비스 인수가 없으면 각각 오류 메시지를 출력하고 종료함. 인수가 있으면 smolerfiles/Dockerfile.<서비스>를 이미지로 지정하고 NETBSD_ROOT 디렉터리에서 ./smoler.sh build를 실행함.

NetBSD 마이크로VM에서 Emacs 실행

  • 실행 스크립트도 NETBSD_ROOT와 서비스 인수를 검사함. 조건이 충족되면 NETBSD_ROOT로 이동해 ./startnb.sh를 실행하며, 빌드 단계에서 자동 생성되는 etc/<서비스>.conf 설정 파일을 사용함.
  • 실행 옵션은 -P로 PTY 터미널을 사용하고, -n 2로 ksh에서 su처럼 VM을 종료할 수 있도록 설정하며, -w ${HOME}/workspace/devel로 호스트 경로를 게스트의 /mnt/에 마운트함. 종료 기능은 . /etc/include/shutdown으로 사용할 수 있음.
  • 호스트 foxtrot에서 devsh 마이크로VM을 실행한 결과, 구형 Dell Latitude 7400에서 NetBSD 커널이 26ms 만에 시작하고 전체 VM의 초기 호스트 메모리 사용량은 180MB임.
  • 마이크로VM 안에서 Emacs를 실행할 수 있음.