우리가 만든 RISC-V 에뮬레이터 PasRISCV
요약
본 글은 게임 SEEDS에 사용되는 RISC-V 에뮬레이터 PasRISCV를 소개합니다. PasRISCV는 Object Pascal로 작성되었으며, 사용자 공간뿐 아니라 디스플레이, 스토리지 등 완전한 하드웨어 시스템을 에뮬레이션하는 것이 특징입니다. 이 에뮬레이터는 64비트 RISC-V ISA 기반으로 하며, Hypervisor 및 Vector 확장 기능 등을 지원합니다.
핵심 포인트
- PasRISCV는 Object Pascal로 구현된 오픈 소스 RISC-V 에뮬레이터입니다.
- 사용자 공간을 넘어 완전한 하드웨어 시스템 수준의 에뮬레이션을 제공합니다.
- 64비트 RISC-V ISA를 기반으로 하며, Hypervisor 및 Vector 확장 기능을 지원합니다.
- CPU는 인터프리터와 트레이싱 JIT 컴파일러가 결합된 하이브리드 방식을 사용합니다.
우리의 RISC-V 에뮬레이터 PasRISCV
기술/개발 블로그
우리의 RISC-V 에뮬레이터 PasRISCV
여러분은 이미 저희 게임 SEEDS가 플레이어의 인게임 도구를 실행하는 완전한 에뮬레이션 Linux 시스템을 포함하고 있다는 것을 알고 계실 겁니다. 예를 들어, 홈베이스 컴퓨터에서 프로그램 선택기를 통해 행성 개요 및 통계에 접근한다면, 이 앱들은 네이티브 Linux 프로그램입니다. 비록 여러분이 Windows 기기에서 게임을 플레이하더라도, 이 ELF 바이너리들은 Alpine Linux 배포판을 실행하는 에뮬레이션 RISC-V 64비트 시스템에서 실행됩니다.
이번 기회에 저희의 에뮬레이터에 대해 살짝 내부를 보여드리고 말씀드리고 싶습니다. 이것은 Object Pascal로 프로그래밍되었으며 누구나 무료 오픈 소스 소프트웨어(FOSS)로 접근할 수 있는 사내 PasRISCV 프로젝트를 통해 구동됩니다. 여러분을 초대하여 그 소스를 확인하고 어쩌면 사용해 보시길 바랍니다. PasRISCV와 그 프론트엔드 동반 프로그램인 pasriscvemu는 관대한 zlib 라이선스 하에 라이선스가 부여되었습니다.

에뮬레이션
먼저, 저희가 할 수 있었던 방법은 두 가지였습니다. 사용자 공간(userspace)만 에뮬레이션하거나, 완전한 가상 머신을 에뮬레이션하는 것이었습니다. PasRISCV의 경우 후자를 선택하여 디스플레이 및 스토리지 장치, 인터럽트 등 모든 것을 마지막 한 가지까지 포함하는 기계를 에뮬레이션합니다. 따라서 실행되는 커널에게는 비록 가상일지라도 완전한 하드웨어 시스템처럼 보입니다.
에뮬레이션된 기계는 64비트 RISC-V 명령어 세트 아키텍처(ISA)를 사용하며, 이는 x86이나 ARM과 같은 대부분의 독점 아키텍처와 달리 오픈 표준이며 관대한 라이선스 하에서 완전히 개방적이고 자유롭게 사용할 수 있습니다. 이것은 만약 여러분이 이를 기반으로 새로운 하드웨어 장치를 구축한다면, RISC-V ISA 자체를 사용하는 데 대해 어떠한 로열티도 지불할 필요가 없다는 것을 의미합니다.
기술적인 측면에서, 이 시스템은 Hypervisor와 Vector 확장 기능을 포함하여 SMP/MultiHART, RV64GC, RVA23 지원을 제공하며, 추가적인 스칼라 및 벡터 암호화 확장 기능도 갖추고 있습니다. 그럼에도 불구하고, 에뮬레이션된 모든 기능을 나열하고 설명하는 것은 이 소개의 범위를 벗어나므로, 전체 개요는 PasRISCV 저장소로 가시기 바랍니다.
CPU 및 FPU
CPU를 에뮬레이션하기 위해, 에뮬레이터는 인터프리터와 트레이싱 JIT 컴파일러를 결합한 하이브리드 접근 방식을 사용합니다. 현재 JIT는 x86-64 호스트로 제한되어 있지만, 우리가 접하는 명령어의 약 99%가 이를 지원합니다.
예를 들어, 부동 소수점 연산은 호스트 FPU에 의해 직접 처리될 수 있습니다. 더 엄격한 동작이 필요한 경우, PasRISCV는 소프트웨어 부동 소수점을 인터프리터와 결합하는 선택적 모드를 제공합니다. 이는 IEEE 754-2008에서 x86 부동 소수점 하드웨어로는 정확하게 재현할 수 없는 일부 동작을 지정하기 때문에 존재합니다.

