Our RISC-V emulator PasRISCV
RISC-V 에뮬레이터 PasRISCV
게임 SEEDS는 자체 제작한 Object Pascal 기반 RISC-V 에뮬레이터 PasRISCV로 Alpine Linux를 실행하고, 게임 안에서 Linux 프로그램을 구동합니다. 글은 CPU·저장장치·그래픽·오디오·네트워크 에뮬레이션과 게임 연동 구조를 소개합니다.
- 주제
AI 요약
게임 SEEDS는 플레이어가 기지 컴퓨터에서 여는 도구를 실제 Linux 프로그램으로 구현했습니다. Windows에서도 실행되는 이 프로그램들은 Alpine Linux를 구동하는 RISC-V 64비트 가상 시스템 안에서 돌아갑니다. 이 글은 게임에 통합한 자체 에뮬레이터 PasRISCV의 구성과 기능을 설명합니다. PasRISCV와 프런트엔드 pasriscvemu는 Object Pascal로 작성했고, 관대한 zlib 라이선스로 공개했습니다.
전체 가상 머신 에뮬레이션
PasRISCV는 사용자 공간만 흉내 내는 대신 디스플레이와 저장장치, 인터럽트까지 갖춘 가상 머신 전체를 구현합니다. 실행 중인 커널은 실제 하드웨어 시스템에서 구동되는 것처럼 동작합니다. 대상은 64비트 RISC-V 명령어 집합 구조(ISA)입니다. 글은 RISC-V가 공개 표준이며 ISA 사용에 로열티가 없다고 설명합니다. 에뮬레이터는 SMP/MultiHART, RV64GC, RVA23를 지원하고 Hypervisor와 Vector 확장, 스칼라·벡터 암호화 확장도 포함합니다.
CPU 실행에는 인터프리터와 트레이싱 JIT 컴파일러를 함께 쓰는 하이브리드 방식을 적용했습니다. 현재 JIT는 x86-64 호스트에서만 작동하지만, 실제로 마주치는 명령어의 약 99%를 지원합니다. 부동소수점 연산은 호스트 FPU로 처리할 수 있습니다. 다만 IEEE 754-2008이 규정한 일부 동작은 x86 부동소수점 하드웨어에서 정확히 재현되지 않습니다. 엄격한 동작이 필요하면 소프트웨어 부동소수점과 인터프리터를 결합하는 선택 모드를 사용할 수 있습니다.
Linux 부팅과 저장장치
SEEDS에서 새 게임을 시작하거나 저장된 게임을 불러오면 가상 머신이 백그라운드에서 부팅을 시작합니다. Linux 커널은 OpenSBI에서 바로 부팅하거나, OpenSBI에서 U-Boot를 거쳐 부팅할 수 있습니다. 직접 부팅하는 방식은 필요한 모듈과 디스크 이미지가 initramfs 안에 있어야 합니다. 그래서 PasRISCV는 OpenSBI와 U-Boot를 잇는 구성을 택해 일반 디스크 이미지를 사용합니다.
게스트 시스템에는 VirtIO Block 장치나 PCIe 기반 NVMe 장치로 디스크를 연결합니다. 디스크는 읽기·쓰기가 가능하며 읽기 전용으로도 연결할 수 있습니다. 게임 업데이트 때 루트 파티션을 교체하고 플레이어 데이터는 별도 파티션에 남기는 데 이 방식이 쓰입니다. 현재 별도 파티션에는 미니게임 최고 점수 등이 저장됩니다. VirtIO-9P와 VirtIO-FS로 호스트 디렉터리도 게스트에 공유합니다. 개발자는 호스트에서 도구를 컴파일한 뒤 에뮬레이터를 재시작하지 않고 게스트에서 바로 실행할 수 있습니다.
게임은 자체 커널 빌드와 함께 일부 수정한 Alpine Linux v3.23.6을 사용합니다. 최근 기본 Alpine 이미지도 문제없이 실행된다고 합니다.
그래픽과 오디오
게임 화면은 커스텀 MMIO 디스플레이 버퍼에 연결한 SimpleFB 프레임버퍼 장치로 픽셀을 표시합니다. 단순한 프레임버퍼 출력은 속도가 충분하고 게임 안에서 커스텀 셰이더를 적용하기도 편합니다. 스캔라인과 인광 잔광 같은 복고풍 효과도 이 방식으로 처리합니다. PasRISCV는 EDID와 2D 기능을 지원하는 VirtIO GPU, 실험 단계의 3D/VirGL, Bochs VBE와 Cirrus Logic 장치도 제공합니다. 가상 머신에서 Motif Window Manager를 포함한 X 서버도 실행했지만, 대부분의 기기에서는 사용하기에 느립니다.
오디오 장치로는 CMI8738과 FM801을 에뮬레이션합니다. 두 장치 모두 PCM, OPL2, OPL3를 지원하고 Intel HDA와 VirtIO sound도 구현했습니다. 글은 FM 합성 계열 OPL과 OPN이 1980년대 중후반부터 1990년대 초 콘솔·PC 음악에 영향을 줬다고 소개합니다. SEEDS의 우주 게임 Space Prowler는 OPL3 합성과 PCM 드럼 샘플을 함께 쓴 칩튠 테마곡을 제공합니다. 제작자는 Linux 콘솔에서 동작하는 음악 편집기 chOPLin으로 곡을 만들었으며, 편집기를 다듬은 뒤 오픈소스로 공개할 계획이라고 밝혔습니다.
게임과 게스트의 통신
게임과 가상 머신은 Linux Virtual Sockets(vsock)로 통신합니다. 데이터는 빠른 직렬화를 위한 소형 바이너리 형식으로 주고받습니다. 이 형식은 개념상 바이너리 JSON과 비슷합니다. 메시지 우선순위 큐와 요청·응답 참조 기능도 있어 긴급 메시지와 일반 교환을 구분합니다. 예를 들어 가상 컴퓨터 안의 클라이언트 프로그램은 행성 지형 정보나 동물 위치를 요청하고, 가상 머신을 실행하는 게임은 갱신된 데이터를 돌려줍니다.
게스트 Linux에는 Slirp와 비슷한 자체 사용자 공간 NAT 네트워크 구현이 있으며, 외부 라이브러리 없이 IPv4와 IPv6를 지원합니다. 따라서 Alpine 패키지 관리자인 apk로 패키지를 설치할 수 있고, 게임 제작 도구도 서명된 Alpine 패키지로 설치합니다. 다만 보안과 격리, 재현성을 위해 게임에서는 당분간 네트워크를 끕니다. 가상 머신이 외부로 연결하지 못하도록 제한합니다.
PasRISCV에는 자체 디스어셈블러와 디버거가 있고 GDB 서버 역할도 합니다. 구현은 아직 일부에 그치지만 GDB 원격 디버깅 프로토콜을 지원하는 도구와 연동할 수 있습니다. 제작자는 플레이어가 Linux 환경에서 Ruby, Python, Rust, C, C++, Go 등을 사용해 행성을 자동화하고 바꾸는 기능도 준비 중이라고 설명합니다. 현재 게임의 주된 방향은 아니며, 직접 행성을 만드는 재미도 있다고 덧붙입니다.
Lobsters 반응
- @MarkMLl — 이 프로젝트가 오래됐다는 점 말고도 Pascal로 작성한 이유가 있나요? 트집 잡으려는 건 아니지만, 요즘 Pascal은 자연스러운 선택이라고 보기 어렵습니다.
원문: Against All Odds Games / 번역·요약: Trawling