아, 그리고 오타를 발견하세요…

Linux
SEEDS에서 새 게임을 시작하거나 저장된 게임을 로드하면, 백그라운드에서 에뮬레이터가 시스템 부팅을 진행합니다. 일반적인 Linux 커널은 OpenSBI를 통해 직접 또는 U-Boot를 통해 두 가지 방식으로 부팅할 수 있습니다. OpenSBI에서 커널로의 직접 부팅을 위해서는 필요한 모든 모듈과, 더 중요하게는 디스크 이미지가 현재 initramfs에 존재해야 합니다. 따라서 우리는 보다 전통적인 OpenSBI부터 U-Boot 체인을 사용하며, 이것이 커널을 로드하고 실행합니다. 이를 통해 시스템을 담고 있는 일반적인 디스크 이미지를 가질 수 있습니다.
이러한 이미지들은 게스트 시스템에 VirtIO Block 장치 또는 PCIe를 통한 에뮬레이션된 NVMe 하드웨어로 연결될 수 있습니다. 디스크는 읽기-쓰기 모드로 정상 작동할 수 있지만, 읽기 전용으로만 연결하는 것도 가능합니다. 이는 특히 저희 게임의 경우 유용한데, 게임 업데이트에 의해 교체되는 루트 파티션을 가질 수 있기 때문입니다. 게다가, 미니게임의 하이 스코어 테이블과 같은 플레이어 고유 데이터를 보관하기 위해 별도의 사용자 파티션을 유지하는데, 이는 게임 상태 자체에 해당 상태를 담을 적절한 메커니즘이 마련될 때까지의 방편입니다.
호스트 디렉토리 역시 VirtIO-9P 또는 VirtIO-FS를 통해 게스트 내부에서 사용할 수 있도록 만들 수 있습니다. 이는 개발 과정 중에 특히 편리합니다. 왜냐하면 호스트에서 도구를 직접 컴파일한 다음, 에뮬레이션된 머신 내부에서 즉시 접근할 수 있기 때문입니다. 그렇지 않았다면, 메모리에 바이너리를 직접 주입하거나, 별도의 교환 메커니즘을 사용해야 하거나, 심지어 최악의 경우 작은 변경 사항이 있을 때마다 에뮬레이터를 재부팅해야 했을 것입니다.
저희 게임은 저희 중 일부가 서버에서 실행하는 것을 좋아하는 간결하고 훌륭한 Alpine Linux v3.23.6 시스템의 약간 수정된 버전을 사용하며, 여기에 커스텀 커널 빌드를 함께 사용합니다. 하지만 최근의 순정 Alpine 이미지도 문제없이 작동합니다.
그래픽스
그래픽스의 경우, 저희 가상 게임 화면은 현재 에뮬레이터 프레임버퍼 장치를 사용하여 표시된 픽셀에 접근합니다. 더 구체적으로는 커스텀 MMIO 디스플레이 버퍼를 백업으로 사용하는 SimpleFB를 사용합니다.
PasRISCV는 여러 다른 가상 그래픽 어댑터도 제공합니다. 한 가지 옵션은 EDID와 2D 기능뿐만 아니라 실험적인 3D/VirGL 기능을 지원하는 VirtIO GPU입니다. PCI 에뮬레이션을 통해 Bochs VBE 및 Cirrus Logic과 같은 드라이버가 지원하는 장치들도 제공합니다. 저희는 심지어 VM에서 Motif Window Manager를 사용하는 X 서버를 실행해 보기도 했지만, 대부분의 기기에서는 실제로 사용하기에는 너무 느립니다.
하지만 저희 게임의 경우, 간단한 프레임버퍼 디스플레이가 매우 유용합니다. 충분히 빠르기 때문에 게임 내에서 커스텀 셰이더를 실행하여 그 출력을 처리할 수 있습니다. 이런 방식으로 스캔라인(scanlines), 인광체 발광(phosphor glow) 등 추가적인 레트로 효과—저는 아름답다고 말하고 싶지만, 물론 이는 플레이어의 눈에 달린 것—즉 80년대와 90년대의 시각적 열화를 더합니다.

오디오
물론 에뮬레이터는 오디오도 지원합니다. 저희는 CMI8738 및 FM801과 같은 레트로 사운드 카드를 PCM, OPL2, OPL3으로 에뮬레이션하며 모두 사용할 수 있습니다. Intel HDA와 VirtIO 사운드도 지원됩니다. OPL과 OPN은 80년대 중후반과 90년대 초반의 다양한 콘솔 및 PC 사운드에 영향을 준 야마하(Yamaha) FM 합성 계열로, 밀접하게 관련되어 있습니다.
심지어 야마하 DX7 같은 전문 신시사이저조차도 관련된 FM 합성 칩으로 구동되었습니다. 최신 카드들은 PCM 재생 기능을 갖추는 경우가 많았고, FM 합성은 종종 레거시 기능으로만 유지되다가 나중의 카드들에서는 완전히 제외되었습니다. PCM은 샘플 재생을 가능하게 했고, 이는 빠르게—그리고 제 생각에는 유감스럽게도—독특한 OPL 칩튠 사운드를 대체했습니다. 당시 대부분의 사람들은 사운드 칩 대신 샘플을 사용하는 더 사실적인 소리의 음악에 매료되었습니다. 그래서 점점 더 많은 게임이 새로운 샘플 기반 사운드를 사용하게 되었습니다.
오늘날 OPL 사운드는 컴퓨터 음악을 좋아하는 레트로 커뮤니티에서 비교적 큰 팬층을 가지고 있습니다. 다양한 웹사이트와 아카이브는 80년대와 90년대 칩튠 음악의 방대한 라이브러리에 쉽게 접근할 수 있게 해줍니다. 저희의 다소 레트로한 80년대 테마에 맞춰, SEEDS 컴퓨터에서 실행되는 작은 개념 증명(proof-of-concept) 우주 게임은 Space Prowler라고 불립니다. 이 게임은 매력적인 레트로 픽셀 스타일을 특징으로 하며, 드럼에는 OPL3 합성과 PCM 사운드 샘플을 결합한 전용 칩튠 타이틀 테마를 가지고 있습니다.
실제로 이 음악을 작곡하기 위해 chOPLin이라는 작은 에디터를 만들었습니다. 소위 트래커는 일반 Linux 콘솔에서 완전히 실행됩니다. 심지어 컴퓨터의 80×50 문자, 640×400 픽셀 프레임버퍼 콘솔 내에서도 작동하지만, 음악을 이런 방식으로 만드는 것은 다소 번거롭습니다. 시간이 날 때 트래커를 자유 오픈 소스 소프트웨어로 공개할 계획입니다. 아직 다듬고 사용자 친화적으로 만들 부분이 남아있기 때문입니다.
통합(Integration)
에뮬레이션된 머신과 주변 게임 간의 연결은 통신을 위해 Linux Virtual Sockets (vsock)를 사용합니다. 게다가, 우리는 작은 바이너리 직렬화 형식(binary serialization format)을 사용합니다. 개념적으로는 JSON의 바이너리 버전과 같으며, 빠른 (역)직렬화에 고도로 최적화되어 있습니다. 데이터는 일반 네트워크 프로토콜처럼 양방향으로 흐를 수 있습니다. 또한, 작은 우선순위 큐와 메시지 참조 시스템을 갖추고 있어 긴급하고 우선순위가 지정된 메시지는 물론 요청-응답 교환도 처리할 수 있습니다.
예를 들어, 게임 내 컴퓨터가 행성 구체를 표시한다고 상상해 보세요. 가상 컴퓨터 안에 있는 클라이언트 프로그램은 지형 정보나 동물의 위치와 같은 항목에 대한 업데이트된 정보를 요청하고, 이 데이터를 가상 머신을 실행하는 게임으로부터 받을 수 있습니다.
또한, 플레이어가 자동화를 통해 전체 행성을 프로그래밍하고, 재구성하고, 채울 수 있도록 대부분의 배선 작업이 준비되어 있습니다. 일반 Linux 시스템이기 때문에 Ruby, Python 또는 심지어 Rust, C, C++, Go를 사용하여 당신의 세계를 변경하고 자동화할 수 있습니다.
그렇긴 하지만, 현재로서는 이것이 게임의 주된 콘셉트는 아닙니다. 손으로 무언가를 만들고 행성을 아름다운 형태로 수동으로 모양을 만드는 것에서 오는 만족감이 크기 때문입니다.


네트워킹(Networking)
에뮬레이터는 자체 Slirp과 유사한 사용자 공간 NAT 구현을 통해 실제 네트워크 기능을 갖추고 있습니다. 이를 위해 외부 라이브러리에 의존하지 않으며, IPv4와 IPv6를 모두 지원합니다.
그 결과, 에뮬레이션된 리눅스 시스템은 정상적인 네트워크 접속이 가능합니다. 예를 들어, 가상 머신 내부에서 Alpine의 패키지 관리자인 apk update와 apk install을 실행하여 직접 패키지를 설치할 수 있습니다. 저희 자체 도구들 역시 서명된 Alpine 패키지로 설치됩니다.
하지만 네트워킹 기능은 당분간 게임 내에서는 비활성화되어 있습니다. 이는 주로 보안, 격리, 그리고 재현성(reproducibility)을 위한 것이며, VM이 외부로 어떠한 연결도 할 수 없도록 하기 위함입니다.
디버깅 (Debugging)
PasRISCV는 자체 커스텀 디어셈블러와 디버거를 포함하고 있습니다. 게다가 GDB 서버 역할도 수행할 수 있습니다. 현재 부분적으로만 구현되었지만, 이는 사용자가 선호하는 디버깅 도구를 사용할 수 있다는 의미이며, 단지 해당 도구가 GDB의 원격 디버깅 프로토콜(remote debugging protocol)을 지원해야 합니다.
마무리 (Coda)
SEEDS와 PasRISCV가 어떻게 함께 작동하여 Naxiah가 우주에서 여정을 떠나는 몰입감 있는 경험을 위해 완전히 사용 가능한 게임 내 리눅스 시스템을 제공하는지에 대한 통찰력을 얻으셨기를 바랍니다. 또한, 저희(그리고 아마도 가까운 미래에는 여러분의) 프로그램을 실행할 수 있게 해줍니다.
그리고 이 점은 언급할 필요가 없다고 생각합니다. 바로 리눅스가 저희 게임을 플레이하기 위한 일급 플랫폼(first-class platform)이라는 것입니다.
재미있는 사실: 크리에이티브 및 개발 팀의 3분의 2는 리눅스를 주 운영 체제(OS)로 사용합니다. ;)
AI 자동 생성 콘텐츠
본 콘텐츠는 HN Show HN (AI)의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기